Download raw body.
bgpd: basic stats for bitmaps
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);
}
bgpd: basic stats for bitmaps