Module: xenomai-jki Branch: for-upstream Commit: 26f8b98b1231bd21978f8b61f025d9cf0cfa0a67 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=26f8b98b1231bd21978f8b61f025d9cf0cfa0a67
Author: Jan Kiszka <[email protected]> Date: Fri Jul 8 18:19:09 2011 +0200 nucleus: Fix race between gatekeeper and thread deletion A task whose shadow is queued in some gatekeeper's gktarget may terminate. In that case, we zapped the thread structure and left the gatekeeper with an invalid reference behind. Fix it by keeping a reference to the associated sched of the busy gatekeeper in the thread structure and synchronize with that helper if the tasks is supposed to terminate. Signed-off-by: Jan Kiszka <[email protected]> --- include/nucleus/thread.h | 2 ++ ksrc/nucleus/shadow.c | 34 +++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/include/nucleus/thread.h b/include/nucleus/thread.h index d5dc531..cfd2ea0 100644 --- a/include/nucleus/thread.h +++ b/include/nucleus/thread.h @@ -330,6 +330,8 @@ typedef struct xnthread { #ifdef CONFIG_XENO_OPT_PERVASIVE unsigned long *u_mode; /* Thread mode variable shared with userland. */ + + struct xnsched *gksched; /* Gatekeeper processing the thread. */ #endif /* CONFIG_XENO_OPT_PERVASIVE */ XNARCH_DECL_DISPLAY_CONTEXT(); diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c index e357351..85fcc16 100644 --- a/ksrc/nucleus/shadow.c +++ b/ksrc/nucleus/shadow.c @@ -898,12 +898,13 @@ static int gatekeeper_thread(void *data) target = sched->gktarget; /* - * In the very rare case where the requestor has been - * awaken by a signal before we have been able to - * process the pending request, just ignore the - * latter. + * In the very rare case where the requester has been + * awaken by a signal or has been deleted before we have + * been able to process the pending request, just ignore + * the latter. */ - if ((xnthread_user_task(target)->state & ~TASK_ATOMICSWITCH) == TASK_INTERRUPTIBLE) { + if (target && (xnthread_user_task(target)->state & + ~TASK_ATOMICSWITCH) == TASK_INTERRUPTIBLE) { rpi_pop(target); xnlock_get_irqsave(&nklock, s); #ifdef CONFIG_SMP @@ -999,6 +1000,7 @@ redo: thread, xnthread_name(thread), this_task->comm); sched->gktarget = thread; + thread->gksched = sched; xnthread_set_info(thread, XNATOMIC); set_current_state(TASK_INTERRUPTIBLE | TASK_ATOMICSWITCH); #ifndef CONFIG_PREEMPT_RT @@ -1039,6 +1041,7 @@ redo: } /* "current" is now running into the Xenomai domain. */ + thread->gksched = NULL; sched = xnsched_finish_unlocked_switch(thread->sched); xnsched_finalize_zombie(sched); @@ -1334,6 +1337,8 @@ int xnshadow_map(xnthread_t *thread, xncompletion_t __user *u_completion, thread->u_mode = u_mode; __xn_put_user(xnheap_mapped_offset(sem_heap, u_mode), u_mode_offset); + thread->gksched = NULL; + xnthread_set_state(thread, XNMAPPED); xnpod_suspend_thread(thread, XNRELAX, XN_INFINITE, XN_RELATIVE, NULL); @@ -2514,6 +2519,7 @@ static inline void do_taskexit_event(struct task_struct *p) { xnthread_t *thread = xnshadow_thread(p); /* p == current */ struct xnsys_ppd *sys_ppd; + struct xnsched *gksched; unsigned magic; spl_t s; @@ -2528,6 +2534,22 @@ static inline void do_taskexit_event(struct task_struct *p) magic = xnthread_get_magic(thread); xnlock_get_irqsave(&nklock, s); + + gksched = thread->gksched; + if (gksched) { + xnlock_put_irqrestore(&nklock, s); + + /* + * Synchronize with gatekeeper so that it no longer holds any + * reference to this thread. + */ + down(&gksched->gksync); + gksched->gktarget = NULL; + up(&gksched->gksync); + + xnlock_get_irqsave(&nklock, s); + } + /* Prevent wakeup call from xnshadow_unmap(). */ xnshadow_thrptd(p) = NULL; xnthread_archtcb(thread)->user_task = NULL; @@ -2535,7 +2557,9 @@ static inline void do_taskexit_event(struct task_struct *p) xnsched_set_resched(thread->sched); xnpod_delete_thread(thread); sys_ppd = xnsys_ppd_get(0); + xnlock_put_irqrestore(&nklock, s); + xnpod_schedule(); if (!xnarch_atomic_get(&sys_ppd->refcnt)) _______________________________________________ Xenomai-git mailing list [email protected] https://mail.gna.org/listinfo/xenomai-git
