Module Name:    src
Committed By:   matt
Date:           Thu Jan 19 17:28:51 UTC 2012

Modified Files:
        src/sys/arch/mips/rmi [matt-nb5-mips64]: rmixl_gpio_pci.c

Log Message:
Fix percpu usage.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.5 -r1.1.2.6 src/sys/arch/mips/rmi/rmixl_gpio_pci.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/mips/rmi/rmixl_gpio_pci.c
diff -u src/sys/arch/mips/rmi/rmixl_gpio_pci.c:1.1.2.5 src/sys/arch/mips/rmi/rmixl_gpio_pci.c:1.1.2.6
--- src/sys/arch/mips/rmi/rmixl_gpio_pci.c:1.1.2.5	Wed Jan  4 16:17:53 2012
+++ src/sys/arch/mips/rmi/rmixl_gpio_pci.c	Thu Jan 19 17:28:50 2012
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: rmixl_gpio_pci.c,v 1.1.2.5 2012/01/04 16:17:53 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: rmixl_gpio_pci.c,v 1.1.2.6 2012/01/19 17:28:50 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -37,6 +37,7 @@ __KERNEL_RCSID(1, "$NetBSD: rmixl_gpio_p
 #include <sys/device.h>
 #include <sys/gpio.h>
 #include <sys/percpu.h>
+#include <sys/kmem.h>
 
 #include "locators.h"
 #include "gpio.h"
@@ -262,10 +263,14 @@ xlgpio_pci_attach(device_t parent, devic
 	}
 
 	/*
-	 * Allocate the evcnts for each pin (regardless if it's available or
-	 * not) on each cpu and then attach the evcnt for each pin.
+	 * Allocate a pointer to each cpu's evcnts and then, for each cpu,
+	 * allocate its evcnts and then attach an evcnt for each pin.
+	 * We can't allocate the evcnt structures directly since
+	 * percpu will move the contents of percpu memory around and 
+	 * corrupt the pointers in the evcnts themselves.  Remember, any
+	 * problem can be solved with sufficient indirection.
 	 */
-	sc->sc_percpu_evs = percpu_alloc(sc->sc_pincnt * sizeof(struct evcnt));
+	sc->sc_percpu_evs = percpu_alloc(sizeof(struct evcnt *));
 	KASSERT(sc->sc_percpu_evs != NULL);
 
 	/*
@@ -354,7 +359,7 @@ xlgpio_group_intr(struct xlgpio_softc *s
 	uint32_t intlevel = (sts & ~gg->gg_inttype);
 
 	struct evcnt * const evs =
-	    (struct evcnt *)percpu_getref(sc->sc_percpu_evs) + group * PINGROUP;
+	    *(struct evcnt **)percpu_getref(sc->sc_percpu_evs) + group * PINGROUP;
 	
 	while (sts != 0) {
 		const int pin = PINMASK - __builtin_clz(sts);
@@ -421,9 +426,14 @@ xlgpio_vm_intr(void *v)
 void
 xlgpio_percpu_evcnt_attach(void *v0, void *v1, struct cpu_info *ci)
 {
-	struct evcnt * const evs = v0;
+	struct evcnt ** const evs_p = v0;
 	struct xlgpio_softc * const sc = v1;
 	const char * const xname = device_xname(ci->ci_dev);
+	struct evcnt *evs;
+
+	evs = kmem_zalloc(sc->sc_pincnt * sizeof(*evs), KM_SLEEP);
+	KASSERT(evs != NULL);
+	*evs_p = evs;
 
 	for (size_t pin = 0; pin < sc->sc_pincnt; pin++) {
 		struct xlgpio_intrpin * const gip = &sc->sc_pins[pin];

Reply via email to