0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007
0008 #include <linux/bitmap.h>
0009 #include <linux/init.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/printk.h>
0013 #include <linux/slab.h>
0014 #include <linux/string.h>
0015 #include <linux/uaccess.h>
0016
0017 #include "../tools/testing/selftests/kselftest_module.h"
0018
0019 KSTM_MODULE_GLOBALS();
0020
0021 static char pbl_buffer[PAGE_SIZE] __initdata;
0022 static char print_buf[PAGE_SIZE * 2] __initdata;
0023
0024 static const unsigned long exp1[] __initconst = {
0025 BITMAP_FROM_U64(1),
0026 BITMAP_FROM_U64(2),
0027 BITMAP_FROM_U64(0x0000ffff),
0028 BITMAP_FROM_U64(0xffff0000),
0029 BITMAP_FROM_U64(0x55555555),
0030 BITMAP_FROM_U64(0xaaaaaaaa),
0031 BITMAP_FROM_U64(0x11111111),
0032 BITMAP_FROM_U64(0x22222222),
0033 BITMAP_FROM_U64(0xffffffff),
0034 BITMAP_FROM_U64(0xfffffffe),
0035 BITMAP_FROM_U64(0x3333333311111111ULL),
0036 BITMAP_FROM_U64(0xffffffff77777777ULL),
0037 BITMAP_FROM_U64(0),
0038 BITMAP_FROM_U64(0x00008000),
0039 BITMAP_FROM_U64(0x80000000),
0040 };
0041
0042 static const unsigned long exp2[] __initconst = {
0043 BITMAP_FROM_U64(0x3333333311111111ULL),
0044 BITMAP_FROM_U64(0xffffffff77777777ULL),
0045 };
0046
0047
0048 static const unsigned long exp2_to_exp3_mask[] __initconst = {
0049 BITMAP_FROM_U64(0x008000020020212eULL),
0050 };
0051
0052 static const unsigned long exp3_0_1[] __initconst = {
0053 BITMAP_FROM_U64(0x33b3333311313137ULL),
0054 };
0055
0056 static const unsigned long exp3_1_0[] __initconst = {
0057 BITMAP_FROM_U64(0xff7fffff77575751ULL),
0058 };
0059
0060 static bool __init
0061 __check_eq_uint(const char *srcfile, unsigned int line,
0062 const unsigned int exp_uint, unsigned int x)
0063 {
0064 if (exp_uint != x) {
0065 pr_err("[%s:%u] expected %u, got %u\n",
0066 srcfile, line, exp_uint, x);
0067 return false;
0068 }
0069 return true;
0070 }
0071
0072
0073 static bool __init
0074 __check_eq_bitmap(const char *srcfile, unsigned int line,
0075 const unsigned long *exp_bmap, const unsigned long *bmap,
0076 unsigned int nbits)
0077 {
0078 if (!bitmap_equal(exp_bmap, bmap, nbits)) {
0079 pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n",
0080 srcfile, line,
0081 nbits, exp_bmap, nbits, bmap);
0082 return false;
0083 }
0084 return true;
0085 }
0086
0087 static bool __init
0088 __check_eq_pbl(const char *srcfile, unsigned int line,
0089 const char *expected_pbl,
0090 const unsigned long *bitmap, unsigned int nbits)
0091 {
0092 snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap);
0093 if (strcmp(expected_pbl, pbl_buffer)) {
0094 pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n",
0095 srcfile, line,
0096 expected_pbl, pbl_buffer);
0097 return false;
0098 }
0099 return true;
0100 }
0101
0102 static bool __init
0103 __check_eq_u32_array(const char *srcfile, unsigned int line,
0104 const u32 *exp_arr, unsigned int exp_len,
0105 const u32 *arr, unsigned int len) __used;
0106 static bool __init
0107 __check_eq_u32_array(const char *srcfile, unsigned int line,
0108 const u32 *exp_arr, unsigned int exp_len,
0109 const u32 *arr, unsigned int len)
0110 {
0111 if (exp_len != len) {
0112 pr_warn("[%s:%u] array length differ: expected %u, got %u\n",
0113 srcfile, line,
0114 exp_len, len);
0115 return false;
0116 }
0117
0118 if (memcmp(exp_arr, arr, len*sizeof(*arr))) {
0119 pr_warn("[%s:%u] array contents differ\n", srcfile, line);
0120 print_hex_dump(KERN_WARNING, " exp: ", DUMP_PREFIX_OFFSET,
0121 32, 4, exp_arr, exp_len*sizeof(*exp_arr), false);
0122 print_hex_dump(KERN_WARNING, " got: ", DUMP_PREFIX_OFFSET,
0123 32, 4, arr, len*sizeof(*arr), false);
0124 return false;
0125 }
0126
0127 return true;
0128 }
0129
0130 static bool __init __check_eq_clump8(const char *srcfile, unsigned int line,
0131 const unsigned int offset,
0132 const unsigned int size,
0133 const unsigned char *const clump_exp,
0134 const unsigned long *const clump)
0135 {
0136 unsigned long exp;
0137
0138 if (offset >= size) {
0139 pr_warn("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u\n",
0140 srcfile, line, size, offset);
0141 return false;
0142 }
0143
0144 exp = clump_exp[offset / 8];
0145 if (!exp) {
0146 pr_warn("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0",
0147 srcfile, line, offset);
0148 return false;
0149 }
0150
0151 if (*clump != exp) {
0152 pr_warn("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX",
0153 srcfile, line, exp, *clump);
0154 return false;
0155 }
0156
0157 return true;
0158 }
0159
0160 static bool __init
0161 __check_eq_str(const char *srcfile, unsigned int line,
0162 const char *exp_str, const char *str,
0163 unsigned int len)
0164 {
0165 bool eq;
0166
0167 eq = strncmp(exp_str, str, len) == 0;
0168 if (!eq)
0169 pr_err("[%s:%u] expected %s, got %s\n", srcfile, line, exp_str, str);
0170
0171 return eq;
0172 }
0173
0174 #define __expect_eq(suffix, ...) \
0175 ({ \
0176 int result = 0; \
0177 total_tests++; \
0178 if (!__check_eq_ ## suffix(__FILE__, __LINE__, \
0179 ##__VA_ARGS__)) { \
0180 failed_tests++; \
0181 result = 1; \
0182 } \
0183 result; \
0184 })
0185
0186 #define expect_eq_uint(...) __expect_eq(uint, ##__VA_ARGS__)
0187 #define expect_eq_bitmap(...) __expect_eq(bitmap, ##__VA_ARGS__)
0188 #define expect_eq_pbl(...) __expect_eq(pbl, ##__VA_ARGS__)
0189 #define expect_eq_u32_array(...) __expect_eq(u32_array, ##__VA_ARGS__)
0190 #define expect_eq_clump8(...) __expect_eq(clump8, ##__VA_ARGS__)
0191 #define expect_eq_str(...) __expect_eq(str, ##__VA_ARGS__)
0192
0193 static void __init test_zero_clear(void)
0194 {
0195 DECLARE_BITMAP(bmap, 1024);
0196
0197
0198 memset(bmap, 0xff, 128);
0199
0200 expect_eq_pbl("0-22", bmap, 23);
0201 expect_eq_pbl("0-1023", bmap, 1024);
0202
0203
0204 bitmap_clear(bmap, 0, 9);
0205 expect_eq_pbl("9-1023", bmap, 1024);
0206
0207 bitmap_zero(bmap, 35);
0208 expect_eq_pbl("64-1023", bmap, 1024);
0209
0210
0211 bitmap_clear(bmap, 79, 19);
0212 expect_eq_pbl("64-78,98-1023", bmap, 1024);
0213
0214 bitmap_zero(bmap, 115);
0215 expect_eq_pbl("128-1023", bmap, 1024);
0216
0217
0218 bitmap_zero(bmap, 1024);
0219 expect_eq_pbl("", bmap, 1024);
0220 }
0221
0222 static void __init test_fill_set(void)
0223 {
0224 DECLARE_BITMAP(bmap, 1024);
0225
0226
0227 memset(bmap, 0x00, 128);
0228
0229 expect_eq_pbl("", bmap, 23);
0230 expect_eq_pbl("", bmap, 1024);
0231
0232
0233 bitmap_set(bmap, 0, 9);
0234 expect_eq_pbl("0-8", bmap, 1024);
0235
0236 bitmap_fill(bmap, 35);
0237 expect_eq_pbl("0-63", bmap, 1024);
0238
0239
0240 bitmap_set(bmap, 79, 19);
0241 expect_eq_pbl("0-63,79-97", bmap, 1024);
0242
0243 bitmap_fill(bmap, 115);
0244 expect_eq_pbl("0-127", bmap, 1024);
0245
0246
0247 bitmap_fill(bmap, 1024);
0248 expect_eq_pbl("0-1023", bmap, 1024);
0249 }
0250
0251 static void __init test_copy(void)
0252 {
0253 DECLARE_BITMAP(bmap1, 1024);
0254 DECLARE_BITMAP(bmap2, 1024);
0255
0256 bitmap_zero(bmap1, 1024);
0257 bitmap_zero(bmap2, 1024);
0258
0259
0260 bitmap_set(bmap1, 0, 19);
0261 bitmap_copy(bmap2, bmap1, 23);
0262 expect_eq_pbl("0-18", bmap2, 1024);
0263
0264 bitmap_set(bmap2, 0, 23);
0265 bitmap_copy(bmap2, bmap1, 23);
0266 expect_eq_pbl("0-18", bmap2, 1024);
0267
0268
0269 bitmap_set(bmap1, 0, 109);
0270 bitmap_copy(bmap2, bmap1, 1024);
0271 expect_eq_pbl("0-108", bmap2, 1024);
0272
0273 bitmap_fill(bmap2, 1024);
0274 bitmap_copy(bmap2, bmap1, 1024);
0275 expect_eq_pbl("0-108", bmap2, 1024);
0276
0277
0278
0279
0280
0281 bitmap_fill(bmap2, 1024);
0282 bitmap_copy(bmap2, bmap1, 109);
0283 expect_eq_pbl("0-108,128-1023", bmap2, 1024);
0284
0285 bitmap_fill(bmap2, 1024);
0286 bitmap_copy(bmap2, bmap1, 97);
0287 expect_eq_pbl("0-108,128-1023", bmap2, 1024);
0288 }
0289
0290 #define EXP2_IN_BITS (sizeof(exp2) * 8)
0291
0292 static void __init test_replace(void)
0293 {
0294 unsigned int nbits = 64;
0295 unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG);
0296 DECLARE_BITMAP(bmap, 1024);
0297
0298 BUILD_BUG_ON(EXP2_IN_BITS < nbits * 2);
0299
0300 bitmap_zero(bmap, 1024);
0301 bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
0302 expect_eq_bitmap(bmap, exp3_0_1, nbits);
0303
0304 bitmap_zero(bmap, 1024);
0305 bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
0306 expect_eq_bitmap(bmap, exp3_1_0, nbits);
0307
0308 bitmap_fill(bmap, 1024);
0309 bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
0310 expect_eq_bitmap(bmap, exp3_0_1, nbits);
0311
0312 bitmap_fill(bmap, 1024);
0313 bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
0314 expect_eq_bitmap(bmap, exp3_1_0, nbits);
0315 }
0316
0317 #define PARSE_TIME 0x1
0318 #define NO_LEN 0x2
0319
0320 struct test_bitmap_parselist{
0321 const int errno;
0322 const char *in;
0323 const unsigned long *expected;
0324 const int nbits;
0325 const int flags;
0326 };
0327
0328 static const struct test_bitmap_parselist parselist_tests[] __initconst = {
0329 #define step (sizeof(u64) / sizeof(unsigned long))
0330
0331 {0, "0", &exp1[0], 8, 0},
0332 {0, "1", &exp1[1 * step], 8, 0},
0333 {0, "0-15", &exp1[2 * step], 32, 0},
0334 {0, "16-31", &exp1[3 * step], 32, 0},
0335 {0, "0-31:1/2", &exp1[4 * step], 32, 0},
0336 {0, "1-31:1/2", &exp1[5 * step], 32, 0},
0337 {0, "0-31:1/4", &exp1[6 * step], 32, 0},
0338 {0, "1-31:1/4", &exp1[7 * step], 32, 0},
0339 {0, "0-31:4/4", &exp1[8 * step], 32, 0},
0340 {0, "1-31:4/4", &exp1[9 * step], 32, 0},
0341 {0, "0-31:1/4,32-63:2/4", &exp1[10 * step], 64, 0},
0342 {0, "0-31:3/4,32-63:4/4", &exp1[11 * step], 64, 0},
0343 {0, " ,, 0-31:3/4 ,, 32-63:4/4 ,, ", &exp1[11 * step], 64, 0},
0344
0345 {0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4", exp2, 128, 0},
0346
0347 {0, "0-2047:128/256", NULL, 2048, PARSE_TIME},
0348
0349 {0, "", &exp1[12 * step], 8, 0},
0350 {0, "\n", &exp1[12 * step], 8, 0},
0351 {0, ",, ,, , , ,", &exp1[12 * step], 8, 0},
0352 {0, " , ,, , , ", &exp1[12 * step], 8, 0},
0353 {0, " , ,, , , \n", &exp1[12 * step], 8, 0},
0354
0355 {0, "0-0", &exp1[0], 32, 0},
0356 {0, "1-1", &exp1[1 * step], 32, 0},
0357 {0, "15-15", &exp1[13 * step], 32, 0},
0358 {0, "31-31", &exp1[14 * step], 32, 0},
0359
0360 {0, "0-0:0/1", &exp1[12 * step], 32, 0},
0361 {0, "0-0:1/1", &exp1[0], 32, 0},
0362 {0, "0-0:1/31", &exp1[0], 32, 0},
0363 {0, "0-0:31/31", &exp1[0], 32, 0},
0364 {0, "1-1:1/1", &exp1[1 * step], 32, 0},
0365 {0, "0-15:16/31", &exp1[2 * step], 32, 0},
0366 {0, "15-15:1/2", &exp1[13 * step], 32, 0},
0367 {0, "15-15:31/31", &exp1[13 * step], 32, 0},
0368 {0, "15-31:1/31", &exp1[13 * step], 32, 0},
0369 {0, "16-31:16/31", &exp1[3 * step], 32, 0},
0370 {0, "31-31:31/31", &exp1[14 * step], 32, 0},
0371
0372 {0, "N-N", &exp1[14 * step], 32, 0},
0373 {0, "0-0:1/N", &exp1[0], 32, 0},
0374 {0, "0-0:N/N", &exp1[0], 32, 0},
0375 {0, "0-15:16/N", &exp1[2 * step], 32, 0},
0376 {0, "15-15:N/N", &exp1[13 * step], 32, 0},
0377 {0, "15-N:1/N", &exp1[13 * step], 32, 0},
0378 {0, "16-N:16/N", &exp1[3 * step], 32, 0},
0379 {0, "N-N:N/N", &exp1[14 * step], 32, 0},
0380
0381 {0, "0-N:1/3,1-N:1/3,2-N:1/3", &exp1[8 * step], 32, 0},
0382 {0, "0-31:1/3,1-31:1/3,2-31:1/3", &exp1[8 * step], 32, 0},
0383 {0, "1-10:8/12,8-31:24/29,0-31:0/3", &exp1[9 * step], 32, 0},
0384
0385 {0, "all", &exp1[8 * step], 32, 0},
0386 {0, "0, 1, all, ", &exp1[8 * step], 32, 0},
0387 {0, "all:1/2", &exp1[4 * step], 32, 0},
0388 {0, "ALL:1/2", &exp1[4 * step], 32, 0},
0389 {-EINVAL, "al", NULL, 8, 0},
0390 {-EINVAL, "alll", NULL, 8, 0},
0391
0392 {-EINVAL, "-1", NULL, 8, 0},
0393 {-EINVAL, "-0", NULL, 8, 0},
0394 {-EINVAL, "10-1", NULL, 8, 0},
0395 {-ERANGE, "8-8", NULL, 8, 0},
0396 {-ERANGE, "0-31", NULL, 8, 0},
0397 {-EINVAL, "0-31:", NULL, 32, 0},
0398 {-EINVAL, "0-31:0", NULL, 32, 0},
0399 {-EINVAL, "0-31:0/", NULL, 32, 0},
0400 {-EINVAL, "0-31:0/0", NULL, 32, 0},
0401 {-EINVAL, "0-31:1/0", NULL, 32, 0},
0402 {-EINVAL, "0-31:10/1", NULL, 32, 0},
0403 {-EOVERFLOW, "0-98765432123456789:10/1", NULL, 8, 0},
0404
0405 {-EINVAL, "a-31", NULL, 8, 0},
0406 {-EINVAL, "0-a1", NULL, 8, 0},
0407 {-EINVAL, "a-31:10/1", NULL, 8, 0},
0408 {-EINVAL, "0-31:a/1", NULL, 8, 0},
0409 {-EINVAL, "0-\n", NULL, 8, 0},
0410
0411 };
0412
0413 static void __init test_bitmap_parselist(void)
0414 {
0415 int i;
0416 int err;
0417 ktime_t time;
0418 DECLARE_BITMAP(bmap, 2048);
0419
0420 for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) {
0421 #define ptest parselist_tests[i]
0422
0423 time = ktime_get();
0424 err = bitmap_parselist(ptest.in, bmap, ptest.nbits);
0425 time = ktime_get() - time;
0426
0427 if (err != ptest.errno) {
0428 pr_err("parselist: %d: input is %s, errno is %d, expected %d\n",
0429 i, ptest.in, err, ptest.errno);
0430 continue;
0431 }
0432
0433 if (!err && ptest.expected
0434 && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) {
0435 pr_err("parselist: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
0436 i, ptest.in, bmap[0],
0437 *ptest.expected);
0438 continue;
0439 }
0440
0441 if (ptest.flags & PARSE_TIME)
0442 pr_err("parselist: %d: input is '%s' OK, Time: %llu\n",
0443 i, ptest.in, time);
0444
0445 #undef ptest
0446 }
0447 }
0448
0449 static void __init test_bitmap_printlist(void)
0450 {
0451 unsigned long *bmap = kmalloc(PAGE_SIZE, GFP_KERNEL);
0452 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
0453 char expected[256];
0454 int ret, slen;
0455 ktime_t time;
0456
0457 if (!buf || !bmap)
0458 goto out;
0459
0460 memset(bmap, -1, PAGE_SIZE);
0461 slen = snprintf(expected, 256, "0-%ld", PAGE_SIZE * 8 - 1);
0462 if (slen < 0)
0463 goto out;
0464
0465 time = ktime_get();
0466 ret = bitmap_print_to_pagebuf(true, buf, bmap, PAGE_SIZE * 8);
0467 time = ktime_get() - time;
0468
0469 if (ret != slen + 1) {
0470 pr_err("bitmap_print_to_pagebuf: result is %d, expected %d\n", ret, slen);
0471 goto out;
0472 }
0473
0474 if (strncmp(buf, expected, slen)) {
0475 pr_err("bitmap_print_to_pagebuf: result is %s, expected %s\n", buf, expected);
0476 goto out;
0477 }
0478
0479 pr_err("bitmap_print_to_pagebuf: input is '%s', Time: %llu\n", buf, time);
0480 out:
0481 kfree(buf);
0482 kfree(bmap);
0483 }
0484
0485 static const unsigned long parse_test[] __initconst = {
0486 BITMAP_FROM_U64(0),
0487 BITMAP_FROM_U64(1),
0488 BITMAP_FROM_U64(0xdeadbeef),
0489 BITMAP_FROM_U64(0x100000000ULL),
0490 };
0491
0492 static const unsigned long parse_test2[] __initconst = {
0493 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xdeadbeef),
0494 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xbaadf00ddeadbeef),
0495 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0x0badf00ddeadbeef),
0496 };
0497
0498 static const struct test_bitmap_parselist parse_tests[] __initconst = {
0499 {0, "", &parse_test[0 * step], 32, 0},
0500 {0, " ", &parse_test[0 * step], 32, 0},
0501 {0, "0", &parse_test[0 * step], 32, 0},
0502 {0, "0\n", &parse_test[0 * step], 32, 0},
0503 {0, "1", &parse_test[1 * step], 32, 0},
0504 {0, "deadbeef", &parse_test[2 * step], 32, 0},
0505 {0, "1,0", &parse_test[3 * step], 33, 0},
0506 {0, "deadbeef,\n,0,1", &parse_test[2 * step], 96, 0},
0507
0508 {0, "deadbeef,1,0", &parse_test2[0 * 2 * step], 96, 0},
0509 {0, "baadf00d,deadbeef,1,0", &parse_test2[1 * 2 * step], 128, 0},
0510 {0, "badf00d,deadbeef,1,0", &parse_test2[2 * 2 * step], 124, 0},
0511 {0, "badf00d,deadbeef,1,0", &parse_test2[2 * 2 * step], 124, NO_LEN},
0512 {0, " badf00d,deadbeef,1,0 ", &parse_test2[2 * 2 * step], 124, 0},
0513 {0, " , badf00d,deadbeef,1,0 , ", &parse_test2[2 * 2 * step], 124, 0},
0514 {0, " , badf00d, ,, ,,deadbeef,1,0 , ", &parse_test2[2 * 2 * step], 124, 0},
0515
0516 {-EINVAL, "goodfood,deadbeef,1,0", NULL, 128, 0},
0517 {-EOVERFLOW, "3,0", NULL, 33, 0},
0518 {-EOVERFLOW, "123badf00d,deadbeef,1,0", NULL, 128, 0},
0519 {-EOVERFLOW, "badf00d,deadbeef,1,0", NULL, 90, 0},
0520 {-EOVERFLOW, "fbadf00d,deadbeef,1,0", NULL, 95, 0},
0521 {-EOVERFLOW, "badf00d,deadbeef,1,0", NULL, 100, 0},
0522 #undef step
0523 };
0524
0525 static void __init test_bitmap_parse(void)
0526 {
0527 int i;
0528 int err;
0529 ktime_t time;
0530 DECLARE_BITMAP(bmap, 2048);
0531
0532 for (i = 0; i < ARRAY_SIZE(parse_tests); i++) {
0533 struct test_bitmap_parselist test = parse_tests[i];
0534 size_t len = test.flags & NO_LEN ? UINT_MAX : strlen(test.in);
0535
0536 time = ktime_get();
0537 err = bitmap_parse(test.in, len, bmap, test.nbits);
0538 time = ktime_get() - time;
0539
0540 if (err != test.errno) {
0541 pr_err("parse: %d: input is %s, errno is %d, expected %d\n",
0542 i, test.in, err, test.errno);
0543 continue;
0544 }
0545
0546 if (!err && test.expected
0547 && !__bitmap_equal(bmap, test.expected, test.nbits)) {
0548 pr_err("parse: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
0549 i, test.in, bmap[0],
0550 *test.expected);
0551 continue;
0552 }
0553
0554 if (test.flags & PARSE_TIME)
0555 pr_err("parse: %d: input is '%s' OK, Time: %llu\n",
0556 i, test.in, time);
0557 }
0558 }
0559
0560 #define EXP1_IN_BITS (sizeof(exp1) * 8)
0561
0562 static void __init test_bitmap_arr32(void)
0563 {
0564 unsigned int nbits, next_bit;
0565 u32 arr[EXP1_IN_BITS / 32];
0566 DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
0567
0568 memset(arr, 0xa5, sizeof(arr));
0569
0570 for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
0571 bitmap_to_arr32(arr, exp1, nbits);
0572 bitmap_from_arr32(bmap2, arr, nbits);
0573 expect_eq_bitmap(bmap2, exp1, nbits);
0574
0575 next_bit = find_next_bit(bmap2,
0576 round_up(nbits, BITS_PER_LONG), nbits);
0577 if (next_bit < round_up(nbits, BITS_PER_LONG))
0578 pr_err("bitmap_copy_arr32(nbits == %d:"
0579 " tail is not safely cleared: %d\n",
0580 nbits, next_bit);
0581
0582 if (nbits < EXP1_IN_BITS - 32)
0583 expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
0584 0xa5a5a5a5);
0585 }
0586 }
0587
0588 static void __init test_bitmap_arr64(void)
0589 {
0590 unsigned int nbits, next_bit;
0591 u64 arr[EXP1_IN_BITS / 64];
0592 DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
0593
0594 memset(arr, 0xa5, sizeof(arr));
0595
0596 for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
0597 memset(bmap2, 0xff, sizeof(arr));
0598 bitmap_to_arr64(arr, exp1, nbits);
0599 bitmap_from_arr64(bmap2, arr, nbits);
0600 expect_eq_bitmap(bmap2, exp1, nbits);
0601
0602 next_bit = find_next_bit(bmap2, round_up(nbits, BITS_PER_LONG), nbits);
0603 if (next_bit < round_up(nbits, BITS_PER_LONG))
0604 pr_err("bitmap_copy_arr64(nbits == %d:"
0605 " tail is not safely cleared: %d\n", nbits, next_bit);
0606
0607 if ((nbits % 64) &&
0608 (arr[(nbits - 1) / 64] & ~GENMASK_ULL((nbits - 1) % 64, 0)))
0609 pr_err("bitmap_to_arr64(nbits == %d): tail is not safely cleared: 0x%016llx (must be 0x%016llx)\n",
0610 nbits, arr[(nbits - 1) / 64],
0611 GENMASK_ULL((nbits - 1) % 64, 0));
0612
0613 if (nbits < EXP1_IN_BITS - 64)
0614 expect_eq_uint(arr[DIV_ROUND_UP(nbits, 64)], 0xa5a5a5a5);
0615 }
0616 }
0617
0618 static void noinline __init test_mem_optimisations(void)
0619 {
0620 DECLARE_BITMAP(bmap1, 1024);
0621 DECLARE_BITMAP(bmap2, 1024);
0622 unsigned int start, nbits;
0623
0624 for (start = 0; start < 1024; start += 8) {
0625 for (nbits = 0; nbits < 1024 - start; nbits += 8) {
0626 memset(bmap1, 0x5a, sizeof(bmap1));
0627 memset(bmap2, 0x5a, sizeof(bmap2));
0628
0629 bitmap_set(bmap1, start, nbits);
0630 __bitmap_set(bmap2, start, nbits);
0631 if (!bitmap_equal(bmap1, bmap2, 1024)) {
0632 printk("set not equal %d %d\n", start, nbits);
0633 failed_tests++;
0634 }
0635 if (!__bitmap_equal(bmap1, bmap2, 1024)) {
0636 printk("set not __equal %d %d\n", start, nbits);
0637 failed_tests++;
0638 }
0639
0640 bitmap_clear(bmap1, start, nbits);
0641 __bitmap_clear(bmap2, start, nbits);
0642 if (!bitmap_equal(bmap1, bmap2, 1024)) {
0643 printk("clear not equal %d %d\n", start, nbits);
0644 failed_tests++;
0645 }
0646 if (!__bitmap_equal(bmap1, bmap2, 1024)) {
0647 printk("clear not __equal %d %d\n", start,
0648 nbits);
0649 failed_tests++;
0650 }
0651 }
0652 }
0653 }
0654
0655 static const unsigned char clump_exp[] __initconst = {
0656 0x01,
0657 0x02,
0658 0x00,
0659 0x38,
0660 0x38,
0661 0x0F,
0662 0xFF,
0663 0x05,
0664 };
0665
0666 static void __init test_for_each_set_clump8(void)
0667 {
0668 #define CLUMP_EXP_NUMBITS 64
0669 DECLARE_BITMAP(bits, CLUMP_EXP_NUMBITS);
0670 unsigned int start;
0671 unsigned long clump;
0672
0673
0674 bitmap_zero(bits, CLUMP_EXP_NUMBITS);
0675 bitmap_set(bits, 0, 1);
0676 bitmap_set(bits, 9, 1);
0677 bitmap_set(bits, 27, 3);
0678 bitmap_set(bits, 35, 3);
0679 bitmap_set(bits, 40, 4);
0680 bitmap_set(bits, 48, 8);
0681 bitmap_set(bits, 56, 1);
0682 bitmap_set(bits, 58, 1);
0683
0684 for_each_set_clump8(start, clump, bits, CLUMP_EXP_NUMBITS)
0685 expect_eq_clump8(start, CLUMP_EXP_NUMBITS, clump_exp, &clump);
0686 }
0687
0688 struct test_bitmap_cut {
0689 unsigned int first;
0690 unsigned int cut;
0691 unsigned int nbits;
0692 unsigned long in[4];
0693 unsigned long expected[4];
0694 };
0695
0696 static struct test_bitmap_cut test_cut[] = {
0697 { 0, 0, 8, { 0x0000000aUL, }, { 0x0000000aUL, }, },
0698 { 0, 0, 32, { 0xdadadeadUL, }, { 0xdadadeadUL, }, },
0699 { 0, 3, 8, { 0x000000aaUL, }, { 0x00000015UL, }, },
0700 { 3, 3, 8, { 0x000000aaUL, }, { 0x00000012UL, }, },
0701 { 0, 1, 32, { 0xa5a5a5a5UL, }, { 0x52d2d2d2UL, }, },
0702 { 0, 8, 32, { 0xdeadc0deUL, }, { 0x00deadc0UL, }, },
0703 { 1, 1, 32, { 0x5a5a5a5aUL, }, { 0x2d2d2d2cUL, }, },
0704 { 0, 15, 32, { 0xa5a5a5a5UL, }, { 0x00014b4bUL, }, },
0705 { 0, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
0706 { 15, 15, 32, { 0xa5a5a5a5UL, }, { 0x000125a5UL, }, },
0707 { 15, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
0708 { 16, 15, 32, { 0xa5a5a5a5UL, }, { 0x0001a5a5UL, }, },
0709
0710 { BITS_PER_LONG, BITS_PER_LONG, BITS_PER_LONG,
0711 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
0712 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
0713 },
0714 { 1, BITS_PER_LONG - 1, BITS_PER_LONG,
0715 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
0716 { 0x00000001UL, 0x00000001UL, },
0717 },
0718
0719 { 0, BITS_PER_LONG * 2, BITS_PER_LONG * 2 + 1,
0720 { 0xa5a5a5a5UL, 0x00000001UL, 0x00000001UL, 0x00000001UL },
0721 { 0x00000001UL, },
0722 },
0723 { 16, BITS_PER_LONG * 2 + 1, BITS_PER_LONG * 2 + 1 + 16,
0724 { 0x0000ffffUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL },
0725 { 0x2d2dffffUL, },
0726 },
0727 };
0728
0729 static void __init test_bitmap_cut(void)
0730 {
0731 unsigned long b[5], *in = &b[1], *out = &b[0];
0732 int i;
0733
0734 for (i = 0; i < ARRAY_SIZE(test_cut); i++) {
0735 struct test_bitmap_cut *t = &test_cut[i];
0736
0737 memcpy(in, t->in, sizeof(t->in));
0738
0739 bitmap_cut(out, in, t->first, t->cut, t->nbits);
0740
0741 expect_eq_bitmap(t->expected, out, t->nbits);
0742 }
0743 }
0744
0745 struct test_bitmap_print {
0746 const unsigned long *bitmap;
0747 unsigned long nbits;
0748 const char *mask;
0749 const char *list;
0750 };
0751
0752 static const unsigned long small_bitmap[] __initconst = {
0753 BITMAP_FROM_U64(0x3333333311111111ULL),
0754 };
0755
0756 static const char small_mask[] __initconst = "33333333,11111111\n";
0757 static const char small_list[] __initconst = "0,4,8,12,16,20,24,28,32-33,36-37,40-41,44-45,48-49,52-53,56-57,60-61\n";
0758
0759 static const unsigned long large_bitmap[] __initconst = {
0760 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0761 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0762 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0763 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0764 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0765 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0766 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0767 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0768 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0769 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0770 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0771 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0772 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0773 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0774 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0775 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0776 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0777 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0778 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0779 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
0780 };
0781
0782 static const char large_mask[] __initconst = "33333333,11111111,33333333,11111111,"
0783 "33333333,11111111,33333333,11111111,"
0784 "33333333,11111111,33333333,11111111,"
0785 "33333333,11111111,33333333,11111111,"
0786 "33333333,11111111,33333333,11111111,"
0787 "33333333,11111111,33333333,11111111,"
0788 "33333333,11111111,33333333,11111111,"
0789 "33333333,11111111,33333333,11111111,"
0790 "33333333,11111111,33333333,11111111,"
0791 "33333333,11111111,33333333,11111111,"
0792 "33333333,11111111,33333333,11111111,"
0793 "33333333,11111111,33333333,11111111,"
0794 "33333333,11111111,33333333,11111111,"
0795 "33333333,11111111,33333333,11111111,"
0796 "33333333,11111111,33333333,11111111,"
0797 "33333333,11111111,33333333,11111111,"
0798 "33333333,11111111,33333333,11111111,"
0799 "33333333,11111111,33333333,11111111,"
0800 "33333333,11111111,33333333,11111111,"
0801 "33333333,11111111,33333333,11111111\n";
0802
0803 static const char large_list[] __initconst =
0804 "0,4,8,12,16,20,24,28,32-33,36-37,40-41,44-45,48-49,52-53,56-57,60-61,64,68,72,76,80,84,88,92,96-97,100-101,104-1"
0805 "05,108-109,112-113,116-117,120-121,124-125,128,132,136,140,144,148,152,156,160-161,164-165,168-169,172-173,176-1"
0806 "77,180-181,184-185,188-189,192,196,200,204,208,212,216,220,224-225,228-229,232-233,236-237,240-241,244-245,248-2"
0807 "49,252-253,256,260,264,268,272,276,280,284,288-289,292-293,296-297,300-301,304-305,308-309,312-313,316-317,320,3"
0808 "24,328,332,336,340,344,348,352-353,356-357,360-361,364-365,368-369,372-373,376-377,380-381,384,388,392,396,400,4"
0809 "04,408,412,416-417,420-421,424-425,428-429,432-433,436-437,440-441,444-445,448,452,456,460,464,468,472,476,480-4"
0810 "81,484-485,488-489,492-493,496-497,500-501,504-505,508-509,512,516,520,524,528,532,536,540,544-545,548-549,552-5"
0811 "53,556-557,560-561,564-565,568-569,572-573,576,580,584,588,592,596,600,604,608-609,612-613,616-617,620-621,624-6"
0812 "25,628-629,632-633,636-637,640,644,648,652,656,660,664,668,672-673,676-677,680-681,684-685,688-689,692-693,696-6"
0813 "97,700-701,704,708,712,716,720,724,728,732,736-737,740-741,744-745,748-749,752-753,756-757,760-761,764-765,768,7"
0814 "72,776,780,784,788,792,796,800-801,804-805,808-809,812-813,816-817,820-821,824-825,828-829,832,836,840,844,848,8"
0815 "52,856,860,864-865,868-869,872-873,876-877,880-881,884-885,888-889,892-893,896,900,904,908,912,916,920,924,928-9"
0816 "29,932-933,936-937,940-941,944-945,948-949,952-953,956-957,960,964,968,972,976,980,984,988,992-993,996-997,1000-"
0817 "1001,1004-1005,1008-1009,1012-1013,1016-1017,1020-1021,1024,1028,1032,1036,1040,1044,1048,1052,1056-1057,1060-10"
0818 "61,1064-1065,1068-1069,1072-1073,1076-1077,1080-1081,1084-1085,1088,1092,1096,1100,1104,1108,1112,1116,1120-1121"
0819 ",1124-1125,1128-1129,1132-1133,1136-1137,1140-1141,1144-1145,1148-1149,1152,1156,1160,1164,1168,1172,1176,1180,1"
0820 "184-1185,1188-1189,1192-1193,1196-1197,1200-1201,1204-1205,1208-1209,1212-1213,1216,1220,1224,1228,1232,1236,124"
0821 "0,1244,1248-1249,1252-1253,1256-1257,1260-1261,1264-1265,1268-1269,1272-1273,1276-1277,1280,1284,1288,1292,1296,"
0822 "1300,1304,1308,1312-1313,1316-1317,1320-1321,1324-1325,1328-1329,1332-1333,1336-1337,1340-1341,1344,1348,1352,13"
0823 "56,1360,1364,1368,1372,1376-1377,1380-1381,1384-1385,1388-1389,1392-1393,1396-1397,1400-1401,1404-1405,1408,1412"
0824 ",1416,1420,1424,1428,1432,1436,1440-1441,1444-1445,1448-1449,1452-1453,1456-1457,1460-1461,1464-1465,1468-1469,1"
0825 "472,1476,1480,1484,1488,1492,1496,1500,1504-1505,1508-1509,1512-1513,1516-1517,1520-1521,1524-1525,1528-1529,153"
0826 "2-1533,1536,1540,1544,1548,1552,1556,1560,1564,1568-1569,1572-1573,1576-1577,1580-1581,1584-1585,1588-1589,1592-"
0827 "1593,1596-1597,1600,1604,1608,1612,1616,1620,1624,1628,1632-1633,1636-1637,1640-1641,1644-1645,1648-1649,1652-16"
0828 "53,1656-1657,1660-1661,1664,1668,1672,1676,1680,1684,1688,1692,1696-1697,1700-1701,1704-1705,1708-1709,1712-1713"
0829 ",1716-1717,1720-1721,1724-1725,1728,1732,1736,1740,1744,1748,1752,1756,1760-1761,1764-1765,1768-1769,1772-1773,1"
0830 "776-1777,1780-1781,1784-1785,1788-1789,1792,1796,1800,1804,1808,1812,1816,1820,1824-1825,1828-1829,1832-1833,183"
0831 "6-1837,1840-1841,1844-1845,1848-1849,1852-1853,1856,1860,1864,1868,1872,1876,1880,1884,1888-1889,1892-1893,1896-"
0832 "1897,1900-1901,1904-1905,1908-1909,1912-1913,1916-1917,1920,1924,1928,1932,1936,1940,1944,1948,1952-1953,1956-19"
0833 "57,1960-1961,1964-1965,1968-1969,1972-1973,1976-1977,1980-1981,1984,1988,1992,1996,2000,2004,2008,2012,2016-2017"
0834 ",2020-2021,2024-2025,2028-2029,2032-2033,2036-2037,2040-2041,2044-2045,2048,2052,2056,2060,2064,2068,2072,2076,2"
0835 "080-2081,2084-2085,2088-2089,2092-2093,2096-2097,2100-2101,2104-2105,2108-2109,2112,2116,2120,2124,2128,2132,213"
0836 "6,2140,2144-2145,2148-2149,2152-2153,2156-2157,2160-2161,2164-2165,2168-2169,2172-2173,2176,2180,2184,2188,2192,"
0837 "2196,2200,2204,2208-2209,2212-2213,2216-2217,2220-2221,2224-2225,2228-2229,2232-2233,2236-2237,2240,2244,2248,22"
0838 "52,2256,2260,2264,2268,2272-2273,2276-2277,2280-2281,2284-2285,2288-2289,2292-2293,2296-2297,2300-2301,2304,2308"
0839 ",2312,2316,2320,2324,2328,2332,2336-2337,2340-2341,2344-2345,2348-2349,2352-2353,2356-2357,2360-2361,2364-2365,2"
0840 "368,2372,2376,2380,2384,2388,2392,2396,2400-2401,2404-2405,2408-2409,2412-2413,2416-2417,2420-2421,2424-2425,242"
0841 "8-2429,2432,2436,2440,2444,2448,2452,2456,2460,2464-2465,2468-2469,2472-2473,2476-2477,2480-2481,2484-2485,2488-"
0842 "2489,2492-2493,2496,2500,2504,2508,2512,2516,2520,2524,2528-2529,2532-2533,2536-2537,2540-2541,2544-2545,2548-25"
0843 "49,2552-2553,2556-2557\n";
0844
0845 static const struct test_bitmap_print test_print[] __initconst = {
0846 { small_bitmap, sizeof(small_bitmap) * BITS_PER_BYTE, small_mask, small_list },
0847 { large_bitmap, sizeof(large_bitmap) * BITS_PER_BYTE, large_mask, large_list },
0848 };
0849
0850 static void __init test_bitmap_print_buf(void)
0851 {
0852 int i;
0853
0854 for (i = 0; i < ARRAY_SIZE(test_print); i++) {
0855 const struct test_bitmap_print *t = &test_print[i];
0856 int n;
0857
0858 n = bitmap_print_bitmask_to_buf(print_buf, t->bitmap, t->nbits,
0859 0, 2 * PAGE_SIZE);
0860 expect_eq_uint(strlen(t->mask) + 1, n);
0861 expect_eq_str(t->mask, print_buf, n);
0862
0863 n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
0864 0, 2 * PAGE_SIZE);
0865 expect_eq_uint(strlen(t->list) + 1, n);
0866 expect_eq_str(t->list, print_buf, n);
0867
0868
0869 if (strlen(t->list) > PAGE_SIZE) {
0870 n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
0871 PAGE_SIZE, PAGE_SIZE);
0872 expect_eq_uint(strlen(t->list) + 1 - PAGE_SIZE, n);
0873 expect_eq_str(t->list + PAGE_SIZE, print_buf, n);
0874 }
0875 }
0876 }
0877
0878 static void __init test_bitmap_const_eval(void)
0879 {
0880 DECLARE_BITMAP(bitmap, BITS_PER_LONG);
0881 unsigned long initvar = BIT(2);
0882 unsigned long bitopvar = 0;
0883 unsigned long var = 0;
0884 int res;
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902 bitmap_clear(bitmap, 0, BITS_PER_LONG);
0903 #if defined(__s390__) && defined(__clang__)
0904 if (!const_test_bit(7, bitmap))
0905 #else
0906 if (!test_bit(7, bitmap))
0907 #endif
0908 bitmap_set(bitmap, 5, 2);
0909
0910
0911 __change_bit(31, &bitopvar);
0912 bitmap_shift_right(&bitopvar, &bitopvar, 11, BITS_PER_LONG);
0913
0914
0915 var |= BIT(25);
0916 if (var & BIT(0))
0917 var ^= GENMASK(9, 6);
0918
0919
0920 res = bitmap_weight(bitmap, 20);
0921 BUILD_BUG_ON(!__builtin_constant_p(res));
0922 BUILD_BUG_ON(res != 2);
0923
0924
0925 res = !test_bit(18, &bitopvar);
0926 BUILD_BUG_ON(!__builtin_constant_p(res));
0927 BUILD_BUG_ON(!res);
0928
0929
0930 res = initvar & GENMASK(14, 8);
0931 BUILD_BUG_ON(!__builtin_constant_p(res));
0932 BUILD_BUG_ON(res);
0933
0934
0935 BUILD_BUG_ON(!__builtin_constant_p(~var));
0936 BUILD_BUG_ON(~var != ~BIT(25));
0937 }
0938
0939 static void __init selftest(void)
0940 {
0941 test_zero_clear();
0942 test_fill_set();
0943 test_copy();
0944 test_replace();
0945 test_bitmap_arr32();
0946 test_bitmap_arr64();
0947 test_bitmap_parse();
0948 test_bitmap_parselist();
0949 test_bitmap_printlist();
0950 test_mem_optimisations();
0951 test_for_each_set_clump8();
0952 test_bitmap_cut();
0953 test_bitmap_print_buf();
0954 test_bitmap_const_eval();
0955 }
0956
0957 KSTM_MODULE_LOADERS(test_bitmap);
0958 MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>");
0959 MODULE_LICENSE("GPL");