diff options
author | Maria Matejka <mq@ucw.cz> | 2021-11-15 22:48:24 +0100 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2021-11-22 19:05:44 +0100 |
commit | df476c2e5d0684c3beab9058bc85d627b0e4d7ed (patch) | |
tree | 523c5c08a86ea377367d2d2b56a01167d842cb39 | |
parent | 0fd1c1d091ee8e43eb0e15c67a92960ca581ed5f (diff) |
Corking also feed start to keep BIRD running when refeeds would easily cause congestion
-rw-r--r-- | nest/proto.c | 2 | ||||
-rw-r--r-- | nest/rt-table.c | 36 |
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) |