summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatt <matt@NetBSD.org>2014-03-03 08:50:48 +0000
committermatt <matt@NetBSD.org>2014-03-03 08:50:48 +0000
commit94de2ce59195003e435c6a9a140f09880103fd28 (patch)
tree33a36dd6f0c3d61c04308313f95f1908d193d9be
parent96ddf8082a3820233e1ca5bdd25e9df8a05d2d61 (diff)
Add a mpsafe flag to the intrsource
-rw-r--r--sys/arch/arm/pic/pic.c36
-rw-r--r--sys/arch/arm/pic/picvar.h3
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];
};