]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Garbage collector events and counters are now per table and one day
authorMartin Mares <mj@ucw.cz>
Sat, 4 Mar 2000 22:21:06 +0000 (22:21 +0000)
committerMartin Mares <mj@ucw.cz>
Sat, 4 Mar 2000 22:21:06 +0000 (22:21 +0000)
they can be made configurable if it turns out to be useful.

nest/config.Y
nest/route.h
nest/rt-table.c
sysdep/unix/krt.c

index bc2a3fec438e27da41e1d6fc45cad43b3a18e41f..391107609316f739e872cd630cf006b7c13bc251 100644 (file)
@@ -61,11 +61,7 @@ idval:
 CF_ADDTO(conf, newtab)
 
 newtab: TABLE SYM {
-     struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
-     struct symbol *s = $2;
-     cf_define_symbol(s, SYM_TABLE, c);
-     c->name = s->name;
-     add_tail(&new_config->tables, &c->n);
+   rt_new_table($2);
    }
  ;
 
index 74fbf9ce52f43c948e242e2ff5f7890d4bb42350..375ea9bf746ce6407eabf71fc05d4d8643221a04 100644 (file)
@@ -113,6 +113,8 @@ struct rtable_config {
   char *name;
   struct rtable *table;
   struct proto_config *krt_attached;   /* Kernel syncer attached to this table */
+  int gc_max_ops;                      /* Maximum number of operations before GC is run */
+  int gc_min_time;                     /* Minimum time between two consecutive GC runs */
 };
 
 typedef struct rtable {
@@ -122,10 +124,14 @@ typedef struct rtable {
   list hooks;                          /* List of announcement hooks */
   int pipe_busy;                       /* Pipe loop detection */
   int use_count;                       /* Number of protocols using this table */
+  struct rtable_config *config;                /* Configuration of this table */
   struct config *deleted;              /* Table doesn't exist in current configuration,
                                         * delete as soon as use_count becomes 0 and remove
                                         * obstacle from this routing table.
                                         */
+  struct event *gc_event;              /* Garbage collector event */
+  int gc_counter;                      /* Number of operations since last GC */
+  bird_clock_t gc_time;                        /* Time of last GC */
 } rtable;
 
 typedef struct network {
@@ -179,7 +185,7 @@ void rt_preconfig(struct config *);
 void rt_commit(struct config *new, struct config *old);
 void rt_lock_table(rtable *);
 void rt_unlock_table(rtable *);
-void rt_setup(pool *, rtable *, char *);
+void rt_setup(pool *, rtable *, char *, struct rtable_config *);
 static inline net *net_find(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_find(&tab->fib, &addr, len); }
 static inline net *net_get(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_get(&tab->fib, &addr, len); }
 rte *rte_find(net *net, struct proto *p);
@@ -195,6 +201,7 @@ void rt_dump_all(void);
 void rt_feed_baby(struct proto *p);
 void rt_prune(rtable *tab);
 void rt_prune_all(void);
+struct rtable_config *rt_new_table(struct symbol *s);
 
 struct rt_show_data {
   ip_addr prefix;
index 4c406cf7c3dd0ccd4e13bacd46062fc635550a2c..b77047d9668bf47be95c91d0c73f245724c0e175 100644 (file)
 static slab *rte_slab;
 static linpool *rte_update_pool;
 
-#define RT_GC_MIN_TIME 5               /* FIXME: Make configurable */
-#define RT_GC_MIN_COUNT 100
-
 static pool *rt_table_pool;
 static list routing_tables;
-static event *rt_gc_event;
-static bird_clock_t rt_last_gc;
-static int rt_gc_counter;
 
 static void
 rte_init(struct fib_node *N)
@@ -42,15 +36,6 @@ rte_init(struct fib_node *N)
   n->routes = NULL;
 }
 
-void
-rt_setup(pool *p, rtable *t, char *name)
-{
-  bzero(t, sizeof(*t));
-  fib_init(&t->fib, p, sizeof(net), 0, rte_init);
-  t->name = name;
-  init_list(&t->hooks);
-}
-
 rte *
 rte_find(net *net, struct proto *p)
 {
@@ -277,8 +262,10 @@ rte_recalculate(rtable *table, net *net, struct proto *p, rte *new, ea_list *tmp
                }
              r->next = net->routes;
              net->routes = r;
-             if (!r && rt_gc_counter++ >= RT_GC_MIN_COUNT && rt_last_gc + RT_GC_MIN_TIME <= now)
-               ev_schedule(rt_gc_event);
+             if (!r &&
+                 table->gc_counter++ >= table->config->gc_max_ops &&
+                 table->gc_time + table->config->gc_min_time <= now)
+               ev_schedule(table->gc_event);
            }
        }
       if (new)                         /* Link in the new non-optimal route */
@@ -406,17 +393,32 @@ rt_dump_all(void)
 }
 
 static int
