Blame view

lib/test_bitmap.c 17.5 KB
09c434b8a   Thomas Gleixner   treewide: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0-only
5fd003f56   David Decotigny   test_bitmap: unit...
2
  /*
780ff33b8   Andy Shevchenko   lib/test_bitmap: ...
3
   * Test cases for bitmap API.
5fd003f56   David Decotigny   test_bitmap: unit...
4
5
6
7
8
9
10
11
12
13
14
   */
  
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
  #include <linux/bitmap.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/printk.h>
  #include <linux/slab.h>
  #include <linux/string.h>
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
15
  #include <linux/uaccess.h>
5fd003f56   David Decotigny   test_bitmap: unit...
16

6b1a4d5b1   Tobin C. Harding   lib: Use new ksel...
17
  #include "../tools/testing/selftests/kselftest_module.h"
5fd003f56   David Decotigny   test_bitmap: unit...
18
19
20
21
  static unsigned total_tests __initdata;
  static unsigned failed_tests __initdata;
  
  static char pbl_buffer[PAGE_SIZE] __initdata;
c21dd8a7b   Andy Shevchenko   lib/test_bitmap: ...
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  static const unsigned long exp1[] __initconst = {
  	BITMAP_FROM_U64(1),
  	BITMAP_FROM_U64(2),
  	BITMAP_FROM_U64(0x0000ffff),
  	BITMAP_FROM_U64(0xffff0000),
  	BITMAP_FROM_U64(0x55555555),
  	BITMAP_FROM_U64(0xaaaaaaaa),
  	BITMAP_FROM_U64(0x11111111),
  	BITMAP_FROM_U64(0x22222222),
  	BITMAP_FROM_U64(0xffffffff),
  	BITMAP_FROM_U64(0xfffffffe),
  	BITMAP_FROM_U64(0x3333333311111111ULL),
  	BITMAP_FROM_U64(0xffffffff77777777ULL),
  	BITMAP_FROM_U64(0),
  };
  
  static const unsigned long exp2[] __initconst = {
  	BITMAP_FROM_U64(0x3333333311111111ULL),
  	BITMAP_FROM_U64(0xffffffff77777777ULL),
  };
5fd003f56   David Decotigny   test_bitmap: unit...
42

30544ed5d   Andy Shevchenko   lib/bitmap: intro...
43
44
45
46
47
48
49
50
51
52
53
54
  /* Fibonacci sequence */
  static const unsigned long exp2_to_exp3_mask[] __initconst = {
  	BITMAP_FROM_U64(0x008000020020212eULL),
  };
  /* exp3_0_1 = (exp2[0] & ~exp2_to_exp3_mask) | (exp2[1] & exp2_to_exp3_mask) */
  static const unsigned long exp3_0_1[] __initconst = {
  	BITMAP_FROM_U64(0x33b3333311313137ULL),
  };
  /* exp3_1_0 = (exp2[1] & ~exp2_to_exp3_mask) | (exp2[0] & exp2_to_exp3_mask) */
  static const unsigned long exp3_1_0[] __initconst = {
  	BITMAP_FROM_U64(0xff7fffff77575751ULL),
  };
5fd003f56   David Decotigny   test_bitmap: unit...
55
56
57
58
59
  static bool __init
  __check_eq_uint(const char *srcfile, unsigned int line,
  		const unsigned int exp_uint, unsigned int x)
  {
  	if (exp_uint != x) {
3aa56885e   Yury Norov   bitmap: replace b...
60
61
  		pr_err("[%s:%u] expected %u, got %u
  ",
5fd003f56   David Decotigny   test_bitmap: unit...
62
63
64
65
66
67
68
69
70
  			srcfile, line, exp_uint, x);
  		return false;
  	}
  	return true;
  }
  
  
  static bool __init
  __check_eq_bitmap(const char *srcfile, unsigned int line,
3aa56885e   Yury Norov   bitmap: replace b...
71
72
  		  const unsigned long *exp_bmap, const unsigned long *bmap,
  		  unsigned int nbits)
