From: Claudio Jeker Subject: bgpd: basic stats for bitmaps To: tech@openbsd.org Date: Wed, 4 Mar 2026 17:54:43 +0100 This adds some stats for the use of bitmaps. Only account for the extended bitmaps that allocate extra memory. So the count may be much lower since up to 127 bits the map uses the struct itself for storage. It would be nice to also account for the embedded bitmaps but the API makes it hard to correctly do the accounting. Also it is unclear if that will gain us much more information. -- :wq Claudio Index: bgpctl/output.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpctl/output.c,v diff -u -p -r1.70 output.c --- bgpctl/output.c 2 Mar 2026 12:09:10 -0000 1.70 +++ bgpctl/output.c 2 Mar 2026 13:45:14 -0000 @@ -1112,6 +1112,8 @@ show_rib_mem(struct rde_memstats *stats) printf("%10lld pending prefix entries using %s of memory\n", stats->pend_prefix_cnt, fmt_mem(stats->pend_prefix_cnt * sizeof(struct pend_prefix))); + printf("%10lld extended bitmaps using %s of memory\n", + stats->bitmap_cnt, fmt_mem(stats->bitmap_size)); printf("%10lld filters using %s of memory\n", stats->filter_cnt, fmt_mem(stats->filter_size)); printf("\t and holding %lld references\n", @@ -1136,7 +1138,7 @@ show_rib_mem(struct rde_memstats *stats) stats->rib_cnt * sizeof(struct rib_entry) + stats->path_cnt * sizeof(struct rde_aspath) + stats->aspath_size + stats->attr_cnt * sizeof(struct attr) + - stats->attr_data)); + stats->attr_data) + stats->bitmap_size); printf("Sets and filters using %s of memory\n", fmt_mem(stats->aset_size + stats->pset_size + stats->aspa_size + stats->filter_set_size)); Index: bgpctl/output_json.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpctl/output_json.c,v diff -u -p -r1.61 output_json.c --- bgpctl/output_json.c 2 Mar 2026 12:09:10 -0000 1.61 +++ bgpctl/output_json.c 2 Mar 2026 13:46:04 -0000 @@ -937,6 +937,8 @@ json_rib_mem(struct rde_memstats *stats) stats->attr_cnt * sizeof(struct attr), stats->attr_refs); json_rib_mem_element("attributes", stats->attr_dcnt, stats->attr_data, UINT64_MAX); + json_rib_mem_element("bitmaps", stats->bitmap_cnt, + stats->bitmap_size, UINT64_MAX); json_rib_mem_element("total", UINT64_MAX, pts + stats->prefix_cnt * sizeof(struct prefix) + stats->adjout_prefix_cnt * sizeof(struct adjout_prefix) + @@ -946,7 +948,7 @@ json_rib_mem(struct rde_memstats *stats) stats->rib_cnt * sizeof(struct rib_entry) + stats->path_cnt * sizeof(struct rde_aspath) + stats->aspath_size + stats->attr_cnt * sizeof(struct attr) + - stats->attr_data, UINT64_MAX); + stats->attr_data + stats->bitmap_size, UINT64_MAX); json_do_end(); json_do_object("filters", 0); Index: bgpctl/output_ometric.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpctl/output_ometric.c,v diff -u -p -r1.25 output_ometric.c --- bgpctl/output_ometric.c 2 Mar 2026 12:09:10 -0000 1.25 +++ bgpctl/output_ometric.c 2 Mar 2026 13:46:42 -0000 @@ -334,6 +334,8 @@ ometric_rib_mem(struct rde_memstats *sta stats->attr_cnt * sizeof(struct attr), stats->attr_refs); ometric_rib_mem_element("attributes", stats->attr_dcnt, stats->attr_data, UINT64_MAX); + ometric_rib_mem_element("bitmap", stats->bitmap_cnt, + stats->bitmap_size, UINT64_MAX); ometric_rib_mem_element("total", UINT64_MAX, pts + stats->prefix_cnt * sizeof(struct prefix) + @@ -344,7 +346,7 @@ ometric_rib_mem(struct rde_memstats *sta stats->rib_cnt * sizeof(struct rib_entry) + stats->path_cnt * sizeof(struct rde_aspath) + stats->aspath_size + stats->attr_cnt * sizeof(struct attr) + - stats->attr_data, UINT64_MAX); + stats->attr_data + stats->bitmap_size, UINT64_MAX); ometric_rib_mem_element("filter", stats->filter_cnt, stats->filter_size, stats->filter_refs); Index: bgpd/bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v diff -u -p -r1.534 bgpd.h --- bgpd/bgpd.h 2 Mar 2026 12:08:30 -0000 1.534 +++ bgpd/bgpd.h 2 Mar 2026 13:30:15 -0000 @@ -1425,6 +1425,8 @@ struct rde_memstats { long long pset_size; long long aspa_cnt; long long aspa_size; + long long bitmap_cnt; + long long bitmap_size; long long filter_cnt; long long filter_size; long long filter_refs; Index: bgpd/bitmap.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bitmap.c,v diff -u -p -r1.1 bitmap.c --- bgpd/bitmap.c 11 Dec 2025 12:18:27 -0000 1.1 +++ bgpd/bitmap.c 2 Mar 2026 13:31:52 -0000 @@ -29,6 +29,9 @@ #define BITMAP_SETPTR(x) ((uint64_t)(x) | 0x1) #define BITMAP_GETPTR(x) (uint64_t *)((x) & ~0x1) +size_t bitmap_size; +uint64_t bitmap_cnt; + static inline void bitmap_getset(struct bitmap *map, uint64_t **ptr, uint32_t *max) { @@ -41,13 +44,28 @@ bitmap_getset(struct bitmap *map, uint64 } } +static void +bitmap_free(struct bitmap *map) +{ + uint64_t *ptr; + uint32_t max; + + if (map->data[0] & 0x1) { + bitmap_getset(map, &ptr, &max); + bitmap_size -= max / 8; + bitmap_cnt--; + free(ptr); + } + +} + static int bitmap_resize(struct bitmap *map, uint32_t bid) { uint64_t *ptr, *new; - uint32_t elm, max, newmax; + uint32_t elm, size, oldmax, newmax; - bitmap_getset(map, &ptr, &max); + bitmap_getset(map, &ptr, &oldmax); /* get new map */ newmax = BITMAP_ROUNDUP(bid + 1, BITMAP_ALLOCBITS); @@ -55,19 +73,21 @@ bitmap_resize(struct bitmap *map, uint32 return -1; /* copy data over */ - max /= BITMAP_BITS; - for (elm = 0; elm < max; elm++) + size = oldmax / BITMAP_BITS; + for (elm = 0; elm < size; elm++) new[elm] = ptr[elm]; - max = newmax / BITMAP_BITS; - for ( ; elm < max; elm++) + size = newmax / BITMAP_BITS; + for ( ; elm < size; elm++) new[elm] = 0; /* free old data */ - if (map->data[0] & 0x1) - free(BITMAP_GETPTR(map->data[0])); + bitmap_free(map); + /* set new data */ map->data[0] = BITMAP_SETPTR(new); map->data[1] = newmax; + bitmap_size += newmax / 8; + bitmap_cnt++; return 0; } @@ -222,8 +242,6 @@ bitmap_init(struct bitmap *map) void bitmap_reset(struct bitmap *map) { - if (map->data[0] & 0x1) - free(BITMAP_GETPTR(map->data[0])); - + bitmap_free(map); bitmap_init(map); }