Module: xenomai-2.6
Branch: master
Commit: b03e3d08379f236eb75b34c1b705e127c6e3b2e5

Author: Philippe Gerum <>
Date:   Fri Jun 26 15:50:41 2015 +0200

nucleus/pod: fix missed rescheduling in SMP

During parallel multi-core operations involving two threads, the
following scenario may happen:

CPU0: thread A
      xnpod_suspend_thread() on self
        => XNSCHED raised via xnsched_set_resched(), local scheduler (no IPI)
        => suspend eventually denied (bad timeout)
           => no rescheduling

CPU1: thread B
      xnpod_resume_thread() on A
        => XNSCHED seen pending by xnsched_set_resched(), no resched IPI marked
           => __xnpod_schedule() does not send a resched IPI to CPU0

The outcome is that CPU1 won't send any resched IPI to CPU0 although
it should have done so, which practically delays wakeup of thread A
until some operation on CPU0 eventually causes a local rescheduling.

The bottom line is that any code raising XNSCHED __must__ trigger the
rescheduling procedure.


 ksrc/nucleus/pod.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index 0a361e9..ef6fb41 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -1361,9 +1361,6 @@ void xnpod_suspend_thread(xnthread_t *thread, xnflags_t 
        sched = thread->sched;
        oldstate = thread->state;
-       if (thread == sched->curr)
-               xnsched_set_resched(sched);
        /* Is the thread ready to run? */
        if (!xnthread_test_state(thread, XNTHREAD_BLOCK_BITS)) {
@@ -1435,6 +1432,7 @@ void xnpod_suspend_thread(xnthread_t *thread, xnflags_t 
 #endif /* __XENO_SIM__ */
        if (thread == sched->curr) {
+               xnsched_set_resched(sched);
                __clrbits(sched->lflags, XNINLOCK);
                 * If the current thread is being relaxed, we must

Xenomai-git mailing list

Reply via email to