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