diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 06b34da20932..19ac7819cfd0 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -3318,6 +3318,16 @@ uint32_t dplane_get_in_queue_len(void) memory_order_seq_cst); } +void dplane_sub_in_queue_len(uint32_t counter) +{ + if (dplane_get_in_queue_len() >= counter) + atomic_fetch_sub_explicit(&zdplane_info.dg_routes_queued, + counter, memory_order_relaxed); + else + zlog_err("%s:error counter, dg_routes_queued:%u, counter:%u", + __func__, dplane_get_in_queue_len(), counter); +} + /* * Internal helper that copies information from a zebra ns object; this is * called in the zebra main pthread context as part of dplane ctx init. @@ -6512,6 +6522,8 @@ void dplane_provider_enqueue_to_zebra(struct zebra_dplane_ctx *ctx) /* Zebra's api takes a list, so we need to use a temporary list */ dplane_ctx_list_init(&temp_list); + atomic_fetch_add_explicit(&(zdplane_info.dg_routes_queued), 1, + memory_order_seq_cst); dplane_ctx_list_add_tail(&temp_list, ctx); (zdplane_info.dg_results_cb)(&temp_list); @@ -7342,9 +7354,6 @@ static void dplane_thread_loop(struct event *event) DPLANE_UNLOCK(); - atomic_fetch_sub_explicit(&zdplane_info.dg_routes_queued, counter, - memory_order_relaxed); - if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) zlog_debug("dplane: incoming new work counter: %d", counter); @@ -7465,12 +7474,14 @@ static void dplane_thread_loop(struct event *event) */ /* Call through to zebra main */ - (zdplane_info.dg_results_cb)(&error_list); + if (!dplane_ctx_list_count(&error_list)) + (zdplane_info.dg_results_cb)(&error_list); dplane_ctx_list_init(&error_list); /* Call through to zebra main */ - (zdplane_info.dg_results_cb)(&work_list); + if (!dplane_ctx_list_count(&work_list)) + (zdplane_info.dg_results_cb)(&work_list); dplane_ctx_list_init(&work_list); } diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 060b1c8b9e03..9cac268db86b 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -1075,6 +1075,7 @@ void dplane_set_in_queue_limit(uint32_t limit, bool set); /* Retrieve the current queue depth of incoming, unprocessed updates */ uint32_t dplane_get_in_queue_len(void); +void dplane_sub_in_queue_len(uint32_t counter); /* * Vty/cli apis diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 5b95d8668af0..a175ea13df65 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -4806,6 +4806,7 @@ static void rib_process_dplane_results(struct event *thread) struct zebra_dplane_ctx *ctx; struct dplane_ctx_list_head ctxlist; bool shut_p = false; + uint32_t counter = 0; #ifdef HAVE_SCRIPTING char *script_name = @@ -4970,10 +4971,12 @@ static void rib_process_dplane_results(struct event *thread) } /* Dispatch by op code */ dplane_ctx_fini(&ctx); + counter++; ctx = dplane_ctx_dequeue(&ctxlist); } } while (1); + dplane_sub_in_queue_len(counter); #ifdef HAVE_SCRIPTING if (fs)