diff options
| author | matt <matt@NetBSD.org> | 2014-03-03 08:50:48 +0000 |
|---|---|---|
| committer | matt <matt@NetBSD.org> | 2014-03-03 08:50:48 +0000 |
| commit | 94de2ce59195003e435c6a9a140f09880103fd28 (patch) | |
| tree | 33a36dd6f0c3d61c04308313f95f1908d193d9be | |
| parent | 96ddf8082a3820233e1ca5bdd25e9df8a05d2d61 (diff) | |
Add a mpsafe flag to the intrsource
| -rw-r--r-- | sys/arch/arm/pic/pic.c | 36 | ||||
| -rw-r--r-- | sys/arch/arm/pic/picvar.h | 3 |
2 files changed, 26 insertions, 13 deletions
diff --git a/sys/arch/arm/pic/pic.c b/sys/arch/arm/pic/pic.c index 2a7db57055a..f96d9fb733a 100644 --- a/sys/arch/arm/pic/pic.c +++ b/sys/arch/arm/pic/pic.c @@ -1,4 +1,4 @@ -/* $NetBSD: pic.c,v 1.19 2014/01/28 13:20:30 martin Exp $ */ +/* $NetBSD: pic.c,v 1.20 2014/03/03 08:50:48 matt Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. * All rights reserved. @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.19 2014/01/28 13:20:30 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.20 2014/03/03 08:50:48 matt Exp $"); #define _INTR_PRIVATE #include <sys/param.h> @@ -255,18 +255,27 @@ pic_find_pending_irqs_by_ipl(struct pic_softc *pic, size_t irq_base, void pic_dispatch(struct intrsource *is, void *frame) { - int rv __unused; - - if (__predict_false(is->is_arg == NULL) - && __predict_true(frame != NULL)) { - rv = (*is->is_func)(frame); - } else if (__predict_true(is->is_arg != NULL)) { - rv = (*is->is_func)(is->is_arg); - } else { - pic_deferral_ev.ev_count++; - return; + int (*func)(void *) = is->is_func; + void *arg = is->is_arg; + + if (__predict_false(arg == NULL)) { + if (__predict_false(frame == NULL)) { + pic_deferral_ev.ev_count++; + return; + } + arg = frame; } +#ifdef MULTIPROCESSOR + if (!is->is_mpsafe) { + KERNEL_LOCK(1, NULL); + (void)(*func)(arg); + KERNEL_UNLOCK_ONE(NULL); + } else +#endif + (void)(*func)(arg); + + struct pic_percpu * const pcpu = percpu_getref(is->is_pic->pic_percpu); KASSERT(pcpu->pcpu_magic == PICPERCPU_MAGIC); pcpu->pcpu_evs[is->is_irq].ev_count++; @@ -607,6 +616,9 @@ pic_establish_intr(struct pic_softc *pic, int irq, int ipl, int type, is->is_type = type; is->is_func = func; is->is_arg = arg; +#ifdef MULTIPROCESSOR + is->is_mpsafe = false; +#endif if (pic->pic_ops->pic_source_name) (*pic->pic_ops->pic_source_name)(pic, irq, is->is_source, diff --git a/sys/arch/arm/pic/picvar.h b/sys/arch/arm/pic/picvar.h index f4eb83d85fe..5f9d96e40b9 100644 --- a/sys/arch/arm/pic/picvar.h +++ b/sys/arch/arm/pic/picvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: picvar.h,v 1.7 2012/09/01 00:00:42 matt Exp $ */ +/* $NetBSD: picvar.h,v 1.8 2014/03/03 08:50:48 matt Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. * All rights reserved. @@ -99,6 +99,7 @@ struct intrsource { uint8_t is_ipl; /* IPL_xxx */ uint8_t is_irq; /* local to pic */ uint8_t is_iplidx; + bool is_mpsafe; char is_source[16]; }; |
