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 */

Reply via email to