mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-10 05:08:42 +00:00
Merge branch 'master' into HEAD
This commit is contained in:
commit
b50224a003
@ -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;
|
||||
|
||||
|
@ -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)),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
33
lib/slab.c
33
lib/slab.c
@ -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)
|
||||
heads++;
|
||||
WALK_LIST(h, s->partial_heads)
|
||||
heads++;
|
||||
WALK_LIST(h, s->full_heads)
|
||||
heads++;
|
||||
|
||||
return ALLOC_OVERHEAD + sizeof(struct slab) + heads * page_size;
|
||||
size_t items = heads * s->objs_per_slab;
|
||||
|
||||
WALK_LIST(h, s->partial_heads)
|
||||
{
|
||||
heads++;
|
||||
items += h->num_full;
|
||||
}
|
||||
|
||||
WALK_LIST(h, s->empty_heads)
|
||||
heads++;
|
||||
|
||||
size_t eff = items * s->obj_size;
|
||||
|
||||
return (struct resmem) {
|
||||
.effective = eff,
|
||||
.overhead = ALLOC_OVERHEAD + sizeof(struct slab) + heads * page_size - eff,
|
||||
};
|
||||
}
|
||||
|
||||
static resource *
|
||||
|
38
nest/cmds.c
38
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));
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user