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));

Reply via email to