summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2015-09-26 04:05:43 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2015-09-26 04:05:43 +0000
commit05bf2c82dcc92186f9f4d44be819da1e8c4f84db (patch)
tree0729a8d02283d3da7d7841d7cc1d5c988436d638 /sys
parentd65c7af0283e6177490f92894adf560c07246ccf (diff)
Let MP-safe interrupt handlers run without the kernel lock on octeon.
ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/octeon/dev/octeon_intr.c22
-rw-r--r--sys/arch/octeon/include/intr.h5
2 files changed, 19 insertions, 8 deletions
diff --git a/sys/arch/octeon/dev/octeon_intr.c b/sys/arch/octeon/dev/octeon_intr.c
index 65f77e719f1..fecaa63d45b 100644
--- a/sys/arch/octeon/dev/octeon_intr.c
+++ b/sys/arch/octeon/dev/octeon_intr.c
@@ -91,6 +91,7 @@ octeon_intr_establish(int irq, int level,
{
int cpuid = cpu_number();
struct intrhand **p, *q, *ih;
+ int flags;
int s;
#ifdef DIAGNOSTIC
@@ -98,6 +99,9 @@ octeon_intr_establish(int irq, int level,
panic("intr_establish: illegal irq %d", irq);
#endif
+ flags = (level & IPL_MPSAFE) ? IH_MPSAFE : 0;
+ level &= ~IPL_MPSAFE;
+
ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
if (ih == NULL)
return NULL;
@@ -106,6 +110,7 @@ octeon_intr_establish(int irq, int level,
ih->ih_fun = ih_fun;
ih->ih_arg = ih_arg;
ih->ih_level = level;
+ ih->ih_flags = flags;
ih->ih_irq = irq;
evcount_attach(&ih->ih_count, ih_what, (void *)&ih->ih_irq);
@@ -272,15 +277,21 @@ octeon_iointr(uint32_t hwpend, struct trap_frame *frame)
ih = ih->ih_next) {
#ifdef MULTIPROCESSOR
register_t sr;
+ int need_lock;
#endif
splraise(ih->ih_level);
#ifdef MULTIPROCESSOR
if (ih->ih_level < IPL_IPI) {
sr = getsr();
ENABLEIPI();
- if (ih->ih_level < IPL_CLOCK)
- __mp_lock(&kernel_lock);
}
+ if (ih->ih_flags & IH_MPSAFE)
+ need_lock = 0;
+ else
+ need_lock =
+ ih->ih_level < IPL_CLOCK;
+ if (need_lock)
+ __mp_lock(&kernel_lock);
#endif
if ((*ih->ih_fun)(ih->ih_arg) != 0) {
rc = 1;
@@ -288,11 +299,10 @@ octeon_iointr(uint32_t hwpend, struct trap_frame *frame)
&ih->ih_count.ec_count);
}
#ifdef MULTIPROCESSOR
- if (ih->ih_level < IPL_IPI) {
- if (ih->ih_level < IPL_CLOCK)
- __mp_unlock(&kernel_lock);
+ if (need_lock)
+ __mp_unlock(&kernel_lock);
+ if (ih->ih_level < IPL_IPI)
setsr(sr);
- }
#endif
__asm__ (".set noreorder\n");
ci->ci_ipl = ipl;
diff --git a/sys/arch/octeon/include/intr.h b/sys/arch/octeon/include/intr.h
index c5e78f6bcf6..51afa341243 100644
--- a/sys/arch/octeon/include/intr.h
+++ b/sys/arch/octeon/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.5 2015/09/13 20:38:45 kettenis Exp $ */
+/* $OpenBSD: intr.h,v 1.6 2015/09/26 04:05:42 visa Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -62,7 +62,7 @@
#define IPL_MPFLOOR IPL_TTY
/* Interrupt priority 'flags'. */
-#define IPL_MPSAFE 0 /* no "mpsafe" interrupts */
+#define IPL_MPSAFE 0x100
/* Interrupt sharing types. */
#define IST_NONE 0 /* none */
@@ -171,6 +171,7 @@ struct intrhand {
struct evcount ih_count;
int ih_flags;
#define IH_ALLOCATED 0x01
+#define IH_MPSAFE 0x02
};
void intr_barrier(void *);