]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Corking also feed start to keep BIRD running when refeeds would easily cause congestion
authorMaria Matejka <mq@ucw.cz>
Mon, 15 Nov 2021 21:48:24 +0000 (22:48 +0100)
committerMaria Matejka <mq@ucw.cz>
Mon, 22 Nov 2021 18:05:44 +0000 (19:05 +0100)
nest/proto.c
nest/rt-table.c

index 8babedee45bfc29b2aa1420edf943615ba4f8996..978582ca595d71d15525549f8c62ad5ecdbe49eb 100644 (file)
@@ -883,6 +883,7 @@ channel_setup_in_table(struct channel *c, int best)
 
   cat->tab_cf.name = cat->name;
   cat->tab_cf.addr_type = c->net_type;
+  cat->tab_cf.cork_limit = 4 * page_size / sizeof(struct rt_pending_export);
 
   c->in_table = &cat->cat;
   c->in_table->push = (struct rt_import_request) {
@@ -926,6 +927,7 @@ channel_setup_out_table(struct channel *c)
 
   cat->tab_cf.name = cat->name;
   cat->tab_cf.addr_type = c->net_type;
+  cat->tab_cf.cork_limit = 4 * page_size / sizeof(struct rt_pending_export);
 
   c->out_table = &cat->cat;
   c->out_table->push = (struct rt_import_request) {
index f33b9153b8611fe10bb5231eb2bd310cfd6129c9..a2f62df7b8c24bd38b51044ed678397ab40c5dcf 100644 (file)
@@ -1099,8 +1099,13 @@ rte_announce(rtable_private *tab, net *net, struct rte_storage *new, struct rte_
   if (tab->first_export == NULL)
     tab->first_export = rpe;
 
-  if ((tab->first_export->seq + tab->config->cork_limit <= tab->next_export_seq) && !tab->cork_active)
+  if (!EMPTY_LIST(tab->exports) &&
+      (tab->first_export->seq + tab->config->cork_limit <= tab->next_export_seq) &&
+      !tab->cork_active)
   {
+    if (config->table_debug)
+      log(L_TRACE "%s: cork activated", tab->name);
+
     ev_cork(&rt_cork);
     tab->cork_active = 1;
   }
@@ -1777,22 +1782,14 @@ rt_request_export(rtable *t, struct rt_export_request *req)
 
   rt_set_export_state(hook, TES_HUNGRY);
 
-  struct rt_pending_export *rpe = rt_last_export(tab);
-  DBG("store hook=%p last_export=%p seq=%lu\n", hook, rpe, rpe ? rpe->seq : 0);
-  atomic_store_explicit(&hook->last_export, rpe, memory_order_relaxed);
-
   hook->n = (node) {};
   add_tail(&tab->exports, &hook->n);
 
-  FIB_ITERATE_INIT(&hook->feed_fit, &tab->fib);
-
   DBG("New export hook %p req %p in table %s uc=%u\n", hook, req, tab->name, tab->use_count);
 
   hook->event = ev_new_init(p, rt_feed_channel, hook);
   RT_UNLOCK(t);
 
-  rt_set_export_state(hook, TES_FEEDING);
-  ASSERT_DIE(hook->export_state == TES_FEEDING);
   rt_send_export_event(hook);
 }
 
@@ -2506,6 +2503,8 @@ done:;
   {
     tab->cork_active = 0;
     ev_uncork(&rt_cork);
+    if (config->table_debug)
+      log(L_TRACE "%s: cork released", tab->name);
   }
 }
 
@@ -2955,10 +2954,23 @@ rt_feed_channel(void *data)
   struct fib_iterator *fit = &c->feed_fit;
   int max_feed = 256;
 
-  RT_LOCK(c->table);
-  rtable_private *tab = RT_PRIV(c->table);
+  rtable_private *tab;
+  if (c->export_state == TES_HUNGRY)
+  {
+    rt_set_export_state(c, TES_FEEDING);
+
+    tab = RT_LOCK(c->table);
+
+    struct rt_pending_export *rpe = rt_last_export(tab);
+    DBG("store hook=%p last_export=%p seq=%lu\n", c, rpe, rpe ? rpe->seq : 0);
+    atomic_store_explicit(&c->last_export, rpe, memory_order_relaxed);
+
+    FIB_ITERATE_INIT(&c->feed_fit, &tab->fib);
+  }
+  else
+    tab = RT_LOCK(c->table);
 
-  ASSERT(atomic_load_explicit(&c->export_state, memory_order_relaxed) == TES_FEEDING);
+  ASSERT_DIE(c->export_state == TES_FEEDING);
 
 redo:
   FIB_ITERATE_START(&tab->fib, fit, net, n)