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