This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch releases/12.7
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 5e2d205e1b9bc95585c9897a1b9475935ab5a9d7
Author: xuxingliang <[email protected]>
AuthorDate: Tue Jul 16 14:59:15 2024 +0800

    sched: handle sched lock in interrupt
    
    Signed-off-by: xuxingliang <[email protected]>
---
 sched/sched/sched_smp.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/sched/sched/sched_smp.c b/sched/sched/sched_smp.c
index 94aab39130..af6c88a4e5 100644
--- a/sched/sched/sched_smp.c
+++ b/sched/sched/sched_smp.c
@@ -26,6 +26,7 @@
 
 #include <nuttx/config.h>
 
+#include <assert.h>
 #include <nuttx/arch.h>
 #include <nuttx/nuttx.h>
 #include <nuttx/queue.h>
@@ -61,6 +62,7 @@ struct smp_call_data_s
 
 static sq_queue_t g_smp_call_queue[CONFIG_SMP_NCPUS];
 static struct smp_call_data_s g_smp_call_data;
+static spinlock_t g_smp_call_lock;
 
 /****************************************************************************
  * Private Functions
@@ -86,9 +88,9 @@ static void nxsched_smp_call_add(int cpu,
 {
   irqstate_t flags;
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&g_smp_call_lock);
   sq_addlast(&call_data->node[cpu], &g_smp_call_queue[cpu]);
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&g_smp_call_lock, flags);
 }
 
 /****************************************************************************
@@ -119,7 +121,7 @@ int nxsched_smp_call_handler(int irq, FAR void *context,
   FAR sq_entry_t *next;
   int cpu = this_cpu();
 
-  irqstate_t flags = enter_critical_section();
+  irqstate_t flags = spin_lock_irqsave(&g_smp_call_lock);
 
   call_queue = &g_smp_call_queue[cpu];
 
@@ -132,11 +134,11 @@ int nxsched_smp_call_handler(int irq, FAR void *context,
 
       sq_rem(&call_data->node[cpu], call_queue);
 
-      leave_critical_section(flags);
+      spin_unlock_irqrestore(&g_smp_call_lock, flags);
 
       ret = call_data->func(call_data->arg);
 
-      flags = enter_critical_section();
+      flags = spin_lock_irqsave(&g_smp_call_lock);
       if (spin_is_locked(&call_data->lock))
         {
           if (--call_data->refcount == 0)
@@ -157,7 +159,7 @@ int nxsched_smp_call_handler(int irq, FAR void *context,
     }
 
   up_cpu_paused_restore();
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&g_smp_call_lock, flags);
   return OK;
 }
 
@@ -219,13 +221,20 @@ int nxsched_smp_call(cpu_set_t cpuset, nxsched_smp_call_t 
func,
     };
 
   FAR struct smp_call_data_s *call_data;
-  int remote_cpus = 0;
+  int remote_cpus;
   int ret = OK;
   int i;
 
+  /* Cannot wait in interrupt context. */
+
+  DEBUGASSERT(!(wait && up_interrupt_context()));
+
   /* Prevent reschedule on another processor */
 
-  sched_lock();
+  if (!up_interrupt_context())
+    {
+      sched_lock();
+    }
 
   if (CPU_ISSET(this_cpu(), &cpuset))
     {
@@ -293,6 +302,10 @@ int nxsched_smp_call(cpu_set_t cpuset, nxsched_smp_call_t 
func,
     }
 
 out:
-  sched_unlock();
+  if (!up_interrupt_context())
+    {
+      sched_unlock();
+    }
+
   return ret;
 }

Reply via email to