diff --git a/lib/thread.c b/lib/thread.c index 73e0e4887c..376f61c247 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -787,6 +787,7 @@ static struct thread *thread_get(struct thread_master *m, uint8_t type, thread->arg = arg; thread->yield = THREAD_YIELD_TIME_SLOT; /* default */ thread->ref = NULL; + thread->ignore_timer_late = false; /* * So if the passed in funcname is not what we have @@ -1667,12 +1668,12 @@ static unsigned int thread_process_timers(struct thread_master *m, * really getting behind on handling of events. * Let's log it and do the right thing with it. */ - if (timercmp(timenow, &prev, >)) { - if (!displayed) - flog_warn( - EC_LIB_STARVE_THREAD, - "Thread Starvation: %pTHD was scheduled to pop greater than 4s ago", - thread); + if (!displayed && !thread->ignore_timer_late && + timercmp(timenow, &prev, >)) { + flog_warn( + EC_LIB_STARVE_THREAD, + "Thread Starvation: %pTHD was scheduled to pop greater than 4s ago", + thread); displayed = true; } diff --git a/lib/thread.h b/lib/thread.h index 49a70696d0..660f8bd28e 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -126,6 +126,7 @@ struct thread { unsigned long yield; /* yield time in microseconds */ const struct xref_threadsched *xref; /* origin location */ pthread_mutex_t mtx; /* mutex for thread.c functions */ + bool ignore_timer_late; }; #ifdef _FRR_ATTRIBUTE_PRINTFRR @@ -285,6 +286,11 @@ extern bool thread_is_scheduled(struct thread *thread); /* Debug signal mask */ void debug_signals(const sigset_t *sigs); +static inline void thread_ignore_late_timer(struct thread *thread) +{ + thread->ignore_timer_late = true; +} + #ifdef __cplusplus } #endif diff --git a/lib/workqueue.c b/lib/workqueue.c index 2a8326c056..86afe4082e 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -135,10 +135,11 @@ static int work_queue_schedule(struct work_queue *wq, unsigned int delay) /* Schedule timer if there's a delay, otherwise just schedule * as an 'event' */ - if (delay > 0) + if (delay > 0) { thread_add_timer_msec(wq->master, work_queue_run, wq, delay, &wq->thread); - else + thread_ignore_late_timer(wq->thread); + } else thread_add_event(wq->master, work_queue_run, wq, 0, &wq->thread); diff --git a/zebra/interface.c b/zebra/interface.c index 8b5dbabb92..534953d903 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -91,9 +91,12 @@ static int if_zebra_speed_update(struct thread *thread) changed = true; } - if (changed || new_speed == UINT32_MAX) + if (changed || new_speed == UINT32_MAX) { thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 5, &zif->speed_update); + thread_ignore_late_timer(zif->speed_update); + } + return 1; } @@ -187,6 +190,8 @@ static int if_zebra_new_hook(struct interface *ifp) */ thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15, &zebra_if->speed_update); + thread_ignore_late_timer(zebra_if->speed_update); + return 0; } @@ -1074,6 +1079,7 @@ void if_up(struct interface *ifp) thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 0, &zif->speed_update); + thread_ignore_late_timer(zif->speed_update); } /* Interface goes down. We have to manage different behavior of based