-rt_gc(void *unused)
+rt_gc(void *tab)
 {
-  rtable *t;
+  rtable *t = tab;
 
-  DBG("Entered routing table garbage collector after %d seconds and %d deletes\n", (int)(now - rt_last_gc), rt_gc_counter);
-  rt_prune_all();
-  rt_last_gc = now;
-  rt_gc_counter = 0;
+  DBG("Entered routing table garbage collector for %s after %d seconds and %d deletes\n",
+      t->name, (int)(now - t->gc_time), t->gc_counter);
+  rt_prune(t);
   return 0;
 }
 
+void
+rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
+{
+  bzero(t, sizeof(*t));
+  fib_init(&t->fib, p, sizeof(net), 0, rte_init);
+  t->name = name;
+  t->config = cf;
+  init_list(&t->hooks);
+  if (cf)
+    {
+      t->gc_event = ev_new(p);
+      t->gc_event->hook = rt_gc;
+      t->gc_event->data = t;
+    }
+}
+
 void
 rt_init(void)
 {
@@ -424,9 +426,6 @@ rt_init(void)
   rt_table_pool = rp_new(&root_pool, "Routing tables");
   rte_update_pool = lp_new(rt_table_pool, 4080);
   rte_slab = sl_new(rt_table_pool, sizeof(rte));
-  rt_last_gc = now;
-  rt_gc_event = ev_new(rt_table_pool);
-  rt_gc_event->hook = rt_gc;
   init_list(&routing_tables);
 }
 
@@ -462,6 +461,8 @@ again:
     }
   FIB_ITERATE_END(f);
   DBG("Pruned %d of %d routes and %d of %d networks\n", rcnt, rdel, ncnt, ndel);
+  tab->gc_counter = 0;
+  tab->gc_time = now;
 }
 
 void
@@ -473,17 +474,26 @@ rt_prune_all(void)
     rt_prune(t);
 }
 
+struct rtable_config *
+rt_new_table(struct symbol *s)
+{
+  struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
+
+  cf_define_symbol(s, SYM_TABLE, c);
+  c->name = s->name;
+  add_tail(&new_config->tables, &c->n);
+  c->gc_max_ops = 100;
+  c->gc_min_time = 5;
+  return c;
+}
+
 void
 rt_preconfig(struct config *c)
 {
   struct symbol *s = cf_find_symbol("master");
-  struct rtable_config *r = cfg_allocz(sizeof(struct rtable_config));
 
-  cf_define_symbol(s, SYM_TABLE, r);
-  r->name = s->name;
   init_list(&c->tables);
-  add_tail(&c->tables, &r->n);
-  c->master_rtc = r;
+  c->master_rtc = rt_new_table(s);
 }
 
 void
@@ -526,6 +536,7 @@ rt_commit(struct config *new, struct config *old)
                  r = sym->def;
                  r->table = ot;
                  ot->name = r->name;
+                 ot->config = r;
                }
              else
                {
@@ -544,7 +555,7 @@ rt_commit(struct config *new, struct config *old)
       {
        rtable *t = mb_alloc(rt_table_pool, sizeof(struct rtable));
        DBG("\t%s: created\n", r->name);
-       rt_setup(rt_table_pool, t, r->name);
+       rt_setup(rt_table_pool, t, r->name, r);
        add_tail(&routing_tables, &t->n);
        r->table = t;
       }
index 55986f0e6a127a4f507d8169d02f312d7bae8ac7..440ca362e5621c71325722236f7523ac869f9ac2 100644 (file)
@@ -385,7 +385,7 @@ static void
 krt_learn_init(struct krt_proto *p)
 {
   if (KRT_CF->learn)
-    rt_setup(p->p.pool, &p->krt_table, "Inherited");
+    rt_setup(p->p.pool, &p->krt_table, "Inherited", NULL);
 }
 
 static void