Blame view

lib/test_bitmap.c 16.8 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
276
277
  	DECLARE_BITMAP(bmap, 1024);
  
  	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
  };
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
349
  static void __init __test_bitmap_parselist(int is_user)
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
  	DECLARE_BITMAP(bmap, 2048);
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
355
  	char *mode = is_user ? "_user"  : "";
6df0d464d   Yury Norov   lib/test_bitmap.c...
356
357
358
  
  	for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) {
  #define ptest parselist_tests[i]
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
359
360
361
362
363
364
  		if (is_user) {
  			mm_segment_t orig_fs = get_fs();
  			size_t len = strlen(ptest.in);
  
  			set_fs(KERNEL_DS);
  			time = ktime_get();
17b6753ff   Andy Shevchenko   lib/test_bitmap: ...
365
  			err = bitmap_parselist_user((__force const char __user *)ptest.in, len,
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
366
367
368
369
370
371
372
373
  						    bmap, ptest.nbits);
  			time = ktime_get() - time;
  			set_fs(orig_fs);
  		} else {
  			time = ktime_get();
  			err = bitmap_parselist(ptest.in, bmap, ptest.nbits);
  			time = ktime_get() - time;
  		}
6df0d464d   Yury Norov   lib/test_bitmap.c...
374
375
  
  		if (err != ptest.errno) {
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
376
377
378
  			pr_err("parselist%s: %d: input is %s, errno is %d, expected %d
  ",
  					mode, i, ptest.in, err, ptest.errno);
6df0d464d   Yury Norov   lib/test_bitmap.c...
379
380
381
382
383
  			continue;
  		}
  
  		if (!err && ptest.expected
  			 && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) {
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
384
385
386
387
  			pr_err("parselist%s: %d: input is %s, result is 0x%lx, expected 0x%lx
  ",
  					mode, i, ptest.in, bmap[0],
  					*ptest.expected);
6df0d464d   Yury Norov   lib/test_bitmap.c...
388
389
390
391
  			continue;
  		}
  
  		if (ptest.flags & PARSE_TIME)
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
392
393
394
  			pr_err("parselist%s: %d: input is '%s' OK, Time: %llu
  ",
  					mode, i, ptest.in, time);
542240440   Andy Shevchenko   lib/test_bitmap: ...
395
396
  
  #undef ptest
6df0d464d   Yury Norov   lib/test_bitmap.c...
397
398
  	}
  }
7eb2e94e9   Yury Norov   lib: add test for...
399
400
401
402
403
404
405
406
407
408
409
410
411
412
  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...
413
414
  	{0, "",				&parse_test[0 * step], 32, 0},
  	{0, " ",			&parse_test[0 * step], 32, 0},
7eb2e94e9   Yury Norov   lib: add test for...
415
  	{0, "0",			&parse_test[0 * step], 32, 0},
