This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit dfc8f82b0b86d8392cf32dd90d8219f86c99d663 Author: raiden00pl <[email protected]> AuthorDate: Wed Sep 2 15:24:45 2026 +0200 arch/intel64: fix self-deadlock in intel64_oneshot_start() intel64_oneshot_start() takes g_oneshot_spin and then, if the timer is already running, calls intel64_oneshot_cancel(), which takes the same spinlock again. Spinlocks are not recursive, so the CPU spins forever on its own lock while holding the critical section; the HPET timer ISR on another CPU then blocks on g_cpu_irqlock and the system hangs. This is hit as soon as the tickless scheduler re-arms a running HPET oneshot timer under SMP (ostest task_restart, LTP aio tests). Stop the running timer inline instead of calling cancel: disable the interrupt, detach the ISR so up_enable_irq() does not assert on a busy IRQ, and clear the running flag. The ISR, comparator and interrupt enable are reprogrammed by the rest of the function anyway. Assisted-by: Claude Code Signed-off-by: raiden00pl <[email protected]> --- arch/x86_64/src/intel64/intel64_oneshot.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/x86_64/src/intel64/intel64_oneshot.c b/arch/x86_64/src/intel64/intel64_oneshot.c index a98b8cea555..eb907eaed17 100644 --- a/arch/x86_64/src/intel64/intel64_oneshot.c +++ b/arch/x86_64/src/intel64/intel64_oneshot.c @@ -301,10 +301,21 @@ int intel64_oneshot_start(struct intel64_oneshot_s *oneshot, flags = spin_lock_irqsave(&g_oneshot_spin); if (oneshot->running) { - /* Yes.. then cancel it */ + /* Yes.. then stop it. Do NOT call intel64_oneshot_cancel() here: + * it takes g_oneshot_spin, which we already hold, and spinlocks are + * not recursive, so that deadlocks the CPU. Everything else that + * cancel would do (ISR, comparator, interrupt enable) is + * reprogrammed below anyway. + */ tmrinfo("Already running... cancelling\n"); - intel64_oneshot_cancel(oneshot, NULL); + +#ifndef CONFIG_INTEL64_HPET_FSB + INTEL64_TIM_DISABLEINT(oneshot->tch, oneshot->chan); + INTEL64_TIM_SETISR(oneshot->tch, oneshot->chan, NULL, NULL, false); +#endif + + oneshot->running = false; } /* Save the new handler and its argument */
