Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
19KSTM_MODULE_GLOBALS();
20
21static char pbl_buffer[PAGE_SIZE] __initdata;
22static char print_buf[PAGE_SIZE * 2] __initdata;
23
24static 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
42static const unsigned long exp2[] __initconst = {
43 BITMAP_FROM_U64(0x3333333311111111ULL),
44 BITMAP_FROM_U64(0xffffffff77777777ULL),
45};
46
47/* Fibonacci sequence */
48static 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) */
52static 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) */
56static const unsigned long exp3_1_0[] __initconst = {
57 BITMAP_FROM_U64(0xff7fffff77575751ULL),
58};
59
60static 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
73static 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
87static 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
102static 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;
106static 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
130static 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
160static 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
193static 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
222static 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
251static 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
292static 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
320struct 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
328static 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
413static 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
449static void __init test_bitmap_printlist(void)
450{
451 unsigned long *bmap = kmalloc(PAGE_SIZE, GFP_KERNEL);
452 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
453 char expected[256];
454 int ret, slen;
455 ktime_t time;
456
457 if (!buf || !bmap)
458 goto out;
459
460 memset(bmap, -1, PAGE_SIZE);
461 slen = snprintf(expected, 256, "0-%ld", PAGE_SIZE * 8 - 1);
462 if (slen < 0)
463 goto out;
464
465 time = ktime_get();
466 ret = bitmap_print_to_pagebuf(true, buf, bmap, PAGE_SIZE * 8);
467 time = ktime_get() - time;
468
469 if (ret != slen + 1) {
470 pr_err("bitmap_print_to_pagebuf: result is %d, expected %d\n", ret, slen);
471 goto out;
472 }
473
474 if (strncmp(buf, expected, slen)) {
475 pr_err("bitmap_print_to_pagebuf: result is %s, expected %s\n", buf, expected);
476 goto out;
477 }
478
479 pr_err("bitmap_print_to_pagebuf: input is '%s', Time: %llu\n", buf, time);
480out:
481 kfree(buf);
482 kfree(bmap);
483}
484
485static const unsigned long parse_test[] __initconst = {
486 BITMAP_FROM_U64(0),
487 BITMAP_FROM_U64(1),
488 BITMAP_FROM_U64(0xdeadbeef),
489 BITMAP_FROM_U64(0x100000000ULL),
490};
491
492static const unsigned long parse_test2[] __initconst = {
493 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xdeadbeef),
494 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xbaadf00ddeadbeef),
495 BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0x0badf00ddeadbeef),
496};
497
498static const struct test_bitmap_parselist parse_tests[] __initconst = {
499 {0, "", &parse_test[0 * step], 32, 0},
500 {0, " ", &parse_test[0 * step], 32, 0},
501 {0, "0", &parse_test[0 * step], 32, 0},
502 {0, "0\n", &parse_test[0 * step], 32, 0},
503 {0, "1", &parse_test[1 * step], 32, 0},
504 {0, "deadbeef", &parse_test[2 * step], 32, 0},
505 {0, "1,0", &parse_test[3 * step], 33, 0},
506 {0, "deadbeef,\n,0,1", &parse_test[2 * step], 96, 0},
507
508 {0, "deadbeef,1,0", &parse_test2[0 * 2 * step], 96, 0},
509 {0, "baadf00d,deadbeef,1,0", &parse_test2[1 * 2 * step], 128, 0},
510 {0, "badf00d,deadbeef,1,0", &parse_test2[2 * 2 * step], 124, 0},
511 {0, "badf00d,deadbeef,1,0", &parse_test2[2 * 2 * step], 124, NO_LEN},
512 {0, " badf00d,deadbeef,1,0 ", &parse_test2[2 * 2 * step], 124, 0},
513 {0, " , badf00d,deadbeef,1,0 , ", &parse_test2[2 * 2 * step], 124, 0},
514 {0, " , badf00d, ,, ,,deadbeef,1,0 , ", &parse_test2[2 * 2 * step], 124, 0},
515
516 {-EINVAL, "goodfood,deadbeef,1,0", NULL, 128, 0},
517 {-EOVERFLOW, "3,0", NULL, 33, 0},
518 {-EOVERFLOW, "123badf00d,deadbeef,1,0", NULL, 128, 0},
519 {-EOVERFLOW, "badf00d,deadbeef,1,0", NULL, 90, 0},
520 {-EOVERFLOW, "fbadf00d,deadbeef,1,0", NULL, 95, 0},
521 {-EOVERFLOW, "badf00d,deadbeef,1,0", NULL, 100, 0},
522#undef step
523};
524
525static void __init test_bitmap_parse(void)
526{
527 int i;
528 int err;
529 ktime_t time;
530 DECLARE_BITMAP(bmap, 2048);
531
532 for (i = 0; i < ARRAY_SIZE(parse_tests); i++) {
533 struct test_bitmap_parselist test = parse_tests[i];
534 size_t len = test.flags & NO_LEN ? UINT_MAX : strlen(test.in);
535
536 time = ktime_get();
537 err = bitmap_parse(test.in, len, bmap, test.nbits);
538 time = ktime_get() - time;
539
540 if (err != test.errno) {
541 pr_err("parse: %d: input is %s, errno is %d, expected %d\n",
542 i, test.in, err, test.errno);
543 continue;
544 }
545
546 if (!err && test.expected
547 && !__bitmap_equal(bmap, test.expected, test.nbits)) {
548 pr_err("parse: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
549 i, test.in, bmap[0],
550 *test.expected);
551 continue;
552 }
553
554 if (test.flags & PARSE_TIME)
555 pr_err("parse: %d: input is '%s' OK, Time: %llu\n",
556 i, test.in, time);
557 }
558}
559
560#define EXP1_IN_BITS (sizeof(exp1) * 8)
561
562static void __init test_bitmap_arr32(void)
563{
564 unsigned int nbits, next_bit;
565 u32 arr[EXP1_IN_BITS / 32];
566 DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
567
568 memset(arr, 0xa5, sizeof(arr));
569
570 for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
571 bitmap_to_arr32(arr, exp1, nbits);
572 bitmap_from_arr32(bmap2, arr, nbits);
573 expect_eq_bitmap(bmap2, exp1, nbits);
574
575 next_bit = find_next_bit(bmap2,
576 round_up(nbits, BITS_PER_LONG), nbits);
577 if (next_bit < round_up(nbits, BITS_PER_LONG))
578 pr_err("bitmap_copy_arr32(nbits == %d:"
579 " tail is not safely cleared: %d\n",
580 nbits, next_bit);
581
582 if (nbits < EXP1_IN_BITS - 32)
583 expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
584 0xa5a5a5a5);
585 }
586}
587
588static void __init test_bitmap_arr64(void)
589{
590 unsigned int nbits, next_bit;
591 u64 arr[EXP1_IN_BITS / 64];
592 DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
593
594 memset(arr, 0xa5, sizeof(arr));
595
596 for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
597 memset(bmap2, 0xff, sizeof(arr));
598 bitmap_to_arr64(arr, exp1, nbits);
599 bitmap_from_arr64(bmap2, arr, nbits);
600 expect_eq_bitmap(bmap2, exp1, nbits);
601
602 next_bit = find_next_bit(bmap2, round_up(nbits, BITS_PER_LONG), nbits);
603 if (next_bit < round_up(nbits, BITS_PER_LONG))
604 pr_err("bitmap_copy_arr64(nbits == %d:"
605 " tail is not safely cleared: %d\n", nbits, next_bit);
606
607 if (nbits < EXP1_IN_BITS - 64)
608 expect_eq_uint(arr[DIV_ROUND_UP(nbits, 64)], 0xa5a5a5a5);
609 }
610}
611
612static void noinline __init test_mem_optimisations(void)
613{
614 DECLARE_BITMAP(bmap1, 1024);
615 DECLARE_BITMAP(bmap2, 1024);
616 unsigned int start, nbits;
617
618 for (start = 0; start < 1024; start += 8) {
619 for (nbits = 0; nbits < 1024 - start; nbits += 8) {
620 memset(bmap1, 0x5a, sizeof(bmap1));
621 memset(bmap2, 0x5a, sizeof(bmap2));
622
623 bitmap_set(bmap1, start, nbits);
624 __bitmap_set(bmap2, start, nbits);
625 if (!bitmap_equal(bmap1, bmap2, 1024)) {
626 printk("set not equal %d %d\n", start, nbits);
627 failed_tests++;
628 }
629 if (!__bitmap_equal(bmap1, bmap2, 1024)) {
630 printk("set not __equal %d %d\n", start, nbits);
631 failed_tests++;
632 }
633
634 bitmap_clear(bmap1, start, nbits);
635 __bitmap_clear(bmap2, start, nbits);
636 if (!bitmap_equal(bmap1, bmap2, 1024)) {
637 printk("clear not equal %d %d\n", start, nbits);
638 failed_tests++;
639 }
640 if (!__bitmap_equal(bmap1, bmap2, 1024)) {
641 printk("clear not __equal %d %d\n", start,
642 nbits);
643 failed_tests++;
644 }
645 }
646 }
647}
648
649static const unsigned char clump_exp[] __initconst = {
650 0x01, /* 1 bit set */
651 0x02, /* non-edge 1 bit set */
652 0x00, /* zero bits set */
653 0x38, /* 3 bits set across 4-bit boundary */
654 0x38, /* Repeated clump */
655 0x0F, /* 4 bits set */
656 0xFF, /* all bits set */
657 0x05, /* non-adjacent 2 bits set */
658};
659
660static void __init test_for_each_set_clump8(void)
661{
662#define CLUMP_EXP_NUMBITS 64
663 DECLARE_BITMAP(bits, CLUMP_EXP_NUMBITS);
664 unsigned int start;
665 unsigned long clump;
666
667 /* set bitmap to test case */
668 bitmap_zero(bits, CLUMP_EXP_NUMBITS);
669 bitmap_set(bits, 0, 1); /* 0x01 */
670 bitmap_set(bits, 9, 1); /* 0x02 */
671 bitmap_set(bits, 27, 3); /* 0x28 */
672 bitmap_set(bits, 35, 3); /* 0x28 */
673 bitmap_set(bits, 40, 4); /* 0x0F */
674 bitmap_set(bits, 48, 8); /* 0xFF */
675 bitmap_set(bits, 56, 1); /* 0x05 - part 1 */
676 bitmap_set(bits, 58, 1); /* 0x05 - part 2 */
677
678 for_each_set_clump8(start, clump, bits, CLUMP_EXP_NUMBITS)
679 expect_eq_clump8(start, CLUMP_EXP_NUMBITS, clump_exp, &clump);
680}
681
682struct test_bitmap_cut {
683 unsigned int first;
684 unsigned int cut;
685 unsigned int nbits;
686 unsigned long in[4];
687 unsigned long expected[4];
688};
689
690static struct test_bitmap_cut test_cut[] = {
691 { 0, 0, 8, { 0x0000000aUL, }, { 0x0000000aUL, }, },
692 { 0, 0, 32, { 0xdadadeadUL, }, { 0xdadadeadUL, }, },
693 { 0, 3, 8, { 0x000000aaUL, }, { 0x00000015UL, }, },
694 { 3, 3, 8, { 0x000000aaUL, }, { 0x00000012UL, }, },
695 { 0, 1, 32, { 0xa5a5a5a5UL, }, { 0x52d2d2d2UL, }, },
696 { 0, 8, 32, { 0xdeadc0deUL, }, { 0x00deadc0UL, }, },
697 { 1, 1, 32, { 0x5a5a5a5aUL, }, { 0x2d2d2d2cUL, }, },
698 { 0, 15, 32, { 0xa5a5a5a5UL, }, { 0x00014b4bUL, }, },
699 { 0, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
700 { 15, 15, 32, { 0xa5a5a5a5UL, }, { 0x000125a5UL, }, },
701 { 15, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
702 { 16, 15, 32, { 0xa5a5a5a5UL, }, { 0x0001a5a5UL, }, },
703
704 { BITS_PER_LONG, BITS_PER_LONG, BITS_PER_LONG,
705 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
706 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
707 },
708 { 1, BITS_PER_LONG - 1, BITS_PER_LONG,
709 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
710 { 0x00000001UL, 0x00000001UL, },
711 },
712
713 { 0, BITS_PER_LONG * 2, BITS_PER_LONG * 2 + 1,
714 { 0xa5a5a5a5UL, 0x00000001UL, 0x00000001UL, 0x00000001UL },
715 { 0x00000001UL, },
716 },
717 { 16, BITS_PER_LONG * 2 + 1, BITS_PER_LONG * 2 + 1 + 16,
718 { 0x0000ffffUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL },
719 { 0x2d2dffffUL, },
720 },
721};
722
723static void __init test_bitmap_cut(void)
724{
725 unsigned long b[5], *in = &b[1], *out = &b[0]; /* Partial overlap */
726 int i;
727
728 for (i = 0; i < ARRAY_SIZE(test_cut); i++) {
729 struct test_bitmap_cut *t = &test_cut[i];
730
731 memcpy(in, t->in, sizeof(t->in));
732
733 bitmap_cut(out, in, t->first, t->cut, t->nbits);
734
735 expect_eq_bitmap(t->expected, out, t->nbits);
736 }
737}
738
739struct test_bitmap_print {
740 const unsigned long *bitmap;
741 unsigned long nbits;
742 const char *mask;
743 const char *list;
744};
745
746static const unsigned long small_bitmap[] __initconst = {
747 BITMAP_FROM_U64(0x3333333311111111ULL),
748};
749
750static const char small_mask[] __initconst = "33333333,11111111\n";
751static 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";
752
753static const unsigned long large_bitmap[] __initconst = {
754 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
755 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
756 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
757 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
758 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
759 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
760 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
761 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
762 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
763 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
764 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
765 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
766 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
767 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
768 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
769 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
770 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
771 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
772 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
773 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
774};
775
776static const char large_mask[] __initconst = "33333333,11111111,33333333,11111111,"
777 "33333333,11111111,33333333,11111111,"
778 "33333333,11111111,33333333,11111111,"
779 "33333333,11111111,33333333,11111111,"
780 "33333333,11111111,33333333,11111111,"
781 "33333333,11111111,33333333,11111111,"
782 "33333333,11111111,33333333,11111111,"
783 "33333333,11111111,33333333,11111111,"
784 "33333333,11111111,33333333,11111111,"
785 "33333333,11111111,33333333,11111111,"
786 "33333333,11111111,33333333,11111111,"
787 "33333333,11111111,33333333,11111111,"
788 "33333333,11111111,33333333,11111111,"
789 "33333333,11111111,33333333,11111111,"
790 "33333333,11111111,33333333,11111111,"
791 "33333333,11111111,33333333,11111111,"
792 "33333333,11111111,33333333,11111111,"
793 "33333333,11111111,33333333,11111111,"
794 "33333333,11111111,33333333,11111111,"
795 "33333333,11111111,33333333,11111111\n";
796
797static const char large_list[] __initconst = /* more than 4KB */
798 "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"
799 "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"
800 "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"
801 "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"
802 "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"
803 "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"
804 "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"
805 "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"
806 "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"
807 "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"
808 "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"
809 "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"
810 "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-"
811 "1001,1004-1005,1008-1009,1012-1013,1016-1017,1020-1021,1024,1028,1032,1036,1040,1044,1048,1052,1056-1057,1060-10"
812 "61,1064-1065,1068-1069,1072-1073,1076-1077,1080-1081,1084-1085,1088,1092,1096,1100,1104,1108,1112,1116,1120-1121"
813 ",1124-1125,1128-1129,1132-1133,1136-1137,1140-1141,1144-1145,1148-1149,1152,1156,1160,1164,1168,1172,1176,1180,1"
814 "184-1185,1188-1189,1192-1193,1196-1197,1200-1201,1204-1205,1208-1209,1212-1213,1216,1220,1224,1228,1232,1236,124"
815 "0,1244,1248-1249,1252-1253,1256-1257,1260-1261,1264-1265,1268-1269,1272-1273,1276-1277,1280,1284,1288,1292,1296,"
816 "1300,1304,1308,1312-1313,1316-1317,1320-1321,1324-1325,1328-1329,1332-1333,1336-1337,1340-1341,1344,1348,1352,13"
817 "56,1360,1364,1368,1372,1376-1377,1380-1381,1384-1385,1388-1389,1392-1393,1396-1397,1400-1401,1404-1405,1408,1412"
818 ",1416,1420,1424,1428,1432,1436,1440-1441,1444-1445,1448-1449,1452-1453,1456-1457,1460-1461,1464-1465,1468-1469,1"
819 "472,1476,1480,1484,1488,1492,1496,1500,1504-1505,1508-1509,1512-1513,1516-1517,1520-1521,1524-1525,1528-1529,153"
820 "2-1533,1536,1540,1544,1548,1552,1556,1560,1564,1568-1569,1572-1573,1576-1577,1580-1581,1584-1585,1588-1589,1592-"
821 "1593,1596-1597,1600,1604,1608,1612,1616,1620,1624,1628,1632-1633,1636-1637,1640-1641,1644-1645,1648-1649,1652-16"
822 "53,1656-1657,1660-1661,1664,1668,1672,1676,1680,1684,1688,1692,1696-1697,1700-1701,1704-1705,1708-1709,1712-1713"
823 ",1716-1717,1720-1721,1724-1725,1728,1732,1736,1740,1744,1748,1752,1756,1760-1761,1764-1765,1768-1769,1772-1773,1"
824 "776-1777,1780-1781,1784-1785,1788-1789,1792,1796,1800,1804,1808,1812,1816,1820,1824-1825,1828-1829,1832-1833,183"
825 "6-1837,1840-1841,1844-1845,1848-1849,1852-1853,1856,1860,1864,1868,1872,1876,1880,1884,1888-1889,1892-1893,1896-"
826 "1897,1900-1901,1904-1905,1908-1909,1912-1913,1916-1917,1920,1924,1928,1932,1936,1940,1944,1948,1952-1953,1956-19"
827 "57,1960-1961,1964-1965,1968-1969,1972-1973,1976-1977,1980-1981,1984,1988,1992,1996,2000,2004,2008,2012,2016-2017"
828 ",2020-2021,2024-2025,2028-2029,2032-2033,2036-2037,2040-2041,2044-2045,2048,2052,2056,2060,2064,2068,2072,2076,2"
829 "080-2081,2084-2085,2088-2089,2092-2093,2096-2097,2100-2101,2104-2105,2108-2109,2112,2116,2120,2124,2128,2132,213"
830 "6,2140,2144-2145,2148-2149,2152-2153,2156-2157,2160-2161,2164-2165,2168-2169,2172-2173,2176,2180,2184,2188,2192,"
831 "2196,2200,2204,2208-2209,2212-2213,2216-2217,2220-2221,2224-2225,2228-2229,2232-2233,2236-2237,2240,2244,2248,22"
832 "52,2256,2260,2264,2268,2272-2273,2276-2277,2280-2281,2284-2285,2288-2289,2292-2293,2296-2297,2300-2301,2304,2308"
833 ",2312,2316,2320,2324,2328,2332,2336-2337,2340-2341,2344-2345,2348-2349,2352-2353,2356-2357,2360-2361,2364-2365,2"
834 "368,2372,2376,2380,2384,2388,2392,2396,2400-2401,2404-2405,2408-2409,2412-2413,2416-2417,2420-2421,2424-2425,242"
835 "8-2429,2432,2436,2440,2444,2448,2452,2456,2460,2464-2465,2468-2469,2472-2473,2476-2477,2480-2481,2484-2485,2488-"
836 "2489,2492-2493,2496,2500,2504,2508,2512,2516,2520,2524,2528-2529,2532-2533,2536-2537,2540-2541,2544-2545,2548-25"
837 "49,2552-2553,2556-2557\n";
838
839static const struct test_bitmap_print test_print[] __initconst = {
840 { small_bitmap, sizeof(small_bitmap) * BITS_PER_BYTE, small_mask, small_list },
841 { large_bitmap, sizeof(large_bitmap) * BITS_PER_BYTE, large_mask, large_list },
842};
843
844static void __init test_bitmap_print_buf(void)
845{
846 int i;
847
848 for (i = 0; i < ARRAY_SIZE(test_print); i++) {
849 const struct test_bitmap_print *t = &test_print[i];
850 int n;
851
852 n = bitmap_print_bitmask_to_buf(print_buf, t->bitmap, t->nbits,
853 0, 2 * PAGE_SIZE);
854 expect_eq_uint(strlen(t->mask) + 1, n);
855 expect_eq_str(t->mask, print_buf, n);
856
857 n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
858 0, 2 * PAGE_SIZE);
859 expect_eq_uint(strlen(t->list) + 1, n);
860 expect_eq_str(t->list, print_buf, n);
861
862 /* test by non-zero offset */
863 if (strlen(t->list) > PAGE_SIZE) {
864 n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
865 PAGE_SIZE, PAGE_SIZE);
866 expect_eq_uint(strlen(t->list) + 1 - PAGE_SIZE, n);
867 expect_eq_str(t->list + PAGE_SIZE, print_buf, n);
868 }
869 }
870}
871
872static void __init selftest(void)
873{
874 test_zero_clear();
875 test_fill_set();
876 test_copy();
877 test_replace();
878 test_bitmap_arr32();
879 test_bitmap_arr64();
880 test_bitmap_parse();
881 test_bitmap_parselist();
882 test_bitmap_printlist();
883 test_mem_optimisations();
884 test_for_each_set_clump8();
885 test_bitmap_cut();
886 test_bitmap_print_buf();
887}
888
889KSTM_MODULE_LOADERS(test_bitmap);
890MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>");
891MODULE_LICENSE("GPL");