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


The following commit(s) were added to refs/heads/master by this push:
     new 791c1a4ab5e sched/setpriority: handle CPU affinity change for running 
task
791c1a4ab5e is described below

commit 791c1a4ab5ed146f43badd8c3df3d827059e9d65
Author: hujun5 <[email protected]>
AuthorDate: Wed Aug 5 12:28:57 2026 +0800

    sched/setpriority: handle CPU affinity change for running task
    
    When a running task changes its affinity on SMP and is no longer eligible 
to run on the current CPU, merely delivering an equal-priority scheduling 
request can leave the task in g_readytorun while the target CPU remains idle. 
The task then never runs again.
    
    Remove the task from its current CPU, add it back to the ready-to-run list 
so a suitable CPU is selected, and perform the context switch unconditionally. 
This ensures the task is migrated according to its updated affinity.
    
    Fixes: https://github.com/apache/nuttx/issues/19680
    
    Assisted-by: GitHub Copilot:ppio/pa/gpt-5.6-sol
    
    Signed-off-by: hujun5 <[email protected]>
---
 sched/sched/sched_setpriority.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/sched/sched/sched_setpriority.c b/sched/sched/sched_setpriority.c
index 8bb457fd79d..8d903fc294b 100644
--- a/sched/sched/sched_setpriority.c
+++ b/sched/sched/sched_setpriority.c
@@ -92,7 +92,26 @@ static inline void nxsched_running_setpriority(FAR struct 
tcb_s *tcb,
     {
 #ifdef CONFIG_SMP
       tcb->sched_priority = (uint8_t)sched_priority;
-      if (nxsched_deliver_task(this_cpu(), tcb->cpu, SWITCH_EQUAL))
+
+      /* If the task no longer is eligible to run on this CPU, then
+       * we need to perform the context switch unconditionally.
+       */
+
+      if ((tcb == this_task()) && (tcb->affinity & (1 << tcb->cpu)) == 0)
+        {
+          bool switch_needed;
+
+          switch_needed = nxsched_remove_readytorun(tcb);
+          DEBUGASSERT(switch_needed == true);
+
+          switch_needed = nxsched_add_readytorun(tcb);
+          DEBUGASSERT(switch_needed == false);
+
+          DEBUGASSERT(tcb != this_task());
+          up_switch_context(this_task(), tcb);
+          UNUSED(switch_needed);
+        }
+      else if (nxsched_deliver_task(this_cpu(), tcb->cpu, SWITCH_EQUAL))
         {
           up_switch_context(this_task(), tcb);
         }

Reply via email to