diff options
author | Maria Matejka <mq@ucw.cz> | 2021-12-01 13:02:44 +0100 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2021-12-01 13:04:52 +0100 |
commit | b50224a00351904f25a5105a98d56a62ed2c33a4 (patch) | |
tree | 8478675603fd2a91fb4f36f8ac2e4ffd0ac20cd3 | |
parent | 55ee9961e0d130bb16b22b7b5acffd815f266d63 (diff) | |
parent | f772afc525156498900770ffe5a98349df89a45c (diff) |
Merge branch 'master' into HEAD
-rw-r--r-- | conf/conf.c | 3 | ||||
-rw-r--r-- | lib/mempool.c | 12 | ||||
-rw-r--r-- | lib/resource.c | 40 | ||||
-rw-r--r-- | lib/resource.h | 14 | ||||
-rw-r--r-- | lib/slab.c | 29 | ||||
-rw-r--r-- | nest/cmds.c | 38 | ||||
-rw-r--r-- | sysdep/unix/alloc.c | 2 | ||||
-rw-r--r-- | sysdep/unix/io-loop.c | 1 |
8 files changed, 104 insertions, 35 deletions
diff --git a/conf/conf.c b/conf/conf.c index c6837a07..e8f1559a 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -520,6 +520,9 @@ order_shutdown(int gr) memcpy(c, config, sizeof(struct config)); init_list(&c->protos); init_list(&c->tables); + init_list(&c->symbols); + memset(c->def_tables, 0, sizeof(c->def_tables)); + HASH_INIT(c->sym_hash, c->pool, 4); c->shutdown = 1; c->gr_down = gr; diff --git a/lib/mempool.c b/lib/mempool.c index ed3ae8de..6d157e5c 100644 --- a/lib/mempool.c +++ b/lib/mempool.c @@ -46,7 +46,7 @@ struct linpool { static void lp_free(resource *); static void lp_dump(resource *); static resource *lp_lookup(resource *, unsigned long); -static size_t lp_memsize(resource *r); +static struct resmem lp_memsize(resource *r); static struct resclass lp_class = { "LinPool", @@ -302,7 +302,7 @@ lp_dump(resource *r) m->total_large); } -static size_t +static struct resmem lp_memsize(resource *r) { linpool *m = (linpool *) r; @@ -314,9 +314,11 @@ lp_memsize(resource *r) for(c=m->first_large; c; c=c->next) cnt++; - return ALLOC_OVERHEAD + sizeof(struct linpool) + - cnt * (ALLOC_OVERHEAD + sizeof(struct lp_chunk)) + - m->total + m->total_large; + return (struct resmem) { + .effective = m->total + m->total_large, + .overhead = ALLOC_OVERHEAD + sizeof(struct linpool) + + cnt * (ALLOC_OVERHEAD + sizeof(struct lp_chunk)), + }; } diff --git a/lib/resource.c b/lib/resource.c index d98cd4ff..9a4c7717 100644 --- a/lib/resource.c +++ b/lib/resource.c @@ -2,6 +2,7 @@ * BIRD Resource Manager * * (c) 1998--2000 Martin Mares <mj@ucw.cz> + * (c) 2021 Maria Matejka <mq@jmq.cz> * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -33,7 +34,7 @@ static void pool_dump(resource *); static void pool_free(resource *); static resource *pool_lookup(resource *, unsigned long); -static size_t pool_memsize(resource *P); +static struct resmem pool_memsize(resource *P); static struct resclass pool_class = { "Pool", @@ -155,19 +156,26 @@ rp_dump(pool *p) birdloop_leave(p->loop); } -static size_t +static struct resmem pool_memsize_locked(pool *p) { resource *r; - size_t sum = sizeof(pool) + ALLOC_OVERHEAD; + struct resmem sum = { + .effective = 0, + .overhead = sizeof(pool) + ALLOC_OVERHEAD, + }; WALK_LIST(r, p->inside) - sum += rmemsize(r); + { + struct resmem add = rmemsize(r); + sum.effective += add.effective; + sum.overhead += add.overhead; + } return sum; } -static size_t +static struct resmem pool_memsize(resource *P) { pool *p = (pool *) P; @@ -178,7 +186,7 @@ pool_memsize(resource *P) if (p->loop != parent->loop) birdloop_enter(p->loop); - size_t sum = pool_memsize_locked(p); + struct resmem sum = pool_memsize_locked(p); if (p->loop != parent->loop) birdloop_leave(p->loop); @@ -188,7 +196,7 @@ pool_memsize(resource *P) return sum; } -size_t +struct resmem rp_memsize(pool *p) { int inside = birdloop_inside(p->loop); @@ -197,7 +205,7 @@ rp_memsize(pool *p) ASSERT_DIE(pool_parent == NULL); pool_parent = p; - size_t sum = pool_memsize_locked(p); + struct resmem sum = pool_memsize_locked(p); ASSERT_DIE(pool_parent == p); pool_parent = NULL; @@ -290,14 +298,17 @@ rdump(void *res) debug("NULL\n"); } -size_t +struct resmem rmemsize(void *res) { resource *r = res; if (!r) - return 0; + return (struct resmem) {}; if (!r->class->memsize) - return r->class->size + ALLOC_OVERHEAD; + return (struct resmem) { + .effective = r->class->size - sizeof(resource), + .overhead = ALLOC_OVERHEAD + sizeof(resource), + }; return r->class->memsize(r); } @@ -407,11 +418,14 @@ mbl_lookup(resource *r, unsigned long a) return NULL; } -static size_t +static struct resmem mbl_memsize(resource *r) { struct mblock *m = (struct mblock *) r; - return ALLOC_OVERHEAD + sizeof(struct mblock) + m->size; + return (struct resmem) { + .effective = m->size, + .overhead = ALLOC_OVERHEAD + sizeof(struct mblock), + }; } static struct resclass mb_class = { diff --git a/lib/resource.h b/lib/resource.h index 9d7dae69..b80ff8c6 100644 --- a/lib/resource.h +++ b/lib/resource.h @@ -2,6 +2,7 @@ * BIRD Resource Manager * * (c) 1998--1999 Martin Mares <mj@ucw.cz> + * (c) 2021 Maria Matejka <mq@jmq.cz> * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -11,6 +12,11 @@ #include "lib/lists.h" +struct resmem { + size_t effective; /* Memory actually used for data storage */ + size_t overhead; /* Overhead memory imposed by allocator strategies */ +}; + /* Resource */ typedef struct resource { @@ -26,11 +32,11 @@ struct resclass { void (*free)(resource *); /* Freeing function */ void (*dump)(resource *); /* Dump to debug output */ resource *(*lookup)(resource *, unsigned long); /* Look up address (only for debugging) */ - size_t (*memsize)(resource *); /* Return size of memory used by the resource, may be NULL */ + struct resmem (*memsize)(resource *); /* Return size of memory used by the resource, may be NULL */ }; /* Estimate of system allocator overhead per item, for memory consumtion stats */ -#define ALLOC_OVERHEAD 8 +#define ALLOC_OVERHEAD 16 /* Generic resource manipulation */ @@ -46,7 +52,7 @@ void resource_init(void); void rfree(void *); /* Free single resource */ void rdump(void *); /* Dump to debug output */ -size_t rmemsize(void *res); /* Return size of memory used by the resource */ +struct resmem rmemsize(void *res); /* Return size of memory used by the resource */ void rlookup(unsigned long); /* Look up address (only for debugging) */ void rmove(void *, pool *); /* Move to a different pool */ @@ -54,7 +60,7 @@ void *ralloc(pool *, struct resclass *); pool *rp_new(pool *, struct birdloop *loop, const char *); /* Create new pool */ void rp_free(pool *p, pool *parent); /* Free parent pool */ -size_t rp_memsize(pool *p); /* Return size of memory used by the pool */ +struct resmem rp_memsize(pool *p); /* Return size of memory used by the pool */ void rp_dump(pool *p); /* Dump pool to debug output */ extern pool root_pool; @@ -42,7 +42,7 @@ static void slab_free(resource *r); static void slab_dump(resource *r); static resource *slab_lookup(resource *r, unsigned long addr); -static size_t slab_memsize(resource *r); +static struct resmem slab_memsize(resource *r); #ifdef FAKE_SLAB @@ -128,7 +128,7 @@ slab_dump(resource *r) debug("(%d objects per %d bytes)\n", cnt, s->size); } -static size_t +static struct resmem slab_memsize(resource *r) { slab *s = (slab *) r; @@ -138,7 +138,10 @@ slab_memsize(resource *r) WALK_LIST(o, s->objs) cnt++; - return ALLOC_OVERHEAD + sizeof(struct slab) + cnt * (ALLOC_OVERHEAD + s->size); + return (struct resmem) { + .effective = cnt * s->size, + .overhead = ALLOC_OVERHEAD + sizeof(struct slab) + cnt * ALLOC_OVERHEAD, + }; } @@ -372,21 +375,33 @@ slab_dump(resource *r) debug("(%de+%dp+%df blocks per %d objs per %d bytes)\n", ec, pc, fc, s->objs_per_slab, s->obj_size); } -static size_t +static struct resmem slab_memsize(resource *r) { slab *s = (slab *) r; size_t heads = 0; struct sl_head *h; - WALK_LIST(h, s->empty_heads) + WALK_LIST(h, s->full_heads) heads++; + + size_t items = heads * s->objs_per_slab; + WALK_LIST(h, s->partial_heads) + { heads++; - WALK_LIST(h, s->full_heads) + items += h->num_full; + } + + WALK_LIST(h, s->empty_heads) heads++; - return ALLOC_OVERHEAD + sizeof(struct slab) + heads * page_size; + size_t eff = items * s->obj_size; + + return (struct resmem) { + .effective = eff, + .overhead = ALLOC_OVERHEAD + sizeof(struct slab) + heads * page_size - eff, + }; } static resource * diff --git a/nest/cmds.c b/nest/cmds.c index 2f2ad94c..77c92077 100644 --- a/nest/cmds.c +++ b/nest/cmds.c @@ -67,18 +67,43 @@ cmd_show_symbols(struct sym_show_data *sd) } } -static void -print_size(char *dsc, size_t val) +#define SIZE_SUFFIX " kMGT" +#define SIZE_FORMAT "% 4u.%1u % 1cB" +#define SIZE_ARGS(a) (a).val, (a).decimal, SIZE_SUFFIX[(a).magnitude] + +struct size_args { + u64 val:48; + u64 decimal:8; + u64 magnitude:8; +}; + +static struct size_args +get_size_args(u64 val) { - char *px = " kMG"; - int i = 0; - while ((val >= 10000) && (i < 3)) +#define VALDEC 10 /* One decimal place */ + val *= VALDEC; + + uint i = 0; + while ((val >= 10000 * VALDEC) && (i < 4)) { val = (val + 512) / 1024; i++; } - cli_msg(-1018, "%-17s %4u %cB", dsc, (unsigned) val, px[i]); + return (struct size_args) { + .val = (val / VALDEC), + .decimal = (val % VALDEC), + .magnitude = i, + }; +} + +static void +print_size(char *dsc, struct resmem vals) +{ + struct size_args effective = get_size_args(vals.effective); + struct size_args overhead = get_size_args(vals.overhead); + + cli_msg(-1018, "%-17s " SIZE_FORMAT " " SIZE_FORMAT, dsc, SIZE_ARGS(effective), SIZE_ARGS(overhead)); } extern pool *rt_table_pool; @@ -88,6 +113,7 @@ void cmd_show_memory(void) { cli_msg(-1018, "BIRD memory usage"); + cli_msg(-1018, "%-17s Effective Overhead", ""); print_size("Routing tables:", rp_memsize(rt_table_pool)); print_size("Route attributes:", rp_memsize(rta_pool)); print_size("Protocols:", rp_memsize(proto_pool)); diff --git a/sysdep/unix/alloc.c b/sysdep/unix/alloc.c index 77c504e3..d18f286b 100644 --- a/sysdep/unix/alloc.c +++ b/sysdep/unix/alloc.c @@ -8,6 +8,8 @@ #include "nest/bird.h" #include "lib/resource.h" +#include "lib/lists.h" +#include "lib/event.h" #include "sysdep/unix/io-loop.h" diff --git a/sysdep/unix/io-loop.c b/sysdep/unix/io-loop.c index 732ea64d..a9927b39 100644 --- a/sysdep/unix/io-loop.c +++ b/sysdep/unix/io-loop.c @@ -340,6 +340,7 @@ birdloop_init(void) timers_init(&main_birdloop.time, &root_pool); root_pool.loop = &main_birdloop; + main_birdloop.pool = &root_pool; birdloop_enter_locked(&main_birdloop); } |