xref: /linux-6.15/lib/test_bitmap.c (revision 158e9d2f)
109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
25fd003f5SDavid Decotigny /*
3780ff33bSAndy Shevchenko  * Test cases for bitmap API.
45fd003f5SDavid Decotigny  */
55fd003f5SDavid Decotigny 
65fd003f5SDavid Decotigny #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
75fd003f5SDavid Decotigny 
85fd003f5SDavid Decotigny #include <linux/bitmap.h>
95fd003f5SDavid Decotigny #include <linux/init.h>
105fd003f5SDavid Decotigny #include <linux/kernel.h>
115fd003f5SDavid Decotigny #include <linux/module.h>
125fd003f5SDavid Decotigny #include <linux/printk.h>
135fd003f5SDavid Decotigny #include <linux/slab.h>
145fd003f5SDavid Decotigny #include <linux/string.h>
156ea86bdfSYury Norov #include <linux/uaccess.h>
165fd003f5SDavid Decotigny 
176b1a4d5bSTobin C. Harding #include "../tools/testing/selftests/kselftest_module.h"
186b1a4d5bSTobin C. Harding 
19e3783c80SYury Norov #define EXP1_IN_BITS	(sizeof(exp1) * 8)
20e3783c80SYury Norov 
214e89a787STimur Tabi KSTM_MODULE_GLOBALS();
225fd003f5SDavid Decotigny 
235fd003f5SDavid Decotigny static char pbl_buffer[PAGE_SIZE] __initdata;
24291f93caSBarry Song static char print_buf[PAGE_SIZE * 2] __initdata;
255fd003f5SDavid Decotigny 
26c21dd8a7SAndy Shevchenko static const unsigned long exp1[] __initconst = {
27c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(1),
28c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(2),
29c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x0000ffff),
30c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xffff0000),
31c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x55555555),
32c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xaaaaaaaa),
33c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x11111111),
34c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x22222222),
35c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xffffffff),
36c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xfffffffe),
37c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x3333333311111111ULL),
38c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xffffffff77777777ULL),
39c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0),
4097330db3SPaul Gortmaker 	BITMAP_FROM_U64(0x00008000),
4197330db3SPaul Gortmaker 	BITMAP_FROM_U64(0x80000000),
42c21dd8a7SAndy Shevchenko };
43c21dd8a7SAndy Shevchenko 
44c21dd8a7SAndy Shevchenko static const unsigned long exp2[] __initconst = {
45c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0x3333333311111111ULL),
46c21dd8a7SAndy Shevchenko 	BITMAP_FROM_U64(0xffffffff77777777ULL),
47c21dd8a7SAndy Shevchenko };
485fd003f5SDavid Decotigny 
4930544ed5SAndy Shevchenko /* Fibonacci sequence */
5030544ed5SAndy Shevchenko static const unsigned long exp2_to_exp3_mask[] __initconst = {
5130544ed5SAndy Shevchenko 	BITMAP_FROM_U64(0x008000020020212eULL),
5230544ed5SAndy Shevchenko };
5330544ed5SAndy Shevchenko /* exp3_0_1 = (exp2[0] & ~exp2_to_exp3_mask) | (exp2[1] & exp2_to_exp3_mask) */
5430544ed5SAndy Shevchenko static const unsigned long exp3_0_1[] __initconst = {
5530544ed5SAndy Shevchenko 	BITMAP_FROM_U64(0x33b3333311313137ULL),
5630544ed5SAndy Shevchenko };
5730544ed5SAndy Shevchenko /* exp3_1_0 = (exp2[1] & ~exp2_to_exp3_mask) | (exp2[0] & exp2_to_exp3_mask) */
5830544ed5SAndy Shevchenko static const unsigned long exp3_1_0[] __initconst = {
5930544ed5SAndy Shevchenko 	BITMAP_FROM_U64(0xff7fffff77575751ULL),
6030544ed5SAndy Shevchenko };
6130544ed5SAndy Shevchenko 
625fd003f5SDavid Decotigny static bool __init
__check_eq_ulong(const char * srcfile,unsigned int line,const unsigned long exp_ulong,unsigned long x)63991e5583SAlexander Potapenko __check_eq_ulong(const char *srcfile, unsigned int line,
64991e5583SAlexander Potapenko 		 const unsigned long exp_ulong, unsigned long x)
655fd003f5SDavid Decotigny {
66991e5583SAlexander Potapenko 	if (exp_ulong != x) {
67991e5583SAlexander Potapenko 		pr_err("[%s:%u] expected %lu, got %lu\n",
68991e5583SAlexander Potapenko 			srcfile, line, exp_ulong, x);
695fd003f5SDavid Decotigny 		return false;
705fd003f5SDavid Decotigny 	}
715fd003f5SDavid Decotigny 	return true;
725fd003f5SDavid Decotigny }
735fd003f5SDavid Decotigny 
745fd003f5SDavid Decotigny static bool __init
__check_eq_bitmap(const char * srcfile,unsigned int line,const unsigned long * exp_bmap,const unsigned long * bmap,unsigned int nbits)755fd003f5SDavid Decotigny __check_eq_bitmap(const char *srcfile, unsigned int line,
763aa56885SYury Norov 		  const unsigned long *exp_bmap, const unsigned long *bmap,
773aa56885SYury Norov 		  unsigned int nbits)
785fd003f5SDavid Decotigny {
795fd003f5SDavid Decotigny 	if (!bitmap_equal(exp_bmap, bmap, nbits)) {
805fd003f5SDavid Decotigny 		pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n",
815fd003f5SDavid Decotigny 			srcfile, line,
823aa56885SYury Norov 			nbits, exp_bmap, nbits, bmap);
835fd003f5SDavid Decotigny 		return false;
845fd003f5SDavid Decotigny 	}
855fd003f5SDavid Decotigny 	return true;
865fd003f5SDavid Decotigny }
875fd003f5SDavid Decotigny 
885fd003f5SDavid Decotigny static bool __init
__check_eq_pbl(const char * srcfile,unsigned int line,const char * expected_pbl,const unsigned long * bitmap,unsigned int nbits)895fd003f5SDavid Decotigny __check_eq_pbl(const char *srcfile, unsigned int line,
905fd003f5SDavid Decotigny 	       const char *expected_pbl,
915fd003f5SDavid Decotigny 	       const unsigned long *bitmap, unsigned int nbits)
925fd003f5SDavid Decotigny {
935fd003f5SDavid Decotigny 	snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap);
945fd003f5SDavid Decotigny 	if (strcmp(expected_pbl, pbl_buffer)) {
955fd003f5SDavid Decotigny 		pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n",
965fd003f5SDavid Decotigny 			srcfile, line,
975fd003f5SDavid Decotigny 			expected_pbl, pbl_buffer);
985fd003f5SDavid Decotigny 		return false;
995fd003f5SDavid Decotigny 	}
1005fd003f5SDavid Decotigny 	return true;
1015fd003f5SDavid Decotigny }
1025fd003f5SDavid Decotigny 
__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)103e4aa168dSWilliam Breathitt Gray static bool __init __check_eq_clump8(const char *srcfile, unsigned int line,
104e4aa168dSWilliam Breathitt Gray 				    const unsigned int offset,
105e4aa168dSWilliam Breathitt Gray 				    const unsigned int size,
106e4aa168dSWilliam Breathitt Gray 				    const unsigned char *const clump_exp,
107e4aa168dSWilliam Breathitt Gray 				    const unsigned long *const clump)
108e4aa168dSWilliam Breathitt Gray {
109e4aa168dSWilliam Breathitt Gray 	unsigned long exp;
110e4aa168dSWilliam Breathitt Gray 
111e4aa168dSWilliam Breathitt Gray 	if (offset >= size) {
112e4aa168dSWilliam Breathitt Gray 		pr_warn("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u\n",
113e4aa168dSWilliam Breathitt Gray 			srcfile, line, size, offset);
114e4aa168dSWilliam Breathitt Gray 		return false;
115e4aa168dSWilliam Breathitt Gray 	}
116e4aa168dSWilliam Breathitt Gray 
117e4aa168dSWilliam Breathitt Gray 	exp = clump_exp[offset / 8];
118e4aa168dSWilliam Breathitt Gray 	if (!exp) {
119e4aa168dSWilliam Breathitt Gray 		pr_warn("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0",
120e4aa168dSWilliam Breathitt Gray 			srcfile, line, offset);
121e4aa168dSWilliam Breathitt Gray 		return false;
122e4aa168dSWilliam Breathitt Gray 	}
123e4aa168dSWilliam Breathitt Gray 
124e4aa168dSWilliam Breathitt Gray 	if (*clump != exp) {
125e4aa168dSWilliam Breathitt Gray 		pr_warn("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX",
126e4aa168dSWilliam Breathitt Gray 			srcfile, line, exp, *clump);
127e4aa168dSWilliam Breathitt Gray 		return false;
128e4aa168dSWilliam Breathitt Gray 	}
129e4aa168dSWilliam Breathitt Gray 
130e4aa168dSWilliam Breathitt Gray 	return true;
131e4aa168dSWilliam Breathitt Gray }
132e4aa168dSWilliam Breathitt Gray 
133291f93caSBarry Song static bool __init
__check_eq_str(const char * srcfile,unsigned int line,const char * exp_str,const char * str,unsigned int len)134291f93caSBarry Song __check_eq_str(const char *srcfile, unsigned int line,
135291f93caSBarry Song 		const char *exp_str, const char *str,
136291f93caSBarry Song 		unsigned int len)
137291f93caSBarry Song {
138291f93caSBarry Song 	bool eq;
139291f93caSBarry Song 
140291f93caSBarry Song 	eq = strncmp(exp_str, str, len) == 0;
141291f93caSBarry Song 	if (!eq)
142291f93caSBarry Song 		pr_err("[%s:%u] expected %s, got %s\n", srcfile, line, exp_str, str);
143291f93caSBarry Song 
144291f93caSBarry Song 	return eq;
145291f93caSBarry Song }
146291f93caSBarry Song 
1475fd003f5SDavid Decotigny #define __expect_eq(suffix, ...)					\
1485fd003f5SDavid Decotigny 	({								\
1495fd003f5SDavid Decotigny 		int result = 0;						\
1505fd003f5SDavid Decotigny 		total_tests++;						\
1515fd003f5SDavid Decotigny 		if (!__check_eq_ ## suffix(__FILE__, __LINE__,		\
1525fd003f5SDavid Decotigny 					   ##__VA_ARGS__)) {		\
1535fd003f5SDavid Decotigny 			failed_tests++;					\
1545fd003f5SDavid Decotigny 			result = 1;					\
1555fd003f5SDavid Decotigny 		}							\
1565fd003f5SDavid Decotigny 		result;							\
1575fd003f5SDavid Decotigny 	})
1585fd003f5SDavid Decotigny 
159991e5583SAlexander Potapenko #define expect_eq_ulong(...)		__expect_eq(ulong, ##__VA_ARGS__)
160991e5583SAlexander Potapenko #define expect_eq_uint(x, y)		expect_eq_ulong((unsigned int)(x), (unsigned int)(y))
1615fd003f5SDavid Decotigny #define expect_eq_bitmap(...)		__expect_eq(bitmap, ##__VA_ARGS__)
1625fd003f5SDavid Decotigny #define expect_eq_pbl(...)		__expect_eq(pbl, ##__VA_ARGS__)
1635fd003f5SDavid Decotigny #define expect_eq_u32_array(...)	__expect_eq(u32_array, ##__VA_ARGS__)
164e4aa168dSWilliam Breathitt Gray #define expect_eq_clump8(...)		__expect_eq(clump8, ##__VA_ARGS__)
165291f93caSBarry Song #define expect_eq_str(...)		__expect_eq(str, ##__VA_ARGS__)
1665fd003f5SDavid Decotigny 
test_zero_clear(void)167ee3527bdSAndy Shevchenko static void __init test_zero_clear(void)
168ee3527bdSAndy Shevchenko {
169ee3527bdSAndy Shevchenko 	DECLARE_BITMAP(bmap, 1024);
170ee3527bdSAndy Shevchenko 
171ee3527bdSAndy Shevchenko 	/* Known way to set all bits */
172ee3527bdSAndy Shevchenko 	memset(bmap, 0xff, 128);
173ee3527bdSAndy Shevchenko 
174ee3527bdSAndy Shevchenko 	expect_eq_pbl("0-22", bmap, 23);
175ee3527bdSAndy Shevchenko 	expect_eq_pbl("0-1023", bmap, 1024);
176ee3527bdSAndy Shevchenko 
177ee3527bdSAndy Shevchenko 	/* single-word bitmaps */
178ee3527bdSAndy Shevchenko 	bitmap_clear(bmap, 0, 9);
179ee3527bdSAndy Shevchenko 	expect_eq_pbl("9-1023", bmap, 1024);
180ee3527bdSAndy Shevchenko 
181ee3527bdSAndy Shevchenko 	bitmap_zero(bmap, 35);
182ee3527bdSAndy Shevchenko 	expect_eq_pbl("64-1023", bmap, 1024);
183ee3527bdSAndy Shevchenko 
184ee3527bdSAndy Shevchenko 	/* cross boundaries operations */
185ee3527bdSAndy Shevchenko 	bitmap_clear(bmap, 79, 19);
186ee3527bdSAndy Shevchenko 	expect_eq_pbl("64-78,98-1023", bmap, 1024);
187ee3527bdSAndy Shevchenko 
188ee3527bdSAndy Shevchenko 	bitmap_zero(bmap, 115);
189ee3527bdSAndy Shevchenko 	expect_eq_pbl("128-1023", bmap, 1024);
190ee3527bdSAndy Shevchenko 
191ee3527bdSAndy Shevchenko 	/* Zeroing entire area */
192ee3527bdSAndy Shevchenko 	bitmap_zero(bmap, 1024);
193ee3527bdSAndy Shevchenko 	expect_eq_pbl("", bmap, 1024);
194ee3527bdSAndy Shevchenko }
195ee3527bdSAndy Shevchenko 
test_find_nth_bit(void)196e3783c80SYury Norov static void __init test_find_nth_bit(void)
197e3783c80SYury Norov {
198e3783c80SYury Norov 	unsigned long b, bit, cnt = 0;
199e3783c80SYury Norov 	DECLARE_BITMAP(bmap, 64 * 3);
200e3783c80SYury Norov 
201e3783c80SYury Norov 	bitmap_zero(bmap, 64 * 3);
202e3783c80SYury Norov 	__set_bit(10, bmap);
203e3783c80SYury Norov 	__set_bit(20, bmap);
204e3783c80SYury Norov 	__set_bit(30, bmap);
205e3783c80SYury Norov 	__set_bit(40, bmap);
206e3783c80SYury Norov 	__set_bit(50, bmap);
207e3783c80SYury Norov 	__set_bit(60, bmap);
208e3783c80SYury Norov 	__set_bit(80, bmap);
209e3783c80SYury Norov 	__set_bit(123, bmap);
210e3783c80SYury Norov 
211e3783c80SYury Norov 	expect_eq_uint(10,  find_nth_bit(bmap, 64 * 3, 0));
212e3783c80SYury Norov 	expect_eq_uint(20,  find_nth_bit(bmap, 64 * 3, 1));
213e3783c80SYury Norov 	expect_eq_uint(30,  find_nth_bit(bmap, 64 * 3, 2));
214e3783c80SYury Norov 	expect_eq_uint(40,  find_nth_bit(bmap, 64 * 3, 3));
215e3783c80SYury Norov 	expect_eq_uint(50,  find_nth_bit(bmap, 64 * 3, 4));
216e3783c80SYury Norov 	expect_eq_uint(60,  find_nth_bit(bmap, 64 * 3, 5));
217e3783c80SYury Norov 	expect_eq_uint(80,  find_nth_bit(bmap, 64 * 3, 6));
218e3783c80SYury Norov 	expect_eq_uint(123, find_nth_bit(bmap, 64 * 3, 7));
2190b2811baSYury Norov 	expect_eq_uint(0,   !!(find_nth_bit(bmap, 64 * 3, 8) < 64 * 3));
220e3783c80SYury Norov 
221e3783c80SYury Norov 	expect_eq_uint(10,  find_nth_bit(bmap, 64 * 3 - 1, 0));
222e3783c80SYury Norov 	expect_eq_uint(20,  find_nth_bit(bmap, 64 * 3 - 1, 1));
223e3783c80SYury Norov 	expect_eq_uint(30,  find_nth_bit(bmap, 64 * 3 - 1, 2));
224e3783c80SYury Norov 	expect_eq_uint(40,  find_nth_bit(bmap, 64 * 3 - 1, 3));
225e3783c80SYury Norov 	expect_eq_uint(50,  find_nth_bit(bmap, 64 * 3 - 1, 4));
226e3783c80SYury Norov 	expect_eq_uint(60,  find_nth_bit(bmap, 64 * 3 - 1, 5));
227e3783c80SYury Norov 	expect_eq_uint(80,  find_nth_bit(bmap, 64 * 3 - 1, 6));
228e3783c80SYury Norov 	expect_eq_uint(123, find_nth_bit(bmap, 64 * 3 - 1, 7));
2290b2811baSYury Norov 	expect_eq_uint(0,   !!(find_nth_bit(bmap, 64 * 3 - 1, 8) < 64 * 3 - 1));
230e3783c80SYury Norov 
231e3783c80SYury Norov 	for_each_set_bit(bit, exp1, EXP1_IN_BITS) {
232e3783c80SYury Norov 		b = find_nth_bit(exp1, EXP1_IN_BITS, cnt++);
233e3783c80SYury Norov 		expect_eq_uint(b, bit);
234e3783c80SYury Norov 	}
235e3783c80SYury Norov }
236e3783c80SYury Norov 
test_fill_set(void)237978f369cSAndy Shevchenko static void __init test_fill_set(void)
238978f369cSAndy Shevchenko {
239978f369cSAndy Shevchenko 	DECLARE_BITMAP(bmap, 1024);
240978f369cSAndy Shevchenko 
241978f369cSAndy Shevchenko 	/* Known way to clear all bits */
242978f369cSAndy Shevchenko 	memset(bmap, 0x00, 128);
243978f369cSAndy Shevchenko 
244978f369cSAndy Shevchenko 	expect_eq_pbl("", bmap, 23);
245978f369cSAndy Shevchenko 	expect_eq_pbl("", bmap, 1024);
246978f369cSAndy Shevchenko 
247978f369cSAndy Shevchenko 	/* single-word bitmaps */
248978f369cSAndy Shevchenko 	bitmap_set(bmap, 0, 9);
249978f369cSAndy Shevchenko 	expect_eq_pbl("0-8", bmap, 1024);
250978f369cSAndy Shevchenko 
251978f369cSAndy Shevchenko 	bitmap_fill(bmap, 35);
252978f369cSAndy Shevchenko 	expect_eq_pbl("0-63", bmap, 1024);
253978f369cSAndy Shevchenko 
254978f369cSAndy Shevchenko 	/* cross boundaries operations */
255978f369cSAndy Shevchenko 	bitmap_set(bmap, 79, 19);
256978f369cSAndy Shevchenko 	expect_eq_pbl("0-63,79-97", bmap, 1024);
257978f369cSAndy Shevchenko 
258978f369cSAndy Shevchenko 	bitmap_fill(bmap, 115);
259978f369cSAndy Shevchenko 	expect_eq_pbl("0-127", bmap, 1024);
260978f369cSAndy Shevchenko 
261978f369cSAndy Shevchenko 	/* Zeroing entire area */
262978f369cSAndy Shevchenko 	bitmap_fill(bmap, 1024);
263978f369cSAndy Shevchenko 	expect_eq_pbl("0-1023", bmap, 1024);
264978f369cSAndy Shevchenko }
265978f369cSAndy Shevchenko 
test_copy(void)266fe81814cSAndy Shevchenko static void __init test_copy(void)
2675fd003f5SDavid Decotigny {
2685fd003f5SDavid Decotigny 	DECLARE_BITMAP(bmap1, 1024);
2695fd003f5SDavid Decotigny 	DECLARE_BITMAP(bmap2, 1024);
2705fd003f5SDavid Decotigny 
2715fd003f5SDavid Decotigny 	bitmap_zero(bmap1, 1024);
2725fd003f5SDavid Decotigny 	bitmap_zero(bmap2, 1024);
2735fd003f5SDavid Decotigny 
2745fd003f5SDavid Decotigny 	/* single-word bitmaps */
275fe81814cSAndy Shevchenko 	bitmap_set(bmap1, 0, 19);
2765fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 23);
2775fd003f5SDavid Decotigny 	expect_eq_pbl("0-18", bmap2, 1024);
2785fd003f5SDavid Decotigny 
279fe81814cSAndy Shevchenko 	bitmap_set(bmap2, 0, 23);
2805fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 23);
2815fd003f5SDavid Decotigny 	expect_eq_pbl("0-18", bmap2, 1024);
2825fd003f5SDavid Decotigny 
2835fd003f5SDavid Decotigny 	/* multi-word bitmaps */
284fe81814cSAndy Shevchenko 	bitmap_set(bmap1, 0, 109);
2855fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 1024);
2865fd003f5SDavid Decotigny 	expect_eq_pbl("0-108", bmap2, 1024);
2875fd003f5SDavid Decotigny 
2885fd003f5SDavid Decotigny 	bitmap_fill(bmap2, 1024);
2895fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 1024);
2905fd003f5SDavid Decotigny 	expect_eq_pbl("0-108", bmap2, 1024);
2915fd003f5SDavid Decotigny 
2925fd003f5SDavid Decotigny 	/* the following tests assume a 32- or 64-bit arch (even 128b
2935fd003f5SDavid Decotigny 	 * if we care)
2945fd003f5SDavid Decotigny 	 */
2955fd003f5SDavid Decotigny 
2965fd003f5SDavid Decotigny 	bitmap_fill(bmap2, 1024);
2975fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 109);  /* ... but 0-padded til word length */
2985fd003f5SDavid Decotigny 	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
2995fd003f5SDavid Decotigny 
3005fd003f5SDavid Decotigny 	bitmap_fill(bmap2, 1024);
3015fd003f5SDavid Decotigny 	bitmap_copy(bmap2, bmap1, 97);  /* ... but aligned on word length */
3025fd003f5SDavid Decotigny 	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
3035fd003f5SDavid Decotigny }
3045fd003f5SDavid Decotigny 
test_bitmap_region(void)3056d5d3a0cSYury Norov static void __init test_bitmap_region(void)
3066d5d3a0cSYury Norov {
3076d5d3a0cSYury Norov 	int pos, order;
3086d5d3a0cSYury Norov 
3096d5d3a0cSYury Norov 	DECLARE_BITMAP(bmap, 1000);
3106d5d3a0cSYury Norov 
3116d5d3a0cSYury Norov 	bitmap_zero(bmap, 1000);
3126d5d3a0cSYury Norov 
3136d5d3a0cSYury Norov 	for (order = 0; order < 10; order++) {
3146d5d3a0cSYury Norov 		pos = bitmap_find_free_region(bmap, 1000, order);
3156d5d3a0cSYury Norov 		if (order == 0)
3166d5d3a0cSYury Norov 			expect_eq_uint(pos, 0);
3176d5d3a0cSYury Norov 		else
3186d5d3a0cSYury Norov 			expect_eq_uint(pos, order < 9 ? BIT(order) : -ENOMEM);
3196d5d3a0cSYury Norov 	}
3206d5d3a0cSYury Norov 
3216d5d3a0cSYury Norov 	bitmap_release_region(bmap, 0, 0);
3226d5d3a0cSYury Norov 	for (order = 1; order < 9; order++)
3236d5d3a0cSYury Norov 		bitmap_release_region(bmap, BIT(order), order);
3246d5d3a0cSYury Norov 
3256d5d3a0cSYury Norov 	expect_eq_uint(bitmap_weight(bmap, 1000), 0);
3266d5d3a0cSYury Norov }
3276d5d3a0cSYury Norov 
32830544ed5SAndy Shevchenko #define EXP2_IN_BITS	(sizeof(exp2) * 8)
32930544ed5SAndy Shevchenko 
test_replace(void)33030544ed5SAndy Shevchenko static void __init test_replace(void)
33130544ed5SAndy Shevchenko {
33230544ed5SAndy Shevchenko 	unsigned int nbits = 64;
33369334ca5SAndy Shevchenko 	unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG);
33430544ed5SAndy Shevchenko 	DECLARE_BITMAP(bmap, 1024);
33530544ed5SAndy Shevchenko 
336caa7f776SAndy Shevchenko 	BUILD_BUG_ON(EXP2_IN_BITS < nbits * 2);
337caa7f776SAndy Shevchenko 
33830544ed5SAndy Shevchenko 	bitmap_zero(bmap, 1024);
33969334ca5SAndy Shevchenko 	bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
34030544ed5SAndy Shevchenko 	expect_eq_bitmap(bmap, exp3_0_1, nbits);
34130544ed5SAndy Shevchenko 
34230544ed5SAndy Shevchenko 	bitmap_zero(bmap, 1024);
34369334ca5SAndy Shevchenko 	bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
34430544ed5SAndy Shevchenko 	expect_eq_bitmap(bmap, exp3_1_0, nbits);
34530544ed5SAndy Shevchenko 
34630544ed5SAndy Shevchenko 	bitmap_fill(bmap, 1024);
34769334ca5SAndy Shevchenko 	bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits);
34830544ed5SAndy Shevchenko 	expect_eq_bitmap(bmap, exp3_0_1, nbits);
34930544ed5SAndy Shevchenko 
35030544ed5SAndy Shevchenko 	bitmap_fill(bmap, 1024);
35169334ca5SAndy Shevchenko 	bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits);
35230544ed5SAndy Shevchenko 	expect_eq_bitmap(bmap, exp3_1_0, nbits);
35330544ed5SAndy Shevchenko }
35430544ed5SAndy Shevchenko 
355de5f8433SAndy Shevchenko static const unsigned long sg_mask[] __initconst = {
356de5f8433SAndy Shevchenko 	BITMAP_FROM_U64(0x000000000000035aULL),
357de5f8433SAndy Shevchenko };
358de5f8433SAndy Shevchenko 
359de5f8433SAndy Shevchenko static const unsigned long sg_src[] __initconst = {
360de5f8433SAndy Shevchenko 	BITMAP_FROM_U64(0x0000000000000667ULL),
361de5f8433SAndy Shevchenko };
362de5f8433SAndy Shevchenko 
363de5f8433SAndy Shevchenko static const unsigned long sg_gather_exp[] __initconst = {
364de5f8433SAndy Shevchenko 	BITMAP_FROM_U64(0x0000000000000029ULL),
365de5f8433SAndy Shevchenko };
366de5f8433SAndy Shevchenko 
367de5f8433SAndy Shevchenko static const unsigned long sg_scatter_exp[] __initconst = {
368de5f8433SAndy Shevchenko 	BITMAP_FROM_U64(0x000000000000021aULL),
369de5f8433SAndy Shevchenko };
370de5f8433SAndy Shevchenko 
test_bitmap_sg(void)371de5f8433SAndy Shevchenko static void __init test_bitmap_sg(void)
372de5f8433SAndy Shevchenko {
373de5f8433SAndy Shevchenko 	unsigned int nbits = 64;
374de5f8433SAndy Shevchenko 	DECLARE_BITMAP(bmap_gather, 100);
375de5f8433SAndy Shevchenko 	DECLARE_BITMAP(bmap_scatter, 100);
376de5f8433SAndy Shevchenko 	DECLARE_BITMAP(bmap_tmp, 100);
377de5f8433SAndy Shevchenko 	DECLARE_BITMAP(bmap_res, 100);
378de5f8433SAndy Shevchenko 
379de5f8433SAndy Shevchenko 	/* Simple gather call */
380de5f8433SAndy Shevchenko 	bitmap_zero(bmap_gather, 100);
381de5f8433SAndy Shevchenko 	bitmap_gather(bmap_gather, sg_src, sg_mask, nbits);
382de5f8433SAndy Shevchenko 	expect_eq_bitmap(sg_gather_exp, bmap_gather, nbits);
383de5f8433SAndy Shevchenko 
384de5f8433SAndy Shevchenko 	/* Simple scatter call */
385de5f8433SAndy Shevchenko 	bitmap_zero(bmap_scatter, 100);
386de5f8433SAndy Shevchenko 	bitmap_scatter(bmap_scatter, sg_src, sg_mask, nbits);
387de5f8433SAndy Shevchenko 	expect_eq_bitmap(sg_scatter_exp, bmap_scatter, nbits);
388de5f8433SAndy Shevchenko 
389de5f8433SAndy Shevchenko 	/* Scatter/gather relationship */
390de5f8433SAndy Shevchenko 	bitmap_zero(bmap_tmp, 100);
391de5f8433SAndy Shevchenko 	bitmap_gather(bmap_tmp, bmap_scatter, sg_mask, nbits);
392de5f8433SAndy Shevchenko 	bitmap_scatter(bmap_res, bmap_tmp, sg_mask, nbits);
393de5f8433SAndy Shevchenko 	expect_eq_bitmap(bmap_scatter, bmap_res, nbits);
394de5f8433SAndy Shevchenko }
395de5f8433SAndy Shevchenko 
3966df0d464SYury Norov #define PARSE_TIME	0x1
3977eb2e94eSYury Norov #define NO_LEN		0x2
3986df0d464SYury Norov 
3996df0d464SYury Norov struct test_bitmap_parselist{
4006df0d464SYury Norov 	const int errno;
4016df0d464SYury Norov 	const char *in;
4026df0d464SYury Norov 	const unsigned long *expected;
4036df0d464SYury Norov 	const int nbits;
4046df0d464SYury Norov 	const int flags;
4056df0d464SYury Norov };
4066df0d464SYury Norov 
4076df0d464SYury Norov static const struct test_bitmap_parselist parselist_tests[] __initconst = {
40860ef6900SYury Norov #define step (sizeof(u64) / sizeof(unsigned long))
40960ef6900SYury Norov 
4100ee312e3SAndy Shevchenko 	{0, "0",			&exp1[0], 8, 0},
4110ee312e3SAndy Shevchenko 	{0, "1",			&exp1[1 * step], 8, 0},
4120ee312e3SAndy Shevchenko 	{0, "0-15",			&exp1[2 * step], 32, 0},
4130ee312e3SAndy Shevchenko 	{0, "16-31",			&exp1[3 * step], 32, 0},
4140ee312e3SAndy Shevchenko 	{0, "0-31:1/2",			&exp1[4 * step], 32, 0},
4150ee312e3SAndy Shevchenko 	{0, "1-31:1/2",			&exp1[5 * step], 32, 0},
4160ee312e3SAndy Shevchenko 	{0, "0-31:1/4",			&exp1[6 * step], 32, 0},
4170ee312e3SAndy Shevchenko 	{0, "1-31:1/4",			&exp1[7 * step], 32, 0},
4180ee312e3SAndy Shevchenko 	{0, "0-31:4/4",			&exp1[8 * step], 32, 0},
4190ee312e3SAndy Shevchenko 	{0, "1-31:4/4",			&exp1[9 * step], 32, 0},
4200ee312e3SAndy Shevchenko 	{0, "0-31:1/4,32-63:2/4",	&exp1[10 * step], 64, 0},
4210ee312e3SAndy Shevchenko 	{0, "0-31:3/4,32-63:4/4",	&exp1[11 * step], 64, 0},
4220ee312e3SAndy Shevchenko 	{0, "  ,,  0-31:3/4  ,, 32-63:4/4  ,,  ",	&exp1[11 * step], 64, 0},
4236df0d464SYury Norov 
4246df0d464SYury Norov 	{0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4",	exp2, 128, 0},
4256df0d464SYury Norov 
4266df0d464SYury Norov 	{0, "0-2047:128/256", NULL, 2048, PARSE_TIME},
4276df0d464SYury Norov 
4280ee312e3SAndy Shevchenko 	{0, "",				&exp1[12 * step], 8, 0},
4290ee312e3SAndy Shevchenko 	{0, "\n",			&exp1[12 * step], 8, 0},
4300ee312e3SAndy Shevchenko 	{0, ",,  ,,  , ,  ,",		&exp1[12 * step], 8, 0},
4310ee312e3SAndy Shevchenko 	{0, " ,  ,,  , ,   ",		&exp1[12 * step], 8, 0},
4320ee312e3SAndy Shevchenko 	{0, " ,  ,,  , ,   \n",		&exp1[12 * step], 8, 0},
433a4ab5050SYury Norov 
43497330db3SPaul Gortmaker 	{0, "0-0",			&exp1[0], 32, 0},
43597330db3SPaul Gortmaker 	{0, "1-1",			&exp1[1 * step], 32, 0},
43697330db3SPaul Gortmaker 	{0, "15-15",			&exp1[13 * step], 32, 0},
43797330db3SPaul Gortmaker 	{0, "31-31",			&exp1[14 * step], 32, 0},
43897330db3SPaul Gortmaker 
43997330db3SPaul Gortmaker 	{0, "0-0:0/1",			&exp1[12 * step], 32, 0},
44097330db3SPaul Gortmaker 	{0, "0-0:1/1",			&exp1[0], 32, 0},
44197330db3SPaul Gortmaker 	{0, "0-0:1/31",			&exp1[0], 32, 0},
44297330db3SPaul Gortmaker 	{0, "0-0:31/31",		&exp1[0], 32, 0},
44397330db3SPaul Gortmaker 	{0, "1-1:1/1",			&exp1[1 * step], 32, 0},
44497330db3SPaul Gortmaker 	{0, "0-15:16/31",		&exp1[2 * step], 32, 0},
44597330db3SPaul Gortmaker 	{0, "15-15:1/2",		&exp1[13 * step], 32, 0},
44697330db3SPaul Gortmaker 	{0, "15-15:31/31",		&exp1[13 * step], 32, 0},
44797330db3SPaul Gortmaker 	{0, "15-31:1/31",		&exp1[13 * step], 32, 0},
44897330db3SPaul Gortmaker 	{0, "16-31:16/31",		&exp1[3 * step], 32, 0},
44997330db3SPaul Gortmaker 	{0, "31-31:31/31",		&exp1[14 * step], 32, 0},
45097330db3SPaul Gortmaker 
45199c58d1aSPaul Gortmaker 	{0, "N-N",			&exp1[14 * step], 32, 0},
45299c58d1aSPaul Gortmaker 	{0, "0-0:1/N",			&exp1[0], 32, 0},
45399c58d1aSPaul Gortmaker 	{0, "0-0:N/N",			&exp1[0], 32, 0},
45499c58d1aSPaul Gortmaker 	{0, "0-15:16/N",		&exp1[2 * step], 32, 0},
45599c58d1aSPaul Gortmaker 	{0, "15-15:N/N",		&exp1[13 * step], 32, 0},
45699c58d1aSPaul Gortmaker 	{0, "15-N:1/N",			&exp1[13 * step], 32, 0},
45799c58d1aSPaul Gortmaker 	{0, "16-N:16/N",		&exp1[3 * step], 32, 0},
45899c58d1aSPaul Gortmaker 	{0, "N-N:N/N",			&exp1[14 * step], 32, 0},
45999c58d1aSPaul Gortmaker 
46099c58d1aSPaul Gortmaker 	{0, "0-N:1/3,1-N:1/3,2-N:1/3",		&exp1[8 * step], 32, 0},
46197330db3SPaul Gortmaker 	{0, "0-31:1/3,1-31:1/3,2-31:1/3",	&exp1[8 * step], 32, 0},
46297330db3SPaul Gortmaker 	{0, "1-10:8/12,8-31:24/29,0-31:0/3",	&exp1[9 * step], 32, 0},
46397330db3SPaul Gortmaker 
464b18def12SYury Norov 	{0,	  "all",		&exp1[8 * step], 32, 0},
465b18def12SYury Norov 	{0,	  "0, 1, all,  ",	&exp1[8 * step], 32, 0},
466b18def12SYury Norov 	{0,	  "all:1/2",		&exp1[4 * step], 32, 0},
467b18def12SYury Norov 	{0,	  "ALL:1/2",		&exp1[4 * step], 32, 0},
468b18def12SYury Norov 	{-EINVAL, "al", NULL, 8, 0},
469b18def12SYury Norov 	{-EINVAL, "alll", NULL, 8, 0},
470b18def12SYury Norov 
4716df0d464SYury Norov 	{-EINVAL, "-1",	NULL, 8, 0},
4726df0d464SYury Norov 	{-EINVAL, "-0",	NULL, 8, 0},
4736df0d464SYury Norov 	{-EINVAL, "10-1", NULL, 8, 0},
4746fef5905SPaul Gortmaker 	{-ERANGE, "8-8", NULL, 8, 0},
4756fef5905SPaul Gortmaker 	{-ERANGE, "0-31", NULL, 8, 0},
476494215fbSPaul Gortmaker 	{-EINVAL, "0-31:", NULL, 32, 0},
477494215fbSPaul Gortmaker 	{-EINVAL, "0-31:0", NULL, 32, 0},
478494215fbSPaul Gortmaker 	{-EINVAL, "0-31:0/", NULL, 32, 0},
479494215fbSPaul Gortmaker 	{-EINVAL, "0-31:0/0", NULL, 32, 0},
480494215fbSPaul Gortmaker 	{-EINVAL, "0-31:1/0", NULL, 32, 0},
481494215fbSPaul Gortmaker 	{-EINVAL, "0-31:10/1", NULL, 32, 0},
482a4ab5050SYury Norov 	{-EOVERFLOW, "0-98765432123456789:10/1", NULL, 8, 0},
483a4ab5050SYury Norov 
484a4ab5050SYury Norov 	{-EINVAL, "a-31", NULL, 8, 0},
485a4ab5050SYury Norov 	{-EINVAL, "0-a1", NULL, 8, 0},
486a4ab5050SYury Norov 	{-EINVAL, "a-31:10/1", NULL, 8, 0},
487a4ab5050SYury Norov 	{-EINVAL, "0-31:a/1", NULL, 8, 0},
488a4ab5050SYury Norov 	{-EINVAL, "0-\n", NULL, 8, 0},
48954224044SAndy Shevchenko 
4906df0d464SYury Norov };
4916df0d464SYury Norov 
test_bitmap_parselist(void)49281b1e242SChristoph Hellwig static void __init test_bitmap_parselist(void)
4936df0d464SYury Norov {
4946df0d464SYury Norov 	int i;
4956df0d464SYury Norov 	int err;
4960c2111a5SYury Norov 	ktime_t time;
4976df0d464SYury Norov 	DECLARE_BITMAP(bmap, 2048);
4986df0d464SYury Norov 
4996df0d464SYury Norov 	for (i = 0; i < ARRAY_SIZE(parselist_tests); i++) {
5006df0d464SYury Norov #define ptest parselist_tests[i]
5016df0d464SYury Norov 
5020c2111a5SYury Norov 		time = ktime_get();
5036df0d464SYury Norov 		err = bitmap_parselist(ptest.in, bmap, ptest.nbits);
5040c2111a5SYury Norov 		time = ktime_get() - time;
5056df0d464SYury Norov 
5066df0d464SYury Norov 		if (err != ptest.errno) {
50781b1e242SChristoph Hellwig 			pr_err("parselist: %d: input is %s, errno is %d, expected %d\n",
50881b1e242SChristoph Hellwig 					i, ptest.in, err, ptest.errno);
509c4c14c29SYury Norov 			failed_tests++;
5106df0d464SYury Norov 			continue;
5116df0d464SYury Norov 		}
5126df0d464SYury Norov 
5136df0d464SYury Norov 		if (!err && ptest.expected
5146df0d464SYury Norov 			 && !__bitmap_equal(bmap, ptest.expected, ptest.nbits)) {
51581b1e242SChristoph Hellwig 			pr_err("parselist: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
51681b1e242SChristoph Hellwig 					i, ptest.in, bmap[0],
5176ea86bdfSYury Norov 					*ptest.expected);
518c4c14c29SYury Norov 			failed_tests++;
5196df0d464SYury Norov 			continue;
5206df0d464SYury Norov 		}
5216df0d464SYury Norov 
5226df0d464SYury Norov 		if (ptest.flags & PARSE_TIME)
523f3e28876SAlexander Potapenko 			pr_info("parselist: %d: input is '%s' OK, Time: %llu\n",
52481b1e242SChristoph Hellwig 					i, ptest.in, time);
52554224044SAndy Shevchenko 
52654224044SAndy Shevchenko #undef ptest
5276df0d464SYury Norov 	}
5286df0d464SYury Norov }
5296df0d464SYury Norov 
test_bitmap_printlist(void)530db731300SYury Norov static void __init test_bitmap_printlist(void)
531db731300SYury Norov {
532db731300SYury Norov 	unsigned long *bmap = kmalloc(PAGE_SIZE, GFP_KERNEL);
533db731300SYury Norov 	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
534db731300SYury Norov 	char expected[256];
535db731300SYury Norov 	int ret, slen;
536db731300SYury Norov 	ktime_t time;
537db731300SYury Norov 
538db731300SYury Norov 	if (!buf || !bmap)
539db731300SYury Norov 		goto out;
540db731300SYury Norov 
541db731300SYury Norov 	memset(bmap, -1, PAGE_SIZE);
542db731300SYury Norov 	slen = snprintf(expected, 256, "0-%ld", PAGE_SIZE * 8 - 1);
543db731300SYury Norov 	if (slen < 0)
544db731300SYury Norov 		goto out;
545db731300SYury Norov 
546db731300SYury Norov 	time = ktime_get();
547db731300SYury Norov 	ret = bitmap_print_to_pagebuf(true, buf, bmap, PAGE_SIZE * 8);
548db731300SYury Norov 	time = ktime_get() - time;
549db731300SYury Norov 
550db731300SYury Norov 	if (ret != slen + 1) {
551db731300SYury Norov 		pr_err("bitmap_print_to_pagebuf: result is %d, expected %d\n", ret, slen);
552c4c14c29SYury Norov 		failed_tests++;
553db731300SYury Norov 		goto out;
554db731300SYury Norov 	}
555db731300SYury Norov 
556db731300SYury Norov 	if (strncmp(buf, expected, slen)) {
557db731300SYury Norov 		pr_err("bitmap_print_to_pagebuf: result is %s, expected %s\n", buf, expected);
558c4c14c29SYury Norov 		failed_tests++;
559db731300SYury Norov 		goto out;
560db731300SYury Norov 	}
561db731300SYury Norov 
562f3e28876SAlexander Potapenko 	pr_info("bitmap_print_to_pagebuf: input is '%s', Time: %llu\n", buf, time);
563db731300SYury Norov out:
564db731300SYury Norov 	kfree(buf);
565db731300SYury Norov 	kfree(bmap);
566db731300SYury Norov }
567db731300SYury Norov 
5687eb2e94eSYury Norov static const unsigned long parse_test[] __initconst = {
5697eb2e94eSYury Norov 	BITMAP_FROM_U64(0),
5707eb2e94eSYury Norov 	BITMAP_FROM_U64(1),
5717eb2e94eSYury Norov 	BITMAP_FROM_U64(0xdeadbeef),
5727eb2e94eSYury Norov 	BITMAP_FROM_U64(0x100000000ULL),
5737eb2e94eSYury Norov };
5747eb2e94eSYury Norov 
5757eb2e94eSYury Norov static const unsigned long parse_test2[] __initconst = {
5767eb2e94eSYury Norov 	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xdeadbeef),
5777eb2e94eSYury Norov 	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xbaadf00ddeadbeef),
5787eb2e94eSYury Norov 	BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0x0badf00ddeadbeef),
5797eb2e94eSYury Norov };
5807eb2e94eSYury Norov 
5817eb2e94eSYury Norov static const struct test_bitmap_parselist parse_tests[] __initconst = {
582809e308fSYury Norov 	{0, "",				&parse_test[0 * step], 32, 0},
583809e308fSYury Norov 	{0, " ",			&parse_test[0 * step], 32, 0},
5847eb2e94eSYury Norov 	{0, "0",			&parse_test[0 * step], 32, 0},
585809e308fSYury Norov 	{0, "0\n",			&parse_test[0 * step], 32, 0},
5867eb2e94eSYury Norov 	{0, "1",			&parse_test[1 * step], 32, 0},
5877eb2e94eSYury Norov 	{0, "deadbeef",			&parse_test[2 * step], 32, 0},
5887eb2e94eSYury Norov 	{0, "1,0",			&parse_test[3 * step], 33, 0},
589809e308fSYury Norov 	{0, "deadbeef,\n,0,1",		&parse_test[2 * step], 96, 0},
5907eb2e94eSYury Norov 
5917eb2e94eSYury Norov 	{0, "deadbeef,1,0",		&parse_test2[0 * 2 * step], 96, 0},
5927eb2e94eSYury Norov 	{0, "baadf00d,deadbeef,1,0",	&parse_test2[1 * 2 * step], 128, 0},
5937eb2e94eSYury Norov 	{0, "badf00d,deadbeef,1,0",	&parse_test2[2 * 2 * step], 124, 0},
594809e308fSYury Norov 	{0, "badf00d,deadbeef,1,0",	&parse_test2[2 * 2 * step], 124, NO_LEN},
595809e308fSYury Norov 	{0, "  badf00d,deadbeef,1,0  ",	&parse_test2[2 * 2 * step], 124, 0},
596809e308fSYury Norov 	{0, " , badf00d,deadbeef,1,0 , ",	&parse_test2[2 * 2 * step], 124, 0},
597809e308fSYury Norov 	{0, " , badf00d, ,, ,,deadbeef,1,0 , ",	&parse_test2[2 * 2 * step], 124, 0},
5987eb2e94eSYury Norov 
5997eb2e94eSYury Norov 	{-EINVAL,    "goodfood,deadbeef,1,0",	NULL, 128, 0},
6007eb2e94eSYury Norov 	{-EOVERFLOW, "3,0",			NULL, 33, 0},
6017eb2e94eSYury Norov 	{-EOVERFLOW, "123badf00d,deadbeef,1,0",	NULL, 128, 0},
6027eb2e94eSYury Norov 	{-EOVERFLOW, "badf00d,deadbeef,1,0",	NULL, 90, 0},
6037eb2e94eSYury Norov 	{-EOVERFLOW, "fbadf00d,deadbeef,1,0",	NULL, 95, 0},
6047eb2e94eSYury Norov 	{-EOVERFLOW, "badf00d,deadbeef,1,0",	NULL, 100, 0},
6057eb2e94eSYury Norov #undef step
6067eb2e94eSYury Norov };
6077eb2e94eSYury Norov 
test_bitmap_parse(void)60881b1e242SChristoph Hellwig static void __init test_bitmap_parse(void)
6097eb2e94eSYury Norov {
6107eb2e94eSYury Norov 	int i;
6117eb2e94eSYury Norov 	int err;
6127eb2e94eSYury Norov 	ktime_t time;
6137eb2e94eSYury Norov 	DECLARE_BITMAP(bmap, 2048);
6147eb2e94eSYury Norov 
6157eb2e94eSYury Norov 	for (i = 0; i < ARRAY_SIZE(parse_tests); i++) {
6167eb2e94eSYury Norov 		struct test_bitmap_parselist test = parse_tests[i];
61781b1e242SChristoph Hellwig 		size_t len = test.flags & NO_LEN ? UINT_MAX : strlen(test.in);
6187eb2e94eSYury Norov 
6197eb2e94eSYury Norov 		time = ktime_get();
6207eb2e94eSYury Norov 		err = bitmap_parse(test.in, len, bmap, test.nbits);
6217eb2e94eSYury Norov 		time = ktime_get() - time;
6227eb2e94eSYury Norov 
6237eb2e94eSYury Norov 		if (err != test.errno) {
62481b1e242SChristoph Hellwig 			pr_err("parse: %d: input is %s, errno is %d, expected %d\n",
62581b1e242SChristoph Hellwig 					i, test.in, err, test.errno);
626c4c14c29SYury Norov 			failed_tests++;
6277eb2e94eSYury Norov 			continue;
6287eb2e94eSYury Norov 		}
6297eb2e94eSYury Norov 
6307eb2e94eSYury Norov 		if (!err && test.expected
6317eb2e94eSYury Norov 			 && !__bitmap_equal(bmap, test.expected, test.nbits)) {
63281b1e242SChristoph Hellwig 			pr_err("parse: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
63381b1e242SChristoph Hellwig 					i, test.in, bmap[0],
6347eb2e94eSYury Norov 					*test.expected);
635c4c14c29SYury Norov 			failed_tests++;
6367eb2e94eSYury Norov 			continue;
6377eb2e94eSYury Norov 		}
6387eb2e94eSYury Norov 
6397eb2e94eSYury Norov 		if (test.flags & PARSE_TIME)
640f3e28876SAlexander Potapenko 			pr_info("parse: %d: input is '%s' OK, Time: %llu\n",
64181b1e242SChristoph Hellwig 					i, test.in, time);
6427eb2e94eSYury Norov 	}
6437eb2e94eSYury Norov }
6447eb2e94eSYury Norov 
test_bitmap_arr32(void)6453aa56885SYury Norov static void __init test_bitmap_arr32(void)
6465fd003f5SDavid Decotigny {
647f6f66c1bSKees Cook 	unsigned int nbits, next_bit;
648a4881d1cSAndy Shevchenko 	u32 arr[EXP1_IN_BITS / 32];
649a4881d1cSAndy Shevchenko 	DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
6505fd003f5SDavid Decotigny 
6513aa56885SYury Norov 	memset(arr, 0xa5, sizeof(arr));
6525fd003f5SDavid Decotigny 
653a4881d1cSAndy Shevchenko 	for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
6540ee312e3SAndy Shevchenko 		bitmap_to_arr32(arr, exp1, nbits);
6553aa56885SYury Norov 		bitmap_from_arr32(bmap2, arr, nbits);
6560ee312e3SAndy Shevchenko 		expect_eq_bitmap(bmap2, exp1, nbits);
6575fd003f5SDavid Decotigny 
6583aa56885SYury Norov 		next_bit = find_next_bit(bmap2,
6593aa56885SYury Norov 				round_up(nbits, BITS_PER_LONG), nbits);
660c4c14c29SYury Norov 		if (next_bit < round_up(nbits, BITS_PER_LONG)) {
6613aa56885SYury Norov 			pr_err("bitmap_copy_arr32(nbits == %d:"
6623aa56885SYury Norov 				" tail is not safely cleared: %d\n",
6633aa56885SYury Norov 				nbits, next_bit);
664c4c14c29SYury Norov 			failed_tests++;
665c4c14c29SYury Norov 		}
6665fd003f5SDavid Decotigny 
667a4881d1cSAndy Shevchenko 		if (nbits < EXP1_IN_BITS - 32)
6683aa56885SYury Norov 			expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
6693aa56885SYury Norov 								0xa5a5a5a5);
6705fd003f5SDavid Decotigny 	}
6715fd003f5SDavid Decotigny }
6725fd003f5SDavid Decotigny 
test_bitmap_arr64(void)6732c523550SYury Norov static void __init test_bitmap_arr64(void)
6742c523550SYury Norov {
6752c523550SYury Norov 	unsigned int nbits, next_bit;
6762c523550SYury Norov 	u64 arr[EXP1_IN_BITS / 64];
6772c523550SYury Norov 	DECLARE_BITMAP(bmap2, EXP1_IN_BITS);
6782c523550SYury Norov 
6792c523550SYury Norov 	memset(arr, 0xa5, sizeof(arr));
6802c523550SYury Norov 
6812c523550SYury Norov 	for (nbits = 0; nbits < EXP1_IN_BITS; ++nbits) {
6822c523550SYury Norov 		memset(bmap2, 0xff, sizeof(arr));
6832c523550SYury Norov 		bitmap_to_arr64(arr, exp1, nbits);
6842c523550SYury Norov 		bitmap_from_arr64(bmap2, arr, nbits);
6852c523550SYury Norov 		expect_eq_bitmap(bmap2, exp1, nbits);
6862c523550SYury Norov 
6872c523550SYury Norov 		next_bit = find_next_bit(bmap2, round_up(nbits, BITS_PER_LONG), nbits);
688c4c14c29SYury Norov 		if (next_bit < round_up(nbits, BITS_PER_LONG)) {
6892c523550SYury Norov 			pr_err("bitmap_copy_arr64(nbits == %d:"
6902c523550SYury Norov 				" tail is not safely cleared: %d\n", nbits, next_bit);
691c4c14c29SYury Norov 			failed_tests++;
692c4c14c29SYury Norov 		}
6932c523550SYury Norov 
69430fd8cdfSAlexander Lobakin 		if ((nbits % 64) &&
695c4c14c29SYury Norov 		    (arr[(nbits - 1) / 64] & ~GENMASK_ULL((nbits - 1) % 64, 0))) {
69630fd8cdfSAlexander Lobakin 			pr_err("bitmap_to_arr64(nbits == %d): tail is not safely cleared: 0x%016llx (must be 0x%016llx)\n",
69730fd8cdfSAlexander Lobakin 			       nbits, arr[(nbits - 1) / 64],
69830fd8cdfSAlexander Lobakin 			       GENMASK_ULL((nbits - 1) % 64, 0));
699c4c14c29SYury Norov 			failed_tests++;
700c4c14c29SYury Norov 		}
70130fd8cdfSAlexander Lobakin 
7022c523550SYury Norov 		if (nbits < EXP1_IN_BITS - 64)
7032c523550SYury Norov 			expect_eq_uint(arr[DIV_ROUND_UP(nbits, 64)], 0xa5a5a5a5);
7042c523550SYury Norov 	}
7052c523550SYury Norov }
7062c523550SYury Norov 
test_mem_optimisations(void)7073cc78125SMatthew Wilcox static void noinline __init test_mem_optimisations(void)
7083cc78125SMatthew Wilcox {
7093cc78125SMatthew Wilcox 	DECLARE_BITMAP(bmap1, 1024);
7103cc78125SMatthew Wilcox 	DECLARE_BITMAP(bmap2, 1024);
7113cc78125SMatthew Wilcox 	unsigned int start, nbits;
7123cc78125SMatthew Wilcox 
7133cc78125SMatthew Wilcox 	for (start = 0; start < 1024; start += 8) {
7141e3054b9SMatthew Wilcox 		for (nbits = 0; nbits < 1024 - start; nbits += 8) {
7153cc78125SMatthew Wilcox 			memset(bmap1, 0x5a, sizeof(bmap1));
7163cc78125SMatthew Wilcox 			memset(bmap2, 0x5a, sizeof(bmap2));
7171e3054b9SMatthew Wilcox 
7183cc78125SMatthew Wilcox 			bitmap_set(bmap1, start, nbits);
7193cc78125SMatthew Wilcox 			__bitmap_set(bmap2, start, nbits);
7201e3054b9SMatthew Wilcox 			if (!bitmap_equal(bmap1, bmap2, 1024)) {
7213cc78125SMatthew Wilcox 				printk("set not equal %d %d\n", start, nbits);
7221e3054b9SMatthew Wilcox 				failed_tests++;
7231e3054b9SMatthew Wilcox 			}
7241e3054b9SMatthew Wilcox 			if (!__bitmap_equal(bmap1, bmap2, 1024)) {
7253cc78125SMatthew Wilcox 				printk("set not __equal %d %d\n", start, nbits);
7261e3054b9SMatthew Wilcox 				failed_tests++;
7271e3054b9SMatthew Wilcox 			}
7283cc78125SMatthew Wilcox 
7293cc78125SMatthew Wilcox 			bitmap_clear(bmap1, start, nbits);
7303cc78125SMatthew Wilcox 			__bitmap_clear(bmap2, start, nbits);
7311e3054b9SMatthew Wilcox 			if (!bitmap_equal(bmap1, bmap2, 1024)) {
7323cc78125SMatthew Wilcox 				printk("clear not equal %d %d\n", start, nbits);
7331e3054b9SMatthew Wilcox 				failed_tests++;
7341e3054b9SMatthew Wilcox 			}
7351e3054b9SMatthew Wilcox 			if (!__bitmap_equal(bmap1, bmap2, 1024)) {
7363cc78125SMatthew Wilcox 				printk("clear not __equal %d %d\n", start,
7373cc78125SMatthew Wilcox 									nbits);
7381e3054b9SMatthew Wilcox 				failed_tests++;
7391e3054b9SMatthew Wilcox 			}
7403cc78125SMatthew Wilcox 		}
7413cc78125SMatthew Wilcox 	}
7423cc78125SMatthew Wilcox }
7433cc78125SMatthew Wilcox 
744e4aa168dSWilliam Breathitt Gray static const unsigned char clump_exp[] __initconst = {
745e4aa168dSWilliam Breathitt Gray 	0x01,	/* 1 bit set */
746e4aa168dSWilliam Breathitt Gray 	0x02,	/* non-edge 1 bit set */
747e4aa168dSWilliam Breathitt Gray 	0x00,	/* zero bits set */
748e4aa168dSWilliam Breathitt Gray 	0x38,	/* 3 bits set across 4-bit boundary */
749e4aa168dSWilliam Breathitt Gray 	0x38,	/* Repeated clump */
750e4aa168dSWilliam Breathitt Gray 	0x0F,	/* 4 bits set */
751e4aa168dSWilliam Breathitt Gray 	0xFF,	/* all bits set */
752e4aa168dSWilliam Breathitt Gray 	0x05,	/* non-adjacent 2 bits set */
753e4aa168dSWilliam Breathitt Gray };
754e4aa168dSWilliam Breathitt Gray 
test_for_each_set_clump8(void)755e4aa168dSWilliam Breathitt Gray static void __init test_for_each_set_clump8(void)
756e4aa168dSWilliam Breathitt Gray {
757e4aa168dSWilliam Breathitt Gray #define CLUMP_EXP_NUMBITS 64
758e4aa168dSWilliam Breathitt Gray 	DECLARE_BITMAP(bits, CLUMP_EXP_NUMBITS);
759e4aa168dSWilliam Breathitt Gray 	unsigned int start;
760e4aa168dSWilliam Breathitt Gray 	unsigned long clump;
761e4aa168dSWilliam Breathitt Gray 
762e4aa168dSWilliam Breathitt Gray 	/* set bitmap to test case */
763e4aa168dSWilliam Breathitt Gray 	bitmap_zero(bits, CLUMP_EXP_NUMBITS);
764e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 0, 1);		/* 0x01 */
765e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 9, 1);		/* 0x02 */
766e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 27, 3);	/* 0x28 */
767e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 35, 3);	/* 0x28 */
768e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 40, 4);	/* 0x0F */
769e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 48, 8);	/* 0xFF */
770e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 56, 1);	/* 0x05 - part 1 */
771e4aa168dSWilliam Breathitt Gray 	bitmap_set(bits, 58, 1);	/* 0x05 - part 2 */
772e4aa168dSWilliam Breathitt Gray 
773e4aa168dSWilliam Breathitt Gray 	for_each_set_clump8(start, clump, bits, CLUMP_EXP_NUMBITS)
774e4aa168dSWilliam Breathitt Gray 		expect_eq_clump8(start, CLUMP_EXP_NUMBITS, clump_exp, &clump);
775e4aa168dSWilliam Breathitt Gray }
776e4aa168dSWilliam Breathitt Gray 
test_for_each_set_bit_wrap(void)7778173aa26SYury Norov static void __init test_for_each_set_bit_wrap(void)
7788173aa26SYury Norov {
7798173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
7808173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
7818173aa26SYury Norov 	unsigned int wr, bit;
7828173aa26SYury Norov 
7838173aa26SYury Norov 	bitmap_zero(orig, 500);
7848173aa26SYury Norov 
7858173aa26SYury Norov 	/* Set individual bits */
7868173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
7878173aa26SYury Norov 		bitmap_set(orig, bit, 1);
7888173aa26SYury Norov 
7898173aa26SYury Norov 	/* Set range of bits */
7908173aa26SYury Norov 	bitmap_set(orig, 100, 50);
7918173aa26SYury Norov 
7928173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
7938173aa26SYury Norov 		bitmap_zero(copy, 500);
7948173aa26SYury Norov 
7958173aa26SYury Norov 		for_each_set_bit_wrap(bit, orig, 500, wr)
7968173aa26SYury Norov 			bitmap_set(copy, bit, 1);
7978173aa26SYury Norov 
7988173aa26SYury Norov 		expect_eq_bitmap(orig, copy, 500);
7998173aa26SYury Norov 	}
8008173aa26SYury Norov }
8018173aa26SYury Norov 
test_for_each_set_bit(void)8028173aa26SYury Norov static void __init test_for_each_set_bit(void)
8038173aa26SYury Norov {
8048173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
8058173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
8068173aa26SYury Norov 	unsigned int bit;
8078173aa26SYury Norov 
8088173aa26SYury Norov 	bitmap_zero(orig, 500);
8098173aa26SYury Norov 	bitmap_zero(copy, 500);
8108173aa26SYury Norov 
8118173aa26SYury Norov 	/* Set individual bits */
8128173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
8138173aa26SYury Norov 		bitmap_set(orig, bit, 1);
8148173aa26SYury Norov 
8158173aa26SYury Norov 	/* Set range of bits */
8168173aa26SYury Norov 	bitmap_set(orig, 100, 50);
8178173aa26SYury Norov 
8188173aa26SYury Norov 	for_each_set_bit(bit, orig, 500)
8198173aa26SYury Norov 		bitmap_set(copy, bit, 1);
8208173aa26SYury Norov 
8218173aa26SYury Norov 	expect_eq_bitmap(orig, copy, 500);
8228173aa26SYury Norov }
8238173aa26SYury Norov 
test_for_each_set_bit_from(void)8248173aa26SYury Norov static void __init test_for_each_set_bit_from(void)
8258173aa26SYury Norov {
8268173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
8278173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
8288173aa26SYury Norov 	unsigned int wr, bit;
8298173aa26SYury Norov 
8308173aa26SYury Norov 	bitmap_zero(orig, 500);
8318173aa26SYury Norov 
8328173aa26SYury Norov 	/* Set individual bits */
8338173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
8348173aa26SYury Norov 		bitmap_set(orig, bit, 1);
8358173aa26SYury Norov 
8368173aa26SYury Norov 	/* Set range of bits */
8378173aa26SYury Norov 	bitmap_set(orig, 100, 50);
8388173aa26SYury Norov 
8398173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
8408173aa26SYury Norov 		DECLARE_BITMAP(tmp, 500);
8418173aa26SYury Norov 
8428173aa26SYury Norov 		bitmap_zero(copy, 500);
8438173aa26SYury Norov 		bit = wr;
8448173aa26SYury Norov 
8458173aa26SYury Norov 		for_each_set_bit_from(bit, orig, 500)
8468173aa26SYury Norov 			bitmap_set(copy, bit, 1);
8478173aa26SYury Norov 
8488173aa26SYury Norov 		bitmap_copy(tmp, orig, 500);
8498173aa26SYury Norov 		bitmap_clear(tmp, 0, wr);
8508173aa26SYury Norov 		expect_eq_bitmap(tmp, copy, 500);
8518173aa26SYury Norov 	}
8528173aa26SYury Norov }
8538173aa26SYury Norov 
test_for_each_clear_bit(void)8548173aa26SYury Norov static void __init test_for_each_clear_bit(void)
8558173aa26SYury Norov {
8568173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
8578173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
8588173aa26SYury Norov 	unsigned int bit;
8598173aa26SYury Norov 
8608173aa26SYury Norov 	bitmap_fill(orig, 500);
8618173aa26SYury Norov 	bitmap_fill(copy, 500);
8628173aa26SYury Norov 
8638173aa26SYury Norov 	/* Set individual bits */
8648173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
8658173aa26SYury Norov 		bitmap_clear(orig, bit, 1);
8668173aa26SYury Norov 
8678173aa26SYury Norov 	/* Set range of bits */
8688173aa26SYury Norov 	bitmap_clear(orig, 100, 50);
8698173aa26SYury Norov 
8708173aa26SYury Norov 	for_each_clear_bit(bit, orig, 500)
8718173aa26SYury Norov 		bitmap_clear(copy, bit, 1);
8728173aa26SYury Norov 
8738173aa26SYury Norov 	expect_eq_bitmap(orig, copy, 500);
8748173aa26SYury Norov }
8758173aa26SYury Norov 
test_for_each_clear_bit_from(void)8768173aa26SYury Norov static void __init test_for_each_clear_bit_from(void)
8778173aa26SYury Norov {
8788173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
8798173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
8808173aa26SYury Norov 	unsigned int wr, bit;
8818173aa26SYury Norov 
8828173aa26SYury Norov 	bitmap_fill(orig, 500);
8838173aa26SYury Norov 
8848173aa26SYury Norov 	/* Set individual bits */
8858173aa26SYury Norov 	for (bit = 0; bit < 500; bit += 10)
8868173aa26SYury Norov 		bitmap_clear(orig, bit, 1);
8878173aa26SYury Norov 
8888173aa26SYury Norov 	/* Set range of bits */
8898173aa26SYury Norov 	bitmap_clear(orig, 100, 50);
8908173aa26SYury Norov 
8918173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
8928173aa26SYury Norov 		DECLARE_BITMAP(tmp, 500);
8938173aa26SYury Norov 
8948173aa26SYury Norov 		bitmap_fill(copy, 500);
8958173aa26SYury Norov 		bit = wr;
8968173aa26SYury Norov 
8978173aa26SYury Norov 		for_each_clear_bit_from(bit, orig, 500)
8988173aa26SYury Norov 			bitmap_clear(copy, bit, 1);
8998173aa26SYury Norov 
9008173aa26SYury Norov 		bitmap_copy(tmp, orig, 500);
9018173aa26SYury Norov 		bitmap_set(tmp, 0, wr);
9028173aa26SYury Norov 		expect_eq_bitmap(tmp, copy, 500);
9038173aa26SYury Norov 	}
9048173aa26SYury Norov }
9058173aa26SYury Norov 
test_for_each_set_bitrange(void)9068173aa26SYury Norov static void __init test_for_each_set_bitrange(void)
9078173aa26SYury Norov {
9088173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
9098173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
9108173aa26SYury Norov 	unsigned int s, e;
9118173aa26SYury Norov 
9128173aa26SYury Norov 	bitmap_zero(orig, 500);
9138173aa26SYury Norov 	bitmap_zero(copy, 500);
9148173aa26SYury Norov 
9158173aa26SYury Norov 	/* Set individual bits */
9168173aa26SYury Norov 	for (s = 0; s < 500; s += 10)
9178173aa26SYury Norov 		bitmap_set(orig, s, 1);
9188173aa26SYury Norov 
9198173aa26SYury Norov 	/* Set range of bits */
9208173aa26SYury Norov 	bitmap_set(orig, 100, 50);
9218173aa26SYury Norov 
9228173aa26SYury Norov 	for_each_set_bitrange(s, e, orig, 500)
9238173aa26SYury Norov 		bitmap_set(copy, s, e-s);
9248173aa26SYury Norov 
9258173aa26SYury Norov 	expect_eq_bitmap(orig, copy, 500);
9268173aa26SYury Norov }
9278173aa26SYury Norov 
test_for_each_clear_bitrange(void)9288173aa26SYury Norov static void __init test_for_each_clear_bitrange(void)
9298173aa26SYury Norov {
9308173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
9318173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
9328173aa26SYury Norov 	unsigned int s, e;
9338173aa26SYury Norov 
9348173aa26SYury Norov 	bitmap_fill(orig, 500);
9358173aa26SYury Norov 	bitmap_fill(copy, 500);
9368173aa26SYury Norov 
9378173aa26SYury Norov 	/* Set individual bits */
9388173aa26SYury Norov 	for (s = 0; s < 500; s += 10)
9398173aa26SYury Norov 		bitmap_clear(orig, s, 1);
9408173aa26SYury Norov 
9418173aa26SYury Norov 	/* Set range of bits */
9428173aa26SYury Norov 	bitmap_clear(orig, 100, 50);
9438173aa26SYury Norov 
9448173aa26SYury Norov 	for_each_clear_bitrange(s, e, orig, 500)
9458173aa26SYury Norov 		bitmap_clear(copy, s, e-s);
9468173aa26SYury Norov 
9478173aa26SYury Norov 	expect_eq_bitmap(orig, copy, 500);
9488173aa26SYury Norov }
9498173aa26SYury Norov 
test_for_each_set_bitrange_from(void)9508173aa26SYury Norov static void __init test_for_each_set_bitrange_from(void)
9518173aa26SYury Norov {
9528173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
9538173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
9548173aa26SYury Norov 	unsigned int wr, s, e;
9558173aa26SYury Norov 
9568173aa26SYury Norov 	bitmap_zero(orig, 500);
9578173aa26SYury Norov 
9588173aa26SYury Norov 	/* Set individual bits */
9598173aa26SYury Norov 	for (s = 0; s < 500; s += 10)
9608173aa26SYury Norov 		bitmap_set(orig, s, 1);
9618173aa26SYury Norov 
9628173aa26SYury Norov 	/* Set range of bits */
9638173aa26SYury Norov 	bitmap_set(orig, 100, 50);
9648173aa26SYury Norov 
9658173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
9668173aa26SYury Norov 		DECLARE_BITMAP(tmp, 500);
9678173aa26SYury Norov 
9688173aa26SYury Norov 		bitmap_zero(copy, 500);
9698173aa26SYury Norov 		s = wr;
9708173aa26SYury Norov 
9718173aa26SYury Norov 		for_each_set_bitrange_from(s, e, orig, 500)
9728173aa26SYury Norov 			bitmap_set(copy, s, e - s);
9738173aa26SYury Norov 
9748173aa26SYury Norov 		bitmap_copy(tmp, orig, 500);
9758173aa26SYury Norov 		bitmap_clear(tmp, 0, wr);
9768173aa26SYury Norov 		expect_eq_bitmap(tmp, copy, 500);
9778173aa26SYury Norov 	}
9788173aa26SYury Norov }
9798173aa26SYury Norov 
test_for_each_clear_bitrange_from(void)9808173aa26SYury Norov static void __init test_for_each_clear_bitrange_from(void)
9818173aa26SYury Norov {
9828173aa26SYury Norov 	DECLARE_BITMAP(orig, 500);
9838173aa26SYury Norov 	DECLARE_BITMAP(copy, 500);
9848173aa26SYury Norov 	unsigned int wr, s, e;
9858173aa26SYury Norov 
9868173aa26SYury Norov 	bitmap_fill(orig, 500);
9878173aa26SYury Norov 
9888173aa26SYury Norov 	/* Set individual bits */
9898173aa26SYury Norov 	for (s = 0; s < 500; s += 10)
9908173aa26SYury Norov 		bitmap_clear(orig, s, 1);
9918173aa26SYury Norov 
9928173aa26SYury Norov 	/* Set range of bits */
9938173aa26SYury Norov 	bitmap_set(orig, 100, 50);
9948173aa26SYury Norov 
9958173aa26SYury Norov 	for (wr = 0; wr < 500; wr++) {
9968173aa26SYury Norov 		DECLARE_BITMAP(tmp, 500);
9978173aa26SYury Norov 
9988173aa26SYury Norov 		bitmap_fill(copy, 500);
9998173aa26SYury Norov 		s = wr;
10008173aa26SYury Norov 
10018173aa26SYury Norov 		for_each_clear_bitrange_from(s, e, orig, 500)
10028173aa26SYury Norov 			bitmap_clear(copy, s, e - s);
10038173aa26SYury Norov 
10048173aa26SYury Norov 		bitmap_copy(tmp, orig, 500);
10058173aa26SYury Norov 		bitmap_set(tmp, 0, wr);
10068173aa26SYury Norov 		expect_eq_bitmap(tmp, copy, 500);
10078173aa26SYury Norov 	}
10088173aa26SYury Norov }
10098173aa26SYury Norov 
1010bcb32a1dSStefano Brivio struct test_bitmap_cut {
1011bcb32a1dSStefano Brivio 	unsigned int first;
1012bcb32a1dSStefano Brivio 	unsigned int cut;
1013bcb32a1dSStefano Brivio 	unsigned int nbits;
1014bcb32a1dSStefano Brivio 	unsigned long in[4];
1015bcb32a1dSStefano Brivio 	unsigned long expected[4];
1016bcb32a1dSStefano Brivio };
1017bcb32a1dSStefano Brivio 
1018bcb32a1dSStefano Brivio static struct test_bitmap_cut test_cut[] = {
1019bcb32a1dSStefano Brivio 	{  0,  0,  8, { 0x0000000aUL, }, { 0x0000000aUL, }, },
1020bcb32a1dSStefano Brivio 	{  0,  0, 32, { 0xdadadeadUL, }, { 0xdadadeadUL, }, },
1021bcb32a1dSStefano Brivio 	{  0,  3,  8, { 0x000000aaUL, }, { 0x00000015UL, }, },
1022bcb32a1dSStefano Brivio 	{  3,  3,  8, { 0x000000aaUL, }, { 0x00000012UL, }, },
1023bcb32a1dSStefano Brivio 	{  0,  1, 32, { 0xa5a5a5a5UL, }, { 0x52d2d2d2UL, }, },
1024bcb32a1dSStefano Brivio 	{  0,  8, 32, { 0xdeadc0deUL, }, { 0x00deadc0UL, }, },
1025bcb32a1dSStefano Brivio 	{  1,  1, 32, { 0x5a5a5a5aUL, }, { 0x2d2d2d2cUL, }, },
1026bcb32a1dSStefano Brivio 	{  0, 15, 32, { 0xa5a5a5a5UL, }, { 0x00014b4bUL, }, },
1027bcb32a1dSStefano Brivio 	{  0, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
1028bcb32a1dSStefano Brivio 	{ 15, 15, 32, { 0xa5a5a5a5UL, }, { 0x000125a5UL, }, },
1029bcb32a1dSStefano Brivio 	{ 15, 16, 32, { 0xa5a5a5a5UL, }, { 0x0000a5a5UL, }, },
1030bcb32a1dSStefano Brivio 	{ 16, 15, 32, { 0xa5a5a5a5UL, }, { 0x0001a5a5UL, }, },
1031bcb32a1dSStefano Brivio 
1032bcb32a1dSStefano Brivio 	{ BITS_PER_LONG, BITS_PER_LONG, BITS_PER_LONG,
1033bcb32a1dSStefano Brivio 		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
1034bcb32a1dSStefano Brivio 		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
1035bcb32a1dSStefano Brivio 	},
1036bcb32a1dSStefano Brivio 	{ 1, BITS_PER_LONG - 1, BITS_PER_LONG,
1037bcb32a1dSStefano Brivio 		{ 0xa5a5a5a5UL, 0xa5a5a5a5UL, },
1038bcb32a1dSStefano Brivio 		{ 0x00000001UL, 0x00000001UL, },
1039bcb32a1dSStefano Brivio 	},
1040bcb32a1dSStefano Brivio 
1041bcb32a1dSStefano Brivio 	{ 0, BITS_PER_LONG * 2, BITS_PER_LONG * 2 + 1,
1042bcb32a1dSStefano Brivio 		{ 0xa5a5a5a5UL, 0x00000001UL, 0x00000001UL, 0x00000001UL },
1043bcb32a1dSStefano Brivio 		{ 0x00000001UL, },
1044bcb32a1dSStefano Brivio 	},
1045bcb32a1dSStefano Brivio 	{ 16, BITS_PER_LONG * 2 + 1, BITS_PER_LONG * 2 + 1 + 16,
1046bcb32a1dSStefano Brivio 		{ 0x0000ffffUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL, 0x5a5a5a5aUL },
1047bcb32a1dSStefano Brivio 		{ 0x2d2dffffUL, },
1048bcb32a1dSStefano Brivio 	},
1049bcb32a1dSStefano Brivio };
1050bcb32a1dSStefano Brivio 
test_bitmap_cut(void)1051bcb32a1dSStefano Brivio static void __init test_bitmap_cut(void)
1052bcb32a1dSStefano Brivio {
1053bcb32a1dSStefano Brivio 	unsigned long b[5], *in = &b[1], *out = &b[0];	/* Partial overlap */
1054bcb32a1dSStefano Brivio 	int i;
1055bcb32a1dSStefano Brivio 
1056bcb32a1dSStefano Brivio 	for (i = 0; i < ARRAY_SIZE(test_cut); i++) {
1057bcb32a1dSStefano Brivio 		struct test_bitmap_cut *t = &test_cut[i];
1058bcb32a1dSStefano Brivio 
1059bcb32a1dSStefano Brivio 		memcpy(in, t->in, sizeof(t->in));
1060bcb32a1dSStefano Brivio 
1061bcb32a1dSStefano Brivio 		bitmap_cut(out, in, t->first, t->cut, t->nbits);
1062bcb32a1dSStefano Brivio 
1063bcb32a1dSStefano Brivio 		expect_eq_bitmap(t->expected, out, t->nbits);
1064bcb32a1dSStefano Brivio 	}
1065bcb32a1dSStefano Brivio }
1066bcb32a1dSStefano Brivio 
1067291f93caSBarry Song struct test_bitmap_print {
1068291f93caSBarry Song 	const unsigned long *bitmap;
1069291f93caSBarry Song 	unsigned long nbits;
1070291f93caSBarry Song 	const char *mask;
1071291f93caSBarry Song 	const char *list;
1072291f93caSBarry Song };
1073291f93caSBarry Song 
1074291f93caSBarry Song static const unsigned long small_bitmap[] __initconst = {
1075291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL),
1076291f93caSBarry Song };
1077291f93caSBarry Song 
1078291f93caSBarry Song static const char small_mask[] __initconst = "33333333,11111111\n";
1079291f93caSBarry Song static 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";
1080291f93caSBarry Song 
1081291f93caSBarry Song static const unsigned long large_bitmap[] __initconst = {
1082291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1083291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1084291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1085291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1086291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1087291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1088291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1089291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1090291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1091291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1092291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1093291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1094291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1095291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1096291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1097291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1098291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1099291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1100291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1101291f93caSBarry Song 	BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0x3333333311111111ULL),
1102291f93caSBarry Song };
1103291f93caSBarry Song 
1104291f93caSBarry Song static const char large_mask[] __initconst = "33333333,11111111,33333333,11111111,"
1105291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1106291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1107291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1108291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1109291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1110291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1111291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1112291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1113291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1114291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1115291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1116291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1117291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1118291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1119291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1120291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1121291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1122291f93caSBarry Song 					"33333333,11111111,33333333,11111111,"
1123291f93caSBarry Song 					"33333333,11111111,33333333,11111111\n";
1124291f93caSBarry Song 
1125291f93caSBarry Song static const char large_list[] __initconst = /* more than 4KB */
1126291f93caSBarry Song 	"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"
1127291f93caSBarry Song 	"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"
1128291f93caSBarry Song 	"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"
1129291f93caSBarry Song 	"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"
1130291f93caSBarry Song 	"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"
1131291f93caSBarry Song 	"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"
1132291f93caSBarry Song 	"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"
1133291f93caSBarry Song 	"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"
1134291f93caSBarry Song 	"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"
1135291f93caSBarry Song 	"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"
1136291f93caSBarry Song 	"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"
1137291f93caSBarry Song 	"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"
1138291f93caSBarry Song 	"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-"
1139291f93caSBarry Song 	"1001,1004-1005,1008-1009,1012-1013,1016-1017,1020-1021,1024,1028,1032,1036,1040,1044,1048,1052,1056-1057,1060-10"
1140291f93caSBarry Song 	"61,1064-1065,1068-1069,1072-1073,1076-1077,1080-1081,1084-1085,1088,1092,1096,1100,1104,1108,1112,1116,1120-1121"
1141291f93caSBarry Song 	",1124-1125,1128-1129,1132-1133,1136-1137,1140-1141,1144-1145,1148-1149,1152,1156,1160,1164,1168,1172,1176,1180,1"
1142291f93caSBarry Song 	"184-1185,1188-1189,1192-1193,1196-1197,1200-1201,1204-1205,1208-1209,1212-1213,1216,1220,1224,1228,1232,1236,124"
1143291f93caSBarry Song 	"0,1244,1248-1249,1252-1253,1256-1257,1260-1261,1264-1265,1268-1269,1272-1273,1276-1277,1280,1284,1288,1292,1296,"
1144291f93caSBarry Song 	"1300,1304,1308,1312-1313,1316-1317,1320-1321,1324-1325,1328-1329,1332-1333,1336-1337,1340-1341,1344,1348,1352,13"
1145291f93caSBarry Song 	"56,1360,1364,1368,1372,1376-1377,1380-1381,1384-1385,1388-1389,1392-1393,1396-1397,1400-1401,1404-1405,1408,1412"
1146291f93caSBarry Song 	",1416,1420,1424,1428,1432,1436,1440-1441,1444-1445,1448-1449,1452-1453,1456-1457,1460-1461,1464-1465,1468-1469,1"
1147291f93caSBarry Song 	"472,1476,1480,1484,1488,1492,1496,1500,1504-1505,1508-1509,1512-1513,1516-1517,1520-1521,1524-1525,1528-1529,153"
1148291f93caSBarry Song 	"2-1533,1536,1540,1544,1548,1552,1556,1560,1564,1568-1569,1572-1573,1576-1577,1580-1581,1584-1585,1588-1589,1592-"
1149291f93caSBarry Song 	"1593,1596-1597,1600,1604,1608,1612,1616,1620,1624,1628,1632-1633,1636-1637,1640-1641,1644-1645,1648-1649,1652-16"
1150291f93caSBarry Song 	"53,1656-1657,1660-1661,1664,1668,1672,1676,1680,1684,1688,1692,1696-1697,1700-1701,1704-1705,1708-1709,1712-1713"
1151291f93caSBarry Song 	",1716-1717,1720-1721,1724-1725,1728,1732,1736,1740,1744,1748,1752,1756,1760-1761,1764-1765,1768-1769,1772-1773,1"
1152291f93caSBarry Song 	"776-1777,1780-1781,1784-1785,1788-1789,1792,1796,1800,1804,1808,1812,1816,1820,1824-1825,1828-1829,1832-1833,183"
1153291f93caSBarry Song 	"6-1837,1840-1841,1844-1845,1848-1849,1852-1853,1856,1860,1864,1868,1872,1876,1880,1884,1888-1889,1892-1893,1896-"
1154291f93caSBarry Song 	"1897,1900-1901,1904-1905,1908-1909,1912-1913,1916-1917,1920,1924,1928,1932,1936,1940,1944,1948,1952-1953,1956-19"
1155291f93caSBarry Song 	"57,1960-1961,1964-1965,1968-1969,1972-1973,1976-1977,1980-1981,1984,1988,1992,1996,2000,2004,2008,2012,2016-2017"
1156291f93caSBarry Song 	",2020-2021,2024-2025,2028-2029,2032-2033,2036-2037,2040-2041,2044-2045,2048,2052,2056,2060,2064,2068,2072,2076,2"
1157291f93caSBarry Song 	"080-2081,2084-2085,2088-2089,2092-2093,2096-2097,2100-2101,2104-2105,2108-2109,2112,2116,2120,2124,2128,2132,213"
1158291f93caSBarry Song 	"6,2140,2144-2145,2148-2149,2152-2153,2156-2157,2160-2161,2164-2165,2168-2169,2172-2173,2176,2180,2184,2188,2192,"
1159291f93caSBarry Song 	"2196,2200,2204,2208-2209,2212-2213,2216-2217,2220-2221,2224-2225,2228-2229,2232-2233,2236-2237,2240,2244,2248,22"
1160291f93caSBarry Song 	"52,2256,2260,2264,2268,2272-2273,2276-2277,2280-2281,2284-2285,2288-2289,2292-2293,2296-2297,2300-2301,2304,2308"
1161291f93caSBarry Song 	",2312,2316,2320,2324,2328,2332,2336-2337,2340-2341,2344-2345,2348-2349,2352-2353,2356-2357,2360-2361,2364-2365,2"
1162291f93caSBarry Song 	"368,2372,2376,2380,2384,2388,2392,2396,2400-2401,2404-2405,2408-2409,2412-2413,2416-2417,2420-2421,2424-2425,242"
1163291f93caSBarry Song 	"8-2429,2432,2436,2440,2444,2448,2452,2456,2460,2464-2465,2468-2469,2472-2473,2476-2477,2480-2481,2484-2485,2488-"
1164291f93caSBarry Song 	"2489,2492-2493,2496,2500,2504,2508,2512,2516,2520,2524,2528-2529,2532-2533,2536-2537,2540-2541,2544-2545,2548-25"
1165291f93caSBarry Song 	"49,2552-2553,2556-2557\n";
1166291f93caSBarry Song 
1167291f93caSBarry Song static const struct test_bitmap_print test_print[] __initconst = {
1168291f93caSBarry Song 	{ small_bitmap, sizeof(small_bitmap) * BITS_PER_BYTE, small_mask, small_list },
1169291f93caSBarry Song 	{ large_bitmap, sizeof(large_bitmap) * BITS_PER_BYTE, large_mask, large_list },
1170291f93caSBarry Song };
1171291f93caSBarry Song 
test_bitmap_print_buf(void)1172291f93caSBarry Song static void __init test_bitmap_print_buf(void)
1173291f93caSBarry Song {
1174291f93caSBarry Song 	int i;
1175291f93caSBarry Song 
1176291f93caSBarry Song 	for (i = 0; i < ARRAY_SIZE(test_print); i++) {
1177291f93caSBarry Song 		const struct test_bitmap_print *t = &test_print[i];
1178291f93caSBarry Song 		int n;
1179291f93caSBarry Song 
1180291f93caSBarry Song 		n = bitmap_print_bitmask_to_buf(print_buf, t->bitmap, t->nbits,
1181291f93caSBarry Song 						0, 2 * PAGE_SIZE);
1182291f93caSBarry Song 		expect_eq_uint(strlen(t->mask) + 1, n);
1183291f93caSBarry Song 		expect_eq_str(t->mask, print_buf, n);
1184291f93caSBarry Song 
1185291f93caSBarry Song 		n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
1186291f93caSBarry Song 					     0, 2 * PAGE_SIZE);
1187291f93caSBarry Song 		expect_eq_uint(strlen(t->list) + 1, n);
1188291f93caSBarry Song 		expect_eq_str(t->list, print_buf, n);
1189291f93caSBarry Song 
1190291f93caSBarry Song 		/* test by non-zero offset */
1191291f93caSBarry Song 		if (strlen(t->list) > PAGE_SIZE) {
1192291f93caSBarry Song 			n = bitmap_print_list_to_buf(print_buf, t->bitmap, t->nbits,
1193291f93caSBarry Song 						     PAGE_SIZE, PAGE_SIZE);
1194291f93caSBarry Song 			expect_eq_uint(strlen(t->list) + 1 - PAGE_SIZE, n);
1195291f93caSBarry Song 			expect_eq_str(t->list + PAGE_SIZE, print_buf, n);
1196291f93caSBarry Song 		}
1197291f93caSBarry Song 	}
1198291f93caSBarry Song }
1199291f93caSBarry Song 
12002356d198SYury Norov /*
12012356d198SYury Norov  * FIXME: Clang breaks compile-time evaluations when KASAN and GCOV are enabled.
12022356d198SYury Norov  * To workaround it, GCOV is force-disabled in Makefile for this configuration.
12032356d198SYury Norov  */
test_bitmap_const_eval(void)1204dc34d503SAlexander Lobakin static void __init test_bitmap_const_eval(void)
1205dc34d503SAlexander Lobakin {
1206dc34d503SAlexander Lobakin 	DECLARE_BITMAP(bitmap, BITS_PER_LONG);
1207dc34d503SAlexander Lobakin 	unsigned long initvar = BIT(2);
1208dc34d503SAlexander Lobakin 	unsigned long bitopvar = 0;
1209dc34d503SAlexander Lobakin 	unsigned long var = 0;
1210dc34d503SAlexander Lobakin 	int res;
1211dc34d503SAlexander Lobakin 
1212dc34d503SAlexander Lobakin 	/*
1213dc34d503SAlexander Lobakin 	 * Compilers must be able to optimize all of those to compile-time
1214dc34d503SAlexander Lobakin 	 * constants on any supported optimization level (-O2, -Os) and any
1215dc34d503SAlexander Lobakin 	 * architecture. Otherwise, trigger a build bug.
1216dc34d503SAlexander Lobakin 	 * The whole function gets optimized out then, there's nothing to do
1217dc34d503SAlexander Lobakin 	 * in runtime.
1218dc34d503SAlexander Lobakin 	 */
1219dc34d503SAlexander Lobakin 
12207adaf37fSAlexander Lobakin 	/* Equals to `unsigned long bitmap[1] = { GENMASK(6, 5), }` */
1221dc34d503SAlexander Lobakin 	bitmap_clear(bitmap, 0, BITS_PER_LONG);
1222dc34d503SAlexander Lobakin 	if (!test_bit(7, bitmap))
1223dc34d503SAlexander Lobakin 		bitmap_set(bitmap, 5, 2);
1224dc34d503SAlexander Lobakin 
1225dc34d503SAlexander Lobakin 	/* Equals to `unsigned long bitopvar = BIT(20)` */
1226dc34d503SAlexander Lobakin 	__change_bit(31, &bitopvar);
1227dc34d503SAlexander Lobakin 	bitmap_shift_right(&bitopvar, &bitopvar, 11, BITS_PER_LONG);
1228dc34d503SAlexander Lobakin 
1229dc34d503SAlexander Lobakin 	/* Equals to `unsigned long var = BIT(25)` */
1230dc34d503SAlexander Lobakin 	var |= BIT(25);
1231dc34d503SAlexander Lobakin 	if (var & BIT(0))
1232dc34d503SAlexander Lobakin 		var ^= GENMASK(9, 6);
1233dc34d503SAlexander Lobakin 
1234dc34d503SAlexander Lobakin 	/* __const_hweight<32|64>(GENMASK(6, 5)) == 2 */
1235dc34d503SAlexander Lobakin 	res = bitmap_weight(bitmap, 20);
1236dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(res));
1237dc34d503SAlexander Lobakin 	BUILD_BUG_ON(res != 2);
1238dc34d503SAlexander Lobakin 
1239dc34d503SAlexander Lobakin 	/* !(BIT(31) & BIT(18)) == 1 */
1240dc34d503SAlexander Lobakin 	res = !test_bit(18, &bitopvar);
1241dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(res));
1242dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!res);
1243dc34d503SAlexander Lobakin 
1244dc34d503SAlexander Lobakin 	/* BIT(2) & GENMASK(14, 8) == 0 */
1245dc34d503SAlexander Lobakin 	res = initvar & GENMASK(14, 8);
1246dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(res));
1247dc34d503SAlexander Lobakin 	BUILD_BUG_ON(res);
1248dc34d503SAlexander Lobakin 
1249dc34d503SAlexander Lobakin 	/* ~BIT(25) */
1250dc34d503SAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(~var));
1251dc34d503SAlexander Lobakin 	BUILD_BUG_ON(~var != ~BIT(25));
12527adaf37fSAlexander Lobakin 
12537adaf37fSAlexander Lobakin 	/* ~BIT(25) | BIT(25) == ~0UL */
12547adaf37fSAlexander Lobakin 	bitmap_complement(&var, &var, BITS_PER_LONG);
12557adaf37fSAlexander Lobakin 	__assign_bit(25, &var, true);
12567adaf37fSAlexander Lobakin 
12577adaf37fSAlexander Lobakin 	/* !(~(~0UL)) == 1 */
12587adaf37fSAlexander Lobakin 	res = bitmap_full(&var, BITS_PER_LONG);
12597adaf37fSAlexander Lobakin 	BUILD_BUG_ON(!__builtin_constant_p(res));
12607adaf37fSAlexander Lobakin 	BUILD_BUG_ON(!res);
1261dc34d503SAlexander Lobakin }
1262dc34d503SAlexander Lobakin 
1263991e5583SAlexander Potapenko /*
1264991e5583SAlexander Potapenko  * Test bitmap should be big enough to include the cases when start is not in
1265991e5583SAlexander Potapenko  * the first word, and start+nbits lands in the following word.
1266991e5583SAlexander Potapenko  */
1267991e5583SAlexander Potapenko #define TEST_BIT_LEN (1000)
1268991e5583SAlexander Potapenko 
1269991e5583SAlexander Potapenko /*
1270991e5583SAlexander Potapenko  * Helper function to test bitmap_write() overwriting the chosen byte pattern.
1271991e5583SAlexander Potapenko  */
test_bitmap_write_helper(const char * pattern)1272991e5583SAlexander Potapenko static void __init test_bitmap_write_helper(const char *pattern)
1273991e5583SAlexander Potapenko {
1274991e5583SAlexander Potapenko 	DECLARE_BITMAP(bitmap, TEST_BIT_LEN);
1275991e5583SAlexander Potapenko 	DECLARE_BITMAP(exp_bitmap, TEST_BIT_LEN);
1276991e5583SAlexander Potapenko 	DECLARE_BITMAP(pat_bitmap, TEST_BIT_LEN);
1277991e5583SAlexander Potapenko 	unsigned long w, r, bit;
1278991e5583SAlexander Potapenko 	int i, n, nbits;
1279991e5583SAlexander Potapenko 
1280991e5583SAlexander Potapenko 	/*
1281991e5583SAlexander Potapenko 	 * Only parse the pattern once and store the result in the intermediate
1282991e5583SAlexander Potapenko 	 * bitmap.
1283991e5583SAlexander Potapenko 	 */
1284991e5583SAlexander Potapenko 	bitmap_parselist(pattern, pat_bitmap, TEST_BIT_LEN);
1285991e5583SAlexander Potapenko 
1286991e5583SAlexander Potapenko 	/*
1287991e5583SAlexander Potapenko 	 * Check that writing a single bit does not accidentally touch the
1288991e5583SAlexander Potapenko 	 * adjacent bits.
1289991e5583SAlexander Potapenko 	 */
1290991e5583SAlexander Potapenko 	for (i = 0; i < TEST_BIT_LEN; i++) {
1291991e5583SAlexander Potapenko 		bitmap_copy(bitmap, pat_bitmap, TEST_BIT_LEN);
1292991e5583SAlexander Potapenko 		bitmap_copy(exp_bitmap, pat_bitmap, TEST_BIT_LEN);
1293991e5583SAlexander Potapenko 		for (bit = 0; bit <= 1; bit++) {
1294991e5583SAlexander Potapenko 			bitmap_write(bitmap, bit, i, 1);
1295991e5583SAlexander Potapenko 			__assign_bit(i, exp_bitmap, bit);
1296991e5583SAlexander Potapenko 			expect_eq_bitmap(exp_bitmap, bitmap,
1297991e5583SAlexander Potapenko 					 TEST_BIT_LEN);
1298991e5583SAlexander Potapenko 		}
1299991e5583SAlexander Potapenko 	}
1300991e5583SAlexander Potapenko 
1301991e5583SAlexander Potapenko 	/* Ensure writing 0 bits does not change anything. */
1302991e5583SAlexander Potapenko 	bitmap_copy(bitmap, pat_bitmap, TEST_BIT_LEN);
1303991e5583SAlexander Potapenko 	bitmap_copy(exp_bitmap, pat_bitmap, TEST_BIT_LEN);
1304991e5583SAlexander Potapenko 	for (i = 0; i < TEST_BIT_LEN; i++) {
1305991e5583SAlexander Potapenko 		bitmap_write(bitmap, ~0UL, i, 0);
1306991e5583SAlexander Potapenko 		expect_eq_bitmap(exp_bitmap, bitmap, TEST_BIT_LEN);
1307991e5583SAlexander Potapenko 	}
1308991e5583SAlexander Potapenko 
1309991e5583SAlexander Potapenko 	for (nbits = BITS_PER_LONG; nbits >= 1; nbits--) {
1310991e5583SAlexander Potapenko 		w = IS_ENABLED(CONFIG_64BIT) ? 0xdeadbeefdeadbeefUL
1311991e5583SAlexander Potapenko 					     : 0xdeadbeefUL;
1312991e5583SAlexander Potapenko 		w >>= (BITS_PER_LONG - nbits);
1313991e5583SAlexander Potapenko 		for (i = 0; i <= TEST_BIT_LEN - nbits; i++) {
1314991e5583SAlexander Potapenko 			bitmap_copy(bitmap, pat_bitmap, TEST_BIT_LEN);
1315991e5583SAlexander Potapenko 			bitmap_copy(exp_bitmap, pat_bitmap, TEST_BIT_LEN);
1316991e5583SAlexander Potapenko 			for (n = 0; n < nbits; n++)
1317991e5583SAlexander Potapenko 				__assign_bit(i + n, exp_bitmap, w & BIT(n));
1318991e5583SAlexander Potapenko 			bitmap_write(bitmap, w, i, nbits);
1319991e5583SAlexander Potapenko 			expect_eq_bitmap(exp_bitmap, bitmap, TEST_BIT_LEN);
1320991e5583SAlexander Potapenko 			r = bitmap_read(bitmap, i, nbits);
1321991e5583SAlexander Potapenko 			expect_eq_ulong(r, w);
1322991e5583SAlexander Potapenko 		}
1323991e5583SAlexander Potapenko 	}
1324991e5583SAlexander Potapenko }
1325991e5583SAlexander Potapenko 
test_bitmap_read_write(void)1326991e5583SAlexander Potapenko static void __init test_bitmap_read_write(void)
1327991e5583SAlexander Potapenko {
1328991e5583SAlexander Potapenko 	unsigned char *pattern[3] = {"", "all:1/2", "all"};
1329991e5583SAlexander Potapenko 	DECLARE_BITMAP(bitmap, TEST_BIT_LEN);
1330991e5583SAlexander Potapenko 	unsigned long zero_bits = 0, bits_per_long = BITS_PER_LONG;
1331991e5583SAlexander Potapenko 	unsigned long val;
1332991e5583SAlexander Potapenko 	int i, pi;
1333991e5583SAlexander Potapenko 
1334991e5583SAlexander Potapenko 	/*
1335991e5583SAlexander Potapenko 	 * Reading/writing zero bits should not crash the kernel.
1336991e5583SAlexander Potapenko 	 * READ_ONCE() prevents constant folding.
1337991e5583SAlexander Potapenko 	 */
1338991e5583SAlexander Potapenko 	bitmap_write(NULL, 0, 0, READ_ONCE(zero_bits));
1339991e5583SAlexander Potapenko 	/* Return value of bitmap_read() is undefined here. */
1340991e5583SAlexander Potapenko 	bitmap_read(NULL, 0, READ_ONCE(zero_bits));
1341991e5583SAlexander Potapenko 
1342991e5583SAlexander Potapenko 	/*
1343991e5583SAlexander Potapenko 	 * Reading/writing more than BITS_PER_LONG bits should not crash the
1344991e5583SAlexander Potapenko 	 * kernel. READ_ONCE() prevents constant folding.
1345991e5583SAlexander Potapenko 	 */
1346991e5583SAlexander Potapenko 	bitmap_write(NULL, 0, 0, READ_ONCE(bits_per_long) + 1);
1347991e5583SAlexander Potapenko 	/* Return value of bitmap_read() is undefined here. */
1348991e5583SAlexander Potapenko 	bitmap_read(NULL, 0, READ_ONCE(bits_per_long) + 1);
1349991e5583SAlexander Potapenko 
1350991e5583SAlexander Potapenko 	/*
1351991e5583SAlexander Potapenko 	 * Ensure that bitmap_read() reads the same value that was previously
1352991e5583SAlexander Potapenko 	 * written, and two consequent values are correctly merged.
1353991e5583SAlexander Potapenko 	 * The resulting bit pattern is asymmetric to rule out possible issues
1354991e5583SAlexander Potapenko 	 * with bit numeration order.
1355991e5583SAlexander Potapenko 	 */
1356991e5583SAlexander Potapenko 	for (i = 0; i < TEST_BIT_LEN - 7; i++) {
1357991e5583SAlexander Potapenko 		bitmap_zero(bitmap, TEST_BIT_LEN);
1358991e5583SAlexander Potapenko 
1359991e5583SAlexander Potapenko 		bitmap_write(bitmap, 0b10101UL, i, 5);
1360991e5583SAlexander Potapenko 		val = bitmap_read(bitmap, i, 5);
1361991e5583SAlexander Potapenko 		expect_eq_ulong(0b10101UL, val);
1362991e5583SAlexander Potapenko 
1363991e5583SAlexander Potapenko 		bitmap_write(bitmap, 0b101UL, i + 5, 3);
1364991e5583SAlexander Potapenko 		val = bitmap_read(bitmap, i + 5, 3);
1365991e5583SAlexander Potapenko 		expect_eq_ulong(0b101UL, val);
1366991e5583SAlexander Potapenko 
1367991e5583SAlexander Potapenko 		val = bitmap_read(bitmap, i, 8);
1368991e5583SAlexander Potapenko 		expect_eq_ulong(0b10110101UL, val);
1369991e5583SAlexander Potapenko 	}
1370991e5583SAlexander Potapenko 
1371991e5583SAlexander Potapenko 	for (pi = 0; pi < ARRAY_SIZE(pattern); pi++)
1372991e5583SAlexander Potapenko 		test_bitmap_write_helper(pattern[pi]);
1373991e5583SAlexander Potapenko }
1374991e5583SAlexander Potapenko 
test_bitmap_read_perf(void)1375991e5583SAlexander Potapenko static void __init test_bitmap_read_perf(void)
1376991e5583SAlexander Potapenko {
1377991e5583SAlexander Potapenko 	DECLARE_BITMAP(bitmap, TEST_BIT_LEN);
1378991e5583SAlexander Potapenko 	unsigned int cnt, nbits, i;
1379991e5583SAlexander Potapenko 	unsigned long val;
1380991e5583SAlexander Potapenko 	ktime_t time;
1381991e5583SAlexander Potapenko 
1382991e5583SAlexander Potapenko 	bitmap_fill(bitmap, TEST_BIT_LEN);
1383991e5583SAlexander Potapenko 	time = ktime_get();
1384991e5583SAlexander Potapenko 	for (cnt = 0; cnt < 5; cnt++) {
1385991e5583SAlexander Potapenko 		for (nbits = 1; nbits <= BITS_PER_LONG; nbits++) {
1386991e5583SAlexander Potapenko 			for (i = 0; i < TEST_BIT_LEN; i++) {
1387991e5583SAlexander Potapenko 				if (i + nbits > TEST_BIT_LEN)
1388991e5583SAlexander Potapenko 					break;
1389991e5583SAlexander Potapenko 				/*
1390991e5583SAlexander Potapenko 				 * Prevent the compiler from optimizing away the
1391991e5583SAlexander Potapenko 				 * bitmap_read() by using its value.
1392991e5583SAlexander Potapenko 				 */
1393991e5583SAlexander Potapenko 				WRITE_ONCE(val, bitmap_read(bitmap, i, nbits));
1394991e5583SAlexander Potapenko 			}
1395991e5583SAlexander Potapenko 		}
1396991e5583SAlexander Potapenko 	}
1397991e5583SAlexander Potapenko 	time = ktime_get() - time;
1398f3e28876SAlexander Potapenko 	pr_info("Time spent in %s:\t%llu\n", __func__, time);
1399991e5583SAlexander Potapenko }
1400991e5583SAlexander Potapenko 
test_bitmap_write_perf(void)1401991e5583SAlexander Potapenko static void __init test_bitmap_write_perf(void)
1402991e5583SAlexander Potapenko {
1403991e5583SAlexander Potapenko 	DECLARE_BITMAP(bitmap, TEST_BIT_LEN);
1404991e5583SAlexander Potapenko 	unsigned int cnt, nbits, i;
1405991e5583SAlexander Potapenko 	unsigned long val = 0xfeedface;
1406991e5583SAlexander Potapenko 	ktime_t time;
1407991e5583SAlexander Potapenko 
1408991e5583SAlexander Potapenko 	bitmap_zero(bitmap, TEST_BIT_LEN);
1409991e5583SAlexander Potapenko 	time = ktime_get();
1410991e5583SAlexander Potapenko 	for (cnt = 0; cnt < 5; cnt++) {
1411991e5583SAlexander Potapenko 		for (nbits = 1; nbits <= BITS_PER_LONG; nbits++) {
1412991e5583SAlexander Potapenko 			for (i = 0; i < TEST_BIT_LEN; i++) {
1413991e5583SAlexander Potapenko 				if (i + nbits > TEST_BIT_LEN)
1414991e5583SAlexander Potapenko 					break;
1415991e5583SAlexander Potapenko 				bitmap_write(bitmap, val, i, nbits);
1416991e5583SAlexander Potapenko 			}
1417991e5583SAlexander Potapenko 		}
1418991e5583SAlexander Potapenko 	}
1419991e5583SAlexander Potapenko 	time = ktime_get() - time;
1420f3e28876SAlexander Potapenko 	pr_info("Time spent in %s:\t%llu\n", __func__, time);
1421991e5583SAlexander Potapenko }
1422991e5583SAlexander Potapenko 
1423991e5583SAlexander Potapenko #undef TEST_BIT_LEN
1424991e5583SAlexander Potapenko 
selftest(void)14256b1a4d5bSTobin C. Harding static void __init selftest(void)
14265fd003f5SDavid Decotigny {
1427ee3527bdSAndy Shevchenko 	test_zero_clear();
1428978f369cSAndy Shevchenko 	test_fill_set();
1429fe81814cSAndy Shevchenko 	test_copy();
14306d5d3a0cSYury Norov 	test_bitmap_region();
143130544ed5SAndy Shevchenko 	test_replace();
1432de5f8433SAndy Shevchenko 	test_bitmap_sg();
14333aa56885SYury Norov 	test_bitmap_arr32();
14342c523550SYury Norov 	test_bitmap_arr64();
14357eb2e94eSYury Norov 	test_bitmap_parse();
14366df0d464SYury Norov 	test_bitmap_parselist();
1437db731300SYury Norov 	test_bitmap_printlist();
14383cc78125SMatthew Wilcox 	test_mem_optimisations();
1439bcb32a1dSStefano Brivio 	test_bitmap_cut();
1440291f93caSBarry Song 	test_bitmap_print_buf();
1441dc34d503SAlexander Lobakin 	test_bitmap_const_eval();
1442991e5583SAlexander Potapenko 	test_bitmap_read_write();
1443991e5583SAlexander Potapenko 	test_bitmap_read_perf();
1444991e5583SAlexander Potapenko 	test_bitmap_write_perf();
1445e3783c80SYury Norov 
1446e3783c80SYury Norov 	test_find_nth_bit();
14478173aa26SYury Norov 	test_for_each_set_bit();
14488173aa26SYury Norov 	test_for_each_set_bit_from();
14498173aa26SYury Norov 	test_for_each_clear_bit();
14508173aa26SYury Norov 	test_for_each_clear_bit_from();
14518173aa26SYury Norov 	test_for_each_set_bitrange();
14528173aa26SYury Norov 	test_for_each_clear_bitrange();
14538173aa26SYury Norov 	test_for_each_set_bitrange_from();
14548173aa26SYury Norov 	test_for_each_clear_bitrange_from();
14558173aa26SYury Norov 	test_for_each_set_clump8();
14568173aa26SYury Norov 	test_for_each_set_bit_wrap();
14575fd003f5SDavid Decotigny }
14585fd003f5SDavid Decotigny 
14596b1a4d5bSTobin C. Harding KSTM_MODULE_LOADERS(test_bitmap);
14605fd003f5SDavid Decotigny MODULE_AUTHOR("david decotigny <[email protected]>");
1461*e334771dSJeff Johnson MODULE_DESCRIPTION("Test cases for bitmap API");
14625fd003f5SDavid Decotigny MODULE_LICENSE("GPL");
1463