5fd003f56   David Decotigny   test_bitmap: unit...
73
  {
5fd003f56   David Decotigny   test_bitmap: unit...
74
75
76
77
  	if (!bitmap_equal(exp_bmap, bmap, nbits)) {
  		pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"
  ",
  			srcfile, line,
3aa56885e   Yury Norov   bitmap: replace b...
78
  			nbits, exp_bmap, nbits, bmap);
5fd003f56   David Decotigny   test_bitmap: unit...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  		return false;
  	}
  	return true;
  }
  
  static bool __init
  __check_eq_pbl(const char *srcfile, unsigned int line,
  	       const char *expected_pbl,
  	       const unsigned long *bitmap, unsigned int nbits)
  {
  	snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap);
  	if (strcmp(expected_pbl, pbl_buffer)) {
  		pr_warn("[%s:%u] expected \"%s\", got \"%s\"
  ",
  			srcfile, line,
  			expected_pbl, pbl_buffer);
  		return false;
  	}
  	return true;
  }
  
  static bool __init
  __check_eq_u32_array(const char *srcfile, unsigned int line,
  		     const u32 *exp_arr, unsigned int exp_len,
3aa56885e   Yury Norov   bitmap: replace b...
103
104
105
106
  		     const u32 *arr, unsigned int len) __used;
  static bool __init
  __check_eq_u32_array(const char *srcfile, unsigned int line,
  		     const u32 *exp_arr, unsigned int exp_len,
5fd003f56   David Decotigny   test_bitmap: unit...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  		     const u32 *arr, unsigned int len)
  {
  	if (exp_len != len) {
  		pr_warn("[%s:%u] array length differ: expected %u, got %u
  ",
  			srcfile, line,
  			exp_len, len);
  		return false;
  	}
  
  	if (memcmp(exp_arr, arr, len*sizeof(*arr))) {
  		pr_warn("[%s:%u] array contents differ
  ", srcfile, line);
  		print_hex_dump(KERN_WARNING, "  exp:  ", DUMP_PREFIX_OFFSET,
  			       32, 4, exp_arr, exp_len*sizeof(*exp_arr), false);
  		print_hex_dump(KERN_WARNING, "  got:  ", DUMP_PREFIX_OFFSET,
  			       32, 4, arr, len*sizeof(*arr), false);
  		return false;
  	}
  
  	return true;
  }
e4aa168de   William Breathitt Gray   lib/test_bitmap.c...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  static bool __init __check_eq_clump8(const char *srcfile, unsigned int line,
  				    const unsigned int offset,
  				    const unsigned int size,
  				    const unsigned char *const clump_exp,
  				    const unsigned long *const clump)
  {
  	unsigned long exp;
  
  	if (offset >= size) {
  		pr_warn("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u
  ",
  			srcfile, line, size, offset);
  		return false;
  	}
  
  	exp = clump_exp[offset / 8];
  	if (!exp) {
  		pr_warn("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0",
  			srcfile, line, offset);
  		return false;
  	}
  
  	if (*clump != exp) {
  		pr_warn("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX",
  			srcfile, line, exp, *clump);
  		return false;
  	}
  
  	return true;
  }
5fd003f56   David Decotigny   test_bitmap: unit...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
  #define __expect_eq(suffix, ...)					\
  	({								\
  		int result = 0;						\
  		total_tests++;						\
  		if (!__check_eq_ ## suffix(__FILE__, __LINE__,		\
  					   ##__VA_ARGS__)) {		\
  			failed_tests++;					\
  			result = 1;					\
  		}							\
  		result;							\
  	})
  
  #define expect_eq_uint(...)		__expect_eq(uint, ##__VA_ARGS__)
  #define expect_eq_bitmap(...)		__expect_eq(bitmap, ##__VA_ARGS__)
  #define expect_eq_pbl(...)		__expect_eq(pbl, ##__VA_ARGS__)
  #define expect_eq_u32_array(...)	__expect_eq(u32_array, ##__VA_ARGS__)
e4aa168de   William Breathitt Gray   lib/test_bitmap.c...
175
  #define expect_eq_clump8(...)		__expect_eq(clump8, ##__VA_ARGS__)
5fd003f56   David Decotigny   test_bitmap: unit...
176

ee3527bd5   Andy Shevchenko   lib/test_bitmap.c...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  static void __init test_zero_clear(void)
  {
  	DECLARE_BITMAP(bmap, 1024);
  
  	/* Known way to set all bits */
  	memset(bmap, 0xff, 128);
  
  	expect_eq_pbl("0-22", bmap, 23);
  	expect_eq_pbl("0-1023", bmap, 1024);
  
  	/* single-word bitmaps */
  	bitmap_clear(bmap, 0, 9);
  	expect_eq_pbl("9-1023", bmap, 1024);
  
  	bitmap_zero(bmap, 35);
  	expect_eq_pbl("64-1023", bmap, 1024);
  
  	/* cross boundaries operations */
  	bitmap_clear(bmap, 79, 19);
  	expect_eq_pbl("64-78,98-1023", bmap, 1024);
  
  	bitmap_zero(bmap, 115);
  	expect_eq_pbl("128-1023", bmap, 1024);
  
  	/* Zeroing entire area */
  	bitmap_zero(bmap, 1024);
  	expect_eq_pbl("", bmap, 1024);
  }
978f369c5   Andy Shevchenko   lib/test_bitmap.c...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  static void __init test_fill_set(void)
  {
  	DECLARE_BITMAP(bmap, 1024);
  
  	/* Known way to clear all bits */
  	memset(bmap, 0x00, 128);
  
  	expect_eq_pbl("", bmap, 23);
  	expect_eq_pbl("", bmap, 1024);
  
  	/* single-word bitmaps */
  	bitmap_set(bmap, 0, 9);
  	expect_eq_pbl("0-8", bmap, 1024);
  
  	bitmap_fill(bmap, 35);
  	expect_eq_pbl("0-63", bmap, 1024);
  
  	/* cross boundaries operations */
  	bitmap_set(bmap, 79, 19);
  	expect_eq_pbl("0-63,79-97", bmap, 1024);
  
  	bitmap_fill(bmap, 115);
  	expect_eq_pbl("0-127", bmap, 1024);
  
  	/* Zeroing entire area */
  	bitmap_fill(bmap, 1024);
  	expect_eq_pbl("0-1023", bmap, 1024);
  }
fe81814c3   Andy Shevchenko   lib/test_bitmap.c...
233
  static void __init test_copy(void)
5fd003f56   David Decotigny   test_bitmap: unit...
234
235
236
237
238
239
240
241
  {
  	DECLARE_BITMAP(bmap1, 1024);
  	DECLARE_BITMAP(bmap2, 1024);
  
  	bitmap_zero(bmap1, 1024);
  	bitmap_zero(bmap2, 1024);
  
  	/* single-word bitmaps */
fe81814c3   Andy Shevchenko   lib/test_bitmap.c...
242
  	bitmap_set(bmap1, 0, 19);
5fd003f56   David Decotigny   test_bitmap: unit...
243
244
  	bitmap_copy(bmap2, bmap1, 23);
  	expect_eq_pbl("0-18", bmap2, 1024);
fe81814c3   Andy Shevchenko   lib/test_bitmap.c...
245
  	bitmap_set(bmap2, 0, 23);
5fd003f56   David Decotigny   test_bitmap: unit...
246
247
  	bitmap_copy(bmap2, bmap1, 23);
  	expect_eq_pbl("0-18", bmap2, 1024);
5fd003f56   David Decotigny   test_bitmap: unit...
248
  	/* multi-word bitmaps */
fe81814c3   Andy Shevchenko   lib/test_bitmap.c...
249
  	bitmap_set(bmap1, 0, 109);
5fd003f56   David Decotigny   test_bitmap: unit...
250
251
252
253
  	bitmap_copy(bmap2, bmap1, 1024);
  	expect_eq_pbl("0-108", bmap2, 1024);
  
  	bitmap_fill(bmap2, 1024);
5fd003f56   David Decotigny   test_bitmap: unit...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
  	bitmap_copy(bmap2, bmap1, 1024);
  	expect_eq_pbl("0-108", bmap2, 1024);
  
  	/* the following tests assume a 32- or 64-bit arch (even 128b
  	 * if we care)
  	 */
  
  	bitmap_fill(bmap2, 1024);
  	bitmap_copy(bmap2, bmap1, 109);  /* ... but 0-padded til word length */
  	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
  
  	bitmap_fill(bmap2, 1024);
  	bitmap_copy(bmap2, bmap1, 97);  /* ... but aligned on word length */
  	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
5fd003f56   David Decotigny   test_bitmap: unit...
268
  }
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
269
270
271
272
273
  #define EXP2_IN_BITS	(sizeof(exp2) * 8)
  
  static void __init test_replace(void)
  {
  	unsigned int nbits = 64;
69334ca53   Andy Shevchenko   lib/test_bitmap: ...
274
  	unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG);
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
275
  	DECLARE_BITMAP(bmap, 1024);
caa7f776c   Andy Shevchenko   lib/test_bitmap.c...
276
  	BUILD_BUG_ON(EXP2_IN_BITS < nbits * 2);
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
277
  	bitmap_zero(bmap, 1024);
69334ca53   Andy Shevchenko   lib/test_bitmap: ...
278
  	bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
279
280
281
  	expect_eq_bitmap(bmap, exp3_0_1, nbits);
  
  	bitmap_zero(bmap, 1024);
69334ca53   Andy Shevchenko   lib/test_bitmap: ...
282
  	bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
283
284
285
  	expect_eq_bitmap(bmap, exp3_1_0, nbits);
  
  	bitmap_fill(bmap, 1024);
69334ca53   Andy Shevchenko   lib/test_bitmap: ...
286
  	bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
287
288
289
  	expect_eq_bitmap(bmap, exp3_0_1, nbits);
  
  	bitmap_fill(bmap, 1024);
69334ca53   Andy Shevchenko   lib/test_bitmap: ...
290
  	bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
291
292
  	expect_eq_bitmap(bmap, exp3_1_0, nbits);
  }
