Index | Thread | Search

From:
Theo Buehler <tb@theobuehler.org>
Subject:
Re: bgpd: reduce time spent in rib_dump_runner()
To:
tech@openbsd.org
Date:
Sat, 27 Dec 2025 17:37:44 +0100

Download raw body.

Thread
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);
>  }
>