summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-09-26 12:09:14 +0200
committerMaria Matejka <mq@ucw.cz>2022-09-26 12:09:14 +0200
commit6cfe2066ab024251936b119ab5c39a3892d8342a (patch)
tree2978b830b3deba0187ac7a6007bd6003b2f8e1d9
parentecaa3df3c4b090cceac4494658f80eb0a0b1e8b6 (diff)
Higher export settle times when route refresh is running.
This helps the route refresh procedures to finish or at least do more work before the exporters jump in and steal all the CPU time for themselves.
-rw-r--r--doc/bird.sgml8
-rw-r--r--nest/config.Y4
-rw-r--r--nest/rt-table.c32
-rw-r--r--nest/rt.h5
4 files changed, 42 insertions, 7 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 9399137c..0cfe19c4 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -706,6 +706,14 @@ to set options.
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-route-refresh-export-settle-time">route refresh export settle time <m/time/ <m/time/</tag>
+ Minimum and maximum settle times, respectively, for export announcements
+ (the same as above), valid when any channel is currently doing a route refresh.
+ This serves a purpose of even more aggresive change bundling, knowing that there
+ is some active process generating changes in a fast pace. If you don't want
+ this feature, set this to the same values as <ref id="rtable-export-settle-time" name="export settle time">.
+ Default values: <cf/100 ms 3 s/.
+
<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
diff --git a/nest/config.Y b/nest/config.Y
index a8e48cfe..f2904882 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -125,7 +125,7 @@ CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, AS)
CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE)
CF_KEYWORDS(CHECK, LINK)
-CF_KEYWORDS(CORK, SORTED, TRIE, MIN, MAX, ROA, SETTLE, TIME, GC, THRESHOLD, PERIOD)
+CF_KEYWORDS(CORK, SORTED, TRIE, MIN, MAX, ROA, ROUTE, REFRESH, SETTLE, TIME, GC, THRESHOLD, PERIOD)
/* For r_args_channel */
CF_KEYWORDS(IPV4, IPV4_MC, IPV4_MPLS, IPV6, IPV6_MC, IPV6_MPLS, IPV6_SADR, VPN4, VPN4_MC, VPN4_MPLS, VPN6, VPN6_MC, VPN6_MPLS, ROA4, ROA6, FLOW4, FLOW6, MPLS, PRI, SEC)
@@ -233,6 +233,8 @@ table_opt:
if ($3 > $4) cf_error("Cork low threshold must be lower than the high threshold.");
this_table->cork_threshold.low = $3;
this_table->cork_threshold.high = $4; }
+ | EXPORT SETTLE TIME settle { this_table->export_settle = $4; }
+ | ROUTE REFRESH EXPORT SETTLE TIME settle { this_table->export_rr_settle = $6; }
| DEBUG bool { this_table->debug = $2; }
;
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 7a21dc39..36d69d92 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -1440,6 +1440,13 @@ rt_announce_exports(struct settle *s)
}
static void
+rt_kick_export_settle(struct rtable_private *tab)
+{
+ tab->export_settle.cf = tab->rr_counter ? tab->config->export_rr_settle : tab->config->export_settle;
+ settle_kick(&tab->export_settle, tab->loop);
+}
+
+static void
rt_import_announce_exports(void *_hook)
{
struct rt_import_hook *hook = _hook;
@@ -2039,6 +2046,13 @@ rt_stop_import(struct rt_import_request *req, void (*stopped)(struct rt_import_r
rt_schedule_prune(tab);
rt_set_import_state(hook, TIS_STOP);
hook->stopped = stopped;
+
+ if (hook->stale_set != hook->stale_pruned)
+ tab->rr_counter -= (hook->stale_set - hook->stale_pruned - 1);
+ else
+ tab->rr_counter++;
+
+ hook->stale_set = hook->stale_pruned = hook->stale_pruning = hook->stale_valid = 0;
}
}
@@ -2301,6 +2315,7 @@ rt_refresh_begin(struct rt_import_request *req)
e->rte.stale_cycle = 0;
}
FIB_WALK_END;
+ tab->rr_counter -= (hook->stale_set - hook->stale_pruned - 1);
hook->stale_set = 1;
hook->stale_valid = 0;
hook->stale_pruned = 0;
@@ -2311,6 +2326,7 @@ rt_refresh_begin(struct rt_import_request *req)
/* Let's reserve the stale_cycle zero value for always-invalid routes */
hook->stale_set = 1;
hook->stale_valid = 0;
+ tab->rr_counter++;
}
if (req->trace_routes & D_STATES)
@@ -2514,7 +2530,7 @@ rt_flag_handler(struct birdloop_flag_handler *fh, u32 flags)
rt_next_hop_update(tab);
if (flags & RTF_EXPORT)
- settle_kick(&tab->export_settle, tab->loop);
+ rt_kick_export_settle(tab);
if (flags & RTF_CLEANUP)
{
@@ -2947,7 +2963,7 @@ again:
FIB_ITERATE_END;
rt_trace(tab, D_EVENTS, "Prune done, scheduling export timer");
- settle_kick(&tab->export_settle, tab->loop);
+ rt_kick_export_settle(tab);
#ifdef DEBUGGING
fib_check(&tab->fib);
@@ -2997,9 +3013,11 @@ again:
ih->flush_seq = tab->exporter.next_seq;
rt_set_import_state(ih, TIS_WAITING);
flushed_channels++;
+ tab->rr_counter--;
}
else if (ih->stale_pruning != ih->stale_pruned)
{
+ tab->rr_counter -= (ih->stale_pruned - ih->stale_pruning);
ih->stale_pruned = ih->stale_pruning;
if (ih->req->trace_routes & D_STATES)
log(L_TRACE "%s: table prune after refresh end [%u]", ih->req->name, ih->stale_pruned);
@@ -3809,7 +3827,7 @@ 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))
- settle_kick(&tab->export_settle, tab->loop);
+ rt_kick_export_settle(tab);
tab->nhu_corked = tab->nhu_state;
tab->nhu_state = 0;
@@ -3847,7 +3865,7 @@ rt_next_hop_update(struct rtable_private *tab)
/* Finished NHU, cleanup */
rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer");
- settle_kick(&tab->export_settle, tab->loop);
+ rt_kick_export_settle(tab);
/* State change:
* NHU_DIRTY -> NHU_SCHEDULED
@@ -3903,6 +3921,10 @@ rt_new_table(struct symbol *s, uint addr_type)
.min = 1 MS,
.max = 100 MS,
};
+ c->export_rr_settle = (struct settle_config) {
+ .min = 100 MS,
+ .max = 3 S,
+ };
c->debug = new_config->table_debug;
add_tail(&new_config->tables, &c->n);
@@ -4014,8 +4036,6 @@ 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;
diff --git a/nest/rt.h b/nest/rt.h
index d53f54e1..6ee2ce9b 100644
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -65,6 +65,8 @@ struct rtable_config {
byte debug; /* Whether to log */
struct rt_cork_threshold cork_threshold; /* Cork threshold values */
struct settle_config export_settle; /* Export announcement settler */
+ struct settle_config export_rr_settle;/* Export announcement settler config valid when any
+ route refresh is running */
};
struct rt_export_hook;
@@ -136,6 +138,9 @@ struct rtable_private {
btime last_rt_change; /* Last time when route changed */
btime gc_time; /* Time of last GC */
uint gc_counter; /* Number of operations since last GC */
+ uint rr_counter; /* Number of currently running route refreshes,
+ in fact sum of (stale_set - stale_pruned) over all importers
+ + one for each TIS_FLUSHING importer */
byte prune_state; /* Table prune state, 1 -> scheduled, 2-> running */
byte prune_trie; /* Prune prefix trie during next table prune */
byte nhu_state; /* Next Hop Update state */