Module: xenomai-rpm Branch: queue/mayday Commit: 16b5cfad3e519bc8524537e149fc4a6722c7f642 URL: http://git.xenomai.org/?p=xenomai-rpm.git;a=commit;h=16b5cfad3e519bc8524537e149fc4a6722c7f642
Author: Philippe Gerum <[email protected]> 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 [email protected] https://mail.gna.org/listinfo/xenomai-git
