diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2013-05-16 19:26:05 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2013-05-16 19:26:05 +0000 |
commit | 6554a6921bfa3d3903eeea601beb22088b02273a (patch) | |
tree | 3e092a1f21e75c043fd090b47d6262f870dc62bc /sys/arch/i386 | |
parent | 4feef0c81a9728fd079125ca763dcf683534af4c (diff) |
Implement a mechanism to establish interrupt handlers that don't grab the
kernel lock upon entry through a new IPL_MPSAFE flag/level.
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/i386/ioapic.c | 6 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 7 | ||||
-rw-r--r-- | sys/arch/i386/include/intrdefs.h | 4 | ||||
-rw-r--r-- | sys/arch/i386/include/psl.h | 3 | ||||
-rw-r--r-- | sys/arch/i386/isa/isa_machdep.c | 8 | ||||
-rw-r--r-- | sys/arch/i386/pci/pci_machdep.c | 7 |
6 files changed, 28 insertions, 7 deletions
diff --git a/sys/arch/i386/i386/ioapic.c b/sys/arch/i386/i386/ioapic.c index fef840abb44..0b0c6b880b3 100644 --- a/sys/arch/i386/i386/ioapic.c +++ b/sys/arch/i386/i386/ioapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ioapic.c,v 1.27 2012/07/09 16:09:47 deraadt Exp $ */ +/* $OpenBSD: ioapic.c,v 1.28 2013/05/16 19:26:04 kettenis Exp $ */ /* $NetBSD: ioapic.c,v 1.7 2003/07/14 22:32:40 lukem Exp $ */ /*- @@ -672,6 +672,10 @@ apic_intr_establish(int irq, int type, int level, int (*ih_fun)(void *), extern int cold; int minlevel, maxlevel; extern void intr_calculatemasks(void); /* XXX */ + int flags; + + flags = level & IPL_MPSAFE; + level &= ~IPL_MPSAFE; if (sc == NULL) panic("apic_intr_establish: unknown ioapic %d", ioapic); diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 2faff50ffd2..36ba79d3691 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.521 2013/05/12 14:15:31 ratchov Exp $ */ +/* $OpenBSD: machdep.c,v 1.522 2013/05/16 19:26:04 kettenis Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -3942,7 +3942,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/i386/include/intrdefs.h b/sys/arch/i386/include/intrdefs.h index 9bb0ea26cd9..0384febd3f8 100644 --- a/sys/arch/i386/include/intrdefs.h +++ b/sys/arch/i386/include/intrdefs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intrdefs.h,v 1.13 2011/07/05 17:11:07 oga Exp $ */ +/* $OpenBSD: intrdefs.h,v 1.14 2013/05/16 19:26:04 kettenis Exp $ */ /* $NetBSD: intrdefs.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $ */ #ifndef _I386_INTRDEFS_H @@ -70,6 +70,8 @@ #define IPL_HIGH MAKEIPL(10) /* everything */ #define IPL_IPI MAKEIPL(11) /* interprocessor interrupt */ +#define IPL_MPSAFE 0x100 + /* Interrupt sharing types. */ #define IST_NONE 0 /* none */ #define IST_PULSE 1 /* pulsed */ diff --git a/sys/arch/i386/include/psl.h b/sys/arch/i386/include/psl.h index 6d4e12a3572..819935d8256 100644 --- a/sys/arch/i386/include/psl.h +++ b/sys/arch/i386/include/psl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: psl.h,v 1.19 2011/06/08 22:57:59 kettenis Exp $ */ +/* $OpenBSD: psl.h,v 1.20 2013/05/16 19:26:04 kettenis Exp $ */ /* $NetBSD: psl.h,v 1.30 1996/05/13 01:28:05 mycroft Exp $ */ /*- @@ -86,6 +86,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_irq; diff --git a/sys/arch/i386/isa/isa_machdep.c b/sys/arch/i386/isa/isa_machdep.c index 5457f2ddd1d..ad2b74f6796 100644 --- a/sys/arch/i386/isa/isa_machdep.c +++ b/sys/arch/i386/isa/isa_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isa_machdep.c,v 1.72 2011/04/16 00:40:58 deraadt Exp $ */ +/* $OpenBSD: isa_machdep.c,v 1.73 2013/05/16 19:26:04 kettenis Exp $ */ /* $NetBSD: isa_machdep.c,v 1.22 1997/06/12 23:57:32 thorpej Exp $ */ /*- @@ -460,6 +460,7 @@ isa_intr_establish(isa_chipset_tag_t ic, int irq, int type, int level, { struct intrhand **p, *q, *ih; static struct intrhand fakehand = {fakeintr}; + int flags; #if NIOAPIC > 0 struct mp_intr_map *mip; @@ -496,6 +497,10 @@ isa_intr_establish(isa_chipset_tag_t ic, int irq, int type, int level, ih_arg, ih_what)); } #endif + + flags = level & IPL_MPSAFE; + level &= ~IPL_MPSAFE; + /* no point in sleeping unless someone can free memory. */ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); if (ih == NULL) { @@ -555,6 +560,7 @@ isa_intr_establish(isa_chipset_tag_t ic, int irq, int type, int level, ih->ih_arg = ih_arg; ih->ih_next = NULL; ih->ih_level = level; + ih->ih_flags = flags; ih->ih_irq = irq; evcount_attach(&ih->ih_count, ih_what, &ih->ih_irq); *p = ih; diff --git a/sys/arch/i386/pci/pci_machdep.c b/sys/arch/i386/pci/pci_machdep.c index 334d5748f03..c2331b1f39e 100644 --- a/sys/arch/i386/pci/pci_machdep.c +++ b/sys/arch/i386/pci/pci_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.c,v 1.73 2012/09/25 10:32:54 sthen Exp $ */ +/* $OpenBSD: pci_machdep.c,v 1.74 2013/05/16 19:26:04 kettenis Exp $ */ /* $NetBSD: pci_machdep.c,v 1.28 1997/06/06 23:29:17 thorpej Exp $ */ /*- @@ -782,6 +782,10 @@ pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level, struct intrhand *ih; pcireg_t reg, addr; int off, vec; + int flags; + + flags = level & IPL_MPSAFE; + level &= ~IPL_MPSAFE; if (pci_get_capability(pc, tag, PCI_CAP_MSI, &off, ®) == 0) panic("%s: no msi capability", __func__); @@ -798,6 +802,7 @@ pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level, ih->ih_arg = arg; ih->ih_next = NULL; ih->ih_level = level; + ih->ih_flags = flags; ih->ih_irq = irq; ih->ih_pin = tag.mode1; ih->ih_vec = vec; |