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

Reply via email to