Index: kern_timeout.c =================================================================== RCS file: /cvs/src/sys/kern/kern_timeout.c,v diff -u -p -r1.101 kern_timeout.c --- kern_timeout.c 13 Jan 2025 03:21:10 -0000 1.101 +++ kern_timeout.c 29 Apr 2025 12:27:54 -0000 @@ -55,6 +55,7 @@ * T timeout_mutex */ struct mutex timeout_mutex = MUTEX_INITIALIZER(IPL_HIGH); +static unsigned int timeout_running; void *softclock_si; /* [I] softclock() interrupt handle */ struct timeoutstat tostat; /* [T] statistics and totals */ @@ -465,6 +466,7 @@ timeout_del_barrier(struct timeout *to) void timeout_barrier(struct timeout *to) { + struct circq *to_list; struct timeout barrier; struct cond c; int flags; @@ -478,29 +480,28 @@ timeout_barrier(struct timeout *to) cond_init(&c); mtx_enter(&timeout_mutex); - - barrier.to_time = ticks; - SET(barrier.to_flags, TIMEOUT_ONQUEUE); if (ISSET(flags, TIMEOUT_PROC)) { #ifdef MULTIPROCESSOR if (ISSET(flags, TIMEOUT_MPSAFE)) - CIRCQ_INSERT_TAIL(&timeout_proc_mp, &barrier.to_list); + to_list = &timeout_proc_mp; else #endif - CIRCQ_INSERT_TAIL(&timeout_proc, &barrier.to_list); - } else - CIRCQ_INSERT_TAIL(&timeout_todo, &barrier.to_list); + to_list = &timeout_proc; + } else if (timeout_running) + to_list = &timeout_todo; + else { + mtx_leave(&timeout_mutex); + return; + } + barrier.to_time = ticks; + SET(barrier.to_flags, TIMEOUT_ONQUEUE); + CIRCQ_INSERT_TAIL(to_list, &barrier.to_list); mtx_leave(&timeout_mutex); - if (ISSET(flags, TIMEOUT_PROC)) { -#ifdef MULTIPROCESSOR - if (ISSET(flags, TIMEOUT_MPSAFE)) - wakeup_one(&timeout_proc_mp); - else -#endif - wakeup_one(&timeout_proc); - } else + if (ISSET(flags, TIMEOUT_PROC)) + wakeup_one(to_list); + else softintr_schedule(softclock_si); cond_wait(&c, "tmobar"); @@ -689,7 +690,9 @@ softclock_process_kclock_timeout(struct CIRCQ_INSERT_TAIL(&timeout_proc, &to->to_list); return; } + timeout_running = 1; timeout_run(to); + timeout_running = 0; tostat.tos_run_softclock++; } @@ -716,7 +719,9 @@ softclock_process_tick_timeout(struct ti CIRCQ_INSERT_TAIL(&timeout_proc, &to->to_list); return; } + timeout_running = 1; timeout_run(to); + timeout_running = 0; tostat.tos_run_softclock++; }