]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixed the export settle timer to be actually a settle timer
authorMaria Matejka <mq@ucw.cz>
Wed, 21 Sep 2022 16:43:44 +0000 (18:43 +0200)
committerMaria Matejka <mq@ucw.cz>
Wed, 21 Sep 2022 16:47:43 +0000 (18:47 +0200)
doc/bird.sgml
nest/rt-table.c
nest/rt.h

index 54d67e8972423c66302b14d86864e33d57ce47b5..9399137cf98e93f6d18a04a74b4969a16e40fc9d 100644 (file)
@@ -699,6 +699,13 @@ to set options.
         threshold, the more memory can get used. In most cases, the defaults
        should work for you. Default: 128, 512.
 
+       <tag><label id="rtable-export-settle-time">export settle time <m/time/ <m/time/</tag>
+       Minimum and maximum settle times, respectively, for export announcements.
+       When multiple routes are changing, this mechanism waits for the changes
+       to settle before waking up sleeping export threads but if the changes are coming
+       steadily, BIRD isn't waiting forever; at most the maximum time.
+       Default values: <cf/1 ms 100 ms/. You have to always provide both values.
+
        <tag><label id="rtable-debug">debug all|off|{ states|routes|events [, <m/.../] }</tag>
        Set table debugging options. Each table can write some trace messages
        into log with category <cf/trace/. You can request <cf/all/ trace messages
index b8dc6866e6dbc845a3229c7d0e2fa847d0a77d0a..051bc949a0cfd6fb6dabce25f7e8ef6dbdbe4fb2 100644 (file)
@@ -1423,9 +1423,9 @@ rt_send_export_event(struct rt_export_hook *hook)
 }
 
 static void
-rt_announce_exports(timer *tm)
+rt_announce_exports(struct settle *s)
 {
-  RT_LOCKED((rtable *) tm->data, tab)
+  RT_LOCKED(RT_PUB(SKIP_BACK(struct rtable_private, export_settle, s)), tab)
     if (!EMPTY_LIST(tab->exporter.pending))
     {
       struct rt_export_hook *c; node *n;
@@ -1439,13 +1439,6 @@ rt_announce_exports(timer *tm)
     }
 }
 
-static void
-rt_kick_announce_exports(struct rtable_private *tab)
-{
-  if (!tm_active(tab->export_timer))
-    tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop);
-}
-
 static void
 rt_import_announce_exports(void *_hook)
 {
@@ -2521,7 +2514,7 @@ rt_flag_handler(struct birdloop_flag_handler *fh, u32 flags)
       rt_next_hop_update(tab);
 
     if (flags & RTF_EXPORT)
-      rt_kick_announce_exports(tab);
+      settle_kick(&tab->export_settle, tab->loop);
 
     if (flags & RTF_CLEANUP)
     {
@@ -2789,10 +2782,11 @@ rt_setup(pool *pp, struct rtable_config *cf)
 
   t->fh = (struct birdloop_flag_handler) { .hook = rt_flag_handler, };
   t->nhu_uncork_event = ev_new_init(p, rt_nhu_uncork, t);
-  t->export_timer = tm_new_init(p, rt_announce_exports, t, 0, 0);
   t->prune_timer = tm_new_init(p, rt_prune_timer, t, 0, 0);
   t->last_rt_change = t->gc_time = current_time();
 
+  t->export_settle = SETTLE_INIT(&cf->export_settle, rt_announce_exports, NULL);
+
   t->exporter = (struct rt_table_exporter) {
     .e = {
       .class = &rt_table_exporter_class,
@@ -2944,8 +2938,7 @@ again:
   FIB_ITERATE_END;
 
   rt_trace(tab, D_EVENTS, "Prune done, scheduling export timer");
-  if (!tm_active(tab->export_timer))
-    tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop);
+  settle_kick(&tab->export_settle, tab->loop);
 
 #ifdef DEBUGGING
   fib_check(&tab->fib);
@@ -3172,7 +3165,7 @@ done:;
     birdloop_flag(tab->loop, RTF_CLEANUP);
 
   if (EMPTY_LIST(tab->exporter.pending))
-    tm_stop(tab->export_timer);
+    settle_cancel(&tab->export_settle);
 }
 
 static void
@@ -3806,9 +3799,8 @@ rt_next_hop_update(struct rtable_private *tab)
   {
     rt_trace(tab, D_STATES, "Next hop updater corked");
     if ((tab->nhu_state & NHU_RUNNING)
-       && !EMPTY_LIST(tab->exporter.pending)
-       && !tm_active(tab->export_timer))
-      tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop);
+       && !EMPTY_LIST(tab->exporter.pending))
+      settle_kick(&tab->export_settle, tab->loop);
 
     tab->nhu_corked = tab->nhu_state;
     tab->nhu_state = 0;
@@ -3846,9 +3838,7 @@ rt_next_hop_update(struct rtable_private *tab)
 
   /* Finished NHU, cleanup */
   rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer");
-
-  if (!tm_active(tab->export_timer))
-    tm_start_in(tab->export_timer, tab->config->export_settle_time, tab->loop);
+  settle_kick(&tab->export_settle, tab->loop);
 
   /* State change:
    *   NHU_DIRTY   -> NHU_SCHEDULED
@@ -3900,6 +3890,10 @@ rt_new_table(struct symbol *s, uint addr_type)
   c->gc_period = (uint) -1;    /* set in rt_postconfig() */
   c->cork_threshold.low = 128;
   c->cork_threshold.high = 512;
+  c->export_settle = (struct settle_config) {
+    .min = 1 MS,
+    .max = 100 MS,
+  };
   c->debug = new_config->table_debug;
 
   add_tail(&new_config->tables, &c->n);
@@ -4011,6 +4005,8 @@ rt_reconfigure(struct rtable_private *tab, struct rtable_config *new, struct rta
   tab->name = new->name;
   tab->config = new;
 
+  tab->export_settle.cf = new->export_settle;
+
   if (tab->hostcache)
     tab->hostcache->req.trace_routes = new->debug;
 
index c80b1b33e4e2176b7e0802a3da274cc3877e5ba2..d53f54e15f0072ef7e6552900869af3e7f64f2a8 100644 (file)
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -20,6 +20,7 @@
 #include "lib/event.h"
 #include "lib/rcu.h"
 #include "lib/io-loop.h"
+#include "lib/settle.h"
 
 #include <stdatomic.h>
 
@@ -62,8 +63,8 @@ struct rtable_config {
   byte sorted;                         /* Routes of network are sorted according to rte_better() */
   byte trie_used;                      /* Rtable has attached trie */
   byte debug;                          /* Whether to log */
-  btime export_settle_time;            /* Delay before exports are announced */
   struct rt_cork_threshold cork_threshold;     /* Cork threshold values */
+  struct settle_config export_settle;  /* Export announcement settler */
 };
 
 struct rt_export_hook;
@@ -129,7 +130,7 @@ struct rtable_private {
                                         * obstacle from this routing table.
                                         */
   struct event *nhu_uncork_event;      /* Helper event to schedule NHU on uncork */
-  struct timer *export_timer;          /* Timer for export batching */
+  struct settle export_settle;         /* Export batching settle timer */
   struct timer *prune_timer;           /* Timer for periodic pruning / GC */
   struct birdloop_flag_handler fh;     /* Handler for simple events */
   btime last_rt_change;                        /* Last time when route changed */