Module: xenomai-head Branch: master Commit: 470c31356e3d5c8a58815c828b777719087f7427 URL: http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=470c31356e3d5c8a58815c828b777719087f7427
Author: Jan Kiszka <[email protected]> Date: Fri Jul 8 18:19:09 2011 +0200 nucleus: Fix race between gatekeeper and premature task resumption A task that is about to be hardened may receive a signal. In that case the schedule() that the task invoke will set its state to TASK_RUNNING again and may than decide to move it to a different CPU as also the gatekeeper is runnable at that point. Now we start a race between the task continuing to run in Linux context or terminate (on SIGKILL etc.) and the gatekeeper still holding a reference to this object and potentially seeing the task state as TASK_INTERRUPTIBLE again (if it waits long enough). Avoid this race by waiting for the gatekeeper to drop the obsolete migration request before returning from xnshadow_harden. Based on suggestion by Gilles. Signed-off-by: Jan Kiszka <[email protected]> --- ksrc/nucleus/shadow.c | 21 +++++++++++++++------ 1 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c index eea9151..76f326a 100644 --- a/ksrc/nucleus/shadow.c +++ b/ksrc/nucleus/shadow.c @@ -995,12 +995,11 @@ redo: xnthread_clear_info(thread, XNATOMIC); /* - * Rare case: we might have been awaken by a signal before the - * gatekeeper sent us to primary mode. Since - * TASK_UNINTERRUPTIBLE is unavailable to us without wrecking - * the runqueue's count of uniniterruptible tasks, we just - * notice the issue and gracefully fail; the caller will have - * to process this signal anyway. + * Rare case: we might have received a signal before entering + * schedule() and returned early from it. Since TASK_UNINTERRUPTIBLE + * is unavailable to us without wrecking the runqueue's count of + * uniniterruptible tasks, we just notice the issue and gracefully + * fail; the caller will have to process this signal anyway. */ if (rthal_current_domain == rthal_root_domain) { if (XENO_DEBUG(NUCLEUS) && (!signal_pending(this_task) @@ -1008,6 +1007,16 @@ redo: xnpod_fatal ("xnshadow_harden() failed for thread %s[%d]", thread->name, xnthread_user_pid(thread)); + + /* + * Synchronize with the chosen gatekeeper so that it no longer + * holds any reference to this thread and does not develop the + * idea to resume it for the Xenomai domain if, later on, we + * may happen to reenter TASK_INTERRUPTIBLE state. + */ + down(&sched->gksync); + up(&sched->gksync); + return -ERESTARTSYS; } _______________________________________________ Xenomai-git mailing list [email protected] https://mail.gna.org/listinfo/xenomai-git
