summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2011-07-16 20:16:49 +0000
committermarcel <marcel@FreeBSD.org>2011-07-16 20:16:49 +0000
commit87a4ad12f030ac678b2f894a8a168c4b219e3eeb (patch)
tree34b390d20c53cc78182274efbe2fa8340a773b2c /sys/ia64
parent21706948a50344e60f249fb0738da4912bd4ba3e (diff)
downloadFreeBSD-src-87a4ad12f030ac678b2f894a8a168c4b219e3eeb.zip
FreeBSD-src-87a4ad12f030ac678b2f894a8a168c4b219e3eeb.tar.gz
Don't send EOI to the CPU before we handled the interrupt. This could
potentially trigger multiple pending interrupts for level-sensitive interrupts. However, the event timer interrupt does need EOI before being handled to avoid missing clock events. These conflicting requirements are handled by having the XIV handler inform the dispatch code whether or not it send EOI to the CPU. If not, the dispatch code will do it. This allows handlers to send EOI before doing potentially long-running activities, while still have a sensible default behaviour.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/clock.c4
-rw-r--r--sys/ia64/ia64/interrupt.c7
2 files changed, 7 insertions, 4 deletions
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c
index 96d07c4..24623c5 100644
--- a/sys/ia64/ia64/clock.c
+++ b/sys/ia64/ia64/clock.c
@@ -91,12 +91,14 @@ ia64_ih_clock(struct thread *td, u_int xiv, struct trapframe *tf)
ia64_set_itm(itc + load);
} else
ia64_set_itv((1 << 16) | xiv);
+
+ ia64_set_eoi(0);
ia64_srlz_d();
et = &ia64_clock_et;
if (et->et_active)
et->et_event_cb(et, et->et_arg);
- return (0);
+ return (1);
}
/*
diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c
index 27d5e60..c2372b2 100644
--- a/sys/ia64/ia64/interrupt.c
+++ b/sys/ia64/ia64/interrupt.c
@@ -320,11 +320,12 @@ ia64_handle_intr(struct trapframe *tf)
td->td_intr_frame = tf;
do {
- ia64_set_eoi(0);
- ia64_srlz_d();
CTR2(KTR_INTR, "INTR: ITC=%u, XIV=%u",
(u_int)tf->tf_special.ifa, xiv);
- (ia64_handler[xiv])(td, xiv, tf);
+ if (!(ia64_handler[xiv])(td, xiv, tf)) {
+ ia64_set_eoi(0);
+ ia64_srlz_d();
+ }
xiv = ia64_get_ivr();
ia64_srlz_d();
} while (xiv != 15);
OpenPOWER on IntegriCloud