Module Name: src
Committed By: skrll
Date: Sat Apr 18 14:09:32 UTC 2015
Modified Files:
src/sys/arch/arm/pic: pic.c
Log Message:
Serialise work in pic_add.
To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/arm/pic/pic.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/pic/pic.c
diff -u src/sys/arch/arm/pic/pic.c:1.34 src/sys/arch/arm/pic/pic.c:1.35
--- src/sys/arch/arm/pic/pic.c:1.34 Wed Apr 15 15:45:06 2015
+++ src/sys/arch/arm/pic/pic.c Sat Apr 18 14:09:32 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: pic.c,v 1.34 2015/04/15 15:45:06 matt Exp $ */
+/* $NetBSD: pic.c,v 1.35 2015/04/18 14:09:32 skrll Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -33,7 +33,7 @@
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.34 2015/04/15 15:45:06 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.35 2015/04/18 14:09:32 skrll Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -42,6 +42,8 @@ __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.34
#include <sys/intr.h>
#include <sys/kernel.h>
#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/once.h>
#include <sys/xcall.h>
#include <sys/ipi.h>
@@ -98,11 +100,15 @@ struct intrsource **pic_iplsource[NIPL]
[0 ... NIPL-1] = pic__iplsources,
};
size_t pic_ipl_offset[NIPL+1];
+
+static kmutex_t pic_lock;
size_t pic_sourcebase;
static struct evcnt pic_deferral_ev =
EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "deferred", "intr");
EVCNT_ATTACH_STATIC(pic_deferral_ev);
+static int pic_init(void);
+
#ifdef __HAVE_PIC_SET_PRIORITY
void
pic_set_priority(struct cpu_info *ci, int newipl)
@@ -622,10 +628,23 @@ pic_pending_zero(void *v0, void *v1, str
}
#endif /* __HAVE_PIC_PENDING_INTRS && MULTIPROCESSOR */
+static int
+pic_init(void)
+{
+
+ mutex_init(&pic_lock, MUTEX_DEFAULT, IPL_HIGH);
+
+ return 0;
+}
+
void
pic_add(struct pic_softc *pic, int irqbase)
{
int slot, maybe_slot = -1;
+ size_t sourcebase;
+ static ONCE_DECL(pic_once);
+
+ RUN_ONCE(&pic_once, pic_init);
KASSERT(strlen(pic->pic_name) > 0);
@@ -641,6 +660,7 @@ pic_add(struct pic_softc *pic, int irqba
}
#endif /* __HAVE_PIC_PENDING_INTRS && MULTIPROCESSOR */
+ mutex_enter(&pic_lock);
for (slot = 0; slot < PIC_MAXPICS; slot++) {
struct pic_softc * const xpic = pic_list[slot];
if (xpic == NULL) {
@@ -669,6 +689,10 @@ pic_add(struct pic_softc *pic, int irqba
KASSERTMSG(pic->pic_maxsources <= PIC_MAXSOURCES, "%zu",
pic->pic_maxsources);
KASSERT(pic_sourcebase + pic->pic_maxsources <= PIC_MAXMAXSOURCES);
+ sourcebase = pic_sourcebase;
+ pic_sourcebase += pic->pic_maxsources;
+
+ mutex_exit(&pic_lock);
/*
* Allocate a pointer to each cpu's evcnts and then, for each cpu,
@@ -686,9 +710,8 @@ pic_add(struct pic_softc *pic, int irqba
*/
percpu_foreach(pic->pic_percpu, pic_percpu_allocate, pic);
- pic->pic_sources = &pic_sources[pic_sourcebase];
+ pic->pic_sources = &pic_sources[sourcebase];
pic->pic_irqbase = irqbase;
- pic_sourcebase += pic->pic_maxsources;
pic->pic_id = slot;
#ifdef __HAVE_PIC_SET_PRIORITY
KASSERT((slot == 0) == (pic->pic_ops->pic_set_priority != NULL));