0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 02:01:55 +00:00

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.
This commit is contained in:
Maria Matejka 2022-09-26 12:09:14 +02:00
parent ecaa3df3c4
commit 6cfe2066ab
4 changed files with 42 additions and 7 deletions

View File

@ -706,6 +706,14 @@ to set options.
steadily, BIRD isn't waiting forever; at most the maximum time. 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. 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> <tag><label id="rtable-debug">debug all|off|{ states|routes|events [, <m/.../] }</tag>
Set table debugging options. Each table can write some trace messages Set table debugging options. Each table can write some trace messages
into log with category <cf/trace/. You can request <cf/all/ trace messages into log with category <cf/trace/. You can request <cf/all/ trace messages

View File

@ -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(GRACEFUL, RESTART, WAIT, MAX, AS)
CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE) CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE)
CF_KEYWORDS(CHECK, LINK) 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 */ /* 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) 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."); 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.low = $3;
this_table->cork_threshold.high = $4; } 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; } | DEBUG bool { this_table->debug = $2; }
; ;

View File

@ -1439,6 +1439,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 static void
rt_import_announce_exports(void *_hook) rt_import_announce_exports(void *_hook)
{ {
@ -2039,6 +2046,13 @@ rt_stop_import(struct rt_import_request *req, void (*stopped)(struct rt_import_r
rt_schedule_prune(tab); rt_schedule_prune(tab);
rt_set_import_state(hook, TIS_STOP); rt_set_import_state(hook, TIS_STOP);
hook->stopped = stopped; 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; e->rte.stale_cycle = 0;
} }
FIB_WALK_END; FIB_WALK_END;
tab->rr_counter -= (hook->stale_set - hook->stale_pruned - 1);
hook->stale_set = 1; hook->stale_set = 1;
hook->stale_valid = 0; hook->stale_valid = 0;
hook->stale_pruned = 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 */ /* Let's reserve the stale_cycle zero value for always-invalid routes */
hook->stale_set = 1; hook->stale_set = 1;
hook->stale_valid = 0; hook->stale_valid = 0;
tab->rr_counter++;
} }
if (req->trace_routes & D_STATES) 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); rt_next_hop_update(tab);
if (flags & RTF_EXPORT) if (flags & RTF_EXPORT)
settle_kick(&tab->export_settle, tab->loop); rt_kick_export_settle(tab);
if (flags & RTF_CLEANUP) if (flags & RTF_CLEANUP)
{ {
@ -2947,7 +2963,7 @@ again:
FIB_ITERATE_END; FIB_ITERATE_END;
rt_trace(tab, D_EVENTS, "Prune done, scheduling export timer"); rt_trace(tab, D_EVENTS, "Prune done, scheduling export timer");
settle_kick(&tab->export_settle, tab->loop); rt_kick_export_settle(tab);
#ifdef DEBUGGING #ifdef DEBUGGING
fib_check(&tab->fib); fib_check(&tab->fib);
@ -2997,9 +3013,11 @@ again:
ih->flush_seq = tab->exporter.next_seq; ih->flush_seq = tab->exporter.next_seq;
rt_set_import_state(ih, TIS_WAITING); rt_set_import_state(ih, TIS_WAITING);
flushed_channels++; flushed_channels++;
tab->rr_counter--;
} }
else if (ih->stale_pruning != ih->stale_pruned) else if (ih->stale_pruning != ih->stale_pruned)
{ {
tab->rr_counter -= (ih->stale_pruned - ih->stale_pruning);
ih->stale_pruned = ih->stale_pruning; ih->stale_pruned = ih->stale_pruning;
if (ih->req->trace_routes & D_STATES) if (ih->req->trace_routes & D_STATES)
log(L_TRACE "%s: table prune after refresh end [%u]", ih->req->name, ih->stale_pruned); 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"); rt_trace(tab, D_STATES, "Next hop updater corked");
if ((tab->nhu_state & NHU_RUNNING) if ((tab->nhu_state & NHU_RUNNING)
&& !EMPTY_LIST(tab->exporter.pending)) && !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_corked = tab->nhu_state;
tab->nhu_state = 0; tab->nhu_state = 0;
@ -3847,7 +3865,7 @@ rt_next_hop_update(struct rtable_private *tab)
/* Finished NHU, cleanup */ /* Finished NHU, cleanup */
rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer"); rt_trace(tab, D_EVENTS, "NHU done, scheduling export timer");
settle_kick(&tab->export_settle, tab->loop); rt_kick_export_settle(tab);
/* State change: /* State change:
* NHU_DIRTY -> NHU_SCHEDULED * NHU_DIRTY -> NHU_SCHEDULED
@ -3903,6 +3921,10 @@ rt_new_table(struct symbol *s, uint addr_type)
.min = 1 MS, .min = 1 MS,
.max = 100 MS, .max = 100 MS,
}; };
c->export_rr_settle = (struct settle_config) {
.min = 100 MS,
.max = 3 S,
};
c->debug = new_config->table_debug; c->debug = new_config->table_debug;
add_tail(&new_config->tables, &c->n); 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->name = new->name;
tab->config = new; tab->config = new;
tab->export_settle.cf = new->export_settle;
if (tab->hostcache) if (tab->hostcache)
tab->hostcache->req.trace_routes = new->debug; tab->hostcache->req.trace_routes = new->debug;

View File

@ -65,6 +65,8 @@ struct rtable_config {
byte debug; /* Whether to log */ byte debug; /* Whether to log */
struct rt_cork_threshold cork_threshold; /* Cork threshold values */ struct rt_cork_threshold cork_threshold; /* Cork threshold values */
struct settle_config export_settle; /* Export announcement settler */ 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; struct rt_export_hook;
@ -136,6 +138,9 @@ struct rtable_private {
btime last_rt_change; /* Last time when route changed */ btime last_rt_change; /* Last time when route changed */
btime gc_time; /* Time of last GC */ btime gc_time; /* Time of last GC */
uint gc_counter; /* Number of operations since 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_state; /* Table prune state, 1 -> scheduled, 2-> running */
byte prune_trie; /* Prune prefix trie during next table prune */ byte prune_trie; /* Prune prefix trie during next table prune */
byte nhu_state; /* Next Hop Update state */ byte nhu_state; /* Next Hop Update state */