• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Test cases for printf facility.
3   */
4  
5  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
6  
7  #include <linux/bitmap.h>
8  #include <linux/init.h>
9  #include <linux/kernel.h>
10  #include <linux/module.h>
11  #include <linux/printk.h>
12  #include <linux/slab.h>
13  #include <linux/string.h>
14  
15  static unsigned total_tests __initdata;
16  static unsigned failed_tests __initdata;
17  
18  static char pbl_buffer[PAGE_SIZE] __initdata;
19  
20  
21  static bool __init
__check_eq_uint(const char * srcfile,unsigned int line,const unsigned int exp_uint,unsigned int x)22  __check_eq_uint(const char *srcfile, unsigned int line,
23  		const unsigned int exp_uint, unsigned int x)
24  {
25  	if (exp_uint != x) {
26  		pr_warn("[%s:%u] expected %u, got %u\n",
27  			srcfile, line, exp_uint, x);
28  		return false;
29  	}
30  	return true;
31  }
32  
33  
34  static bool __init
__check_eq_bitmap(const char * srcfile,unsigned int line,const unsigned long * exp_bmap,unsigned int exp_nbits,const unsigned long * bmap,unsigned int nbits)35  __check_eq_bitmap(const char *srcfile, unsigned int line,
36  		  const unsigned long *exp_bmap, unsigned int exp_nbits,
37  		  const unsigned long *bmap, unsigned int nbits)
38  {
39  	if (exp_nbits != nbits) {
40  		pr_warn("[%s:%u] bitmap length mismatch: expected %u, got %u\n",
41  			srcfile, line, exp_nbits, nbits);
42  		return false;
43  	}
44  
45  	if (!bitmap_equal(exp_bmap, bmap, nbits)) {
46  		pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n",
47  			srcfile, line,
48  			exp_nbits, exp_bmap, nbits, bmap);
49  		return false;
50  	}
51  	return true;
52  }
53  
54  static bool __init
__check_eq_pbl(const char * srcfile,unsigned int line,const char * expected_pbl,const unsigned long * bitmap,unsigned int nbits)55  __check_eq_pbl(const char *srcfile, unsigned int line,
56  	       const char *expected_pbl,
57  	       const unsigned long *bitmap, unsigned int nbits)
58  {
59  	snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap);
60  	if (strcmp(expected_pbl, pbl_buffer)) {
61  		pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n",
62  			srcfile, line,
63  			expected_pbl, pbl_buffer);
64  		return false;
65  	}
66  	return true;
67  }
68  
69  static bool __init
__check_eq_u32_array(const char * srcfile,unsigned int line,const u32 * exp_arr,unsigned int exp_len,const u32 * arr,unsigned int len)70  __check_eq_u32_array(const char *srcfile, unsigned int line,
71  		     const u32 *exp_arr, unsigned int exp_len,
72  		     const u32 *arr, unsigned int len)
73  {
74  	if (exp_len != len) {
75  		pr_warn("[%s:%u] array length differ: expected %u, got %u\n",
76  			srcfile, line,
77  			exp_len, len);
78  		return false;
79  	}
80  
81  	if (memcmp(exp_arr, arr, len*sizeof(*arr))) {
82  		pr_warn("[%s:%u] array contents differ\n", srcfile, line);
83  		print_hex_dump(KERN_WARNING, "  exp:  ", DUMP_PREFIX_OFFSET,
84  			       32, 4, exp_arr, exp_len*sizeof(*exp_arr), false);
85  		print_hex_dump(KERN_WARNING, "  got:  ", DUMP_PREFIX_OFFSET,
86  			       32, 4, arr, len*sizeof(*arr), false);
87  		return false;
88  	}
89  
90  	return true;
91  }
92  
93  #define __expect_eq(suffix, ...)					\
94  	({								\
95  		int result = 0;						\
96  		total_tests++;						\
97  		if (!__check_eq_ ## suffix(__FILE__, __LINE__,		\
98  					   ##__VA_ARGS__)) {		\
99  			failed_tests++;					\
100  			result = 1;					\
101  		}							\
102  		result;							\
103  	})
104  
105  #define expect_eq_uint(...)		__expect_eq(uint, ##__VA_ARGS__)
106  #define expect_eq_bitmap(...)		__expect_eq(bitmap, ##__VA_ARGS__)
107  #define expect_eq_pbl(...)		__expect_eq(pbl, ##__VA_ARGS__)
108  #define expect_eq_u32_array(...)	__expect_eq(u32_array, ##__VA_ARGS__)
109  
test_zero_fill_copy(void)110  static void __init test_zero_fill_copy(void)
111  {
112  	DECLARE_BITMAP(bmap1, 1024);
113  	DECLARE_BITMAP(bmap2, 1024);
114  
115  	bitmap_zero(bmap1, 1024);
116  	bitmap_zero(bmap2, 1024);
117  
118  	/* single-word bitmaps */
119  	expect_eq_pbl("", bmap1, 23);
120  
121  	bitmap_fill(bmap1, 19);
122  	expect_eq_pbl("0-18", bmap1, 1024);
123  
124  	bitmap_copy(bmap2, bmap1, 23);
125  	expect_eq_pbl("0-18", bmap2, 1024);
126  
127  	bitmap_fill(bmap2, 23);
128  	expect_eq_pbl("0-22", bmap2, 1024);
129  
130  	bitmap_copy(bmap2, bmap1, 23);
131  	expect_eq_pbl("0-18", bmap2, 1024);
132  
133  	bitmap_zero(bmap1, 23);
134  	expect_eq_pbl("", bmap1, 1024);
135  
136  	/* multi-word bitmaps */
137  	bitmap_zero(bmap1, 1024);
138  	expect_eq_pbl("", bmap1, 1024);
139  
140  	bitmap_fill(bmap1, 109);
141  	expect_eq_pbl("0-108", bmap1, 1024);
142  
143  	bitmap_copy(bmap2, bmap1, 1024);
144  	expect_eq_pbl("0-108", bmap2, 1024);
145  
146  	bitmap_fill(bmap2, 1024);
147  	expect_eq_pbl("0-1023", bmap2, 1024);
148  
149  	bitmap_copy(bmap2, bmap1, 1024);
150  	expect_eq_pbl("0-108", bmap2, 1024);
151  
152  	/* the following tests assume a 32- or 64-bit arch (even 128b
153  	 * if we care)
154  	 */
155  
156  	bitmap_fill(bmap2, 1024);
157  	bitmap_copy(bmap2, bmap1, 109);  /* ... but 0-padded til word length */
158  	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
159  
160  	bitmap_fill(bmap2, 1024);
161  	bitmap_copy(bmap2, bmap1, 97);  /* ... but aligned on word length */
162  	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
163  
164  	bitmap_zero(bmap2, 97);  /* ... but 0-padded til word length */
165  	expect_eq_pbl("128-1023", bmap2, 1024);
166  }
167  
test_bitmap_u32_array_conversions(void)168  static void __init test_bitmap_u32_array_conversions(void)
169  {
170  	DECLARE_BITMAP(bmap1, 1024);
171  	DECLARE_BITMAP(bmap2, 1024);
172  	u32 exp_arr[32], arr[32];
173  	unsigned nbits;
174  
175  	for (nbits = 0 ; nbits < 257 ; ++nbits) {
176  		const unsigned int used_u32s = DIV_ROUND_UP(nbits, 32);
177  		unsigned int i, rv;
178  
179  		bitmap_zero(bmap1, nbits);
180  		bitmap_set(bmap1, nbits, 1024 - nbits);  /* garbage */
181  
182  		memset(arr, 0xff, sizeof(arr));
183  		rv = bitmap_to_u32array(arr, used_u32s, bmap1, nbits);
184  		expect_eq_uint(nbits, rv);
185  
186  		memset(exp_arr, 0xff, sizeof(exp_arr));
187  		memset(exp_arr, 0, used_u32s*sizeof(*exp_arr));
188  		expect_eq_u32_array(exp_arr, 32, arr, 32);
189  
190  		bitmap_fill(bmap2, 1024);
191  		rv = bitmap_from_u32array(bmap2, nbits, arr, used_u32s);
192  		expect_eq_uint(nbits, rv);
193  		expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
194  
195  		for (i = 0 ; i < nbits ; ++i) {
196  			/*
197  			 * test conversion bitmap -> u32[]
198  			 */
199  
200  			bitmap_zero(bmap1, 1024);
201  			__set_bit(i, bmap1);
202  			bitmap_set(bmap1, nbits, 1024 - nbits);  /* garbage */
203  
204  			memset(arr, 0xff, sizeof(arr));
205  			rv = bitmap_to_u32array(arr, used_u32s, bmap1, nbits);
206  			expect_eq_uint(nbits, rv);
207  
208  			/* 1st used u32 words contain expected bit set, the
209  			 * remaining words are left unchanged (0xff)
210  			 */
211  			memset(exp_arr, 0xff, sizeof(exp_arr));
212  			memset(exp_arr, 0, used_u32s*sizeof(*exp_arr));
213  			exp_arr[i/32] = (1U<<(i%32));
214  			expect_eq_u32_array(exp_arr, 32, arr, 32);
215  
216  
217  			/* same, with longer array to fill
218  			 */
219  			memset(arr, 0xff, sizeof(arr));
220  			rv = bitmap_to_u32array(arr, 32, bmap1, nbits);
221  			expect_eq_uint(nbits, rv);
222  
223  			/* 1st used u32 words contain expected bit set, the
224  			 * remaining words are all 0s
225  			 */
226  			memset(exp_arr, 0, sizeof(exp_arr));
227  			exp_arr[i/32] = (1U<<(i%32));
228  			expect_eq_u32_array(exp_arr, 32, arr, 32);
229  
230  			/*
231  			 * test conversion u32[] -> bitmap
232  			 */
233  
234  			/* the 1st nbits of bmap2 are identical to
235  			 * bmap1, the remaining bits of bmap2 are left
236  			 * unchanged (all 1s)
237  			 */
238  			bitmap_fill(bmap2, 1024);
239  			rv = bitmap_from_u32array(bmap2, nbits,
240  						  exp_arr, used_u32s);
241  			expect_eq_uint(nbits, rv);
242  
243  			expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
244  
245  			/* same, with more bits to fill
246  			 */
247  			memset(arr, 0xff, sizeof(arr));  /* garbage */
248  			memset(arr, 0, used_u32s*sizeof(u32));
249  			arr[i/32] = (1U<<(i%32));
250  
251  			bitmap_fill(bmap2, 1024);
252  			rv = bitmap_from_u32array(bmap2, 1024, arr, used_u32s);
253  			expect_eq_uint(used_u32s*32, rv);
254  
255  			/* the 1st nbits of bmap2 are identical to
256  			 * bmap1, the remaining bits of bmap2 are cleared
257  			 */
258  			bitmap_zero(bmap1, 1024);
259  			__set_bit(i, bmap1);
260  			expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
261  
262  
263  			/*
264  			 * test short conversion bitmap -> u32[] (1
265  			 * word too short)
266  			 */
267  			if (used_u32s > 1) {
268  				bitmap_zero(bmap1, 1024);
269  				__set_bit(i, bmap1);
270  				bitmap_set(bmap1, nbits,
271  					   1024 - nbits);  /* garbage */
272  				memset(arr, 0xff, sizeof(arr));
273  
274  				rv = bitmap_to_u32array(arr, used_u32s - 1,
275  							bmap1, nbits);
276  				expect_eq_uint((used_u32s - 1)*32, rv);
277  
278  				/* 1st used u32 words contain expected
279  				 * bit set, the remaining words are
280  				 * left unchanged (0xff)
281  				 */
282  				memset(exp_arr, 0xff, sizeof(exp_arr));
283  				memset(exp_arr, 0,
284  				       (used_u32s-1)*sizeof(*exp_arr));
285  				if ((i/32) < (used_u32s - 1))
286  					exp_arr[i/32] = (1U<<(i%32));
287  				expect_eq_u32_array(exp_arr, 32, arr, 32);
288  			}
289  
290  			/*
291  			 * test short conversion u32[] -> bitmap (3
292  			 * bits too short)
293  			 */
294  			if (nbits > 3) {
295  				memset(arr, 0xff, sizeof(arr));  /* garbage */
296  				memset(arr, 0, used_u32s*sizeof(*arr));
297  				arr[i/32] = (1U<<(i%32));
298  
299  				bitmap_zero(bmap1, 1024);
300  				rv = bitmap_from_u32array(bmap1, nbits - 3,
301  							  arr, used_u32s);
302  				expect_eq_uint(nbits - 3, rv);
303  
304  				/* we are expecting the bit < nbits -
305  				 * 3 (none otherwise), and the rest of
306  				 * bmap1 unchanged (0-filled)
307  				 */
308  				bitmap_zero(bmap2, 1024);
309  				if (i < nbits - 3)
310  					__set_bit(i, bmap2);
311  				expect_eq_bitmap(bmap2, 1024, bmap1, 1024);
312  
313  				/* do the same with bmap1 initially
314  				 * 1-filled
315  				 */
316  
317  				bitmap_fill(bmap1, 1024);
318  				rv = bitmap_from_u32array(bmap1, nbits - 3,
319  							 arr, used_u32s);
320  				expect_eq_uint(nbits - 3, rv);
321  
322  				/* we are expecting the bit < nbits -
323  				 * 3 (none otherwise), and the rest of
324  				 * bmap1 unchanged (1-filled)
325  				 */
326  				bitmap_zero(bmap2, 1024);
327  				if (i < nbits - 3)
328  					__set_bit(i, bmap2);
329  				bitmap_set(bmap2, nbits-3, 1024 - nbits + 3);
330  				expect_eq_bitmap(bmap2, 1024, bmap1, 1024);
331  			}
332  		}
333  	}
334  }
335  
test_bitmap_init(void)336  static int __init test_bitmap_init(void)
337  {
338  	test_zero_fill_copy();
339  	test_bitmap_u32_array_conversions();
340  
341  	if (failed_tests == 0)
342  		pr_info("all %u tests passed\n", total_tests);
343  	else
344  		pr_warn("failed %u out of %u tests\n",
345  			failed_tests, total_tests);
346  
347  	return failed_tests ? -EINVAL : 0;
348  }
349  
test_bitmap_cleanup(void)350  static void __exit test_bitmap_cleanup(void)
351  {
352  }
353  
354  module_init(test_bitmap_init);
355  module_exit(test_bitmap_cleanup);
356  
357  MODULE_AUTHOR("david decotigny <david.decotigny@googlers.com>");
358  MODULE_LICENSE("GPL");
359