809e308f7   Yury Norov   lib: new testcase...
416
417
  	{0, "0
  ",			&parse_test[0 * step], 32, 0},
7eb2e94e9   Yury Norov   lib: add test for...
418
419
420
  	{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...
421
422
  	{0, "deadbeef,
  ,0,1",		&parse_test[2 * step], 96, 0},
7eb2e94e9   Yury Norov   lib: add test for...
423
424
425
426
  
  	{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...
427
428
429
430
  	{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...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
  
  	{-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
  };
  
  static void __init __test_bitmap_parse(int is_user)
  {
  	int i;
  	int err;
  	ktime_t time;
  	DECLARE_BITMAP(bmap, 2048);
  	char *mode = is_user ? "_user"  : "";
  
  	for (i = 0; i < ARRAY_SIZE(parse_tests); i++) {
  		struct test_bitmap_parselist test = parse_tests[i];
  
  		if (is_user) {
  			size_t len = strlen(test.in);
  			mm_segment_t orig_fs = get_fs();
  
  			set_fs(KERNEL_DS);
  			time = ktime_get();
  			err = bitmap_parse_user((__force const char __user *)test.in, len,
  						bmap, test.nbits);
  			time = ktime_get() - time;
  			set_fs(orig_fs);
  		} else {
  			size_t len = test.flags & NO_LEN ?
  				UINT_MAX : strlen(test.in);
  			time = ktime_get();
  			err = bitmap_parse(test.in, len, bmap, test.nbits);
  			time = ktime_get() - time;
  		}
  
  		if (err != test.errno) {
  			pr_err("parse%s: %d: input is %s, errno is %d, expected %d
  ",
  					mode, i, test.in, err, test.errno);
  			continue;
  		}
  
  		if (!err && test.expected
  			 && !__bitmap_equal(bmap, test.expected, test.nbits)) {
  			pr_err("parse%s: %d: input is %s, result is 0x%lx, expected 0x%lx
  ",
  					mode, i, test.in, bmap[0],
  					*test.expected);
  			continue;
  		}
  
  		if (test.flags & PARSE_TIME)
  			pr_err("parse%s: %d: input is '%s' OK, Time: %llu
  ",
  					mode, i, test.in, time);
  	}
  }
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
492
493
494
495
496
497
498
499
500
  static void __init test_bitmap_parselist(void)
  {
  	__test_bitmap_parselist(0);
  }
  
  static void __init test_bitmap_parselist_user(void)
  {
  	__test_bitmap_parselist(1);
  }
7eb2e94e9   Yury Norov   lib: add test for...
501
502
503
504
505
506
507
508
509
  static void __init test_bitmap_parse(void)
  {
  	__test_bitmap_parse(0);
  }
  
  static void __init test_bitmap_parse_user(void)
  {
  	__test_bitmap_parse(1);
  }
0ee312e38   Andy Shevchenko   lib/test_bitmap: ...
510
  #define EXP1_IN_BITS	(sizeof(exp1) * 8)
f6f66c1bf   Kees Cook   lib/test_bitmap.c...
511

3aa56885e   Yury Norov   bitmap: replace b...
512
  static void __init test_bitmap_arr32(void)
5fd003f56   David Decotigny   test_bitmap: unit...
513
  {
f6f66c1bf   Kees Cook   lib/test_bitmap.c...
514
  	unsigned int nbits, next_bit;
a4881d1cb   Andy Shevchenko   lib/test_bitmap: ...
515
516
  	u32 arr[EXP1_IN_BITS / 32];
  	DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
3aa56885e   Yury Norov   bitmap: replace b...
517
518
  
  	memset(arr, 0xa5, sizeof(arr));
a4881d1cb   Andy Shevchenko   lib/test_bitmap: ...
519
  	for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
0ee312e38   Andy Shevchenko   lib/test_bitmap: ...
520
  		bitmap_to_arr32(arr, exp1, nbits);
3aa56885e   Yury Norov   bitmap: replace b...
521
  		bitmap_from_arr32(bmap2, arr, nbits);
0ee312e38   Andy Shevchenko   lib/test_bitmap: ...
522
  		expect_eq_bitmap(bmap2, exp1, nbits);
3aa56885e   Yury Norov   bitmap: replace b...
523
524
525
526
527
528
529
530
  
  		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: ...
531
  		if (nbits < EXP1_IN_BITS - 32)
3aa56885e   Yury Norov   bitmap: replace b...
532
533
  			expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
  								0xa5a5a5a5);
5fd003f56   David Decotigny   test_bitmap: unit...
534
535
  	}
  }
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
536
537
538
539
540
541
542
  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...
543
  		for (nbits = 0; nbits < 1024 - start; nbits += 8) {
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
544
545
  			memset(bmap1, 0x5a, sizeof(bmap1));
  			memset(bmap2, 0x5a, sizeof(bmap2));
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
546
547
  			bitmap_set(bmap1, start, nbits);
  			__bitmap_set(bmap2, start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
548
  			if (!bitmap_equal(bmap1, bmap2, 1024)) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
549
550
  				printk("set not equal %d %d
  ", start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
551
552
553
  				failed_tests++;
  			}
  			if (!__bitmap_equal(bmap1, bmap2, 1024)) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
554
555
  				printk("set not __equal %d %d
  ", start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
556
557
  				failed_tests++;
  			}
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
558
559
560
  
  			bitmap_clear(bmap1, start, nbits);
  			__bitmap_clear(bmap2, start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
561
  			if (!bitmap_equal(bmap1, bmap2, 1024)) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
562
563
  				printk("clear not equal %d %d
  ", start, nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
564
565
566
  				failed_tests++;
  			}
  			if (!__bitmap_equal(bmap1, bmap2, 1024)) {
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
567
568
569
  				printk("clear not __equal %d %d
  ", start,
  									nbits);
1e3054b98   Matthew Wilcox   lib/test_bitmap.c...
570
571
  				failed_tests++;
  			}
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
572
573
574
  		}
  	}
  }
e4aa168de   William Breathitt Gray   lib/test_bitmap.c...
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
  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);
  }
6b1a4d5b1   Tobin C. Harding   lib: Use new ksel...
607
  static void __init selftest(void)
5fd003f56   David Decotigny   test_bitmap: unit...
608
  {
ee3527bd5   Andy Shevchenko   lib/test_bitmap.c...
609
  	test_zero_clear();
978f369c5   Andy Shevchenko   lib/test_bitmap.c...
610
  	test_fill_set();
fe81814c3   Andy Shevchenko   lib/test_bitmap.c...
611
  	test_copy();
30544ed5d   Andy Shevchenko   lib/bitmap: intro...
612
  	test_replace();
3aa56885e   Yury Norov   bitmap: replace b...
613
  	test_bitmap_arr32();
7eb2e94e9   Yury Norov   lib: add test for...
614
615
  	test_bitmap_parse();
  	test_bitmap_parse_user();
6df0d464d   Yury Norov   lib/test_bitmap.c...
616
  	test_bitmap_parselist();
6ea86bdfc   Yury Norov   lib/test_bitmap: ...
617
  	test_bitmap_parselist_user();
3cc78125a   Matthew Wilcox   lib/test_bitmap.c...
618
  	test_mem_optimisations();
e4aa168de   William Breathitt Gray   lib/test_bitmap.c...
619
  	test_for_each_set_clump8();
5fd003f56   David Decotigny   test_bitmap: unit...
620
  }
6b1a4d5b1   Tobin C. Harding   lib: Use new ksel...
621
  KSTM_MODULE_LOADERS(test_bitmap);
5fd003f56   David Decotigny   test_bitmap: unit...
622
623
  MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>");
  MODULE_LICENSE("GPL");