Module: xenomai-head Branch: master Commit: d04374ac114d47a66f84312614330758a2a6190d URL: http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=d04374ac114d47a66f84312614330758a2a6190d
Author: Jan Kiszka <jan.kis...@siemens.com> Date: Fri Jun 17 09:46:19 2011 +0200 nucleus: Fix interrupt handler tails Our current interrupt handlers assume that they leave over the same task and CPU they entered. But commit f6af9b831c broke this assumption: xnpod_schedule invoked from the handler tail can now actually trigger a domain migration, and that can also include a CPU migration. This causes subtle corruptions as invalid xnstat_exectime_t objects may be restored and - even worse - we may improperly flush XNHTICK of the old CPU, leaving Linux timer-wise dead there (as happened to us). Fix this by moving exectime accounting before the scheduling point and reload sched for proper XNHTICK replay. Note that this introduces a tiny imprecision in the accounting. Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- ksrc/nucleus/intr.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ksrc/nucleus/intr.c b/ksrc/nucleus/intr.c index 3769949..af17101 100644 --- a/ksrc/nucleus/intr.c +++ b/ksrc/nucleus/intr.c @@ -116,9 +116,12 @@ void xnintr_clock_handler(void) xnstat_exectime_lazy_switch(sched, &nkclock.stat[xnsched_cpu(sched)].account, start); + xnstat_exectime_switch(sched, prev); + if (--sched->inesting == 0) { __clrbits(sched->lflags, XNINIRQ); xnpod_schedule(); + sched = xnpod_current_sched(); } /* * If the clock interrupt preempted a real-time thread, any @@ -132,7 +135,6 @@ void xnintr_clock_handler(void) xnintr_host_tick(sched); trace_mark(xn_nucleus, irq_exit, "irq %u", XNARCH_TIMER_IRQ); - xnstat_exectime_switch(sched, prev); } /* Optional support for shared interrupts. */ @@ -219,13 +221,14 @@ static void xnintr_shirq_handler(unsigned irq, void *cookie) else if (!(s & XN_ISR_NOENABLE)) xnarch_end_irq(irq); + xnstat_exectime_switch(sched, prev); + if (--sched->inesting == 0) { __clrbits(sched->lflags, XNINIRQ); xnpod_schedule(); } trace_mark(xn_nucleus, irq_exit, "irq %u", irq); - xnstat_exectime_switch(sched, prev); } /* @@ -302,12 +305,14 @@ static void xnintr_edge_shirq_handler(unsigned irq, void *cookie) else if (!(s & XN_ISR_NOENABLE)) xnarch_end_irq(irq); + xnstat_exectime_switch(sched, prev); + if (--sched->inesting == 0) { __clrbits(sched->lflags, XNINIRQ); xnpod_schedule(); } + trace_mark(xn_nucleus, irq_exit, "irq %u", irq); - xnstat_exectime_switch(sched, prev); } static inline int xnintr_irq_attach(xnintr_t *intr) @@ -492,13 +497,14 @@ static void xnintr_irq_handler(unsigned irq, void *cookie) else if (!(s & XN_ISR_NOENABLE)) xnarch_end_irq(irq); + xnstat_exectime_switch(sched, prev); + if (--sched->inesting == 0) { __clrbits(sched->lflags, XNINIRQ); xnpod_schedule(); } trace_mark(xn_nucleus, irq_exit, "irq %u", irq); - xnstat_exectime_switch(sched, prev); } int __init xnintr_mount(void) _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git