Module: xenomai-head
Branch: master
Commit: 470c31356e3d5c8a58815c828b777719087f7427
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=470c31356e3d5c8a58815c828b777719087f7427

Author: Jan Kiszka <jan.kis...@siemens.com>
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 <jan.kis...@siemens.com>

---

 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
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to