diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2013-05-16 16:20:01 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2013-05-16 16:20:01 +0000 |
commit | 54dc01e5e011f2625fbdfacb41abd6bc873f9e37 (patch) | |
tree | 4d702c401ef996613338c3fc851ca4cf01f1e670 | |
parent | 627151165ba1fcf359d08ea37f72c1b6e866691a (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.c | 12 | ||||
-rw-r--r-- | sys/arch/amd64/include/intr.h | 3 | ||||
-rw-r--r-- | sys/arch/amd64/include/intrdefs.h | 10 |
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 */ |