Module: xenomai-rpm
Branch: for-upstream
Commit: 47dac49c71e89b684203e854d1b0172ecacbc555
URL:    
http://git.xenomai.org/?p=xenomai-rpm.git;a=commit;h=47dac49c71e89b684203e854d1b0172ecacbc555

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Sep  1 18:01:01 2010 +0200

nucleus/sched: fix race in non-atomic suspend path

f6af9b831 revealed a nasty race on a legit usage of the scheduling
support code, specifically when running the following sequence
non-atomically, i.e. nklock-free:

xnpod_suspend_thread(current_thread)
...
xnpod_schedule()
...

Doing so should have been 100% valid. Unfortunately, this used to be
unsafe under the hood (see __xnpod_schedule).

This patches fixes it, and also goes through testing the XNRESCHED bit
to avoid a useless rescheduling from the code path introduced by
f6af9b831.

---

 ksrc/nucleus/pod.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index c377a31..0f9ea71 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -276,14 +276,17 @@ EXPORT_SYMBOL_GPL(xnpod_fatal_helper);
 
 void xnpod_schedule_handler(void) /* Called with hw interrupts off. */
 {
-       xnsched_t *sched = xnpod_current_sched();
+       xnsched_t *sched;
 
        trace_mark(xn_nucleus, sched_remote, MARK_NOARGS);
 #if defined(CONFIG_SMP) && defined(CONFIG_XENO_OPT_PRIOCPL)
+       sched = xnpod_current_sched();
        if (testbits(sched->status, XNRPICK)) {
                clrbits(sched->status, XNRPICK);
                xnshadow_rpi_check();
        }
+#else
+       (void)sched;
 #endif /* CONFIG_SMP && CONFIG_XENO_OPT_PRIOCPL */
        xnpod_schedule();
 }
@@ -1467,7 +1470,7 @@ void xnpod_suspend_thread(xnthread_t *thread, xnflags_t 
mask,
                 */
                if (mask & XNRELAX) {
                        xnlock_clear_irqon(&nklock);
-                       __xnpod_schedule(sched);
+                       xnpod_schedule();
                        return;
                }
                /*
@@ -2172,8 +2175,8 @@ static inline int __xnpod_test_resched(struct xnsched 
*sched)
 
 void __xnpod_schedule(struct xnsched *sched)
 {
-       struct xnthread *prev, *next, *curr = sched->curr;
        int zombie, switched, need_resched, shadow;
+       struct xnthread *prev, *next, *curr;
        spl_t s;
 
        if (xnarch_escalate())
@@ -2183,6 +2186,8 @@ void __xnpod_schedule(struct xnsched *sched)
 
        xnlock_get_irqsave(&nklock, s);
 
+       curr = sched->curr;
+
        xnarch_trace_pid(xnthread_user_task(curr) ?
                         xnarch_user_pid(xnthread_archtcb(curr)) : -1,
                         xnthread_current_priority(curr));


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to