blob: 0c82f07f74fcba6ae31ea7603da7c57a111339ad [file] [log] [blame]
Thomas Gleixner09c434b2019-05-19 13:08:20 +01001// SPDX-License-Identifier: GPL-2.0-only
David Decotigny5fd003f2016-02-19 09:24:00 -05002/*
Andy Shevchenko780ff332019-12-04 16:53:23 -08003 * Test cases for bitmap API.
David Decotigny5fd003f2016-02-19 09:24:00 -05004 */
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>
Yury Norov6ea86bd2019-05-14 15:43:24 -070015#include <linux/uaccess.h>
David Decotigny5fd003f2016-02-19 09:24:00 -050016
Tobin C. Harding6b1a4d52019-04-05 12:58:57 +110017#include "../tools/testing/selftests/kselftest_module.h"
18
Timur Tabi4e89a782021-02-14 10:13:46 -060019KSTM_MODULE_GLOBALS();
David Decotigny5fd003f2016-02-19 09:24:00 -050020
21static char pbl_buffer[PAGE_SIZE] __initdata;
Barry Song291f93c2021-08-06 23:02:48 +120022static char print_buf[PAGE_SIZE * 2] __initdata;
David Decotigny5fd003f2016-02-19 09:24:00 -050023
Andy Shevchenkoc21dd8a2019-12-04 16:53:20 -080024static 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),
Paul Gortmaker97330db2021-02-21 03:08:22 -050038 BITMAP_FROM_U64(0x00008000),
39 BITMAP_FROM_U64(0x80000000),
Andy Shevchenkoc21dd8a2019-12-04 16:53:20 -080040};
41
42static const unsigned long exp2[] __initconst = {
43 BITMAP_FROM_U64(0x3333333311111111ULL),
44 BITMAP_FROM_U64(0xffffffff77777777ULL),
45};
David Decotigny5fd003f2016-02-19 09:24:00 -050046
Andy Shevchenko30544ed2019-12-04 16:53:26 -080047/* 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
David Decotigny5fd003f2016-02-19 09:24:00 -050060static 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) {
Yury Norov3aa56882018-02-06 15:38:06 -080065 pr_err("[%s:%u] expected %u, got %u\n",
David Decotigny5fd003f2016-02-19 09:24:00 -050066 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,
Yury Norov3aa56882018-02-06 15:38:06 -080075 const unsigned long *exp_bmap, const unsigned long *bmap,
76 unsigned int nbits)
David Decotigny5fd003f2016-02-19 09:24:00 -050077{
David Decotigny5fd003f2016-02-19 09:24:00 -050078 if (!bitmap_equal(exp_bmap, bmap, nbits)) {
79 pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n",
80 srcfile, line,
Yury Norov3aa56882018-02-06 15:38:06 -080081 nbits, exp_bmap, nbits, bmap);
David Decotigny5fd003f2016-02-19 09:24:00 -050082 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,
Yury Norov3aa56882018-02-06 15:38:06 -0800105 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,
David Decotigny5fd003f2016-02-19 09:24:00 -0500109 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
William Breathitt Graye4aa1682019-12-04 16:51:01 -0800130static 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
Barry Song291f93c2021-08-06 23:02:48 +1200160static 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
David Decotigny5fd003f2016-02-19 09:24:00 -0500174#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__)
William Breathitt Graye4aa1682019-12-04 16:51:01 -0800190#define expect_eq_clump8(...) __expect_eq(clump8, ##__VA_ARGS__)
Barry Song291f93c2021-08-06 23:02:48 +1200191#define expect_eq_str(...) __expect_eq(str, ##__VA_ARGS__)
David Decotigny5fd003f2016-02-19 09:24:00 -0500192
Andy Shevchenkoee3527bd2018-02-06 15:38:10 -0800193static 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
Andy Shevchenko978f3692018-02-06 15:38:13 -0800222static 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
Andy Shevchenkofe818142018-02-06 15:38:17 -0800251static void __init test_copy(void)
David Decotigny5fd003f2016-02-19 09:24:00 -0500252{
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 */
Andy Shevchenkofe818142018-02-06 15:38:17 -0800260 bitmap_set(bmap1, 0, 19);
David Decotigny5fd003f2016-02-19 09:24:00 -0500261 bitmap_copy(bmap2, bmap1, 23);
262 expect_eq_pbl("0-18", bmap2, 1024);
263
Andy Shevchenkofe818142018-02-06 15:38:17 -0800264 bitmap_set(bmap2, 0, 23);
David Decotigny5fd003f2016-02-19 09:24:00 -0500265 bitmap_copy(bmap2, bmap1, 23);
266 expect_eq_pbl("0-18", bmap2, 1024);
267
David Decotigny5fd003f2016-02-19 09:24:00 -0500268 /* multi-word bitmaps */
Andy Shevchenkofe818142018-02-06 15:38:17 -0800269 bitmap_set(bmap1, 0, 109);
David Decotigny5fd003f2016-02-19 09:24:00 -0500270 bitmap_copy(bmap2, bmap1, 1024);
271 expect_eq_pbl("0-108", bmap2, 1024);
272
273 bitmap_fill(bmap2, 1024);
David Decotigny5fd003f2016-02-19 09:24:00 -0500274 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);
David Decotigny5fd003f2016-02-19 09:24:00 -0500288}
289
Andy Shevchenko30544ed2019-12-04 16:53:26 -0800290#define EXP2_IN_BITS (sizeof(exp2) * 8)
291
292static void __init test_replace(void)
293{
294 unsigned int nbits = 64;
Andy Shevchenko69334ca2020-01-30 22:11:01 -0800295 unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG);
Andy Shevchenko30544ed2019-12-04 16:53:26 -0800296 DECLARE_BITMAP(bmap, 1024);
297
Andy Shevchenkocaa7f772020-04-06 20:10:28 -0700298 BUILD_BUG_ON(EXP2_IN_BITS < nbits * 2);
299
Andy Shevchenko30544ed2019-12-04 16:53:26 -0800300 bitmap_zero(bmap, 1024);
Andy Shevchenko69334ca2020-01-30 22:11:01 -0800301 bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
Andy Shevchenko30544ed2019-12-04 16:53:26 -0800302 expect_eq_bitmap(bmap, exp3_0_1, nbits);
303
304 bitmap_zero(bmap, 1024);
Andy Shevchenko69334ca2020-01-30 22:11:01 -0800305 bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
Andy Shevchenko30544ed2019-12-04 16:53:26 -0800306 expect_eq_bitmap(bmap, exp3_1_0, nbits);
307
308 bitmap_fill(bmap, 1024);
Andy Shevchenko69334ca2020-01-30 22:11:01 -0800309 bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
Andy Shevchenko30544ed2019-12-04 16:53:26 -0800310 expect_eq_bitmap(bmap, exp3_0_1, nbits);
311
312 bitmap_fill(bmap, 1024);
Andy Shevchenko69334ca2020-01-30 22:11:01 -0800313 bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
Andy Shevchenko30544ed2019-12-04 16:53:26 -0800314 expect_eq_bitmap(bmap, exp3_1_0, nbits);
315}
316
Yury Norov7eb2e942020-02-03 17:37:27 -0800317#define PARSE_TIME 0x1
318#define NO_LEN 0x2
Yury Norov6df0d462017-09-08 16:15:38 -0700319
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
Yury Norov6df0d462017-09-08 16:15:38 -0700328static const struct test_bitmap_parselist parselist_tests[] __initconst = {
Yury Norov60ef6902017-09-08 16:15:41 -0700329#define step (sizeof(u64) / sizeof(unsigned long))
330
Andy Shevchenko0ee312e2019-12-04 16:53:17 -0800331 {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},
Yury Norov6df0d462017-09-08 16:15:38 -0700344
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
Andy Shevchenko0ee312e2019-12-04 16:53:17 -0800349 {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},
Yury Norova4ab5052019-05-14 15:43:21 -0700354
Paul Gortmaker97330db2021-02-21 03:08:22 -0500355 {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
Paul Gortmaker99c58d12021-02-21 03:08:26 -0500372 {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},
Paul Gortmaker97330db2021-02-21 03:08:22 -0500382 {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
Yury Norovb18def12021-04-20 20:13:25 -0700385 {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
Yury Norov6df0d462017-09-08 16:15:38 -0700392 {-EINVAL, "-1", NULL, 8, 0},
393 {-EINVAL, "-0", NULL, 8, 0},
394 {-EINVAL, "10-1", NULL, 8, 0},
Paul Gortmaker6fef5902021-02-21 03:08:21 -0500395 {-ERANGE, "8-8", NULL, 8, 0},
396 {-ERANGE, "0-31", NULL, 8, 0},
Paul Gortmaker494215f2021-02-21 03:08:20 -0500397 {-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},
Yury Norova4ab5052019-05-14 15:43:21 -0700403 {-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},
Andy Shevchenko54224042019-12-04 16:53:09 -0800410
Yury Norov6df0d462017-09-08 16:15:38 -0700411};
412
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200413static void __init test_bitmap_parselist(void)
Yury Norov6df0d462017-09-08 16:15:38 -0700414{
415 int i;
416 int err;
Yury Norov0c2111a2019-05-14 15:43:18 -0700417 ktime_t time;
Yury Norov6df0d462017-09-08 16:15:38 -0700418 DECLARE_BITMAP(bmap, 2048);
419
420 for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) {
421#define ptest parselist_tests[i]
422
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200423 time = ktime_get();
424 err = bitmap_parselist(ptest.in, bmap, ptest.nbits);
425 time = ktime_get() - time;
Yury Norov6df0d462017-09-08 16:15:38 -0700426
427 if (err != ptest.errno) {
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200428 pr_err("parselist: %d: input is %s, errno is %d, expected %d\n",
429 i, ptest.in, err, ptest.errno);
Yury Norov6df0d462017-09-08 16:15:38 -0700430 continue;
431 }
432
433 if (!err && ptest.expected
434 && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) {
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200435 pr_err("parselist: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
436 i, ptest.in, bmap[0],
Yury Norov6ea86bd2019-05-14 15:43:24 -0700437 *ptest.expected);
Yury Norov6df0d462017-09-08 16:15:38 -0700438 continue;
439 }
440
441 if (ptest.flags & PARSE_TIME)
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200442 pr_err("parselist: %d: input is '%s' OK, Time: %llu\n",
443 i, ptest.in, time);
Andy Shevchenko54224042019-12-04 16:53:09 -0800444
445#undef ptest
Yury Norov6df0d462017-09-08 16:15:38 -0700446 }
447}
448
Yury Norovdb731302021-08-14 14:17:12 -0700449static 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
Yury Norov7eb2e942020-02-03 17:37:27 -0800485static 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 = {
Yury Norov809e3082020-02-03 17:37:38 -0800499 {0, "", &parse_test[0 * step], 32, 0},
500 {0, " ", &parse_test[0 * step], 32, 0},
Yury Norov7eb2e942020-02-03 17:37:27 -0800501 {0, "0", &parse_test[0 * step], 32, 0},
Yury Norov809e3082020-02-03 17:37:38 -0800502 {0, "0\n", &parse_test[0 * step], 32, 0},
Yury Norov7eb2e942020-02-03 17:37:27 -0800503 {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},
Yury Norov809e3082020-02-03 17:37:38 -0800506 {0, "deadbeef,\n,0,1", &parse_test[2 * step], 96, 0},
Yury Norov7eb2e942020-02-03 17:37:27 -0800507
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},
Yury Norov809e3082020-02-03 17:37:38 -0800511 {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},
Yury Norov7eb2e942020-02-03 17:37:27 -0800515
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
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200525static void __init test_bitmap_parse(void)
Yury Norov7eb2e942020-02-03 17:37:27 -0800526{
527 int i;
528 int err;
529 ktime_t time;
530 DECLARE_BITMAP(bmap, 2048);
Yury Norov7eb2e942020-02-03 17:37:27 -0800531
532 for (i = 0; i < ARRAY_SIZE(parse_tests); i++) {
533 struct test_bitmap_parselist test = parse_tests[i];
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200534 size_t len = test.flags & NO_LEN ? UINT_MAX : strlen(test.in);
Yury Norov7eb2e942020-02-03 17:37:27 -0800535
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200536 time = ktime_get();
537 err = bitmap_parse(test.in, len, bmap, test.nbits);
538 time = ktime_get() - time;
Yury Norov7eb2e942020-02-03 17:37:27 -0800539
540 if (err != test.errno) {
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200541 pr_err("parse: %d: input is %s, errno is %d, expected %d\n",
542 i, test.in, err, test.errno);
Yury Norov7eb2e942020-02-03 17:37:27 -0800543 continue;
544 }
545
546 if (!err && test.expected
547 && !__bitmap_equal(bmap, test.expected, test.nbits)) {
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200548 pr_err("parse: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
549 i, test.in, bmap[0],
Yury Norov7eb2e942020-02-03 17:37:27 -0800550 *test.expected);
551 continue;
552 }
553
554 if (test.flags & PARSE_TIME)
Christoph Hellwig81b1e242020-09-03 16:22:36 +0200555 pr_err("parse: %d: input is '%s' OK, Time: %llu\n",
556 i, test.in, time);
Yury Norov7eb2e942020-02-03 17:37:27 -0800557 }
558}
559
Andy Shevchenko0ee312e2019-12-04 16:53:17 -0800560#define EXP1_IN_BITS (sizeof(exp1) * 8)
Kees Cookf6f66c12018-04-10 16:32:54 -0700561
Yury Norov3aa56882018-02-06 15:38:06 -0800562static void __init test_bitmap_arr32(void)
David Decotigny5fd003f2016-02-19 09:24:00 -0500563{
Kees Cookf6f66c12018-04-10 16:32:54 -0700564 unsigned int nbits, next_bit;
Andy Shevchenkoa4881d12019-12-04 16:53:13 -0800565 u32 arr[EXP1_IN_BITS / 32];
566 DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
David Decotigny5fd003f2016-02-19 09:24:00 -0500567
Yury Norov3aa56882018-02-06 15:38:06 -0800568 memset(arr, 0xa5, sizeof(arr));
David Decotigny5fd003f2016-02-19 09:24:00 -0500569
Andy Shevchenkoa4881d12019-12-04 16:53:13 -0800570 for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
Andy Shevchenko0ee312e2019-12-04 16:53:17 -0800571 bitmap_to_arr32(arr, exp1, nbits);
Yury Norov3aa56882018-02-06 15:38:06 -0800572 bitmap_from_arr32(bmap2, arr, nbits);
Andy Shevchenko0ee312e2019-12-04 16:53:17 -0800573 expect_eq_bitmap(bmap2, exp1, nbits);
David Decotigny5fd003f2016-02-19 09:24:00 -0500574
Yury Norov3aa56882018-02-06 15:38:06 -0800575 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);
David Decotigny5fd003f2016-02-19 09:24:00 -0500581
Andy Shevchenkoa4881d12019-12-04 16:53:13 -0800582 if (nbits < EXP1_IN_BITS - 32)
Yury Norov3aa56882018-02-06 15:38:06 -0800583 expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
584 0xa5a5a5a5);
David Decotigny5fd003f2016-02-19 09:24:00 -0500585 }
586}
587
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700588static void noinline __init test_mem_optimisations(void)
589{
590 DECLARE_BITMAP(bmap1, 1024);
591 DECLARE_BITMAP(bmap2, 1024);
592 unsigned int start, nbits;
593
594 for (start = 0; start < 1024; start += 8) {
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700595 for (nbits = 0; nbits < 1024 - start; nbits += 8) {
Matthew Wilcox1e3054b2018-05-18 16:08:44 -0700596 memset(bmap1, 0x5a, sizeof(bmap1));
597 memset(bmap2, 0x5a, sizeof(bmap2));
598
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700599 bitmap_set(bmap1, start, nbits);
600 __bitmap_set(bmap2, start, nbits);
Matthew Wilcox1e3054b2018-05-18 16:08:44 -0700601 if (!bitmap_equal(bmap1, bmap2, 1024)) {
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700602 printk("set not equal %d %d\n", start, nbits);
Matthew Wilcox1e3054b2018-05-18 16:08:44 -0700603 failed_tests++;
604 }
605 if (!__bitmap_equal(bmap1, bmap2, 1024)) {
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700606 printk("set not __equal %d %d\n", start, nbits);
Matthew Wilcox1e3054b2018-05-18 16:08:44 -0700607 failed_tests++;
608 }
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700609
610 bitmap_clear(bmap1, start, nbits);
611 __bitmap_clear(bmap2, start, nbits);
Matthew Wilcox1e3054b2018-05-18 16:08:44 -0700612 if (!bitmap_equal(bmap1, bmap2, 1024)) {
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700613 printk("clear not equal %d %d\n", start, nbits);
Matthew Wilcox1e3054b2018-05-18 16:08:44 -0700614 failed_tests++;
615 }
616 if (!__bitmap_equal(bmap1, bmap2, 1024)) {
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700617 printk("clear not __equal %d %d\n", start,
618 nbits);
Matthew Wilcox1e3054b2018-05-18 16:08:44 -0700619 failed_tests++;
620 }
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700621 }
622 }
623}
624
William Breathitt Graye4aa1682019-12-04 16:51:01 -0800625static const unsigned char clump_exp[] __initconst = {
626 0x01, /* 1 bit set */
627 0x02, /* non-edge 1 bit set */
628 0x00, /* zero bits set */
629 0x38, /* 3 bits set across 4-bit boundary */
630 0x38, /* Repeated clump */
631 0x0F, /* 4 bits set */
632 0xFF, /* all bits set */
633 0x05, /* non-adjacent 2 bits set */
634};
635
636static void __init test_for_each_set_clump8(void)
637{
638#define CLUMP_EXP_NUMBITS 64
639 DECLARE_BITMAP(bits, CLUMP_EXP_NUMBITS);
640 unsigned int start;
641 unsigned long clump;
642
643 /* set bitmap to test case */
644 bitmap_zero(bits, CLUMP_EXP_NUMBITS);
645 bitmap_set(bits, 0, 1); /* 0x01 */
646 bitmap_set(bits, 9, 1); /* 0x02 */
647 bitmap_set(bits, 27, 3); /* 0x28 */
648 bitmap_set(bits, 35, 3); /* 0x28 */
649 bitmap_set(bits, 40, 4); /* 0x0F */
650 bitmap_set(bits, 48, 8); /* 0xFF */
651 bitmap_set(bits, 56, 1); /* 0x05 - part 1 */
652 bitmap_set(bits, 58, 1); /* 0x05 - part 2 */
653
654 for_each_set_clump8(start, clump, bits, CLUMP_EXP_NUMBITS)
655 expect_eq_clump8(start, CLUMP_EXP_NUMBITS, clump_exp, &clump);
656}
657
Stefano Briviobcb32a12020-08-11 18:34:32 -0700658struct test_bitmap_cut {
659 unsigned int first;
660 unsigned int cut;
661 unsigned int nbits;
662 unsigned long in[4];
663 unsigned long expected[4];
664};
665
666static struct test_bitmap_cut test_cut[] = {
667 { 0, 0, 8, { 0x0000000aUL, }, { 0x0000000aUL, }, },
668 { 0, 0, 32, { 0xdadadeadUL, }, { 0xdadadeadUL, }, },
669 { 0, 3, 8, { 0x000000aaUL, }, { 0x00000015UL, }, },
670 { 3, 3, 8, { 0x000000aaUL, }, { 0x00000012UL, }, },
671 { 0, 1, 32, { 0xa5a5a5a5UL, }, { 0x52d2d2d2UL, }, },
672 { 0, 8, 32, { 0xdeadc0deUL, }, { 0x00deadc0UL, }, },
673 { 1, 1, 32, { 0x5a5a5a5aUL, }, { 0x2d2d2d2cUL, }, },
674 { 0, 15, 32, { 0xa5a5a5a5UL, }, { 0x00014b4bUL, }, },
675 { 0, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
676 { 15, 15, 32, { 0xa5a5a5a5UL, }, { 0x000125a5UL, }, },
677 { 15, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
678 { 16, 15, 32, { 0xa5a5a5a5UL, }, { 0x0001a5a5UL, }, },
679
680 { BITS_PER_LONG, BITS_PER_LONG, BITS_PER_LONG,
681 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
682 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
683 },
684 { 1, BITS_PER_LONG - 1, BITS_PER_LONG,
685 { 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
686 { 0x00000001UL, 0x00000001UL, },
687 },
688
689 { 0, BITS_PER_LONG * 2, BITS_PER_LONG * 2 + 1,
690 { 0xa5a5a5a5UL, 0x00000001UL, 0x00000001UL, 0x00000001UL },
691 { 0x00000001UL, },
692 },
693 { 16, BITS_PER_LONG * 2 + 1, BITS_PER_LONG * 2 + 1 + 16,
694 { 0x0000ffffUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL },
695 { 0x2d2dffffUL, },
696 },
697};
698
699static void __init test_bitmap_cut(void)
700{
701 unsigned long b[5], *in = &b[1], *out = &b[0]; /* Partial overlap */
702 int i;
703
704 for (i = 0; i < ARRAY_SIZE(test_cut); i++) {
705 struct test_bitmap_cut *t = &test_cut[i];
706
707 memcpy(in, t->in, sizeof(t->in));
708
709 bitmap_cut(out, in, t->first, t->cut, t->nbits);
710
711 expect_eq_bitmap(t->expected, out, t->nbits);
712 }
713}
714
Barry Song291f93c2021-08-06 23:02:48 +1200715struct test_bitmap_print {
716 const unsigned long *bitmap;
717 unsigned long nbits;
718 const char *mask;
719 const char *list;
720};
721
722static const unsigned long small_bitmap[] __initconst = {
723 BITMAP_FROM_U64(0x3333333311111111ULL),
724};
725
726static const char small_mask[] __initconst = "33333333,11111111\n";
727static 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";
728
729static const unsigned long large_bitmap[] __initconst = {
730 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
731 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
732 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
733 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
734 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
735 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
736 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
737 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
738 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
739 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
740 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
741 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
742 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
743 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
744 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
745 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
746 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
747 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
748 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
749 BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
750};
751
752static const char large_mask[] __initconst = "33333333,11111111,33333333,11111111,"
753 "33333333,11111111,33333333,11111111,"
754 "33333333,11111111,33333333,11111111,"
755 "33333333,11111111,33333333,11111111,"
756 "33333333,11111111,33333333,11111111,"
757 "33333333,11111111,33333333,11111111,"
758 "33333333,11111111,33333333,11111111,"
759 "33333333,11111111,33333333,11111111,"
760 "33333333,11111111,33333333,11111111,"
761 "33333333,11111111,33333333,11111111,"
762 "33333333,11111111,33333333,11111111,"
763 "33333333,11111111,33333333,11111111,"
764 "33333333,11111111,33333333,11111111,"
765 "33333333,11111111,33333333,11111111,"
766 "33333333,11111111,33333333,11111111,"
767 "33333333,11111111,33333333,11111111,"
768 "33333333,11111111,33333333,11111111,"
769 "33333333,11111111,33333333,11111111,"
770 "33333333,11111111,33333333,11111111,"
771 "33333333,11111111,33333333,11111111\n";
772
773static const char large_list[] __initconst = /* more than 4KB */
774 "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"
775 "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"
776 "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"
777 "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"
778 "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"
779 "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"
780 "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"
781 "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"
782 "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"
783 "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"
784 "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"
785 "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"
786 "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-"
787 "1001,1004-1005,1008-1009,1012-1013,1016-1017,1020-1021,1024,1028,1032,1036,1040,1044,1048,1052,1056-1057,1060-10"
788 "61,1064-1065,1068-1069,1072-1073,1076-1077,1080-1081,1084-1085,1088,1092,1096,1100,1104,1108,1112,1116,1120-1121"
789 ",1124-1125,1128-1129,1132-1133,1136-1137,1140-1141,1144-1145,1148-1149,1152,1156,1160,1164,1168,1172,1176,1180,1"
790 "184-1185,1188-1189,1192-1193,1196-1197,1200-1201,1204-1205,1208-1209,1212-1213,1216,1220,1224,1228,1232,1236,124"
791 "0,1244,1248-1249,1252-1253,1256-1257,1260-1261,1264-1265,1268-1269,1272-1273,1276-1277,1280,1284,1288,1292,1296,"
792 "1300,1304,1308,1312-1313,1316-1317,1320-1321,1324-1325,1328-1329,1332-1333,1336-1337,1340-1341,1344,1348,1352,13"
793 "56,1360,1364,1368,1372,1376-1377,1380-1381,1384-1385,1388-1389,1392-1393,1396-1397,1400-1401,1404-1405,1408,1412"
794 ",1416,1420,1424,1428,1432,1436,1440-1441,1444-1445,1448-1449,1452-1453,1456-1457,1460-1461,1464-1465,1468-1469,1"
795 "472,1476,1480,1484,1488,1492,1496,1500,1504-1505,1508-1509,1512-1513,1516-1517,1520-1521,1524-1525,1528-1529,153"
796 "2-1533,1536,1540,1544,1548,1552,1556,1560,1564,1568-1569,1572-1573,1576-1577,1580-1581,1584-1585,1588-1589,1592-"
797 "1593,1596-1597,1600,1604,1608,1612,1616,1620,1624,1628,1632-1633,1636-1637,1640-1641,1644-1645,1648-1649,1652-16"
798 "53,1656-1657,1660-1661,1664,1668,1672,1676,1680,1684,1688,1692,1696-1697,1700-1701,1704-1705,1708-1709,1712-1713"
799 ",1716-1717,1720-1721,1724-1725,1728,1732,1736,1740,1744,1748,1752,1756,1760-1761,1764-1765,1768-1769,1772-1773,1"
800 "776-1777,1780-1781,1784-1785,1788-1789,1792,1796,1800,1804,1808,1812,1816,1820,1824-1825,1828-1829,1832-1833,183"
801 "6-1837,1840-1841,1844-1845,1848-1849,1852-1853,1856,1860,1864,1868,1872,1876,1880,1884,1888-1889,1892-1893,1896-"
802 "1897,1900-1901,1904-1905,1908-1909,1912-1913,1916-1917,1920,1924,1928,1932,1936,1940,1944,1948,1952-1953,1956-19"
803 "57,1960-1961,1964-1965,1968-1969,1972-1973,1976-1977,1980-1981,1984,1988,1992,1996,2000,2004,2008,2012,2016-2017"
804 ",2020-2021,2024-2025,2028-2029,2032-2033,2036-2037,2040-2041,2044-2045,2048,2052,2056,2060,2064,2068,2072,2076,2"
805 "080-2081,2084-2085,2088-2089,2092-2093,2096-2097,2100-2101,2104-2105,2108-2109,2112,2116,2120,2124,2128,2132,213"
806 "6,2140,2144-2145,2148-2149,2152-2153,2156-2157,2160-2161,2164-2165,2168-2169,2172-2173,2176,2180,2184,2188,2192,"
807 "2196,2200,2204,2208-2209,2212-2213,2216-2217,2220-2221,2224-2225,2228-2229,2232-2233,2236-2237,2240,2244,2248,22"
808 "52,2256,2260,2264,2268,2272-2273,2276-2277,2280-2281,2284-2285,2288-2289,2292-2293,2296-2297,2300-2301,2304,2308"
809 ",2312,2316,2320,2324,2328,2332,2336-2337,2340-2341,2344-2345,2348-2349,2352-2353,2356-2357,2360-2361,2364-2365,2"
810 "368,2372,2376,2380,2384,2388,2392,2396,2400-2401,2404-2405,2408-2409,2412-2413,2416-2417,2420-2421,2424-2425,242"
811 "8-2429,2432,2436,2440,2444,2448,2452,2456,2460,2464-2465,2468-2469,2472-2473,2476-2477,2480-2481,2484-2485,2488-"
812 "2489,2492-2493,2496,2500,2504,2508,2512,2516,2520,2524,2528-2529,2532-2533,2536-2537,2540-2541,2544-2545,2548-25"
813 "49,2552-2553,2556-2557\n";
814
815static const struct test_bitmap_print test_print[] __initconst = {
816 { small_bitmap, sizeof(small_bitmap) * BITS_PER_BYTE, small_mask, small_list },
817 { large_bitmap, sizeof(large_bitmap) * BITS_PER_BYTE, large_mask, large_list },
818};
819
820static void __init test_bitmap_print_buf(void)
821{
822 int i;
823
824 for (i = 0; i < ARRAY_SIZE(test_print); i++) {
825 const struct test_bitmap_print *t = &test_print[i];
826 int n;
827
828 n = bitmap_print_bitmask_to_buf(print_buf, t->bitmap, t->nbits,
829 0, 2 * PAGE_SIZE);
830 expect_eq_uint(strlen(t->mask) + 1, n);
831 expect_eq_str(t->mask, print_buf, n);
832
833 n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
834 0, 2 * PAGE_SIZE);
835 expect_eq_uint(strlen(t->list) + 1, n);
836 expect_eq_str(t->list, print_buf, n);
837
838 /* test by non-zero offset */
839 if (strlen(t->list) > PAGE_SIZE) {
840 n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
841 PAGE_SIZE, PAGE_SIZE);
842 expect_eq_uint(strlen(t->list) + 1 - PAGE_SIZE, n);
843 expect_eq_str(t->list + PAGE_SIZE, print_buf, n);
844 }
845 }
846}
847
Tobin C. Harding6b1a4d52019-04-05 12:58:57 +1100848static void __init selftest(void)
David Decotigny5fd003f2016-02-19 09:24:00 -0500849{
Andy Shevchenkoee3527bd2018-02-06 15:38:10 -0800850 test_zero_clear();
Andy Shevchenko978f3692018-02-06 15:38:13 -0800851 test_fill_set();
Andy Shevchenkofe818142018-02-06 15:38:17 -0800852 test_copy();
Andy Shevchenko30544ed2019-12-04 16:53:26 -0800853 test_replace();
Yury Norov3aa56882018-02-06 15:38:06 -0800854 test_bitmap_arr32();
Yury Norov7eb2e942020-02-03 17:37:27 -0800855 test_bitmap_parse();
Yury Norov6df0d462017-09-08 16:15:38 -0700856 test_bitmap_parselist();
Yury Norovdb731302021-08-14 14:17:12 -0700857 test_bitmap_printlist();
Matthew Wilcox3cc78122017-07-10 15:51:26 -0700858 test_mem_optimisations();
William Breathitt Graye4aa1682019-12-04 16:51:01 -0800859 test_for_each_set_clump8();
Stefano Briviobcb32a12020-08-11 18:34:32 -0700860 test_bitmap_cut();
Barry Song291f93c2021-08-06 23:02:48 +1200861 test_bitmap_print_buf();
David Decotigny5fd003f2016-02-19 09:24:00 -0500862}
863
Tobin C. Harding6b1a4d52019-04-05 12:58:57 +1100864KSTM_MODULE_LOADERS(test_bitmap);
David Decotigny5fd003f2016-02-19 09:24:00 -0500865MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>");
866MODULE_LICENSE("GPL");