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

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new dc6ddd8d4d7 sched: Fix scheduler CPU selection and ready-to-run list 
management
dc6ddd8d4d7 is described below

commit dc6ddd8d4d7ef1c9bd49c79b3802d4867655d85b
Author: hujun5 <[email protected]>
AuthorDate: Wed Jan 28 20:00:20 2026 +0800

    sched: Fix scheduler CPU selection and ready-to-run list management
    
    Fix critical issues in SMP scheduler: correct CPU selection logic by
    removing redundant lock check and prioritizing eligible CPUs, simplify
    ready-to-run list addition by removing unnecessary condition check and
    early validation, and relocate switch_running() call for proper cleanup
    sequencing in remove_self() operation.
    
    Signed-off-by: hujun5 <[email protected]>
---
 sched/sched/sched.h                   |  6 +++---
 sched/sched/sched_addreadytorun.c     | 17 ++++++++---------
 sched/sched/sched_process_delivered.c |  2 +-
 sched/sched/sched_removereadytorun.c  |  3 ++-
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/sched/sched/sched.h b/sched/sched/sched.h
index db20164b90e..cd75865003e 100644
--- a/sched/sched/sched.h
+++ b/sched/sched/sched.h
@@ -577,7 +577,7 @@ static inline_function int nxsched_select_cpu(cpu_set_t 
affinity)
   int i;
 
   minprio = SCHED_PRIORITY_MAX;
-  cpu     = CONFIG_SMP_NCPUS;
+  cpu     = 0xff;
 
   for (i = 0; i < CONFIG_SMP_NCPUS; i++)
     {
@@ -600,8 +600,7 @@ static inline_function int nxsched_select_cpu(cpu_set_t 
affinity)
               DEBUGASSERT(rtcb->sched_priority == 0);
               return i;
             }
-          else if (rtcb->sched_priority <= minprio &&
-                   !nxsched_islocked_tcb(rtcb))
+          else if (rtcb->sched_priority <= minprio)
             {
               DEBUGASSERT(rtcb->sched_priority > 0);
               minprio = rtcb->sched_priority;
@@ -610,6 +609,7 @@ static inline_function int nxsched_select_cpu(cpu_set_t 
affinity)
         }
     }
 
+  DEBUGASSERT(cpu != 0xff);
   return cpu;
 }
 #  endif
diff --git a/sched/sched/sched_addreadytorun.c 
b/sched/sched/sched_addreadytorun.c
index d4bc4e66d87..2724a1bd5ac 100644
--- a/sched/sched/sched_addreadytorun.c
+++ b/sched/sched/sched_addreadytorun.c
@@ -163,7 +163,7 @@ bool nxsched_switch_running(int cpu, bool switch_equal)
       return false;
     }
 
-  if (switch_equal)
+  if (switch_equal && sched_priority > 0)
     {
       sched_priority--;
     }
@@ -255,6 +255,7 @@ bool nxsched_add_readytorun(FAR struct tcb_s *btcb)
   bool doswitch = false;
   int target_cpu = btcb->flags & TCB_FLAG_CPU_LOCKED ? btcb->cpu :
     nxsched_select_cpu(btcb->affinity);
+  FAR struct tcb_s *tcb = current_task(target_cpu);
 
   /* Add the btcb to the ready to run list, and try to run it on the target
    * CPU
@@ -263,15 +264,13 @@ bool nxsched_add_readytorun(FAR struct tcb_s *btcb)
   btcb->task_state = TSTATE_TASK_READYTORUN;
   nxsched_add_prioritized(btcb, list_readytorun());
 
-  if (target_cpu < CONFIG_SMP_NCPUS)
-    {
-      FAR struct tcb_s *tcb = current_task(target_cpu);
+  /* In some cases, such as setaffinity, cpu need to be used. */
 
-      if (tcb->sched_priority < btcb->sched_priority)
-        {
-          doswitch = nxsched_deliver_task(this_cpu(), target_cpu,
-                                          SWITCH_HIGHER);
-        }
+  btcb->cpu = target_cpu;
+  if (tcb->sched_priority < btcb->sched_priority)
+    {
+      doswitch = nxsched_deliver_task(this_cpu(), target_cpu,
+                                      SWITCH_HIGHER);
     }
 
   return doswitch;
diff --git a/sched/sched/sched_process_delivered.c 
b/sched/sched/sched_process_delivered.c
index 663161de754..36effcd028d 100644
--- a/sched/sched/sched_process_delivered.c
+++ b/sched/sched/sched_process_delivered.c
@@ -105,7 +105,7 @@ void nxsched_process_delivered(int cpu)
         {
           int target_cpu = tcb->flags & TCB_FLAG_CPU_LOCKED ?
             tcb->cpu : nxsched_select_cpu(tcb->affinity);
-          if (target_cpu < CONFIG_SMP_NCPUS && target_cpu != cpu &&
+          if (target_cpu != cpu &&
               current_task(target_cpu)->sched_priority < tcb->sched_priority)
             {
               nxsched_deliver_task(cpu, target_cpu, priority);
diff --git a/sched/sched/sched_removereadytorun.c 
b/sched/sched/sched_removereadytorun.c
index 0166c443fe6..88b11263a44 100644
--- a/sched/sched/sched_removereadytorun.c
+++ b/sched/sched/sched_removereadytorun.c
@@ -162,12 +162,13 @@ static void nxsched_remove_running(FAR struct tcb_s *tcb)
   nxttcb->task_state = TSTATE_TASK_RUNNING;
   g_assignedtasks[cpu] = nxttcb;
   up_update_task(nxttcb);
+
+  nxsched_switch_running(tcb->cpu, false);
 }
 
 void nxsched_remove_self(FAR struct tcb_s *tcb)
 {
   nxsched_remove_running(tcb);
-  nxsched_switch_running(tcb->cpu, false);
 }
 
 bool nxsched_remove_readytorun(FAR struct tcb_s *tcb)

Reply via email to