summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2013-05-16 16:20:01 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2013-05-16 16:20:01 +0000
commit54dc01e5e011f2625fbdfacb41abd6bc873f9e37 (patch)
tree4d702c401ef996613338c3fc851ca4cf01f1e670
parent627151165ba1fcf359d08ea37f72c1b6e866691a (diff)
Implement a mechanism to establish interrupt handlers that don't grab the
kernel lock upon entry through a new IPL_MPSAFE flag/level. ok mikeb@, mpi@
-rw-r--r--sys/arch/amd64/amd64/intr.c12
-rw-r--r--sys/arch/amd64/include/intr.h3
-rw-r--r--sys/arch/amd64/include/intrdefs.h10
3 files changed, 18 insertions, 7 deletions
diff --git a/sys/arch/amd64/amd64/intr.c b/sys/arch/amd64/amd64/intr.c
index 6175d7de464..f5958ded7c9 100644
--- a/sys/arch/amd64/amd64/intr.c
+++ b/sys/arch/amd64/amd64/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.33 2013/05/12 14:15:31 ratchov Exp $ */
+/* $OpenBSD: intr.c,v 1.34 2013/05/16 16:20:00 kettenis Exp $ */
/* $NetBSD: intr.c,v 1.3 2003/03/03 22:16:20 fvdl Exp $ */
/*
@@ -343,6 +343,7 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
int slot, error, idt_vec;
struct intrsource *source;
struct intrstub *stubp;
+ int flags;
#ifdef DIAGNOSTIC
if (legacy_irq != -1 && (legacy_irq < 0 || legacy_irq > 15))
@@ -352,6 +353,9 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
panic("intr_establish: non-legacy IRQ on i8259");
#endif
+ flags = level & IPL_MPSAFE;
+ level &= ~IPL_MPSAFE;
+
error = intr_allocate_slot(pic, legacy_irq, pin, level, &ci, &slot,
&idt_vec);
if (error != 0) {
@@ -426,6 +430,7 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
ih->ih_arg = arg;
ih->ih_next = *p;
ih->ih_level = level;
+ ih->ih_flags = flags;
ih->ih_pin = pin;
ih->ih_cpu = ci;
ih->ih_slot = slot;
@@ -530,7 +535,10 @@ intr_handler(struct intrframe *frame, struct intrhand *ih)
#ifdef MULTIPROCESSOR
int need_lock;
- need_lock = frame->if_ppl < IPL_SCHED;
+ if (ih->ih_flags & IPL_MPSAFE)
+ need_lock = 0;
+ else
+ need_lock = frame->if_ppl < IPL_SCHED;
if (need_lock)
__mp_lock(&kernel_lock);
diff --git a/sys/arch/amd64/include/intr.h b/sys/arch/amd64/include/intr.h
index a4f6674f12e..e6532369e5c 100644
--- a/sys/arch/amd64/include/intr.h
+++ b/sys/arch/amd64/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.24 2013/05/12 14:15:31 ratchov Exp $ */
+/* $OpenBSD: intr.h,v 1.25 2013/05/16 16:20:00 kettenis Exp $ */
/* $NetBSD: intr.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $ */
/*-
@@ -92,6 +92,7 @@ struct intrhand {
int (*ih_fun)(void *);
void *ih_arg;
int ih_level;
+ int ih_flags;
struct intrhand *ih_next;
int ih_pin;
int ih_slot;
diff --git a/sys/arch/amd64/include/intrdefs.h b/sys/arch/amd64/include/intrdefs.h
index 2ac495d5761..0d76886cc95 100644
--- a/sys/arch/amd64/include/intrdefs.h
+++ b/sys/arch/amd64/include/intrdefs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intrdefs.h,v 1.9 2011/06/16 19:46:40 kettenis Exp $ */
+/* $OpenBSD: intrdefs.h,v 1.10 2013/05/16 16:20:00 kettenis Exp $ */
/* $NetBSD: intrdefs.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $ */
#ifndef _AMD64_INTRDEFS_H
@@ -28,12 +28,14 @@
#define IPL_VM 0xa /* memory allocation */
#define IPL_AUDIO 0xb /* audio */
#define IPL_CLOCK 0xc /* clock */
-#define IPL_SCHED IPL_CLOCK
-#define IPL_STATCLOCK IPL_CLOCK
+#define IPL_SCHED IPL_CLOCK
+#define IPL_STATCLOCK IPL_CLOCK
#define IPL_HIGH 0xd /* everything */
-#define IPL_IPI 0xe /* inter-processor interrupts */
+#define IPL_IPI 0xe /* inter-processor interrupts */
#define NIPL 16
+#define IPL_MPSAFE 0x100
+
/* Interrupt sharing types. */
#define IST_NONE 0 /* none */
#define IST_PULSE 1 /* pulsed */