summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2021-11-15 22:48:24 +0100
committerMaria Matejka <mq@ucw.cz>2021-11-22 19:05:44 +0100
commitdf476c2e5d0684c3beab9058bc85d627b0e4d7ed (patch)
tree523c5c08a86ea377367d2d2b56a01167d842cb39
parent0fd1c1d091ee8e43eb0e15c67a92960ca581ed5f (diff)
Corking also feed start to keep BIRD running when refeeds would easily cause congestion
-rw-r--r--nest/proto.c2
-rw-r--r--nest/rt-table.c36
2 files changed, 26 insertions, 12 deletions
diff --git a/nest/proto.c b/nest/proto.c
index 8babedee..978582ca 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -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) {
diff --git a/nest/rt-table.c b/nest/rt-table.c
index f33b9153..a2f62df7 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -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)