// SPDX-License-Identifier: GPL-2.0-only/* * Test cases for bitmap API. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/bitmap.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/printk.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/uaccess.h> #include "../tools/testing/selftests/kselftest_module.h" #define EXP1_IN_BITS (sizeof(exp1) * 8) KSTM_MODULE_GLOBALS(); static char pbl_buffer[PAGE_SIZE] __initdata;static char print_buf[PAGE_SIZE * 2] __initdata; static const unsigned long exp1[] __initconst = { BITMAP_FROM_U64(1), BITMAP_FROM_U64(2), BITMAP_FROM_U64(0x0000ffff), BITMAP_FROM_U64(0xffff0000), BITMAP_FROM_U64(0x55555555), BITMAP_FROM_U64(0xaaaaaaaa), BITMAP_FROM_U64(0x11111111), BITMAP_FROM_U64(0x22222222), BITMAP_FROM_U64(0xffffffff), BITMAP_FROM_U64(0xfffffffe), BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0xffffffff77777777ULL), BITMAP_FROM_U64(0), BITMAP_FROM_U64(0x00008000), BITMAP_FROM_U64(0x80000000),}; static const unsigned long exp2[] __initconst = { BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0xffffffff77777777ULL),}; /* Fibonacci sequence */static const unsigned long exp2_to_exp3_mask[] __initconst = { BITMAP_FROM_U64(0x008000020020212eULL),};/* exp3_0_1 = (exp2[0] & ~exp2_to_exp3_mask) | (exp2[1] & exp2_to_exp3_mask) */static const unsigned long exp3_0_1[] __initconst = { BITMAP_FROM_U64(0x33b3333311313137ULL),};/* exp3_1_0 = (exp2[1] & ~exp2_to_exp3_mask) | (exp2[0] & exp2_to_exp3_mask) */static const unsigned long exp3_1_0[] __initconst = { BITMAP_FROM_U64(0xff7fffff77575751ULL),}; static bool __init__check_eq_ulong(const char *srcfile, unsigned int line, const unsigned long exp_ulong, unsigned long x){ if (exp_ulong != x) { pr_err("[%s:%u] expected %lu, got %lu\n", srcfile, line, exp_ulong, x); return false; } return true;} static bool __init__check_eq_bitmap(const char *srcfile, unsigned int line, const unsigned long *exp_bmap, const unsigned long *bmap, unsigned int nbits){ if (!bitmap_equal(exp_bmap, bmap, nbits)) { pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n", srcfile, line, nbits, exp_bmap, nbits, bmap); return false; } return true;} static bool __init__check_eq_pbl(const char *srcfile, unsigned int line, const char *expected_pbl, const unsigned long *bitmap, unsigned int nbits){ snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap); if (strcmp(expected_pbl, pbl_buffer)) { pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n", srcfile, line, expected_pbl, pbl_buffer); return false; } return true;} static bool __init __check_eq_clump8(const char *srcfile, unsigned int line, const unsigned int offset, const unsigned int size, const unsigned char *const clump_exp, const unsigned long *const clump){ unsigned long exp; if (offset >= size) { pr_warn("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u\n", srcfile, line, size, offset); return false; } exp = clump_exp[offset / 8]; if (!exp) { pr_warn("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0", srcfile, line, offset); return false; } if (*clump != exp) { pr_warn("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX", srcfile, line, exp, *clump); return false; } return true;} static bool __init__check_eq_str(const char *srcfile, unsigned int line, const char *exp_str, const char *str, unsigned int len){ bool eq; eq = strncmp(exp_str, str, len) == 0; if (!eq) pr_err("[%s:%u] expected %s, got %s\n", srcfile, line, exp_str, str); return eq;} #define __expect_eq(suffix, ...) \ ({ \ int result = 0; \ total_tests++; \ if (!__check_eq_ ## suffix(__FILE__, __LINE__, \ ##__VA_ARGS__)) { \ failed_tests++; \ result = 1; \ } \ result; \ }) #define expect_eq_ulong(...) __expect_eq(ulong, ##__VA_ARGS__)#define expect_eq_uint(x, y) expect_eq_ulong((unsigned int)(x), (unsigned int)(y))#define expect_eq_bitmap(...) __expect_eq(bitmap, ##__VA_ARGS__)#define expect_eq_pbl(...) __expect_eq(pbl, ##__VA_ARGS__)#define expect_eq_u32_array(...) __expect_eq(u32_array, ##__VA_ARGS__)#define expect_eq_clump8(...) __expect_eq(clump8, ##__VA_ARGS__)#define expect_eq_str(...) __expect_eq(str, ##__VA_ARGS__) static void __init test_zero_clear(void){ DECLARE_BITMAP(bmap, 1024); /* Known way to set all bits */ memset(bmap, 0xff, 128); expect_eq_pbl("0-22", bmap, 23); expect_eq_pbl("0-1023", bmap, 1024); /* single-word bitmaps */ bitmap_clear(bmap, 0, 9); expect_eq_pbl("9-1023", bmap, 1024); bitmap_zero(bmap, 35); expect_eq_pbl("64-1023", bmap, 1024); /* cross boundaries operations */ bitmap_clear(bmap, 79, 19); expect_eq_pbl("64-78,98-1023", bmap, 1024); bitmap_zero(bmap, 115); expect_eq_pbl("128-1023", bmap, 1024); /* Zeroing entire area */ bitmap_zero(bmap, 1024); expect_eq_pbl("", bmap, 1024);} static void __init test_find_nth_bit(void){ unsigned long b, bit, cnt = 0; DECLARE_BITMAP(bmap, 64 * 3); bitmap_zero(bmap, 64 * 3); __set_bit(10, bmap); __set_bit(20, bmap); __set_bit(30, bmap); __set_bit(40, bmap); __set_bit(50, bmap); __set_bit(60, bmap); __set_bit(80, bmap); __set_bit(123, bmap); expect_eq_uint(10, find_nth_bit(bmap, 64 * 3, 0)); expect_eq_uint(20, find_nth_bit(bmap, 64 * 3, 1)); expect_eq_uint(30, find_nth_bit(bmap, 64 * 3, 2)); expect_eq_uint(40, find_nth_bit(bmap, 64 * 3, 3)); expect_eq_uint(50, find_nth_bit(bmap, 64 * 3, 4)); expect_eq_uint(60, find_nth_bit(bmap, 64 * 3, 5)); expect_eq_uint(80, find_nth_bit(bmap, 64 * 3, 6)); expect_eq_uint(123, find_nth_bit(bmap, 64 * 3, 7)); expect_eq_uint(0, !!(find_nth_bit(bmap, 64 * 3, 8) < 64 * 3)); expect_eq_uint(10, find_nth_bit(bmap, 64 * 3 - 1, 0)); expect_eq_uint(20, find_nth_bit(bmap, 64 * 3 - 1, 1)); expect_eq_uint(30, find_nth_bit(bmap, 64 * 3 - 1, 2)); expect_eq_uint(40, find_nth_bit(bmap, 64 * 3 - 1, 3)); expect_eq_uint(50, find_nth_bit(bmap, 64 * 3 - 1, 4)); expect_eq_uint(60, find_nth_bit(bmap, 64 * 3 - 1, 5)); expect_eq_uint(80, find_nth_bit(bmap, 64 * 3 - 1, 6)); expect_eq_uint(123, find_nth_bit(bmap, 64 * 3 - 1, 7)); expect_eq_uint(0, !!(find_nth_bit(bmap, 64 * 3 - 1, 8) < 64 * 3 - 1)); for_each_set_bit(bit, exp1, EXP1_IN_BITS) { b = find_nth_bit(exp1, EXP1_IN_BITS, cnt++); expect_eq_uint(b, bit); }} static void __init test_fill_set(void){ DECLARE_BITMAP(bmap, 1024); /* Known way to clear all bits */ memset(bmap, 0x00, 128); expect_eq_pbl("", bmap, 23); expect_eq_pbl("", bmap, 1024); /* single-word bitmaps */ bitmap_set(bmap, 0, 9); expect_eq_pbl("0-8", bmap, 1024); bitmap_fill(bmap, 35); expect_eq_pbl("0-63", bmap, 1024); /* cross boundaries operations */ bitmap_set(bmap, 79, 19); expect_eq_pbl("0-63,79-97", bmap, 1024); bitmap_fill(bmap, 115); expect_eq_pbl("0-127", bmap, 1024); /* Zeroing entire area */ bitmap_fill(bmap, 1024); expect_eq_pbl("0-1023", bmap, 1024);} static void __init test_copy(void){ DECLARE_BITMAP(bmap1, 1024); DECLARE_BITMAP(bmap2, 1024); bitmap_zero(bmap1, 1024); bitmap_zero(bmap2, 1024); /* single-word bitmaps */ bitmap_set(bmap1, 0, 19); bitmap_copy(bmap2, bmap1, 23); expect_eq_pbl("0-18", bmap2, 1024); bitmap_set(bmap2, 0, 23); bitmap_copy(bmap2, bmap1, 23); expect_eq_pbl("0-18", bmap2, 1024); /* multi-word bitmaps */ bitmap_set(bmap1, 0, 109); bitmap_copy(bmap2, bmap1, 1024); expect_eq_pbl("0-108", bmap2, 1024); bitmap_fill(bmap2, 1024); bitmap_copy(bmap2, bmap1, 1024); expect_eq_pbl("0-108", bmap2, 1024); /* the following tests assume a 32- or 64-bit arch (even 128b * if we care) */ bitmap_fill(bmap2, 1024); bitmap_copy(bmap2, bmap1, 109); /* ... but 0-padded til word length */ expect_eq_pbl("0-108,128-1023", bmap2, 1024); bitmap_fill(bmap2, 1024); bitmap_copy(bmap2, bmap1, 97); /* ... but aligned on word length */ expect_eq_pbl("0-108,128-1023", bmap2, 1024);} static void __init test_bitmap_region(void){ int pos, order; DECLARE_BITMAP(bmap, 1000); bitmap_zero(bmap, 1000); for (order = 0; order < 10; order++) { pos = bitmap_find_free_region(bmap, 1000, order); if (order == 0) expect_eq_uint(pos, 0); else expect_eq_uint(pos, order < 9 ? BIT(order) : -ENOMEM); } bitmap_release_region(bmap, 0, 0); for (order = 1; order < 9; order++) bitmap_release_region(bmap, BIT(order), order); expect_eq_uint(bitmap_weight(bmap, 1000), 0);} #define EXP2_IN_BITS (sizeof(exp2) * 8) static void __init test_replace(void){ unsigned int nbits = 64; unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG); DECLARE_BITMAP(bmap, 1024); BUILD_BUG_ON(EXP2_IN_BITS < nbits * 2); bitmap_zero(bmap, 1024); bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits); expect_eq_bitmap(bmap, exp3_0_1, nbits); bitmap_zero(bmap, 1024); bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits); expect_eq_bitmap(bmap, exp3_1_0, nbits); bitmap_fill(bmap, 1024); bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits); expect_eq_bitmap(bmap, exp3_0_1, nbits); bitmap_fill(bmap, 1024); bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits); expect_eq_bitmap(bmap, exp3_1_0, nbits);} static const unsigned long sg_mask[] __initconst = { BITMAP_FROM_U64(0x000000000000035aULL), BITMAP_FROM_U64(0x0000000000000000ULL),}; static const unsigned long sg_src[] __initconst = { BITMAP_FROM_U64(0x0000000000000667ULL), BITMAP_FROM_U64(0x0000000000000000ULL),}; static const unsigned long sg_gather_exp[] __initconst = { BITMAP_FROM_U64(0x0000000000000029ULL), BITMAP_FROM_U64(0x0000000000000000ULL),}; static const unsigned long sg_scatter_exp[] __initconst = { BITMAP_FROM_U64(0x000000000000021aULL), BITMAP_FROM_U64(0x0000000000000000ULL),}; static void __init test_bitmap_sg(void){ unsigned int nbits = 64; DECLARE_BITMAP(bmap_gather, 100); DECLARE_BITMAP(bmap_scatter, 100); DECLARE_BITMAP(bmap_tmp, 100); DECLARE_BITMAP(bmap_res, 100); /* Simple gather call */ bitmap_zero(bmap_gather, 100); bitmap_gather(bmap_gather, sg_src, sg_mask, nbits); expect_eq_bitmap(sg_gather_exp, bmap_gather, 100); /* Simple scatter call */ bitmap_zero(bmap_scatter, 100); bitmap_scatter(bmap_scatter, sg_src, sg_mask, nbits); expect_eq_bitmap(sg_scatter_exp, bmap_scatter, 100); /* Scatter/gather relationship */ bitmap_zero(bmap_tmp, 100); bitmap_gather(bmap_tmp, bmap_scatter, sg_mask, nbits); bitmap_scatter(bmap_res, bmap_tmp, sg_mask, nbits); expect_eq_bitmap(bmap_scatter, bmap_res, 100);} #define PARSE_TIME 0x1#define NO_LEN 0x2 struct test_bitmap_parselist{ const int errno; const char *in; const unsigned long *expected; const int nbits; const int flags;}; static const struct test_bitmap_parselist parselist_tests[] __initconst = {#define step (sizeof(u64) / sizeof(unsigned long)) {0, "0", &exp1[0], 8, 0}, {0, "1", &exp1[1 * step], 8, 0}, {0, "0-15", &exp1[2 * step], 32, 0}, {0, "16-31", &exp1[3 * step], 32, 0}, {0, "0-31:1/2", &exp1[4 * step], 32, 0}, {0, "1-31:1/2", &exp1[5 * step], 32, 0}, {0, "0-31:1/4", &exp1[6 * step], 32, 0}, {0, "1-31:1/4", &exp1[7 * step], 32, 0}, {0, "0-31:4/4", &exp1[8 * step], 32, 0}, {0, "1-31:4/4", &exp1[9 * step], 32, 0}, {0, "0-31:1/4,32-63:2/4", &exp1[10 * step], 64, 0}, {0, "0-31:3/4,32-63:4/4", &exp1[11 * step], 64, 0}, {0, " ,, 0-31:3/4 ,, 32-63:4/4 ,, ", &exp1[11 * step], 64, 0}, {0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4", exp2, 128, 0}, {0, "0-2047:128/256", NULL, 2048, PARSE_TIME}, {0, "", &exp1[12 * step], 8, 0}, {0, "\n", &exp1[12 * step], 8, 0}, {0, ",, ,, , , ,", &exp1[12 * step], 8, 0}, {0, " , ,, , , ", &exp1[12 * step], 8, 0}, {0, " , ,, , , \n", &exp1[12 * step], 8, 0}, {0, "0-0", &exp1[0], 32, 0}, {0, "1-1", &exp1[1 * step], 32, 0}, {0, "15-15", &exp1[13 * step], 32, 0}, {0, "31-31", &exp1[14 * step], 32, 0}, {0, "0-0:0/1", &exp1[12 * step], 32, 0}, {0, "0-0:1/1", &exp1[0], 32, 0}, {0, "0-0:1/31", &exp1[0], 32, 0}, {0, "0-0:31/31", &exp1[0], 32, 0}, {0, "1-1:1/1", &exp1[1 * step], 32, 0}, {0, "0-15:16/31", &exp1[2 * step], 32, 0}, {0, "15-15:1/2", &exp1[13 * step], 32, 0}, {0, "15-15:31/31", &exp1[13 * step], 32, 0}, {0, "15-31:1/31", &exp1[13 * step], 32, 0}, {0, "16-31:16/31", &exp1[3 * step], 32, 0}, {0, "31-31:31/31", &exp1[14 * step], 32, 0}, {0, "N-N", &exp1[14 * step], 32, 0}, {0, "0-0:1/N", &exp1[0], 32, 0}, {0, "0-0:N/N", &exp1[0], 32, 0}, {0, "0-15:16/N", &exp1[2 * step], 32, 0}, {0, "15-15:N/N", &exp1[13 * step], 32, 0}, {0, "15-N:1/N", &exp1[13 * step], 32, 0}, {0, "16-N:16/N", &exp1[3 * step], 32, 0}, {0, "N-N:N/N", &exp1[14 * step], 32, 0}, {0, "0-N:1/3,1-N:1/3,2-N:1/3", &exp1[8 * step], 32, 0}, {0, "0-31:1/3,1-31:1/3,2-31:1/3", &exp1[8 * step], 32, 0}, {0, "1-10:8/12,8-31:24/29,0-31:0/3", &exp1[9 * step], 32, 0}, {0, "all", &exp1[8 * step], 32, 0}, {0, "0, 1, all, ", &exp1[8 * step], 32, 0}, {0, "all:1/2", &exp1[4 * step], 32, 0}, {0, "ALL:1/2", &exp1[4 * step], 32, 0}, {-EINVAL, "al", NULL, 8, 0}, {-EINVAL, "alll", NULL, 8, 0}, {-EINVAL, "-1", NULL, 8, 0}, {-EINVAL, "-0", NULL, 8, 0}, {-EINVAL, "10-1", NULL, 8, 0}, {-ERANGE, "8-8", NULL, 8, 0}, {-ERANGE, "0-31", NULL, 8, 0}, {-EINVAL, "0-31:", NULL, 32, 0}, {-EINVAL, "0-31:0", NULL, 32, 0}, {-EINVAL, "0-31:0/", NULL, 32, 0}, {-EINVAL, "0-31:0/0", NULL, 32, 0}, {-EINVAL, "0-31:1/0", NULL, 32, 0}, {-EINVAL, "0-31:10/1", NULL, 32, 0}, {-EOVERFLOW, "0-98765432123456789:10/1", NULL, 8, 0}, {-EINVAL, "a-31", NULL, 8, 0}, {-EINVAL, "0-a1", NULL, 8, 0}, {-EINVAL, "a-31:10/1", NULL, 8, 0}, {-EINVAL, "0-31:a/1", NULL, 8, 0}, {-EINVAL, "0-\n", NULL, 8, 0}, }; static void __init test_bitmap_parselist(void){ int i; int err; ktime_t time;Lines 1–500 of 1567. Load more
// SPDX-License-Identifier: GPL-2.0-only /* * Test cases for bitmap API. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/bitmap.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/printk.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/uaccess.h> #include "../tools/testing/selftests/kselftest_module.h" #define EXP1_IN_BITS (sizeof(exp1) * 8) KSTM_MODULE_GLOBALS(); static char pbl_buffer[PAGE_SIZE] __initdata; static char print_buf[PAGE_SIZE * 2] __initdata; static const unsigned long exp1[] __initconst = { BITMAP_FROM_U64(1), BITMAP_FROM_U64(2), BITMAP_FROM_U64(0x0000ffff), BITMAP_FROM_U64(0xffff0000), BITMAP_FROM_U64(0x55555555), BITMAP_FROM_U64(0xaaaaaaaa), BITMAP_FROM_U64(0x11111111), BITMAP_FROM_U64(0x22222222), BITMAP_FROM_U64(0xffffffff), BITMAP_FROM_U64(0xfffffffe), BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0xffffffff77777777ULL), BITMAP_FROM_U64(0), BITMAP_FROM_U64(0x00008000), BITMAP_FROM_U64(0x80000000), }; static const unsigned long exp2[] __initconst = { BITMAP_FROM_U64(0x3333333311111111ULL), BITMAP_FROM_U64(0xffffffff77777777ULL), }; /* Fibonacci sequence */ static const unsigned long exp2_to_exp3_mask[] __initconst = { BITMAP_FROM_U64(0x008000020020212eULL), }; /* exp3_0_1 = (exp2[0] & ~exp2_to_exp3_mask) | (exp2[1] & exp2_to_exp3_mask) */ static const unsigned long exp3_0_1[] __initconst = { BITMAP_FROM_U64(0x33b3333311313137ULL), }; /* exp3_1_0 = (exp2[1] & ~exp2_to_exp3_mask) | (exp2[0] & exp2_to_exp3_mask) */ static const unsigned long exp3_1_0[] __initconst = { BITMAP_FROM_U64(0xff7fffff77575751ULL), }; static bool __init __check_eq_ulong(const char *srcfile, unsigned int line, const unsigned long exp_ulong, unsigned long x) { if (exp_ulong != x) { pr_err("[%s:%u] expected %lu, got %lu\n", srcfile, line, exp_ulong, x); return false; } return true; } static bool __init __check_eq_bitmap(const char *srcfile, unsigned int line, const unsigned long *exp_bmap, const unsigned long *bmap, unsigned int nbits) { if (!bitmap_equal(exp_bmap, bmap, nbits)) { pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n", srcfile, line, nbits, exp_bmap, nbits, bmap); return false; } return true; } static bool __init __check_eq_pbl(const char *srcfile, unsigned int line, const char *expected_pbl, const unsigned long *bitmap, unsigned int nbits) { snprintf(pbl_buffer, sizeof(pbl_buffer), "%*pbl", nbits, bitmap); if (strcmp(expected_pbl, pbl_buffer)) { pr_warn("[%s:%u] expected \"%s\", got \"%s\"\n", srcfile, line, expected_pbl, pbl_buffer); return false; } return true; } static bool __init __check_eq_clump8(const char *srcfile, unsigned int line, const unsigned int offset, const unsigned int size, const unsigned char *const clump_exp, const unsigned long *const clump) { unsigned long exp; if (offset >= size) { pr_warn("[%s:%u] bit offset for clump out-of-bounds: expected less than %u, got %u\n", srcfile, line, size, offset); return false; } exp = clump_exp[offset / 8]; if (!exp) { pr_warn("[%s:%u] bit offset for zero clump: expected nonzero clump, got bit offset %u with clump value 0", srcfile, line, offset); return false; } if (*clump != exp) { pr_warn("[%s:%u] expected clump value of 0x%lX, got clump value of 0x%lX", srcfile, line, exp, *clump); return false; } return true; } static bool __init __check_eq_str(const char *srcfile, unsigned int line, const char *exp_str, const char *str, unsigned int len) { bool eq; eq = strncmp(exp_str, str, len) == 0; if (!eq) pr_err("[%s:%u] expected %s, got %s\n", srcfile, line, exp_str, str); return eq; } #define __expect_eq(suffix, ...) \ ({ \ int result = 0; \ total_tests++; \ if (!__check_eq_ ## suffix(__FILE__, __LINE__, \ ##__VA_ARGS__)) { \ failed_tests++; \ result = 1; \ } \ result; \ }) #define expect_eq_ulong(...) __expect_eq(ulong, ##__VA_ARGS__) #define expect_eq_uint(x, y) expect_eq_ulong((unsigned int)(x), (unsigned int)(y)) #define expect_eq_bitmap(...) __expect_eq(bitmap, ##__VA_ARGS__) #define expect_eq_pbl(...) __expect_eq(pbl, ##__VA_ARGS__) #define expect_eq_u32_array(...) __expect_eq(u32_array, ##__VA_ARGS__) #define expect_eq_clump8(...) __expect_eq(clump8, ##__VA_ARGS__) #define expect_eq_str(...) __expect_eq(str, ##__VA_ARGS__) static void __init test_zero_clear(void) { DECLARE_BITMAP(bmap, 1024); /* Known way to set all bits */ memset(bmap, 0xff, 128); expect_eq_pbl("0-22", bmap, 23); expect_eq_pbl("0-1023", bmap, 1024); /* single-word bitmaps */ bitmap_clear(bmap, 0, 9); expect_eq_pbl("9-1023", bmap, 1024); bitmap_zero(bmap, 35); expect_eq_pbl("64-1023", bmap, 1024); /* cross boundaries operations */ bitmap_clear(bmap, 79, 19); expect_eq_pbl("64-78,98-1023", bmap, 1024); bitmap_zero(bmap, 115); expect_eq_pbl("128-1023", bmap, 1024); /* Zeroing entire area */ bitmap_zero(bmap, 1024); expect_eq_pbl("", bmap, 1024); } static void __init test_find_nth_bit(void) { unsigned long b, bit, cnt = 0; DECLARE_BITMAP(bmap, 64 * 3); bitmap_zero(bmap, 64 * 3); __set_bit(10, bmap); __set_bit(20, bmap); __set_bit(30, bmap); __set_bit(40, bmap); __set_bit(50, bmap); __set_bit(60, bmap); __set_bit(80, bmap); __set_bit(123, bmap); expect_eq_uint(10, find_nth_bit(bmap, 64 * 3, 0)); expect_eq_uint(20, find_nth_bit(bmap, 64 * 3, 1)); expect_eq_uint(30, find_nth_bit(bmap, 64 * 3, 2)); expect_eq_uint(40, find_nth_bit(bmap, 64 * 3, 3)); expect_eq_uint(50, find_nth_bit(bmap, 64 * 3, 4)); expect_eq_uint(60, find_nth_bit(bmap, 64 * 3, 5)); expect_eq_uint(80, find_nth_bit(bmap, 64 * 3, 6)); expect_eq_uint(123, find_nth_bit(bmap, 64 * 3, 7)); expect_eq_uint(0, !!(find_nth_bit(bmap, 64 * 3, 8) < 64 * 3)); expect_eq_uint(10, find_nth_bit(bmap, 64 * 3 - 1, 0)); expect_eq_uint(20, find_nth_bit(bmap, 64 * 3 - 1, 1)); expect_eq_uint(30, find_nth_bit(bmap, 64 * 3 - 1, 2)); expect_eq_uint(40, find_nth_bit(bmap, 64 * 3 - 1, 3)); expect_eq_uint(50, find_nth_bit(bmap, 64 * 3 - 1, 4)); expect_eq_uint(60, find_nth_bit(bmap, 64 * 3 - 1, 5)); expect_eq_uint(80, find_nth_bit(bmap, 64 * 3 - 1, 6)); expect_eq_uint(123, find_nth_bit(bmap, 64 * 3 - 1, 7)); expect_eq_uint(0, !!(find_nth_bit(bmap, 64 * 3 - 1, 8) < 64 * 3 - 1)); for_each_set_bit(bit, exp1, EXP1_IN_BITS) { b = find_nth_bit(exp1, EXP1_IN_BITS, cnt++); expect_eq_uint(b, bit); } } static void __init test_fill_set(void) { DECLARE_BITMAP(bmap, 1024); /* Known way to clear all bits */ memset(bmap, 0x00, 128); expect_eq_pbl("", bmap, 23); expect_eq_pbl("", bmap, 1024); /* single-word bitmaps */ bitmap_set(bmap, 0, 9); expect_eq_pbl("0-8", bmap, 1024); bitmap_fill(bmap, 35); expect_eq_pbl("0-63", bmap, 1024); /* cross boundaries operations */ bitmap_set(bmap, 79, 19); expect_eq_pbl("0-63,79-97", bmap, 1024); bitmap_fill(bmap, 115); expect_eq_pbl("0-127", bmap, 1024); /* Zeroing entire area */ bitmap_fill(bmap, 1024); expect_eq_pbl("0-1023", bmap, 1024); } static void __init test_copy(void) { DECLARE_BITMAP(bmap1, 1024); DECLARE_BITMAP(bmap2, 1024); bitmap_zero(bmap1, 1024); bitmap_zero(bmap2, 1024); /* single-word bitmaps */ bitmap_set(bmap1, 0, 19); bitmap_copy(bmap2, bmap1, 23); expect_eq_pbl("0-18", bmap2, 1024); bitmap_set(bmap2, 0, 23); bitmap_copy(bmap2, bmap1, 23); expect_eq_pbl("0-18", bmap2, 1024); /* multi-word bitmaps */ bitmap_set(bmap1, 0, 109); bitmap_copy(bmap2, bmap1, 1024); expect_eq_pbl("0-108", bmap2, 1024); bitmap_fill(bmap2, 1024); bitmap_copy(bmap2, bmap1, 1024); expect_eq_pbl("0-108", bmap2, 1024); /* the following tests assume a 32- or 64-bit arch (even 128b * if we care) */ bitmap_fill(bmap2, 1024); bitmap_copy(bmap2, bmap1, 109); /* ... but 0-padded til word length */ expect_eq_pbl("0-108,128-1023", bmap2, 1024); bitmap_fill(bmap2, 1024); bitmap_copy(bmap2, bmap1, 97); /* ... but aligned on word length */ expect_eq_pbl("0-108,128-1023", bmap2, 1024); } static void __init test_bitmap_region(void) { int pos, order; DECLARE_BITMAP(bmap, 1000); bitmap_zero(bmap, 1000); for (order = 0; order < 10; order++) { pos = bitmap_find_free_region(bmap, 1000, order); if (order == 0) expect_eq_uint(pos, 0); else expect_eq_uint(pos, order < 9 ? BIT(order) : -ENOMEM); } bitmap_release_region(bmap, 0, 0); for (order = 1; order < 9; order++) bitmap_release_region(bmap, BIT(order), order); expect_eq_uint(bitmap_weight(bmap, 1000), 0); } #define EXP2_IN_BITS (sizeof(exp2) * 8) static void __init test_replace(void) { unsigned int nbits = 64; unsigned int nlongs = DIV_ROUND_UP(nbits, BITS_PER_LONG); DECLARE_BITMAP(bmap, 1024); BUILD_BUG_ON(EXP2_IN_BITS < nbits * 2); bitmap_zero(bmap, 1024); bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits); expect_eq_bitmap(bmap, exp3_0_1, nbits); bitmap_zero(bmap, 1024); bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits); expect_eq_bitmap(bmap, exp3_1_0, nbits); bitmap_fill(bmap, 1024); bitmap_replace(bmap, &exp2[0 * nlongs], &exp2[1 * nlongs], exp2_to_exp3_mask, nbits); expect_eq_bitmap(bmap, exp3_0_1, nbits); bitmap_fill(bmap, 1024); bitmap_replace(bmap, &exp2[1 * nlongs], &exp2[0 * nlongs], exp2_to_exp3_mask, nbits); expect_eq_bitmap(bmap, exp3_1_0, nbits); } static const unsigned long sg_mask[] __initconst = { BITMAP_FROM_U64(0x000000000000035aULL), BITMAP_FROM_U64(0x0000000000000000ULL), }; static const unsigned long sg_src[] __initconst = { BITMAP_FROM_U64(0x0000000000000667ULL), BITMAP_FROM_U64(0x0000000000000000ULL), }; static const unsigned long sg_gather_exp[] __initconst = { BITMAP_FROM_U64(0x0000000000000029ULL), BITMAP_FROM_U64(0x0000000000000000ULL), }; static const unsigned long sg_scatter_exp[] __initconst = { BITMAP_FROM_U64(0x000000000000021aULL), BITMAP_FROM_U64(0x0000000000000000ULL), }; static void __init test_bitmap_sg(void) { unsigned int nbits = 64; DECLARE_BITMAP(bmap_gather, 100); DECLARE_BITMAP(bmap_scatter, 100); DECLARE_BITMAP(bmap_tmp, 100); DECLARE_BITMAP(bmap_res, 100); /* Simple gather call */ bitmap_zero(bmap_gather, 100); bitmap_gather(bmap_gather, sg_src, sg_mask, nbits); expect_eq_bitmap(sg_gather_exp, bmap_gather, 100); /* Simple scatter call */ bitmap_zero(bmap_scatter, 100); bitmap_scatter(bmap_scatter, sg_src, sg_mask, nbits); expect_eq_bitmap(sg_scatter_exp, bmap_scatter, 100); /* Scatter/gather relationship */ bitmap_zero(bmap_tmp, 100); bitmap_gather(bmap_tmp, bmap_scatter, sg_mask, nbits); bitmap_scatter(bmap_res, bmap_tmp, sg_mask, nbits); expect_eq_bitmap(bmap_scatter, bmap_res, 100); } #define PARSE_TIME 0x1 #define NO_LEN 0x2 struct test_bitmap_parselist{ const int errno; const char *in; const unsigned long *expected; const int nbits; const int flags; }; static const struct test_bitmap_parselist parselist_tests[] __initconst = { #define step (sizeof(u64) / sizeof(unsigned long)) {0, "0", &exp1[0], 8, 0}, {0, "1", &exp1[1 * step], 8, 0}, {0, "0-15", &exp1[2 * step], 32, 0}, {0, "16-31", &exp1[3 * step], 32, 0}, {0, "0-31:1/2", &exp1[4 * step], 32, 0}, {0, "1-31:1/2", &exp1[5 * step], 32, 0}, {0, "0-31:1/4", &exp1[6 * step], 32, 0}, {0, "1-31:1/4", &exp1[7 * step], 32, 0}, {0, "0-31:4/4", &exp1[8 * step], 32, 0}, {0, "1-31:4/4", &exp1[9 * step], 32, 0}, {0, "0-31:1/4,32-63:2/4", &exp1[10 * step], 64, 0}, {0, "0-31:3/4,32-63:4/4", &exp1[11 * step], 64, 0}, {0, " ,, 0-31:3/4 ,, 32-63:4/4 ,, ", &exp1[11 * step], 64, 0}, {0, "0-31:1/4,32-63:2/4,64-95:3/4,96-127:4/4", exp2, 128, 0}, {0, "0-2047:128/256", NULL, 2048, PARSE_TIME}, {0, "", &exp1[12 * step], 8, 0}, {0, "\n", &exp1[12 * step], 8, 0}, {0, ",, ,, , , ,", &exp1[12 * step], 8, 0}, {0, " , ,, , , ", &exp1[12 * step], 8, 0}, {0, " , ,, , , \n", &exp1[12 * step], 8, 0}, {0, "0-0", &exp1[0], 32, 0}, {0, "1-1", &exp1[1 * step], 32, 0}, {0, "15-15", &exp1[13 * step], 32, 0}, {0, "31-31", &exp1[14 * step], 32, 0}, {0, "0-0:0/1", &exp1[12 * step], 32, 0}, {0, "0-0:1/1", &exp1[0], 32, 0}, {0, "0-0:1/31", &exp1[0], 32, 0}, {0, "0-0:31/31", &exp1[0], 32, 0}, {0, "1-1:1/1", &exp1[1 * step], 32, 0}, {0, "0-15:16/31", &exp1[2 * step], 32, 0}, {0, "15-15:1/2", &exp1[13 * step], 32, 0}, {0, "15-15:31/31", &exp1[13 * step], 32, 0}, {0, "15-31:1/31", &exp1[13 * step], 32, 0}, {0, "16-31:16/31", &exp1[3 * step], 32, 0}, {0, "31-31:31/31", &exp1[14 * step], 32, 0}, {0, "N-N", &exp1[14 * step], 32, 0}, {0, "0-0:1/N", &exp1[0], 32, 0}, {0, "0-0:N/N", &exp1[0], 32, 0}, {0, "0-15:16/N", &exp1[2 * step], 32, 0}, {0, "15-15:N/N", &exp1[13 * step], 32, 0}, {0, "15-N:1/N", &exp1[13 * step], 32, 0}, {0, "16-N:16/N", &exp1[3 * step], 32, 0}, {0, "N-N:N/N", &exp1[14 * step], 32, 0}, {0, "0-N:1/3,1-N:1/3,2-N:1/3", &exp1[8 * step], 32, 0}, {0, "0-31:1/3,1-31:1/3,2-31:1/3", &exp1[8 * step], 32, 0}, {0, "1-10:8/12,8-31:24/29,0-31:0/3", &exp1[9 * step], 32, 0}, {0, "all", &exp1[8 * step], 32, 0}, {0, "0, 1, all, ", &exp1[8 * step], 32, 0}, {0, "all:1/2", &exp1[4 * step], 32, 0}, {0, "ALL:1/2", &exp1[4 * step], 32, 0}, {-EINVAL, "al", NULL, 8, 0}, {-EINVAL, "alll", NULL, 8, 0}, {-EINVAL, "-1", NULL, 8, 0}, {-EINVAL, "-0", NULL, 8, 0}, {-EINVAL, "10-1", NULL, 8, 0}, {-ERANGE, "8-8", NULL, 8, 0}, {-ERANGE, "0-31", NULL, 8, 0}, {-EINVAL, "0-31:", NULL, 32, 0}, {-EINVAL, "0-31:0", NULL, 32, 0}, {-EINVAL, "0-31:0/", NULL, 32, 0}, {-EINVAL, "0-31:0/0", NULL, 32, 0}, {-EINVAL, "0-31:1/0", NULL, 32, 0}, {-EINVAL, "0-31:10/1", NULL, 32, 0}, {-EOVERFLOW, "0-98765432123456789:10/1", NULL, 8, 0}, {-EINVAL, "a-31", NULL, 8, 0}, {-EINVAL, "0-a1", NULL, 8, 0}, {-EINVAL, "a-31:10/1", NULL, 8, 0}, {-EINVAL, "0-31:a/1", NULL, 8, 0}, {-EINVAL, "0-\n", NULL, 8, 0}, }; static void __init test_bitmap_parselist(void) { int i; int err; ktime_t time;