From: Theo Buehler Subject: Re: bgpd: reduce time spent in rib_dump_runner() To: tech@openbsd.org Date: Sat, 27 Dec 2025 17:37:44 +0100 On Sat, Dec 27, 2025 at 05:17:31PM +0100, Claudio Jeker wrote: > In some cases the RDE ends up with many RIB dump runners active and so > the rib_dump_runner() code consumes a lot of time to churn through all > of those calls. > > Try to limit the time spend in rib_dump_runner() to roughly 10ms and > then stop and restart from that point on the next poll loop round. > > This again ensures that the poll loop is not blocked for too long and > improves the overall responsiveness of bgpd. > > In rib_dump_free() the code needs to check if the ctx is the currently > queued ctx and if so replace it with the next one in the list. ok tb > -- > :wq Claudio > > Index: rde_rib.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v > diff -u -p -r1.285 rde_rib.c > --- rde_rib.c 24 Dec 2025 07:59:55 -0000 1.285 > +++ rde_rib.c 27 Dec 2025 16:09:53 -0000 > @@ -52,6 +52,7 @@ RB_PROTOTYPE(rib_tree, rib_entry, rib_e, > RB_GENERATE(rib_tree, rib_entry, rib_e, rib_compare); > > LIST_HEAD(, rib_context) rib_dumps = LIST_HEAD_INITIALIZER(rib_dumps); > +static struct rib_context *rib_dump_ctx; > > static inline struct rib_entry * > re_lock(struct rib_entry *re) > @@ -439,8 +440,19 @@ void > rib_dump_runner(void) > { > struct rib_context *ctx, *next; > + monotime_t start; > > - LIST_FOREACH_SAFE(ctx, &rib_dumps, entry, next) { > + start = getmonotime(); > + > + if (rib_dump_ctx != NULL) > + ctx = rib_dump_ctx; > + else > + ctx = LIST_FIRST(&rib_dumps); > + > + for (; ctx != NULL; ctx = next) { > + next = LIST_NEXT(ctx, entry); > + if (monotime_to_msec(monotime_sub(getmonotime(), start)) > 10) > + break; > if (ctx->ctx_throttle && ctx->ctx_throttle(ctx->ctx_arg)) > continue; > if (ctx->ctx_rib_call != NULL) > @@ -448,6 +460,7 @@ rib_dump_runner(void) > else > adjout_prefix_dump_r(ctx); > } > + rib_dump_ctx = ctx; > } > > static void > @@ -467,6 +480,8 @@ rib_dump_free(struct rib_context *ctx) > rib_dump_cleanup(ctx); > if (ctx->ctx_pt) > adjout_prefix_dump_cleanup(ctx); > + if (ctx == rib_dump_ctx) > + rib_dump_ctx = LIST_NEXT(ctx, entry); > LIST_REMOVE(ctx, entry); > free(ctx); > } >