1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Test cases for bitmap API. 4 */ 5 6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 8 #include <linux/bitmap.h> 9 #include <linux/init.h> 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/printk.h> 13 #include <linux/slab.h> 14 #include <linux/string.h> 15 #include <linux/uaccess.h> 16 17 #include "../tools/testing/selftests/kselftest_module.h" 18 19 KSTM_MODULE_GLOBALS(); 20 21 static char pbl_buffer[PAGE_SIZE] __initdata; 22 static char print_buf[PAGE_SIZE * 2] __initdata; 23 24 static const unsigned long exp1[] __initconst = { 25 BITMAP_FROM_U64(1), 26 BITMAP_FROM_U64(2), 27 BITMAP_FROM_U64(0x0000ffff), 28 BITMAP_FROM_U64(0xffff0000), 29 BITMAP_FROM_U64(0x55555555), 30 BITMAP_FROM_U64(0xaaaaaaaa), 31 BITMAP_FROM_U64(0x11111111), 32 BITMAP_FROM_U64(0x22222222), 33 BITMAP_FROM_U64(0xffffffff), 34 BITMAP_FROM_U64(0xfffffffe), 35 BITMAP_FROM_U64(0x3333333311111111ULL), 36 BITMAP_FROM_U64(0xffffffff77777777ULL), 37 BITMAP_FROM_U64(0), 38 BITMAP_FROM_U64(0x00008000), 39 BITMAP_FROM_U64(0x80000000), 40 }; 41 42 static const unsigned long exp2[] __initconst = { 43 BITMAP_FROM_U64(0x3333333311111111ULL), 44 BITMAP_FROM_U64(0xffffffff77777777ULL), 45 }; 46 47 /* Fibonacci sequence */ 48 static const unsigned long exp2_to_exp3_mask[] __initconst = { 49 BITMAP_FROM_U64(0x008000020020212eULL), 50 }; 51 /* exp3_0_1 = (exp2[0] & ~exp2_to_exp3_mask) | (exp2[1] & exp2_to_exp3_mask) */ 52 static const unsigned long exp3_0_1[] __initconst = { 53 BITMAP_FROM_U64(0x33b3333311313137ULL), 54 }; 55 /* exp3_1_0 = (exp2[1] & ~exp2_to_exp3_mask) | (exp2[0] & exp2_to_exp3_mask) */ 56 static const unsigned long exp3_1_0[] __initconst = { 57 BITMAP_FROM_U64(0xff7fffff77575751ULL), 58 }; 59 60 static bool __init 61 __check_eq_uint(const char *srcfile, unsigned int line, 62 const unsigned int exp_uint, unsigned int x) 63 { 64 if (exp_uint != x) { 65 pr_err("[%s:%u] expected %u, got %u\n", 66 srcfile, line, exp_uint, x); 67 return false; 68 } 69 return true; 70 } 71 72 73 static bool __init 74 __check_eq_bitmap(const char *srcfile, unsigned int line, 75 const unsigned long *exp_bmap, const unsigned long *bmap, 76 unsigned int nbits) 77 { 78 if (!bitmap_equal(exp_bmap, bmap, nbits)) { 79 pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n", 80 srcfile, line, 81 nbits, exp_bmap, nbits, bmap); 82 return false; 83 } 84 return true; 85 } 86 87 static bool __init 88 __check_eq_pbl(const char *srcfile, unsigned int line, 89 const char *expected_pbl, 90 const unsigned long *bitmap, unsigned int nbits) 91 { 92 snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap); 93 if (strcmp(expected_pbl, pbl_buffer)) { 94 pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n", 95 srcfile, line, 96 expected_pbl, pbl_buffer); 97 return false; 98 } 99 return true; 100 } 101 102 static bool __init 103 __check_eq_u32_array(const char *srcfile, unsigned int line, 104 const u32 *exp_arr, unsigned int exp_len, 105 const u32 *arr, unsigned int len) __used; 106 static bool __init 107 __check_eq_u32_array(const char *srcfile, unsigned int line, 108 const u32 *exp_arr, unsigned int exp_len, 109 const u32 *arr, unsigned int len) 110 { 111 if (exp_len != len) { 112 pr_warn("[%s:%u] array length differ: expected %u, got %u\n", 113 srcfile, line, 114 exp_len, len); 115 return false; 116 } 117 118 if (memcmp(exp_arr, arr, len*sizeof(*arr))) { 119 pr_warn("[%s:%u] array contents differ\n", srcfile, line); 120 print_hex_dump(KERN_WARNING, " exp: ", DUMP_PREFIX_OFFSET, 121 32, 4, exp_arr, exp_len*sizeof(*exp_arr), false); 122 print_hex_dump(KERN_WARNING, " got: ", DUMP_PREFIX_OFFSET, 123 32, 4, arr, len*sizeof(*arr), false); 124 return false; 125 } 126 127 return true; 128 } 129 130 static bool __init __check_eq_clump8(const char *srcfile, unsigned int line, 131 const unsigned int offset, 132 const unsigned int size, 133 const unsigned char *const clump_exp, 134 const unsigned long *const clump) 135 { 136 unsigned long exp; 137 138 if (offset >= size) { 139 pr_warn("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u\n", 140 srcfile, line, size, offset); 141 return false; 142 } 143 144 exp = clump_exp[offset / 8]; 145 if (!exp) { 146 pr_warn("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0", 147 srcfile, line, offset); 148 return false; 149 } 150 151 if (*clump != exp) { 152 pr_warn("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX", 153 srcfile, line, exp, *clump); 154 return false; 155 } 156 157 return true; 158 } 159 160 static bool __init 161 __check_eq_str(const char *srcfile, unsigned int line, 162 const char *exp_str, const char *str, 163 unsigned int len) 164 { 165 bool eq; 166 167 eq = strncmp(exp_str, str, len) == 0; 168 if (!eq) 169 pr_err("[%s:%u] expected %s, got %s\n", srcfile, line, exp_str, str); 170 171 return eq; 172 } 173 174 #define __expect_eq(suffix, ...) \ 175 ({ \ 176 int result = 0; \ 177 total_tests++; \ 178 if (!__check_eq_ ## suffix(__FILE__, __LINE__, \ 179 ##__VA_ARGS__)) { \ 180 failed_tests++; \ 181 result = 1; \ 182 } \ 183 result; \ 184 }) 185 186 #define expect_eq_uint(...) __expect_eq(uint, ##__VA_ARGS__) 187 #define expect_eq_bitmap(...) __expect_eq(bitmap, ##__VA_ARGS__) 188 #define expect_eq_pbl(...) __expect_eq(pbl, ##__VA_ARGS__) 189 #define expect_eq_u32_array(...) __expect_eq(u32_array, ##__VA_ARGS__) 190 #define expect_eq_clump8(...) __expect_eq(clump8, ##__VA_ARGS__) 191 #define expect_eq_str(...) __expect_eq(str, ##__VA_ARGS__) 192 193 static void __init test_zero_clear(void) 194 { 195 DECLARE_BITMAP(bmap, 1024); 196 197 /* Known way to set all bits */ 198 memset(bmap, 0xff, 128); 199 200 expect_eq_pbl("0-22", bmap, 23); 201 expect_eq_pbl("0-1023", bmap, 1024); 202 203 /* single-word bitmaps */ 204 bitmap_clear(bmap, 0, 9); 205 expect_eq_pbl("9-1023", bmap, 1024); 206 207 bitmap_zero(bmap, 35); 208 expect_eq_pbl("64-1023", bmap, 1024); 209 210 /* cross boundaries operations */ 211 bitmap_clear(bmap, 79, 19); 212 expect_eq_pbl("64-78,98-1023", bmap, 1024); 213 214 bitmap_zero(bmap, 115); 215 expect_eq_pbl("128-1023", bmap, 1024); 216 217 /* Zeroing entire area */ 218 bitmap_zero(bmap, 1024); 219 expect_eq_pbl("", bmap, 1024); 220 } 221 222 static void __init test_fill_set(void) 223 { 224 DECLARE_BITMAP(bmap, 1024); 225 226 /* Known way to clear all bits */ 227 memset(bmap, 0x00, 128); 228 229 expect_eq_pbl("", bmap, 23); 230 expect_eq_pbl("", bmap, 1024); 231 232 /* single-word bitmaps */ 233 bitmap_set(bmap, 0, 9); 234 expect_eq_pbl("0-8", bmap, 1024); 235 236 bitmap_fill(bmap, 35); 237 expect_eq_pbl("0-63", bmap, 1024); 238 239 /* cross boundaries operations */ 240 bitmap_set(bmap, 79, 19); 241 expect_eq_pbl("0-63,79-97", bmap, 1024); 242 243 bitmap_fill(bmap, 115); 244 expect_eq_pbl("0-127", bmap, 1024); 245 246 /* Zeroing entire area */ 247 bitmap_fill(bmap, 1024); 248 expect_eq_pbl("0-1023", bmap, 1024); 249 } 250 251 static void __init test_copy(void) 252 { 253 DECLARE_BITMAP(bmap1, 1024); 254 DECLARE_BITMAP(bmap2, 1024); 255 256 bitmap_zero(bmap1, 1024); 257 bitmap_zero(bmap2, 1024); 258 259 /* single-word bitmaps */ 260 bitmap_set(bmap1, 0, 19); 261 bitmap_copy(bmap2, bmap1, 23); 262 expect_eq_pbl("0-18", bmap2, 1024); 263 264 bitmap_set(bmap2, 0, 23); 265 bitmap_copy(bmap2, bmap1, 23); 266 expect_eq_pbl("0-18", bmap2, 1024); 267 268 /* multi-word bitmaps */ 269 bitmap_set(bmap1, 0, 109); 270 bitmap_copy(bmap2, bmap1, 1024); 271 expect_eq_pbl("0-108", bmap2, 1024); 272 273 bitmap_fill(bmap2, 1024); 274 bitmap_copy(bmap2, bmap1, 1024); 275 expect_eq_pbl("0-108", bmap2, 1024); 276 277 /* the following tests assume a 32- or 64-bit arch (even 128b 278 * if we care) 279 */ 280 281 bitmap_fill(bmap2, 1024); 282 bitmap_copy(bmap2, bmap1, 109); /* ... but 0-padded til word length */ 283 expect_eq_pbl("0-108,128-1023", bmap2, 1024); 284 285 bitmap_fill(bmap2, 1024); 286 bitmap_copy(bmap2, bmap1, 97); /* ... but aligned on word length */ 287 expect_eq_pbl("0-108,128-1023", bmap2, 1024); 288 } 289 290 #define EXP2_IN_BITS (sizeof(exp2) * 8) 291 292 static void __init test_replace(void) 293 { 294 unsigned int nbits = 64; 295 unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG); 296 DECLARE_BITMAP(bmap, 1024); 297 298 BUILD_BUG_ON(EXP2_IN_BITS < nbits * 2); 299 300 bitmap_zero(bmap, 1024); 301 bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits); 302 expect_eq_bitmap(bmap, exp3_0_1, nbits); 303 304 bitmap_zero(bmap, 1024); 305 bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits); 306 expect_eq_bitmap(bmap, exp3_1_0, nbits); 307 308 bitmap_fill(bmap, 1024); 309 bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits); 310 expect_eq_bitmap(bmap, exp3_0_1, nbits); 311 312 bitmap_fill(bmap, 1024); 313 bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits); 314 expect_eq_bitmap(bmap, exp3_1_0, nbits); 315 } 316 317 #define PARSE_TIME 0x1 318 #define NO_LEN 0x2 319 320 struct test_bitmap_parselist{ 321 const int errno; 322 const char *in; 323 const unsigned long *expected; 324 const int nbits; 325 const int flags; 326 }; 327 328 static const struct test_bitmap_parselist parselist_tests[] __initconst = { 329 #define step (sizeof(u64) / sizeof(unsigned long)) 330 331 {0, "0", &exp1[0], 8, 0}, 332 {0, "1", &exp1[1 * step], 8, 0}, 333 {0, "0-15", &exp1[2 * step], 32, 0}, 334 {0, "16-31", &exp1[3 * step], 32, 0}, 335 {0, "0-31:1/2", &exp1[4 * step], 32, 0}, 336 {0, "1-31:1/2", &exp1[5 * step], 32, 0}, 337 {0, "0-31:1/4", &exp1[6 * step], 32, 0}, 338 {0, "1-31:1/4", &exp1[7 * step], 32, 0}, 339 {0, "0-31:4/4", &exp1[8 * step], 32, 0}, 340 {0, "1-31:4/4", &exp1[9 * step], 32, 0}, 341 {0, "0-31:1/4,32-63:2/4", &exp1[10 * step], 64, 0}, 342 {0, "0-31:3/4,32-63:4/4", &exp1[11 * step], 64, 0}, 343 {0, " ,, 0-31:3/4 ,, 32-63:4/4 ,, ", &exp1[11 * step], 64, 0}, 344 345 {0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4", exp2, 128, 0}, 346 347 {0, "0-2047:128/256", NULL, 2048, PARSE_TIME}, 348 349 {0, "", &exp1[12 * step], 8, 0}, 350 {0, "\n", &exp1[12 * step], 8, 0}, 351 {0, ",, ,, , , ,", &exp1[12 * step], 8, 0}, 352 {0, " , ,, , , ", &exp1[12 * step], 8, 0}, 353 {0, " , ,, , , \n", &exp1[12 * step], 8, 0}, 354 355 {0, "0-0", &exp1[0], 32, 0}, 356 {0, "1-1", &exp1[1 * step], 32, 0}, 357 {0, "15-15", &exp1[13 * step], 32, 0}, 358 {0, "31-31", &exp1[14 * step], 32, 0}, 359 360 {0, "0-0:0/1", &exp1[12 * step], 32, 0}, 361 {0, "0-0:1/1", &exp1[0], 32, 0}, 362 {0, "0-0:1/31", &exp1[0], 32, 0}, 363 {0, "0-0:31/31", &exp1[0], 32, 0}, 364 {0, "1-1:1/1", &exp1[1 * step], 32, 0}, 365 {0, "0-15:16/31", &exp1[2 * step], 32, 0}, 366 {0, "15-15:1/2", &exp1[13 * step], 32, 0}, 367 {0, "15-15:31/31", &exp1[13 * step], 32, 0}, 368 {0, "15-31:1/31", &exp1[13 * step], 32, 0}, 369 {0, "16-31:16/31", &exp1[3 * step], 32, 0}, 370 {0, "31-31:31/31", &exp1[14 * step], 32, 0}, 371 372 {0, "N-N", &exp1[14 * step], 32, 0}, 373 {0, "0-0:1/N", &exp1[0], 32, 0}, 374 {0, "0-0:N/N", &exp1[0], 32, 0}, 375 {0, "0-15:16/N", &exp1[2 * step], 32, 0}, 376 {0, "15-15:N/N", &exp1[13 * step], 32, 0}, 377 {0, "15-N:1/N", &exp1[13 * step], 32, 0}, 378 {0, "16-N:16/N", &exp1[3 * step], 32, 0}, 379 {0, "N-N:N/N", &exp1[14 * step], 32, 0}, 380 381 {0, "0-N:1/3,1-N:1/3,2-N:1/3", &exp1[8 * step], 32, 0}, 382 {0, "0-31:1/3,1-31:1/3,2-31:1/3", &exp1[8 * step], 32, 0}, 383 {0, "1-10:8/12,8-31:24/29,0-31:0/3", &exp1[9 * step], 32, 0}, 384 385 {0, "all", &exp1[8 * step], 32, 0}, 386 {0, "0, 1, all, ", &exp1[8 * step], 32, 0}, 387 {0, "all:1/2", &exp1[4 * step], 32, 0}, 388 {0, "ALL:1/2", &exp1[4 * step], 32, 0}, 389 {-EINVAL, "al", NULL, 8, 0}, 390 {-EINVAL, "alll", NULL, 8, 0}, 391 392 {-EINVAL, "-1", NULL, 8, 0}, 393 {-EINVAL, "-0", NULL, 8, 0}, 394 {-EINVAL, "10-1", NULL, 8, 0}, 395 {-ERANGE, "8-8", NULL, 8, 0}, 396 {-ERANGE, "0-31", NULL, 8, 0}, 397 {-EINVAL, "0-31:", NULL, 32, 0}, 398 {-EINVAL, "0-31:0", NULL, 32, 0}, 399 {-EINVAL, "0-31:0/", NULL, 32, 0}, 400 {-EINVAL, "0-31:0/0", NULL, 32, 0}, 401 {-EINVAL, "0-31:1/0", NULL, 32, 0}, 402 {-EINVAL, "0-31:10/1", NULL, 32, 0}, 403 {-EOVERFLOW, "0-98765432123456789:10/1", NULL, 8, 0}, 404 405 {-EINVAL, "a-31", NULL, 8, 0}, 406 {-EINVAL, "0-a1", NULL, 8, 0}, 407 {-EINVAL, "a-31:10/1", NULL, 8, 0}, 408 {-EINVAL, "0-31:a/1", NULL, 8, 0}, 409 {-EINVAL, "0-\n", NULL, 8, 0}, 410 411 }; 412 413 static void __init test_bitmap_parselist(void) 414 { 415 int i; 416 int err; 417 ktime_t time; 418 DECLARE_BITMAP(bmap, 2048); 419 420 for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) { 421 #define ptest parselist_tests[i] 422 423 time = ktime_get(); 424 err = bitmap_parselist(ptest.in, bmap, ptest.nbits); 425 time = ktime_get() - time; 426 427 if (err != ptest.errno) { 428 pr_err("parselist: %d: input is %s, errno is %d, expected %d\n", 429 i, ptest.in, err, ptest.errno); 430 continue; 431 } 432 433 if (!err && ptest.expected 434 && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) { 435 pr_err("parselist: %d: input is %s, result is 0x%lx, expected 0x%lx\n", 436 i, ptest.in, bmap[0], 437 *ptest.expected); 438 continue; 439 } 440 441 if (ptest.flags & PARSE_TIME) 442 pr_err("parselist: %d: input is '%s' OK, Time: %llu\n", 443 i, ptest.in, time); 444 445 #undef ptest 446 } 447 } 448 449 static const unsigned long parse_test[] __initconst = { 450 BITMAP_FROM_U64(0), 451 BITMAP_FROM_U64(1), 452 BITMAP_FROM_U64(0xdeadbeef), 453 BITMAP_FROM_U64(0x100000000ULL), 454 }; 455 456 static const unsigned long parse_test2[] __initconst = { 457 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xdeadbeef), 458 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xbaadf00ddeadbeef), 459 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0x0badf00ddeadbeef), 460 }; 461 462 static const struct test_bitmap_parselist parse_tests[] __initconst = { 463 {0, "", &parse_test[0 * step], 32, 0}, 464 {0, " ", &parse_test[0 * step], 32, 0}, 465 {0, "0", &parse_test[0 * step], 32, 0}, 466 {0, "0\n", &parse_test[0 * step], 32, 0}, 467 {0, "1", &parse_test[1 * step], 32, 0}, 468 {0, "deadbeef", &parse_test[2 * step], 32, 0}, 469 {0, "1,0", &parse_test[3 * step], 33, 0}, 470 {0, "deadbeef,\n,0,1", &parse_test[2 * step], 96, 0}, 471 472 {0, "deadbeef,1,0", &parse_test2[0 * 2 * step], 96, 0}, 473 {0, "baadf00d,deadbeef,1,0", &parse_test2[1 * 2 * step], 128, 0}, 474 {0, "badf00d,deadbeef,1,0", &parse_test2[2 * 2 * step], 124, 0}, 475 {0, "badf00d,deadbeef,1,0", &parse_test2[2 * 2 * step], 124, NO_LEN}, 476 {0, " badf00d,deadbeef,1,0 ", &parse_test2[2 * 2 * step], 124, 0}, 477 {0, " , badf00d,deadbeef,1,0 , ", &parse_test2[2 * 2 * step], 124, 0}, 478 {0, " , badf00d, ,, ,,deadbeef,1,0 , ", &parse_test2[2 * 2 * step], 124, 0}, 479 480 {-EINVAL, "goodfood,deadbeef,1,0", NULL, 128, 0}, 481 {-EOVERFLOW, "3,0", NULL, 33, 0}, 482 {-EOVERFLOW, "123badf00d,deadbeef,1,0", NULL, 128, 0}, 483 {-EOVERFLOW, "badf00d,deadbeef,1,0", NULL, 90, 0}, 484 {-EOVERFLOW, "fbadf00d,deadbeef,1,0", NULL, 95, 0}, 485 {-EOVERFLOW, "badf00d,deadbeef,1,0", NULL, 100, 0}, 486 #undef step 487 }; 488 489 static void __init test_bitmap_parse(void) 490 { 491 int i; 492 int err; 493 ktime_t time; 494 DECLARE_BITMAP(bmap, 2048); 495 496 for (i = 0; i < ARRAY_SIZE(parse_tests); i++) { 497 struct test_bitmap_parselist test = parse_tests[i]; 498 size_t len = test.flags & NO_LEN ? UINT_MAX : strlen(test.in); 499 500 time = ktime_get(); 501 err = bitmap_parse(test.in, len, bmap, test.nbits); 502 time = ktime_get() - time; 503 504 if (err != test.errno) { 505 pr_err("parse: %d: input is %s, errno is %d, expected %d\n", 506 i, test.in, err, test.errno); 507 continue; 508 } 509 510 if (!err && test.expected 511 && !__bitmap_equal(bmap, test.expected, test.nbits)) { 512 pr_err("parse: %d: input is %s, result is 0x%lx, expected 0x%lx\n", 513 i, test.in, bmap[0], 514 *test.expected); 515 continue; 516 } 517 518 if (test.flags & PARSE_TIME) 519 pr_err("parse: %d: input is '%s' OK, Time: %llu\n", 520 i, test.in, time); 521 } 522 } 523 524 #define EXP1_IN_BITS (sizeof(exp1) * 8) 525 526 static void __init test_bitmap_arr32(void) 527 { 528 unsigned int nbits, next_bit; 529 u32 arr[EXP1_IN_BITS / 32]; 530 DECLARE_BITMAP(bmap2, EXP1_IN_BITS); 531 532 memset(arr, 0xa5, sizeof(arr)); 533 534 for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) { 535 bitmap_to_arr32(arr, exp1, nbits); 536 bitmap_from_arr32(bmap2, arr, nbits); 537 expect_eq_bitmap(bmap2, exp1, nbits); 538 539 next_bit = find_next_bit(bmap2, 540 round_up(nbits, BITS_PER_LONG), nbits); 541 if (next_bit < round_up(nbits, BITS_PER_LONG)) 542 pr_err("bitmap_copy_arr32(nbits == %d:" 543 " tail is not safely cleared: %d\n", 544 nbits, next_bit); 545 546 if (nbits < EXP1_IN_BITS - 32) 547 expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)], 548 0xa5a5a5a5); 549 } 550 } 551 552 static void noinline __init test_mem_optimisations(void) 553 { 554 DECLARE_BITMAP(bmap1, 1024); 555 DECLARE_BITMAP(bmap2, 1024); 556 unsigned int start, nbits; 557 558 for (start = 0; start < 1024; start += 8) { 559 for (nbits = 0; nbits < 1024 - start; nbits += 8) { 560 memset(bmap1, 0x5a, sizeof(bmap1)); 561 memset(bmap2, 0x5a, sizeof(bmap2)); 562 563 bitmap_set(bmap1, start, nbits); 564 __bitmap_set(bmap2, start, nbits); 565 if (!bitmap_equal(bmap1, bmap2, 1024)) { 566 printk("set not equal %d %d\n", start, nbits); 567 failed_tests++; 568 } 569 if (!__bitmap_equal(bmap1, bmap2, 1024)) { 570 printk("set not __equal %d %d\n", start, nbits); 571 failed_tests++; 572 } 573 574 bitmap_clear(bmap1, start, nbits); 575 __bitmap_clear(bmap2, start, nbits); 576 if (!bitmap_equal(bmap1, bmap2, 1024)) { 577 printk("clear not equal %d %d\n", start, nbits); 578 failed_tests++; 579 } 580 if (!__bitmap_equal(bmap1, bmap2, 1024)) { 581 printk("clear not __equal %d %d\n", start, 582 nbits); 583 failed_tests++; 584 } 585 } 586 } 587 } 588 589 static const unsigned char clump_exp[] __initconst = { 590 0x01, /* 1 bit set */ 591 0x02, /* non-edge 1 bit set */ 592 0x00, /* zero bits set */ 593 0x38, /* 3 bits set across 4-bit boundary */ 594 0x38, /* Repeated clump */ 595 0x0F, /* 4 bits set */ 596 0xFF, /* all bits set */ 597 0x05, /* non-adjacent 2 bits set */ 598 }; 599 600 static void __init test_for_each_set_clump8(void) 601 { 602 #define CLUMP_EXP_NUMBITS 64 603 DECLARE_BITMAP(bits, CLUMP_EXP_NUMBITS); 604 unsigned int start; 605 unsigned long clump; 606 607 /* set bitmap to test case */ 608 bitmap_zero(bits, CLUMP_EXP_NUMBITS); 609 bitmap_set(bits, 0, 1); /* 0x01 */ 610 bitmap_set(bits, 9, 1); /* 0x02 */ 611 bitmap_set(bits, 27, 3); /* 0x28 */ 612 bitmap_set(bits, 35, 3); /* 0x28 */ 613 bitmap_set(bits, 40, 4); /* 0x0F */ 614 bitmap_set(bits, 48, 8); /* 0xFF */ 615 bitmap_set(bits, 56, 1); /* 0x05 - part 1 */ 616 bitmap_set(bits, 58, 1); /* 0x05 - part 2 */ 617 618 for_each_set_clump8(start, clump, bits, CLUMP_EXP_NUMBITS) 619 expect_eq_clump8(start, CLUMP_EXP_NUMBITS, clump_exp, &clump); 620 } 621 622 struct test_bitmap_cut { 623 unsigned int first; 624 unsigned int cut; 625 unsigned int nbits; 626 unsigned long in[4]; 627 unsigned long expected[4]; 628 }; 629 630 static struct test_bitmap_cut test_cut[] = { 631 { 0, 0, 8, { 0x0000000aUL, }, { 0x0000000aUL, }, }, 632 { 0, 0, 32, { 0xdadadeadUL, }, { 0xdadadeadUL, }, }, 633 { 0, 3, 8, { 0x000000aaUL, }, { 0x00000015UL, }, }, 634 { 3, 3, 8, { 0x000000aaUL, }, { 0x00000012UL, }, }, 635 { 0, 1, 32, { 0xa5a5a5a5UL, }, { 0x52d2d2d2UL, }, }, 636 { 0, 8, 32, { 0xdeadc0deUL, }, { 0x00deadc0UL, }, }, 637 { 1, 1, 32, { 0x5a5a5a5aUL, }, { 0x2d2d2d2cUL, }, }, 638 { 0, 15, 32, { 0xa5a5a5a5UL, }, { 0x00014b4bUL, }, }, 639 { 0, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, }, 640 { 15, 15, 32, { 0xa5a5a5a5UL, }, { 0x000125a5UL, }, }, 641 { 15, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, }, 642 { 16, 15, 32, { 0xa5a5a5a5UL, }, { 0x0001a5a5UL, }, }, 643 644 { BITS_PER_LONG, BITS_PER_LONG, BITS_PER_LONG, 645 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, }, 646 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, }, 647 }, 648 { 1, BITS_PER_LONG - 1, BITS_PER_LONG, 649 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, }, 650 { 0x00000001UL, 0x00000001UL, }, 651 }, 652 653 { 0, BITS_PER_LONG * 2, BITS_PER_LONG * 2 + 1, 654 { 0xa5a5a5a5UL, 0x00000001UL, 0x00000001UL, 0x00000001UL }, 655 { 0x00000001UL, }, 656 }, 657 { 16, BITS_PER_LONG * 2 + 1, BITS_PER_LONG * 2 + 1 + 16, 658 { 0x0000ffffUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL }, 659 { 0x2d2dffffUL, }, 660 }, 661 }; 662 663 static void __init test_bitmap_cut(void) 664 { 665 unsigned long b[5], *in = &b[1], *out = &b[0]; /* Partial overlap */ 666 int i; 667 668 for (i = 0; i < ARRAY_SIZE(test_cut); i++) { 669 struct test_bitmap_cut *t = &test_cut[i]; 670 671 memcpy(in, t->in, sizeof(t->in)); 672 673 bitmap_cut(out, in, t->first, t->cut, t->nbits); 674 675 expect_eq_bitmap(t->expected, out, t->nbits); 676 } 677 } 678 679 struct test_bitmap_print { 680 const unsigned long *bitmap; 681 unsigned long nbits; 682 const char *mask; 683 const char *list; 684 }; 685 686 static const unsigned long small_bitmap[] __initconst = { 687 BITMAP_FROM_U64(0x3333333311111111ULL), 688 }; 689 690 static const char small_mask[] __initconst = "33333333,11111111\n"; 691 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"; 692 693 static const unsigned long large_bitmap[] __initconst = { 694 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 695 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 696 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 697 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 698 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 699 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 700 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 701 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 702 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 703 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 704 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 705 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 706 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 707 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 708 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 709 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 710 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 711 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 712 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 713 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL), 714 }; 715 716 static const char large_mask[] __initconst = "33333333,11111111,33333333,11111111," 717 "33333333,11111111,33333333,11111111," 718 "33333333,11111111,33333333,11111111," 719 "33333333,11111111,33333333,11111111," 720 "33333333,11111111,33333333,11111111," 721 "33333333,11111111,33333333,11111111," 722 "33333333,11111111,33333333,11111111," 723 "33333333,11111111,33333333,11111111," 724 "33333333,11111111,33333333,11111111," 725 "33333333,11111111,33333333,11111111," 726 "33333333,11111111,33333333,11111111," 727 "33333333,11111111,33333333,11111111," 728 "33333333,11111111,33333333,11111111," 729 "33333333,11111111,33333333,11111111," 730 "33333333,11111111,33333333,11111111," 731 "33333333,11111111,33333333,11111111," 732 "33333333,11111111,33333333,11111111," 733 "33333333,11111111,33333333,11111111," 734 "33333333,11111111,33333333,11111111," 735 "33333333,11111111,33333333,11111111\n"; 736 737 static const char large_list[] __initconst = /* more than 4KB */ 738 "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" 739 "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" 740 "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" 741 "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" 742 "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" 743 "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" 744 "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" 745 "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" 746 "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" 747 "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" 748 "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" 749 "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" 750 "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-" 751 "1001,1004-1005,1008-1009,1012-1013,1016-1017,1020-1021,1024,1028,1032,1036,1040,1044,1048,1052,1056-1057,1060-10" 752 "61,1064-1065,1068-1069,1072-1073,1076-1077,1080-1081,1084-1085,1088,1092,1096,1100,1104,1108,1112,1116,1120-1121" 753 ",1124-1125,1128-1129,1132-1133,1136-1137,1140-1141,1144-1145,1148-1149,1152,1156,1160,1164,1168,1172,1176,1180,1" 754 "184-1185,1188-1189,1192-1193,1196-1197,1200-1201,1204-1205,1208-1209,1212-1213,1216,1220,1224,1228,1232,1236,124" 755 "0,1244,1248-1249,1252-1253,1256-1257,1260-1261,1264-1265,1268-1269,1272-1273,1276-1277,1280,1284,1288,1292,1296," 756 "1300,1304,1308,1312-1313,1316-1317,1320-1321,1324-1325,1328-1329,1332-1333,1336-1337,1340-1341,1344,1348,1352,13" 757 "56,1360,1364,1368,1372,1376-1377,1380-1381,1384-1385,1388-1389,1392-1393,1396-1397,1400-1401,1404-1405,1408,1412" 758 ",1416,1420,1424,1428,1432,1436,1440-1441,1444-1445,1448-1449,1452-1453,1456-1457,1460-1461,1464-1465,1468-1469,1" 759 "472,1476,1480,1484,1488,1492,1496,1500,1504-1505,1508-1509,1512-1513,1516-1517,1520-1521,1524-1525,1528-1529,153" 760 "2-1533,1536,1540,1544,1548,1552,1556,1560,1564,1568-1569,1572-1573,1576-1577,1580-1581,1584-1585,1588-1589,1592-" 761 "1593,1596-1597,1600,1604,1608,1612,1616,1620,1624,1628,1632-1633,1636-1637,1640-1641,1644-1645,1648-1649,1652-16" 762 "53,1656-1657,1660-1661,1664,1668,1672,1676,1680,1684,1688,1692,1696-1697,1700-1701,1704-1705,1708-1709,1712-1713" 763 ",1716-1717,1720-1721,1724-1725,1728,1732,1736,1740,1744,1748,1752,1756,1760-1761,1764-1765,1768-1769,1772-1773,1" 764 "776-1777,1780-1781,1784-1785,1788-1789,1792,1796,1800,1804,1808,1812,1816,1820,1824-1825,1828-1829,1832-1833,183" 765 "6-1837,1840-1841,1844-1845,1848-1849,1852-1853,1856,1860,1864,1868,1872,1876,1880,1884,1888-1889,1892-1893,1896-" 766 "1897,1900-1901,1904-1905,1908-1909,1912-1913,1916-1917,1920,1924,1928,1932,1936,1940,1944,1948,1952-1953,1956-19" 767 "57,1960-1961,1964-1965,1968-1969,1972-1973,1976-1977,1980-1981,1984,1988,1992,1996,2000,2004,2008,2012,2016-2017" 768 ",2020-2021,2024-2025,2028-2029,2032-2033,2036-2037,2040-2041,2044-2045,2048,2052,2056,2060,2064,2068,2072,2076,2" 769 "080-2081,2084-2085,2088-2089,2092-2093,2096-2097,2100-2101,2104-2105,2108-2109,2112,2116,2120,2124,2128,2132,213" 770 "6,2140,2144-2145,2148-2149,2152-2153,2156-2157,2160-2161,2164-2165,2168-2169,2172-2173,2176,2180,2184,2188,2192," 771 "2196,2200,2204,2208-2209,2212-2213,2216-2217,2220-2221,2224-2225,2228-2229,2232-2233,2236-2237,2240,2244,2248,22" 772 "52,2256,2260,2264,2268,2272-2273,2276-2277,2280-2281,2284-2285,2288-2289,2292-2293,2296-2297,2300-2301,2304,2308" 773 ",2312,2316,2320,2324,2328,2332,2336-2337,2340-2341,2344-2345,2348-2349,2352-2353,2356-2357,2360-2361,2364-2365,2" 774 "368,2372,2376,2380,2384,2388,2392,2396,2400-2401,2404-2405,2408-2409,2412-2413,2416-2417,2420-2421,2424-2425,242" 775 "8-2429,2432,2436,2440,2444,2448,2452,2456,2460,2464-2465,2468-2469,2472-2473,2476-2477,2480-2481,2484-2485,2488-" 776 "2489,2492-2493,2496,2500,2504,2508,2512,2516,2520,2524,2528-2529,2532-2533,2536-2537,2540-2541,2544-2545,2548-25" 777 "49,2552-2553,2556-2557\n"; 778 779 static const struct test_bitmap_print test_print[] __initconst = { 780 { small_bitmap, sizeof(small_bitmap) * BITS_PER_BYTE, small_mask, small_list }, 781 { large_bitmap, sizeof(large_bitmap) * BITS_PER_BYTE, large_mask, large_list }, 782 }; 783 784 static void __init test_bitmap_print_buf(void) 785 { 786 int i; 787 788 for (i = 0; i < ARRAY_SIZE(test_print); i++) { 789 const struct test_bitmap_print *t = &test_print[i]; 790 int n; 791 792 n = bitmap_print_bitmask_to_buf(print_buf, t->bitmap, t->nbits, 793 0, 2 * PAGE_SIZE); 794 expect_eq_uint(strlen(t->mask) + 1, n); 795 expect_eq_str(t->mask, print_buf, n); 796 797 n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits, 798 0, 2 * PAGE_SIZE); 799 expect_eq_uint(strlen(t->list) + 1, n); 800 expect_eq_str(t->list, print_buf, n); 801 802 /* test by non-zero offset */ 803 if (strlen(t->list) > PAGE_SIZE) { 804 n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits, 805 PAGE_SIZE, PAGE_SIZE); 806 expect_eq_uint(strlen(t->list) + 1 - PAGE_SIZE, n); 807 expect_eq_str(t->list + PAGE_SIZE, print_buf, n); 808 } 809 } 810 } 811 812 static void __init selftest(void) 813 { 814 test_zero_clear(); 815 test_fill_set(); 816 test_copy(); 817 test_replace(); 818 test_bitmap_arr32(); 819 test_bitmap_parse(); 820 test_bitmap_parselist(); 821 test_mem_optimisations(); 822 test_for_each_set_clump8(); 823 test_bitmap_cut(); 824 test_bitmap_print_buf(); 825 } 826 827 KSTM_MODULE_LOADERS(test_bitmap); 828 MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>"); 829 MODULE_LICENSE("GPL"); 830