1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Cavium, Inc 3 */ 4 5 #include <stdio.h> 6 #include <inttypes.h> 7 8 #include <rte_common.h> 9 #include <rte_bitmap.h> 10 #include <rte_malloc.h> 11 12 #include "test.h" 13 14 #define MAX_BITS 1000 15 16 static int 17 test_bitmap_scan_operations(struct rte_bitmap *bmp) 18 { 19 uint64_t slab1_magic = 0xBADC0FFEEBADF00D; 20 uint64_t slab2_magic = 0xFEEDDEADDEADF00D; 21 uint32_t pos = 0, start_pos; 22 int i, nb_clear, nb_set; 23 uint64_t out_slab = 0; 24 25 rte_bitmap_reset(bmp); 26 27 rte_bitmap_set_slab(bmp, pos, slab1_magic); 28 rte_bitmap_set_slab(bmp, pos + RTE_BITMAP_SLAB_BIT_SIZE, slab2_magic); 29 30 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { 31 printf("Failed to get slab from bitmap.\n"); 32 return TEST_FAILED; 33 } 34 35 if (slab1_magic != out_slab) { 36 printf("Scan operation sanity failed.\n"); 37 return TEST_FAILED; 38 } 39 40 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { 41 printf("Failed to get slab from bitmap.\n"); 42 return TEST_FAILED; 43 } 44 45 if (slab2_magic != out_slab) { 46 printf("Scan operation sanity failed.\n"); 47 return TEST_FAILED; 48 } 49 50 /* Wrap around */ 51 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { 52 printf("Failed to get slab from bitmap.\n"); 53 return TEST_FAILED; 54 } 55 56 if (slab1_magic != out_slab) { 57 printf("Scan operation wrap around failed.\n"); 58 return TEST_FAILED; 59 } 60 61 /* Scan reset check. */ 62 __rte_bitmap_scan_init(bmp); 63 64 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { 65 printf("Failed to get slab from bitmap.\n"); 66 return TEST_FAILED; 67 } 68 69 if (slab1_magic != out_slab) { 70 printf("Scan reset operation failed.\n"); 71 return TEST_FAILED; 72 } 73 74 /* Test scan when a cline is half full */ 75 rte_bitmap_reset(bmp); 76 for (i = 0; i < MAX_BITS; i++) 77 rte_bitmap_set(bmp, i); 78 79 nb_clear = RTE_MIN(RTE_BITMAP_CL_BIT_SIZE / 2, MAX_BITS); 80 for (i = 0; i < nb_clear; i++) 81 rte_bitmap_clear(bmp, i); 82 83 /* Find remaining bits set in bmp */ 84 __rte_bitmap_scan_init(bmp); 85 86 if (rte_bitmap_scan(bmp, &pos, &out_slab) != 1) { 87 printf("Initial scan failed with half CL empty.\n"); 88 return TEST_FAILED; 89 } 90 91 start_pos = pos; 92 nb_set = 0; 93 do { 94 nb_set += __builtin_popcountll(out_slab); 95 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) 96 break; 97 } while (pos != start_pos); 98 99 if ((nb_clear + nb_set) != MAX_BITS) { 100 printf("Scan failed to find all set bits. " 101 "Expected %u, found %u.\n", MAX_BITS - nb_clear, nb_set); 102 return TEST_FAILED; 103 } 104 105 return TEST_SUCCESS; 106 } 107 108 static int 109 test_bitmap_slab_set_get(struct rte_bitmap *bmp) 110 { 111 uint32_t pos = 0; 112 uint64_t slab_magic = 0xBADC0FFEEBADF00D; 113 uint64_t out_slab = 0; 114 115 rte_bitmap_reset(bmp); 116 rte_bitmap_set_slab(bmp, pos, slab_magic); 117 118 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) { 119 printf("Failed to get slab from bitmap.\n"); 120 return TEST_FAILED; 121 } 122 123 124 if (slab_magic != out_slab) { 125 printf("Invalid slab in bitmap.\n"); 126 return TEST_FAILED; 127 } 128 129 130 return TEST_SUCCESS; 131 } 132 133 static int 134 test_bitmap_set_get_clear(struct rte_bitmap *bmp) 135 { 136 uint64_t val; 137 int i; 138 139 rte_bitmap_reset(bmp); 140 for (i = 0; i < MAX_BITS; i++) 141 rte_bitmap_set(bmp, i); 142 143 for (i = 0; i < MAX_BITS; i++) { 144 if (!rte_bitmap_get(bmp, i)) { 145 printf("Failed to get set bit.\n"); 146 return TEST_FAILED; 147 } 148 } 149 150 for (i = 0; i < MAX_BITS; i++) 151 rte_bitmap_clear(bmp, i); 152 153 for (i = 0; i < MAX_BITS; i++) { 154 if (rte_bitmap_get(bmp, i)) { 155 printf("Failed to clear set bit.\n"); 156 return TEST_FAILED; 157 } 158 } 159 160 rte_bitmap_reset(bmp); 161 162 /* Alternate slab set test */ 163 for (i = 0; i < MAX_BITS; i++) { 164 if (i % RTE_BITMAP_SLAB_BIT_SIZE) 165 rte_bitmap_set(bmp, i); 166 } 167 168 for (i = 0; i < MAX_BITS; i++) { 169 val = rte_bitmap_get(bmp, i); 170 if (((i % RTE_BITMAP_SLAB_BIT_SIZE) && !val) || 171 (!(i % RTE_BITMAP_SLAB_BIT_SIZE) && val)) { 172 printf("Failed to get set bit.\n"); 173 return TEST_FAILED; 174 } 175 } 176 177 return TEST_SUCCESS; 178 } 179 180 static int 181 test_bitmap_all_clear(void) 182 { 183 void *mem; 184 uint32_t bmp_size; 185 struct rte_bitmap *bmp; 186 187 bmp_size = 188 rte_bitmap_get_memory_footprint(MAX_BITS); 189 190 mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE); 191 if (mem == NULL) { 192 printf("Failed to allocate memory for bitmap\n"); 193 return TEST_FAILED; 194 } 195 196 bmp = rte_bitmap_init(MAX_BITS, mem, bmp_size); 197 if (bmp == NULL) { 198 printf("Failed to init bitmap\n"); 199 return TEST_FAILED; 200 } 201 202 if (test_bitmap_set_get_clear(bmp) < 0) 203 return TEST_FAILED; 204 205 if (test_bitmap_slab_set_get(bmp) < 0) 206 return TEST_FAILED; 207 208 if (test_bitmap_scan_operations(bmp) < 0) 209 return TEST_FAILED; 210 211 rte_bitmap_free(bmp); 212 rte_free(mem); 213 214 return TEST_SUCCESS; 215 } 216 217 static int 218 test_bitmap_all_set(void) 219 { 220 void *mem; 221 uint32_t i; 222 uint64_t slab; 223 uint32_t pos; 224 uint32_t bmp_size; 225 struct rte_bitmap *bmp; 226 227 bmp_size = 228 rte_bitmap_get_memory_footprint(MAX_BITS); 229 230 mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE); 231 if (mem == NULL) { 232 printf("Failed to allocate memory for bitmap\n"); 233 return TEST_FAILED; 234 } 235 236 bmp = rte_bitmap_init_with_all_set(MAX_BITS, mem, bmp_size); 237 if (bmp == NULL) { 238 printf("Failed to init bitmap\n"); 239 return TEST_FAILED; 240 } 241 242 for (i = 0; i < MAX_BITS; i++) { 243 pos = slab = 0; 244 if (!rte_bitmap_scan(bmp, &pos, &slab)) { 245 printf("Failed with init bitmap.\n"); 246 return TEST_FAILED; 247 } 248 pos += (slab ? __builtin_ctzll(slab) : 0); 249 rte_bitmap_clear(bmp, pos); 250 } 251 252 if (rte_bitmap_scan(bmp, &pos, &slab)) { 253 printf("Too much bits set.\n"); 254 return TEST_FAILED; 255 } 256 257 rte_bitmap_free(bmp); 258 rte_free(mem); 259 260 return TEST_SUCCESS; 261 262 } 263 264 static int 265 test_bitmap(void) 266 { 267 if (test_bitmap_all_clear() != TEST_SUCCESS) 268 return TEST_FAILED; 269 return test_bitmap_all_set(); 270 } 271 272 REGISTER_TEST_COMMAND(bitmap_autotest, test_bitmap); 273