From a505383d6a42259b96f5882b493f328bc1dd9301 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 12 Oct 2021 13:22:54 -0400 Subject: [PATCH 1/2] lib: Add a thread_is_scheduled function The function thread_is_scheduled allows us to know if the particular thread is scheduled for execution or not. Signed-off-by: Donald Sharp --- lib/thread.c | 8 ++++++++ lib/thread.h | 1 + 2 files changed, 9 insertions(+) diff --git a/lib/thread.c b/lib/thread.c index 835aa38115..71d7798af5 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -2059,3 +2059,11 @@ void debug_signals(const sigset_t *sigs) zlog_debug("%s: %s", __func__, buf); } + +bool thread_is_scheduled(struct thread *thread) +{ + if (thread == NULL) + return false; + + return true; +} diff --git a/lib/thread.h b/lib/thread.h index abd94ff4f0..c5f0ffbf77 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -273,6 +273,7 @@ extern pthread_key_t thread_current; extern char *thread_timer_to_hhmmss(char *buf, int buf_size, struct thread *t_timer); +extern bool thread_is_scheduled(struct thread *thread); /* Debug signal mask */ void debug_signals(const sigset_t *sigs); From e13f12a7d147a993a0aefd0b2b0ba947746071b4 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 12 Oct 2021 13:23:40 -0400 Subject: [PATCH 2/2] zebra: modify rib_update to be a bit smarter about malloc rib_update() was mallocing memory then attempting to schedule and if the schedule failed( it was already going to be run ) FRR would then free the memory. Fix this memory usage pattern Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 12e82dde94..fcac3328c9 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -3890,14 +3890,16 @@ void rib_update(enum rib_update_event event) { struct rib_update_ctx *ctx; - ctx = rib_update_ctx_init(0, event); + if (thread_is_scheduled(t_rib_update_threads[event])) + return; + ctx = rib_update_ctx_init(0, event); ctx->vrf_all = true; - if (!thread_add_event(zrouter.master, rib_update_handler, ctx, 0, - &t_rib_update_threads[event])) - rib_update_ctx_fini(&ctx); /* Already scheduled */ - else if (IS_ZEBRA_DEBUG_EVENT) + thread_add_event(zrouter.master, rib_update_handler, ctx, 0, + &t_rib_update_threads[event]); + + if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("%s: Scheduled VRF (ALL), event %s", __func__, rib_update_event2str(event)); }