]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements command that shows memory usage.
authorOndrej Zajicek <santiago@crfreenet.org>
Wed, 2 Jun 2010 20:20:40 +0000 (22:20 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 2 Jun 2010 20:20:40 +0000 (22:20 +0200)
13 files changed:
doc/reply_codes
lib/event.c
lib/mempool.c
lib/resource.c
lib/resource.h
lib/slab.c
nest/cmds.c
nest/cmds.h
nest/config.Y
nest/proto.c
nest/rt-attr.c
nest/rt-table.c
sysdep/unix/io.c

index 22e0fd2d682244fb651abe1ab4d04a48ecc7bc62..a0db2cad59202f87638edaa79a4b2b6a0ac86ec6 100644 (file)
@@ -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
index ce5e81c89633694eb80277332da35216fa705848..916cf55c3ac8c5301ac73d57240481c0ebbaf9dc 100644 (file)
@@ -50,6 +50,7 @@ static struct resclass ev_class = {
   sizeof(event),
   (void (*)(resource *)) ev_postpone,
   ev_dump,
+  NULL,
   NULL
 };
 
index 0cb06b586605b755e0be7b828c7eac7ab01da647..65072f9acb7e21cfb465dae069bb7d22cdd041cd 100644 (file)
@@ -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)
 {
index 5ba23f18521d241f5e7ba6e3be0521ae96231f40..24164ec2dd3217bc8ddd3e5520671c5f3f1ac05c 100644 (file)
@@ -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
 };
 
 /**
index 8dd441f0f75f0200cebdafe5a0ef272232c64d65..5cb5e274e5157b4dd424b9b54b0fa9453ab20083 100644 (file)
@@ -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 */
 
index 8cce52fe7a122cf17389dc761f0ab5445f908560..af6b50b049606a9ede01f613499ac44d40ad32ed 100644 (file)
@@ -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)
 {
index 16fbba612a1fa06c10795a6de5d5125923526d5d..8ac32096d78be81cb27830ce570fbd29974bb836 100644 (file)
@@ -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, "");
+}
index ae1c9e2e66501e4e29f0ffdb242812346f964355..3b86a92424c9d511122a814b2b55bcefc310e22b 100644 (file)
@@ -8,3 +8,4 @@
 
 void cmd_show_status(void);
 void cmd_show_symbols(struct symbol *sym);
+void cmd_show_memory(void);
index 7bb05259d16b45fa82e87119948337cab9c21e0a..a8e6bf8cd74abb1e4daf9c39be828bd3e9668bbb 100644 (file)
@@ -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); } ;
 
index 46147a4e138793937b22efdf831e91c6974857e7..c9e2f5c7bfc7216c3115a38f1a17590ed6c967b7 100644 (file)
@@ -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;
index b553475ad0db3f042950be268a15af864f0c928c..abd49c7066e3f1746d2db69df3e241c9014baffc 100644 (file)
@@ -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];
 
index 87365742439c14b04d6d6eac8871df8f5f64dfa9..8cca42a7fbb7c618a6f957e782b567b2ae985a99 100644 (file)
 #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);
index 8058fa66515cb214aede0dfe7c4d85865a30043f..690c8fc9abd4db3206627a2a7a6b1ce7b39d53f9 100644 (file)
@@ -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
 };