Implements command that shows memory usage.
This commit is contained in:
parent
4461b89791
commit
acb60628f5
13 changed files with 143 additions and 9 deletions
|
@ -44,6 +44,7 @@ Reply codes of BIRD command-line interface
|
|||
1015 Show ospf interface
|
||||
1016 Show ospf state/topology
|
||||
1017 Show ospf lsadb
|
||||
1018 Show memory
|
||||
|
||||
8000 Reply too long
|
||||
8001 Route not found
|
||||
|
|
|
@ -50,6 +50,7 @@ static struct resclass ev_class = {
|
|||
sizeof(event),
|
||||
(void (*)(resource *)) ev_postpone,
|
||||
ev_dump,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -43,13 +43,15 @@ 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 resclass lp_class = {
|
||||
"LinPool",
|
||||
sizeof(struct linpool),
|
||||
lp_free,
|
||||
lp_dump,
|
||||
lp_lookup
|
||||
lp_lookup,
|
||||
lp_memsize
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -235,6 +237,24 @@ lp_dump(resource *r)
|
|||
m->total_large);
|
||||
}
|
||||
|
||||
static size_t
|
||||
lp_memsize(resource *r)
|
||||
{
|
||||
linpool *m = (linpool *) r;
|
||||
struct lp_chunk *c;
|
||||
int cnt = 0;
|
||||
|
||||
for(c=m->first; c; c=c->next)
|
||||
cnt++;
|
||||
for(c=m->first_large; c; c=c->next)
|
||||
cnt++;
|
||||
|
||||
return ALLOC_OVERHEAD + sizeof(struct linpool) +
|
||||
cnt * (ALLOC_OVERHEAD + sizeof(sizeof(struct lp_chunk))) +
|
||||
m->total + m->total_large;
|
||||
}
|
||||
|
||||
|
||||
static resource *
|
||||
lp_lookup(resource *r, unsigned long a)
|
||||
{
|
||||
|
|
|
@ -37,13 +37,15 @@ struct pool {
|
|||
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 resclass pool_class = {
|
||||
"Pool",
|
||||
sizeof(pool),
|
||||
pool_free,
|
||||
pool_dump,
|
||||
pool_lookup
|
||||
pool_lookup,
|
||||
pool_memsize
|
||||
};
|
||||
|
||||
pool root_pool;
|
||||
|
@ -95,6 +97,19 @@ pool_dump(resource *P)
|
|||
indent -= 3;
|
||||
}
|
||||
|
||||
static size_t
|
||||
pool_memsize(resource *P)
|
||||
{
|
||||
pool *p = (pool *) P;
|
||||
resource *r;
|
||||
size_t sum = sizeof(pool) + ALLOC_OVERHEAD;
|
||||
|
||||
WALK_LIST(r, p->inside)
|
||||
sum += rmemsize(r);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static resource *
|
||||
pool_lookup(resource *P, unsigned long a)
|
||||
{
|
||||
|
@ -177,6 +192,17 @@ rdump(void *res)
|
|||
debug("NULL\n");
|
||||
}
|
||||
|
||||
size_t
|
||||
rmemsize(void *res)
|
||||
{
|
||||
resource *r = res;
|
||||
if (!r)
|
||||
return 0;
|
||||
if (!r->class->memsize)
|
||||
return r->class->size + ALLOC_OVERHEAD;
|
||||
return r->class->memsize(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* ralloc - create a resource
|
||||
* @p: pool to create the resource in
|
||||
|
@ -277,12 +303,20 @@ mbl_lookup(resource *r, unsigned long a)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static size_t
|
||||
mbl_memsize(resource *r)
|
||||
{
|
||||
struct mblock *m = (struct mblock *) r;
|
||||
return ALLOC_OVERHEAD + sizeof(struct mblock) + m->size;
|
||||
}
|
||||
|
||||
static struct resclass mb_class = {
|
||||
"Memory",
|
||||
0,
|
||||
mbl_free,
|
||||
mbl_debug,
|
||||
mbl_lookup
|
||||
mbl_lookup,
|
||||
mbl_memsize
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,8 +26,12 @@ 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 */
|
||||
};
|
||||
|
||||
/* Estimate of system allocator overhead per item, for memory consumtion stats */
|
||||
#define ALLOC_OVERHEAD 8
|
||||
|
||||
/* Generic resource manipulation */
|
||||
|
||||
typedef struct pool pool;
|
||||
|
@ -36,6 +40,7 @@ void resource_init(void);
|
|||
pool *rp_new(pool *, char *); /* Create new pool */
|
||||
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 */
|
||||
void rlookup(unsigned long); /* Look up address (only for debugging) */
|
||||
void rmove(void *, pool *); /* Move to a different pool */
|
||||
|
||||
|
|
38
lib/slab.c
38
lib/slab.c
|
@ -41,6 +41,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);
|
||||
|
||||
#ifdef FAKE_SLAB
|
||||
|
||||
|
@ -58,7 +59,8 @@ static struct resclass sl_class = {
|
|||
"FakeSlab",
|
||||
sizeof(struct slab),
|
||||
slab_free,
|
||||
slab_dump
|
||||
slab_dump,
|
||||
slab_memsize
|
||||
};
|
||||
|
||||
struct sl_obj {
|
||||
|
@ -116,6 +118,20 @@ slab_dump(resource *r)
|
|||
debug("(%d objects per %d bytes)\n", cnt, s->size);
|
||||
}
|
||||
|
||||
static size_t
|
||||
slab_memsize(resource *r)
|
||||
{
|
||||
slab *s = (slab *) r;
|
||||
int cnt = 0;
|
||||
struct sl_obj *o;
|
||||
|
||||
WALK_LIST(o, s->objs)
|
||||
cnt++;
|
||||
|
||||
return ALLOC_OVERHEAD + sizeof(struct slab) + cnt * (ALLOC_OVERHEAD + s->size);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
|
@ -136,7 +152,8 @@ static struct resclass sl_class = {
|
|||
sizeof(struct slab),
|
||||
slab_free,
|
||||
slab_dump,
|
||||
slab_lookup
|
||||
slab_lookup,
|
||||
slab_memsize
|
||||
};
|
||||
|
||||
struct sl_head {
|
||||
|
@ -324,6 +341,23 @@ 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
|
||||
slab_memsize(resource *r)
|
||||
{
|
||||
slab *s = (slab *) r;
|
||||
int 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 * (ALLOC_OVERHEAD + SLAB_SIZE);
|
||||
}
|
||||
|
||||
static resource *
|
||||
slab_lookup(resource *r, unsigned long a)
|
||||
{
|
||||
|
|
30
nest/cmds.c
30
nest/cmds.c
|
@ -11,6 +11,7 @@
|
|||
#include "conf/conf.h"
|
||||
#include "nest/cmds.h"
|
||||
#include "lib/string.h"
|
||||
#include "lib/resource.h"
|
||||
|
||||
void
|
||||
cmd_show_status(void)
|
||||
|
@ -47,3 +48,32 @@ cmd_show_symbols(struct symbol *sym)
|
|||
cli_msg(0, "");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_size(char *dsc, size_t val)
|
||||
{
|
||||
char *px = " kMG";
|
||||
int i = 0;
|
||||
while ((val >= 10000) && (i < 3))
|
||||
{
|
||||
val = (val + 512) / 1024;
|
||||
i++;
|
||||
}
|
||||
|
||||
cli_msg(-1018, "%-17s %4u %cB", dsc, (unsigned) val, px[i]);
|
||||
}
|
||||
|
||||
extern pool *rt_table_pool;
|
||||
extern pool *rta_pool;
|
||||
extern pool *proto_pool;
|
||||
|
||||
void
|
||||
cmd_show_memory(void)
|
||||
{
|
||||
cli_msg(-1018, "BIRD memory usage");
|
||||
print_size("Routing tables:", rmemsize(rt_table_pool));
|
||||
print_size("Route attributes:", rmemsize(rta_pool));
|
||||
print_size("Protocols:", rmemsize(proto_pool));
|
||||
print_size("Total:", rmemsize(&root_pool));
|
||||
cli_msg(0, "");
|
||||
}
|
||||
|
|
|
@ -8,3 +8,4 @@
|
|||
|
||||
void cmd_show_status(void);
|
||||
void cmd_show_symbols(struct symbol *sym);
|
||||
void cmd_show_memory(void);
|
||||
|
|
|
@ -45,7 +45,7 @@ CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILT
|
|||
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
|
||||
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE)
|
||||
CF_KEYWORDS(LISTEN, BGP, V6ONLY, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
|
||||
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT)
|
||||
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY)
|
||||
|
||||
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
|
||||
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
|
||||
|
@ -324,6 +324,9 @@ CF_CLI_HELP(SHOW, ..., [[Show status information]])
|
|||
CF_CLI(SHOW STATUS,,, [[Show router status]])
|
||||
{ cmd_show_status(); } ;
|
||||
|
||||
CF_CLI(SHOW MEMORY,,, [[Show memory usage]])
|
||||
{ cmd_show_memory(); } ;
|
||||
|
||||
CF_CLI(SHOW PROTOCOLS, proto_patt2, [<protocol> | \"<pattern>\"], [[Show routing protocols]])
|
||||
{ proto_apply_cmd($3, proto_cmd_show, 0, 0); } ;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "nest/cli.h"
|
||||
#include "filter/filter.h"
|
||||
|
||||
static pool *proto_pool;
|
||||
pool *proto_pool;
|
||||
|
||||
static list protocol_list;
|
||||
static list proto_list;
|
||||
|
|
|
@ -54,8 +54,9 @@
|
|||
#include "lib/resource.h"
|
||||
#include "lib/string.h"
|
||||
|
||||
pool *rta_pool;
|
||||
|
||||
static slab *rta_slab;
|
||||
static pool *rta_pool;
|
||||
|
||||
struct protocol *attr_class_to_protocol[EAP_MAX];
|
||||
|
||||
|
|
|
@ -43,10 +43,11 @@
|
|||
#include "lib/string.h"
|
||||
#include "lib/alloca.h"
|
||||
|
||||
pool *rt_table_pool;
|
||||
|
||||
static slab *rte_slab;
|
||||
static linpool *rte_update_pool;
|
||||
|
||||
static pool *rt_table_pool;
|
||||
static list routing_tables;
|
||||
|
||||
static void rt_format_via(rte *e, byte *via);
|
||||
|
|
|
@ -76,6 +76,7 @@ static struct resclass rf_class = {
|
|||
sizeof(struct rfile),
|
||||
rf_free,
|
||||
rf_dump,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -203,6 +204,7 @@ static struct resclass tm_class = {
|
|||
sizeof(timer),
|
||||
tm_free,
|
||||
tm_dump,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -573,6 +575,7 @@ static struct resclass sk_class = {
|
|||
sizeof(sock),
|
||||
sk_free,
|
||||
sk_dump,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue