summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2013-05-16 19:26:05 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2013-05-16 19:26:05 +0000
commit6554a6921bfa3d3903eeea601beb22088b02273a (patch)
tree3e092a1f21e75c043fd090b47d6262f870dc62bc /sys
parent4feef0c81a9728fd079125ca763dcf683534af4c (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')
-rw-r--r--sys/arch/i386/i386/ioapic.c6
-rw-r--r--sys/arch/i386/i386/machdep.c7
-rw-r--r--sys/arch/i386/include/intrdefs.h4
-rw-r--r--sys/arch/i386/include/psl.h3
-rw-r--r--sys/arch/i386/isa/isa_machdep.c8
-rw-r--r--sys/arch/i386/pci/pci_machdep.c7
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, &reg) == 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;