Module: xenomai-2.6 Branch: master Commit: b03e3d08379f236eb75b34c1b705e127c6e3b2e5 URL: http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=b03e3d08379f236eb75b34c1b705e127c6e3b2e5
Author: Philippe Gerum <r...@xenomai.org> 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 mask, 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)) { #ifdef CONFIG_XENO_OPT_PERVASIVE @@ -1435,6 +1432,7 @@ void xnpod_suspend_thread(xnthread_t *thread, xnflags_t mask, #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 Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git