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