Index: xenomai-2.3.x/ChangeLog =================================================================== --- xenomai-2.3.x/ChangeLog (Revision 2954) +++ xenomai-2.3.x/ChangeLog (Arbeitskopie) @@ -1,3 +1,8 @@ +2007-08-29 Jan Kiszka + + * ksrc/nucleus/shadow.c: Postpone module_put() to the lo-stage + APC handler (back-ported from 2.4). + 2007-08-24 Wolfgang Grandegger * ksrc/drivers/can/rtcan_socket.c: protect the list of RTCAN Index: xenomai-2.3.x/ksrc/nucleus/shadow.c =================================================================== --- xenomai-2.3.x/ksrc/nucleus/shadow.c (Revision 2954) +++ xenomai-2.3.x/ksrc/nucleus/shadow.c (Arbeitskopie) @@ -99,6 +99,7 @@ static struct __lostagerq { #define LO_RENICE_REQ 2 #define LO_SIGGRP_REQ 3 #define LO_SIGTHR_REQ 4 +#define LO_UNMAP_REQ 5 int type; struct task_struct *task; int arg; @@ -753,6 +754,28 @@ void xnshadow_reset_shield(void) #endif /* CONFIG_XENO_OPT_ISHIELD */ +static void xnshadow_dereference_skin(unsigned magic) +{ + unsigned muxid; + + for (muxid = 0; muxid < XENOMAI_MUX_NR; muxid++) { + if (muxtable[muxid].magic == magic) { + if (xnarch_atomic_dec_and_test(&muxtable[0].refcnt)) + xnarch_atomic_dec(&muxtable[0].refcnt); + if (xnarch_atomic_dec_and_test(&muxtable[muxid].refcnt)) + + /* We were the last thread, decrement the counter, + since it was incremented by the xn_sys_bind + operation. */ + xnarch_atomic_dec(&muxtable[muxid].refcnt); + if (muxtable[muxid].module) + module_put(muxtable[muxid].module); + + break; + } + } +} + static void lostage_handler(void *cookie) { int cpuid = smp_processor_id(), reqnum, sig; @@ -777,6 +800,12 @@ static void lostage_handler(void *cookie goto do_wakeup; + case LO_UNMAP_REQ: + + xnshadow_dereference_skin( + (unsigned)rq->req[reqnum].arg); + + /* fall through */ case LO_WAKEUP_REQ: /* We need to downgrade the root thread @@ -1256,7 +1285,6 @@ int xnshadow_map(xnthread_t *thread, xnc void xnshadow_unmap(xnthread_t *thread) { struct task_struct *p; - unsigned muxid, magic; if (XENO_DEBUG(NUCLEUS) && !testbits(xnpod_current_sched()->status, XNKCOUT)) @@ -1264,25 +1292,6 @@ void xnshadow_unmap(xnthread_t *thread) p = xnthread_archtcb(thread)->user_task; - magic = xnthread_get_magic(thread); - - for (muxid = 0; muxid < XENOMAI_MUX_NR; muxid++) { - if (muxtable[muxid].magic == magic) { - if (xnarch_atomic_dec_and_test(&muxtable[0].refcnt)) - xnarch_atomic_dec(&muxtable[0].refcnt); - if (xnarch_atomic_dec_and_test(&muxtable[muxid].refcnt)) - - /* We were the last thread, decrement the counter, - since it was incremented by the xn_sys_bind - operation. */ - xnarch_atomic_dec(&muxtable[muxid].refcnt); - if (muxtable[muxid].module) - module_put(muxtable[muxid].module); - - break; - } - } - xnthread_clear_state(thread, XNMAPPED); rpi_pop(thread); @@ -1298,13 +1307,7 @@ void xnshadow_unmap(xnthread_t *thread) xnshadow_thrptd(p) = NULL; - if (p->state != TASK_RUNNING) - /* If the shadow is being unmapped in primary mode or blocked - in secondary mode, the associated Linux task should also - die. In the former case, the zombie Linux side returning to - user-space will be trapped and exited inside the pod's - rescheduling routines. */ - schedule_linux_call(LO_WAKEUP_REQ, p, 0); + schedule_linux_call(LO_UNMAP_REQ, p, xnthread_get_magic(thread)); } int xnshadow_wait_barrier(struct pt_regs *regs) @@ -2010,6 +2013,7 @@ RTHAL_DECLARE_EVENT(losyscall_event); static inline void do_taskexit_event(struct task_struct *p) { xnthread_t *thread = xnshadow_thread(p); /* p == current */ + unsigned magic; spl_t s; if (!thread) @@ -2018,6 +2022,8 @@ static inline void do_taskexit_event(str if (xnpod_shadow_p()) xnshadow_relax(0); + magic = xnthread_get_magic(thread); + xnlock_get_irqsave(&nklock, s); /* Prevent wakeup call from xnshadow_unmap(). */ xnshadow_thrptd(p) = NULL; @@ -2028,6 +2034,7 @@ static inline void do_taskexit_event(str xnlock_put_irqrestore(&nklock, s); xnpod_schedule(); + xnshadow_dereference_skin(magic); xnltt_log_event(xeno_ev_shadowexit, thread->name); }