7eb2e94e9   Yury Norov   lib: add test for...
293
294
  #define PARSE_TIME	0x1
  #define NO_LEN		0x2
6df0d464d   Yury Norov   lib/test_bitmap.c...
295
296
297
298
299
300
301
302
  
  struct test_bitmap_parselist{
  	const int errno;
  	const char *in;
  	const unsigned long *expected;
  	const int nbits;
  	const int flags;
  };
6df0d464d   Yury Norov   lib/test_bitmap.c...
303
  static const struct test_bitmap_parselist parselist_tests[] __initconst = {
60ef69001   Yury Norov   bitmap: introduce...
304
  #define step (sizeof(u64) / sizeof(unsigned long))
0ee312e38   Andy Shevchenko   lib/test_bitmap: ...
305
306
307
308
309
310
311
312
313
314
315
316
317
  	{0, "0",			&exp1[0], 8, 0},
  	{0, "1",			&exp1[1 * step], 8, 0},
  	{0, "0-15",			&exp1[2 * step], 32, 0},
  	{0, "16-31",			&exp1[3 * step], 32, 0},
  	{0, "0-31:1/2",			&exp1[4 * step], 32, 0},
  	{0, "1-31:1/2",			&exp1[5 * step], 32, 0},
  	{0, "0-31:1/4",			&exp1[6 * step], 32, 0},
  	{0, "1-31:1/4",			&exp1[7 * step], 32, 0},
  	{0, "0-31:4/4",			&exp1[8 * step], 32, 0},
  	{0, "1-31:4/4",			&exp1[9 * step], 32, 0},
  	{0, "0-31:1/4,32-63:2/4",	&exp1[10 * step], 64, 0},
  	{0, "0-31:3/4,32-63:4/4",	&exp1[11 * step], 64, 0},
  	{0, "  ,,  0-31:3/4  ,, 32-63:4/4  ,,  ",	&exp1[11 * step], 64, 0},
6df0d464d   Yury Norov   lib/test_bitmap.c...
318
319
320
321
  
  	{0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4",	exp2, 128, 0},
  
  	{0, "0-2047:128/256", NULL, 2048, PARSE_TIME},
0ee312e38   Andy Shevchenko   lib/test_bitmap: ...
322
323
324
325
326
327
328
  	{0, "",				&exp1[12 * step], 8, 0},
  	{0, "
  ",			&exp1[12 * step], 8, 0},
  	{0, ",,  ,,  , ,  ,",		&exp1[12 * step], 8, 0},
  	{0, " ,  ,,  , ,   ",		&exp1[12 * step], 8, 0},
  	{0, " ,  ,,  , ,   
  ",		&exp1[12 * step], 8, 0},
a4ab50509   Yury Norov   lib/test_bitmap: ...
329

6df0d464d   Yury Norov   lib/test_bitmap.c...
330
331
332
  	{-EINVAL, "-1",	NULL, 8, 0},
  	{-EINVAL, "-0",	NULL, 8, 0},
  	{-EINVAL, "10-1", NULL, 8, 0},
8351760ff   Yury Norov   lib: fix stall in...
333
334
  	{-EINVAL, "0-31:", NULL, 8, 0},
  	{-EINVAL, "0-31:0", NULL, 8, 0},
a4ab50509   Yury Norov   lib/test_bitmap: ...
335
  	{-EINVAL, "0-31:0/", NULL, 8, 0},
8351760ff   Yury Norov   lib: fix stall in...
336
337
  	{-EINVAL, "0-31:0/0", NULL, 8, 0},
  	{-EINVAL, "0-31:1/0", NULL, 8, 0},
6df0d464d   Yury Norov   lib/test_bitmap.c...
338
  	{-EINVAL, "0-31:10/1", NULL, 8, 0},
a4ab50509   Yury Norov   lib/test_bitmap: ...
339
340
341
342
343
344
345
346
  	{-EOVERFLOW, "0-98765432123456789:10/1", NULL, 8, 0},
  
  	{-EINVAL, "a-31", NULL, 8, 0},
  	{-EINVAL, "0-a1", NULL, 8, 0},
  	{-EINVAL, "a-31:10/1", NULL, 8, 0},
  	{-EINVAL, "0-31:a/1", NULL, 8, 0},
  	{-EINVAL, "0-
  ", NULL, 8, 0},
542240440   Andy Shevchenko   lib/test_bitmap: ...
347

6df0d464d   Yury Norov   lib/test_bitmap.c...
348
  };
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
349
  static void __init test_bitmap_parselist(void)
6df0d464d   Yury Norov   lib/test_bitmap.c...
350
351
352
  {
  	int i;
  	int err;
0c2111a5c   Yury Norov   lib/test_bitmap: ...
353
  	ktime_t time;
6df0d464d   Yury Norov   lib/test_bitmap.c...
354
355
356
357
  	DECLARE_BITMAP(bmap, 2048);
  
  	for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) {
  #define ptest parselist_tests[i]
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
358
359
360
  		time = ktime_get();
  		err = bitmap_parselist(ptest.in, bmap, ptest.nbits);
  		time = ktime_get() - time;
6df0d464d   Yury Norov   lib/test_bitmap.c...
361
362
  
  		if (err != ptest.errno) {
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
363
364
365
  			pr_err("parselist: %d: input is %s, errno is %d, expected %d
  ",
  					i, ptest.in, err, ptest.errno);
6df0d464d   Yury Norov   lib/test_bitmap.c...
366
367
368
369
370
  			continue;
  		}
  
  		if (!err && ptest.expected
  			 && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) {
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
371
372
373
  			pr_err("parselist: %d: input is %s, result is 0x%lx, expected 0x%lx
  ",
  					i, ptest.in, bmap[0],
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
374
  					*ptest.expected);
6df0d464d   Yury Norov   lib/test_bitmap.c...
375
376
377
378
  			continue;
  		}
  
  		if (ptest.flags & PARSE_TIME)
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
379
380
381
  			pr_err("parselist: %d: input is '%s' OK, Time: %llu
  ",
  					i, ptest.in, time);
542240440   Andy Shevchenko   lib/test_bitmap: ...
382
383
  
  #undef ptest
6df0d464d   Yury Norov   lib/test_bitmap.c...
384
385
  	}
  }
7eb2e94e9   Yury Norov   lib: add test for...
386
387
388
389
390
391
392
393
394
395
396
397
398
399
  static const unsigned long parse_test[] __initconst = {
  	BITMAP_FROM_U64(0),
  	BITMAP_FROM_U64(1),
  	BITMAP_FROM_U64(0xdeadbeef),
  	BITMAP_FROM_U64(0x100000000ULL),
  };
  
  static const unsigned long parse_test2[] __initconst = {
  	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xdeadbeef),
  	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xbaadf00ddeadbeef),
  	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0x0badf00ddeadbeef),
  };
  
  static const struct test_bitmap_parselist parse_tests[] __initconst = {
809e308f7   Yury Norov   lib: new testcase...
400
401
  	{0, "",				&parse_test[0 * step], 32, 0},
  	{0, " ",			&parse_test[0 * step], 32, 0},
7eb2e94e9   Yury Norov   lib: add test for...
402
  	{0, "0",			&parse_test[0 * step], 32, 0},
809e308f7   Yury Norov   lib: new testcase...
403
404
  	{0, "0
  ",			&parse_test[0 * step], 32, 0},
7eb2e94e9   Yury Norov   lib: add test for...
405
406
407
  	{0, "1",			&parse_test[1 * step], 32, 0},
  	{0, "deadbeef",			&parse_test[2 * step], 32, 0},
  	{0, "1,0",			&parse_test[3 * step], 33, 0},
809e308f7   Yury Norov   lib: new testcase...
408
409
  	{0, "deadbeef,
  ,0,1",		&parse_test[2 * step], 96, 0},
7eb2e94e9   Yury Norov   lib: add test for...
410
411
412
413
  
  	{0, "deadbeef,1,0",		&parse_test2[0 * 2 * step], 96, 0},
  	{0, "baadf00d,deadbeef,1,0",	&parse_test2[1 * 2 * step], 128, 0},
  	{0, "badf00d,deadbeef,1,0",	&parse_test2[2 * 2 * step], 124, 0},
809e308f7   Yury Norov   lib: new testcase...
414
415
416
417
  	{0, "badf00d,deadbeef,1,0",	&parse_test2[2 * 2 * step], 124, NO_LEN},
  	{0, "  badf00d,deadbeef,1,0  ",	&parse_test2[2 * 2 * step], 124, 0},
  	{0, " , badf00d,deadbeef,1,0 , ",	&parse_test2[2 * 2 * step], 124, 0},
  	{0, " , badf00d, ,, ,,deadbeef,1,0 , ",	&parse_test2[2 * 2 * step], 124, 0},
7eb2e94e9   Yury Norov   lib: add test for...
418
419
420
421
422
423
424
425
426
  
  	{-EINVAL,    "goodfood,deadbeef,1,0",	NULL, 128, 0},
  	{-EOVERFLOW, "3,0",			NULL, 33, 0},
  	{-EOVERFLOW, "123badf00d,deadbeef,1,0",	NULL, 128, 0},
  	{-EOVERFLOW, "badf00d,deadbeef,1,0",	NULL, 90, 0},
  	{-EOVERFLOW, "fbadf00d,deadbeef,1,0",	NULL, 95, 0},
  	{-EOVERFLOW, "badf00d,deadbeef,1,0",	NULL, 100, 0},
  #undef step
  };
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
427
  static void __init test_bitmap_parse(void)
7eb2e94e9   Yury Norov   lib: add test for...
428
429
430
431
432
  {
  	int i;
  	int err;
  	ktime_t time;
  	DECLARE_BITMAP(bmap, 2048);
7eb2e94e9   Yury Norov   lib: add test for...
433
434
435
  
  	for (i = 0; i < ARRAY_SIZE(parse_tests); i++) {
  		struct test_bitmap_parselist test = parse_tests[i];
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
436
  		size_t len = test.flags & NO_LEN ? UINT_MAX : strlen(test.in);
7eb2e94e9   Yury Norov   lib: add test for...
437

e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
438
439
440
  		time = ktime_get();
  		err = bitmap_parse(test.in, len, bmap, test.nbits);
  		time = ktime_get() - time;
7eb2e94e9   Yury Norov   lib: add test for...
441
442
  
  		if (err != test.errno) {
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
443
444
445
  			pr_err("parse: %d: input is %s, errno is %d, expected %d
  ",
  					i, test.in, err, test.errno);
7eb2e94e9   Yury Norov   lib: add test for...
446
447
448
449
450
  			continue;
  		}
  
  		if (!err && test.expected
  			 && !__bitmap_equal(bmap, test.expected, test.nbits)) {
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
451
452
453
  			pr_err("parse: %d: input is %s, result is 0x%lx, expected 0x%lx
  ",
  					i, test.in, bmap[0],
7eb2e94e9   Yury Norov   lib: add test for...
454
455
456
457
458
  					*test.expected);
  			continue;
  		}
  
  		if (test.flags & PARSE_TIME)
e17f21cfe   Greg Kroah-Hartman   Revert "Revert "t...
459
460
461
  			pr_err("parse: %d: input is '%s' OK, Time: %llu
  ",
  					i, test.in, time);
7eb2e94e9   Yury Norov   lib: add test for...
462
463
  	}
  }
0ee312e38   Andy Shevchenko   lib/test_bitmap: ...
464
  #define EXP1_IN_BITS	(sizeof(exp1) * 8)
f6f66c1bf   Kees Cook   lib/test_bitmap.c...
465

3aa56885e   Yury Norov   bitmap: replace b...
466
  static void __init test_bitmap_arr32(void)
5fd003f56   David Decotigny   test_bitmap: unit...
467
  {
f6f66c1bf   Kees Cook   lib/test_bitmap.c...
468
  	unsigned int nbits, next_bit;
a4881d1cb   Andy Shevchenko   lib/test_bitmap: ...
469
470
  	u32 arr[EXP1_IN_BITS / 32];
  	DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
3aa56885e   Yury Norov   bitmap: replace b...
471
472
  
  	memset(arr, 0xa5, sizeof(arr));
a4881d1cb   Andy Shevchenko   lib/test_bitmap: ...
473
  	for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
0ee312e38   Andy Shevchenko   lib/test_bitmap: ...
474
  		bitmap_to_arr32(arr, exp1, nbits);
3aa56885e   Yury Norov   bitmap: replace b...
475
  		bitmap_from_arr32(bmap2, arr, nbits);
0ee312e38   Andy Shevchenko   lib/test_bitmap: ...
476
  		expect_eq_bitmap(bmap2, exp1, nbits);
3aa56885e   Yury Norov   bitmap: replace b...
477
478
479
480
481
482
483
484
  
  		next_bit = find_next_bit(bmap2,
  				round_up(nbits, BITS_PER_LONG), nbits);
  		if (next_bit < round_up(nbits, BITS_PER_LONG))
  			pr_err("bitmap_copy_arr32(nbits == %d:"
  				" tail is not safely cleared: %d
  ",
  				nbits, next_bit);
a4881d1cb   Andy Shevchenko   lib/test_bitmap: ...
485
  		if (nbits < EXP1_IN_BITS - 32)
3aa56885e   Yury Norov   bitmap: replace b...
486
487
  			expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
  								0xa5a5a5a5);
5fd003f56   David Decotigny   test_bitmap: unit...
488
489
  	}
  }
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
490
491
492
493
494
495
496
  static void noinline __init test_mem_optimisations(void)
  {
  	DECLARE_BITMAP(bmap1, 1024);
  	DECLARE_BITMAP(bmap2, 1024);
  	unsigned int start, nbits;
  
  	for (start = 0; start < 1024; start += 8) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
497
  		for (nbits = 0; nbits < 1024 - start; nbits += 8) {
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
498
499
  			memset(bmap1, 0x5a, sizeof(bmap1));
  			memset(bmap2, 0x5a, sizeof(bmap2));
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
500
501
  			bitmap_set(bmap1, start, nbits);
  			__bitmap_set(bmap2, start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
502
  			if (!bitmap_equal(bmap1, bmap2, 1024)) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
503
504
  				printk("set not equal %d %d
  ", start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
505
506
507
  				failed_tests++;
  			}
  			if (!__bitmap_equal(bmap1, bmap2, 1024)) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
508
509
  				printk("set not __equal %d %d
  ", start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
510
511
  				failed_tests++;
  			}
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
512
513
514
  
  			bitmap_clear(bmap1, start, nbits);
  			__bitmap_clear(bmap2, start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
515
  			if (!bitmap_equal(bmap1, bmap2, 1024)) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
516
517
  				printk("clear not equal %d %d
  ", start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
518
519
520
  				failed_tests++;
  			}
  			if (!__bitmap_equal(bmap1, bmap2, 1024)) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
521
522
523
  				printk("clear not __equal %d %d
  ", start,
  									nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
524
525
  				failed_tests++;
  			}
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
526
527
528
  		}
  	}
  }
e4aa168de   William Breathitt Gray   lib/test_bitmap.c...
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
  static const unsigned char clump_exp[] __initconst = {
  	0x01,	/* 1 bit set */
  	0x02,	/* non-edge 1 bit set */
  	0x00,	/* zero bits set */
  	0x38,	/* 3 bits set across 4-bit boundary */
  	0x38,	/* Repeated clump */
  	0x0F,	/* 4 bits set */
  	0xFF,	/* all bits set */
  	0x05,	/* non-adjacent 2 bits set */
  };
  
  static void __init test_for_each_set_clump8(void)
  {
  #define CLUMP_EXP_NUMBITS 64
  	DECLARE_BITMAP(bits, CLUMP_EXP_NUMBITS);
  	unsigned int start;
  	unsigned long clump;
  
  	/* set bitmap to test case */
  	bitmap_zero(bits, CLUMP_EXP_NUMBITS);
  	bitmap_set(bits, 0, 1);		/* 0x01 */
  	bitmap_set(bits, 9, 1);		/* 0x02 */
  	bitmap_set(bits, 27, 3);	/* 0x28 */
  	bitmap_set(bits, 35, 3);	/* 0x28 */
  	bitmap_set(bits, 40, 4);	/* 0x0F */
  	bitmap_set(bits, 48, 8);	/* 0xFF */
  	bitmap_set(bits, 56, 1);	/* 0x05 - part 1 */
  	bitmap_set(bits, 58, 1);	/* 0x05 - part 2 */
  
  	for_each_set_clump8(start, clump, bits, CLUMP_EXP_NUMBITS)
  		expect_eq_clump8(start, CLUMP_EXP_NUMBITS, clump_exp, &clump);
  }
bcb32a1d8   Stefano Brivio   lib/test_bitmap.c...
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
  struct test_bitmap_cut {
  	unsigned int first;
  	unsigned int cut;
  	unsigned int nbits;
  	unsigned long in[4];
  	unsigned long expected[4];
  };
  
  static struct test_bitmap_cut test_cut[] = {
  	{  0,  0,  8, { 0x0000000aUL, }, { 0x0000000aUL, }, },
  	{  0,  0, 32, { 0xdadadeadUL, }, { 0xdadadeadUL, }, },
  	{  0,  3,  8, { 0x000000aaUL, }, { 0x00000015UL, }, },
  	{  3,  3,  8, { 0x000000aaUL, }, { 0x00000012UL, }, },
  	{  0,  1, 32, { 0xa5a5a5a5UL, }, { 0x52d2d2d2UL, }, },
  	{  0,  8, 32, { 0xdeadc0deUL, }, { 0x00deadc0UL, }, },
  	{  1,  1, 32, { 0x5a5a5a5aUL, }, { 0x2d2d2d2cUL, }, },
  	{  0, 15, 32, { 0xa5a5a5a5UL, }, { 0x00014b4bUL, }, },
  	{  0, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
  	{ 15, 15, 32, { 0xa5a5a5a5UL, }, { 0x000125a5UL, }, },
  	{ 15, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
  	{ 16, 15, 32, { 0xa5a5a5a5UL, }, { 0x0001a5a5UL, }, },
  
  	{ BITS_PER_LONG, BITS_PER_LONG, BITS_PER_LONG,
  		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
  		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
  	},
  	{ 1, BITS_PER_LONG - 1, BITS_PER_LONG,
  		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
  		{ 0x00000001UL, 0x00000001UL, },
  	},
  
  	{ 0, BITS_PER_LONG * 2, BITS_PER_LONG * 2 + 1,
  		{ 0xa5a5a5a5UL, 0x00000001UL, 0x00000001UL, 0x00000001UL },
  		{ 0x00000001UL, },
  	},
  	{ 16, BITS_PER_LONG * 2 + 1, BITS_PER_LONG * 2 + 1 + 16,
  		{ 0x0000ffffUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL },
  		{ 0x2d2dffffUL, },
  	},
  };
  
  static void __init test_bitmap_cut(void)
  {
  	unsigned long b[5], *in = &b[1], *out = &b[0];	/* Partial overlap */
  	int i;
  
  	for (i = 0; i < ARRAY_SIZE(test_cut); i++) {
  		struct test_bitmap_cut *t = &test_cut[i];
  
  		memcpy(in, t->in, sizeof(t->in));
  
  		bitmap_cut(out, in, t->first, t->cut, t->nbits);
  
  		expect_eq_bitmap(t->expected, out, t->nbits);
  	}
  }
6b1a4d5b1   Tobin C. Harding   lib: Use new ksel...
617
  static void __init selftest(void)
5fd003f56   David Decotigny   test_bitmap: unit...
618
  {
ee3527bd5   Andy Shevchenko   lib/test_bitmap.c...
619
  	test_zero_clear();
978f369c5   Andy Shevchenko   lib/test_bitmap.c...
620
  	test_fill_set();
fe81814c3   Andy Shevchenko   lib/test_bitmap.c...
621
  	test_copy();
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
622
  	test_replace();
3aa56885e   Yury Norov   bitmap: replace b...
623
  	test_bitmap_arr32();
7eb2e94e9   Yury Norov   lib: add test for...
624
  	test_bitmap_parse();
6df0d464d   Yury Norov   lib/test_bitmap.c...
625
  	test_bitmap_parselist();
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
626
  	test_mem_optimisations();
e4aa168de   William Breathitt Gray   lib/test_bitmap.c...
627
  	test_for_each_set_clump8();
bcb32a1d8   Stefano Brivio   lib/test_bitmap.c...
628
  	test_bitmap_cut();
5fd003f56   David Decotigny   test_bitmap: unit...
629
  }
6b1a4d5b1   Tobin C. Harding   lib: Use new ksel...
630
  KSTM_MODULE_LOADERS(test_bitmap);
5fd003f56   David Decotigny   test_bitmap: unit...
631
632
  MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>");
  MODULE_LICENSE("GPL");