Module: xenomai-rpm
Branch: queue/mayday
Commit: 16b5cfad3e519bc8524537e149fc4a6722c7f642
URL:    
http://git.xenomai.org/?p=xenomai-rpm.git;a=commit;h=16b5cfad3e519bc8524537e149fc4a6722c7f642

Author: Philippe Gerum <r...@xenomai.org>
Date:   Mon May 17 22:46:07 2010 +0200

nucleus: prevent stack overflow w/ unlocked context switch

Under high IRQ pressure w/ unlocked context switch support enabled, we
could face stack overflows, due to recurring calls to xnpod_schedule()
from xnsched_resched_after_unlocked_switch().

Typically:

__xnpod_schedule()
        xnpod_switch_to()
                xnlock_clear_irqon(&nklock)
                <IRQ>
                        xnsched_set_resched()
        xnsched_resched_after_unlocked_switch()
                __xnpod_schedule()
                        ...etc...

This fix replaces the recursive function call to __xnpod_schedule()
from itself by a plain unconditional branch to respin the scheduling
procedure.

---

 include/nucleus/sched.h |    9 +++++++++
 ksrc/nucleus/pod.c      |    9 +++++----
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/include/nucleus/sched.h b/include/nucleus/sched.h
index 05dd4b1..441a3a2 100644
--- a/include/nucleus/sched.h
+++ b/include/nucleus/sched.h
@@ -203,6 +203,12 @@ struct xnsched *xnsched_finish_unlocked_switch(struct 
xnsched *sched);
 
 #define xnsched_resched_after_unlocked_switch() xnpod_schedule()
 
+static inline
+int xnsched_maybe_resched_after_unlocked_switch(struct xnsched *sched)
+{
+       return testbits(sched->status, XNRESCHED);
+}
+
 #else /* !CONFIG_XENO_HW_UNLOCKED_SWITCH */
 
 #ifdef CONFIG_SMP
@@ -217,6 +223,9 @@ struct xnsched *xnsched_finish_unlocked_switch(struct 
xnsched *sched);
 
 #define xnsched_resched_after_unlocked_switch()                do { } while(0)
 
+#define xnsched_maybe_resched_after_unlocked_switch(sched)     \
+       ({ (void)(sched); 0; })
+
 #endif /* !CONFIG_XENO_HW_UNLOCKED_SWITCH */
 
 #ifdef CONFIG_XENO_OPT_WATCHDOG
diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index fb63f35..7002a73 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -2175,7 +2175,7 @@ void __xnpod_schedule(struct xnsched *sched)
        xnarch_trace_pid(xnthread_user_task(curr) ?
                         xnarch_user_pid(xnthread_archtcb(curr)) : -1,
                         xnthread_current_priority(curr));
-
+reschedule:
        need_resched = __xnpod_test_resched(sched);
 #if !XENO_DEBUG(NUCLEUS)
        if (!need_resched)
@@ -2284,10 +2284,11 @@ void __xnpod_schedule(struct xnsched *sched)
        if (xnthread_signaled_p(curr))
                xnpod_dispatch_signals();
 
-       xnlock_put_irqrestore(&nklock, s);
+       if (switched &&
+           xnsched_maybe_resched_after_unlocked_switch(sched))
+               goto reschedule;
 
-       if (switched)
-               xnsched_resched_after_unlocked_switch();
+       xnlock_put_irqrestore(&nklock, s);
 
        return;
 


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

Reply via email to