diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2015-09-26 04:05:43 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2015-09-26 04:05:43 +0000 |
commit | 05bf2c82dcc92186f9f4d44be819da1e8c4f84db (patch) | |
tree | 0729a8d02283d3da7d7841d7cc1d5c988436d638 /sys | |
parent | d65c7af0283e6177490f92894adf560c07246ccf (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.c | 22 | ||||
-rw-r--r-- | sys/arch/octeon/include/intr.h | 5 |
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 *); |