Date: Wed, 23 Jun 2010 22:33:03 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r209486 - in head/sys/powerpc: aim include mpc85xx powermac powerpc Message-ID: <201006232233.o5NMX3w4099776@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Wed Jun 23 22:33:03 2010 New Revision: 209486 URL: http://svn.freebsd.org/changeset/base/209486 Log: Configure interrupts on SMP systems to be distributed among all online CPUs by default, and provide a functional version of BUS_BIND_INTR(). While here, fix some potential concurrency problems in the interrupt handling code. Modified: head/sys/powerpc/aim/nexus.c head/sys/powerpc/include/intr_machdep.h head/sys/powerpc/include/openpicvar.h head/sys/powerpc/mpc85xx/opic.c head/sys/powerpc/powermac/cpcht.c head/sys/powerpc/powermac/openpic_macio.c head/sys/powerpc/powerpc/intr_machdep.c head/sys/powerpc/powerpc/openpic.c head/sys/powerpc/powerpc/pic_if.m Modified: head/sys/powerpc/aim/nexus.c ============================================================================== --- head/sys/powerpc/aim/nexus.c Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/aim/nexus.c Wed Jun 23 22:33:03 2010 (r209486) @@ -119,6 +119,12 @@ static device_t nexus_add_child(device_t static void nexus_probe_nomatch(device_t, device_t); static int nexus_read_ivar(device_t, device_t, int, uintptr_t *); static int nexus_write_ivar(device_t, device_t, int, uintptr_t); +#ifdef SMP +static int nexus_bind_intr(device_t dev, device_t child, + struct resource *irq, int cpu); +#endif +static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, + enum intr_polarity pol); static int nexus_setup_intr(device_t, device_t, struct resource *, int, driver_filter_t *, driver_intr_t *, void *, void **); static int nexus_teardown_intr(device_t, device_t, struct resource *, @@ -162,6 +168,10 @@ static device_method_t nexus_methods[] = DEVMETHOD(bus_write_ivar, nexus_write_ivar), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), +#ifdef SMP + DEVMETHOD(bus_bind_intr, nexus_bind_intr), +#endif + DEVMETHOD(bus_config_intr, nexus_config_intr), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), @@ -363,6 +373,23 @@ nexus_teardown_intr(device_t dev, device return (powerpc_teardown_intr(cookie)); } +#ifdef SMP +static int +nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu) +{ + + return (powerpc_bind_intr(rman_get_start(irq), cpu)); +} +#endif + +static int +nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, + enum intr_polarity pol) +{ + + return (powerpc_config_intr(irq, trig, pol)); +} + /* * Allocate resources at the behest of a child. This only handles interrupts, * since I/O resources are handled by child busses. Modified: head/sys/powerpc/include/intr_machdep.h ============================================================================== --- head/sys/powerpc/include/intr_machdep.h Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/include/intr_machdep.h Wed Jun 23 22:33:03 2010 (r209486) @@ -56,6 +56,7 @@ int powerpc_enable_intr(void); int powerpc_setup_intr(const char *, u_int, driver_filter_t, driver_intr_t, void *, enum intr_type, void **); int powerpc_teardown_intr(void *); +int powerpc_bind_intr(u_int irq, u_char cpu); int powerpc_config_intr(int, enum intr_trigger, enum intr_polarity); #endif /* _MACHINE_INTR_MACHDEP_H_ */ Modified: head/sys/powerpc/include/openpicvar.h ============================================================================== --- head/sys/powerpc/include/openpicvar.h Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/include/openpicvar.h Wed Jun 23 22:33:03 2010 (r209486) @@ -57,6 +57,7 @@ int openpic_attach(device_t); /* * PIC interface. */ +void openpic_bind(device_t dev, u_int irq, cpumask_t cpumask); void openpic_config(device_t, u_int, enum intr_trigger, enum intr_polarity); void openpic_dispatch(device_t, struct trapframe *); void openpic_enable(device_t, u_int, u_int); Modified: head/sys/powerpc/mpc85xx/opic.c ============================================================================== --- head/sys/powerpc/mpc85xx/opic.c Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/mpc85xx/opic.c Wed Jun 23 22:33:03 2010 (r209486) @@ -57,6 +57,7 @@ static device_method_t openpic_ocpbus_m DEVMETHOD(device_attach, openpic_attach), /* PIC interface */ + DEVMETHOD(pic_bind, openpic_bind), DEVMETHOD(pic_config, openpic_config), DEVMETHOD(pic_dispatch, openpic_dispatch), DEVMETHOD(pic_enable, openpic_enable), Modified: head/sys/powerpc/powermac/cpcht.c ============================================================================== --- head/sys/powerpc/powermac/cpcht.c Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/powermac/cpcht.c Wed Jun 23 22:33:03 2010 (r209486) @@ -751,6 +751,7 @@ static device_method_t openpic_cpcht_me DEVMETHOD(device_attach, openpic_cpcht_attach), /* PIC interface */ + DEVMETHOD(pic_bind, openpic_bind), DEVMETHOD(pic_config, openpic_cpcht_config), DEVMETHOD(pic_dispatch, openpic_dispatch), DEVMETHOD(pic_enable, openpic_cpcht_enable), Modified: head/sys/powerpc/powermac/openpic_macio.c ============================================================================== --- head/sys/powerpc/powermac/openpic_macio.c Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/powermac/openpic_macio.c Wed Jun 23 22:33:03 2010 (r209486) @@ -67,6 +67,7 @@ static device_method_t openpic_macio_me DEVMETHOD(device_attach, openpic_attach), /* PIC interface */ + DEVMETHOD(pic_bind, openpic_bind), DEVMETHOD(pic_config, openpic_config), DEVMETHOD(pic_dispatch, openpic_dispatch), DEVMETHOD(pic_enable, openpic_enable), Modified: head/sys/powerpc/powerpc/intr_machdep.c ============================================================================== --- head/sys/powerpc/powerpc/intr_machdep.c Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/powerpc/intr_machdep.c Wed Jun 23 22:33:03 2010 (r209486) @@ -73,6 +73,7 @@ #include <sys/malloc.h> #include <sys/mutex.h> #include <sys/pcpu.h> +#include <sys/smp.h> #include <sys/syslog.h> #include <sys/vmmeter.h> #include <sys/proc.h> @@ -96,6 +97,7 @@ struct powerpc_intr { device_t pic; u_int intline; u_int vector; + cpumask_t cpu; enum intr_trigger trig; enum intr_polarity pol; }; @@ -127,6 +129,23 @@ intr_init(void *dummy __unused) } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); +#ifdef SMP +static void +smp_intr_init(void *dummy __unused) +{ + struct powerpc_intr *i; + int vector; + + for (vector = 0; vector < nvectors; vector++) { + i = powerpc_intrs[vector]; + if (i != NULL && i->pic == root_pic) + PIC_BIND(i->pic, i->intline, i->cpu); + } +} + +SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL); +#endif + static void intrcnt_setname(const char *name, int index) { @@ -150,11 +169,12 @@ intr_lookup(u_int irq) return (i); } } - mtx_unlock(&intr_table_lock); i = malloc(sizeof(*i), M_INTR, M_NOWAIT); - if (i == NULL) + if (i == NULL) { + mtx_unlock(&intr_table_lock); return (NULL); + } i->event = NULL; i->cntp = NULL; @@ -164,7 +184,12 @@ intr_lookup(u_int irq) i->pic = NULL; i->vector = -1; - mtx_lock(&intr_table_lock); +#ifdef SMP + i->cpu = all_cpus; +#else + i->cpu = 1; +#endif + for (vector = 0; vector < INTR_VECTORS && vector <= nvectors; vector++) { iscan = powerpc_intrs[vector]; @@ -359,6 +384,9 @@ powerpc_setup_intr(const char *name, u_i i->pol != INTR_POLARITY_CONFORM)) PIC_CONFIG(i->pic, i->intline, i->trig, i->pol); + if (!error && i->pic == root_pic) + PIC_BIND(i->pic, i->intline, i->cpu); + if (!error && enable) PIC_ENABLE(i->pic, i->intline, i->vector); } @@ -372,6 +400,27 @@ powerpc_teardown_intr(void *cookie) return (intr_event_remove_handler(cookie)); } +#ifdef SMP +int +powerpc_bind_intr(u_int irq, u_char cpu) +{ + struct powerpc_intr *i; + + i = intr_lookup(irq); + if (i == NULL) + return (ENOMEM); + + if (cpu == NOCPU) + i->cpu = all_cpus; + else + i->cpu = 1 << cpu; + + PIC_BIND(i->pic, i->intline, i->cpu); + + return (intr_event_bind(i->event, cpu)); +} +#endif + int powerpc_config_intr(int irq, enum intr_trigger trig, enum intr_polarity pol) { Modified: head/sys/powerpc/powerpc/openpic.c ============================================================================== --- head/sys/powerpc/powerpc/openpic.c Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/powerpc/openpic.c Wed Jun 23 22:33:03 2010 (r209486) @@ -30,7 +30,9 @@ #include <sys/bus.h> #include <sys/conf.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <sys/rman.h> +#include <sys/sched.h> #include <machine/bus.h> #include <machine/intr.h> @@ -72,11 +74,13 @@ openpic_set_priority(struct openpic_soft u_int tpr; uint32_t x; + sched_pin(); tpr = OPENPIC_PCPU_TPR(PCPU_GET(cpuid)); x = openpic_read(sc, tpr); x &= ~OPENPIC_TPR_MASK; x |= pri; openpic_write(sc, tpr, x); + sched_unpin(); } int @@ -228,6 +232,19 @@ openpic_attach(device_t dev) */ void +openpic_bind(device_t dev, u_int irq, cpumask_t cpumask) +{ + struct openpic_softc *sc; + + /* If we aren't directly connected to the CPU, this won't work */ + if (dev != root_pic) + return; + + sc = device_get_softc(dev); + openpic_write(sc, OPENPIC_IDEST(irq), cpumask); +} + +void openpic_config(device_t dev, u_int irq, enum intr_trigger trig, enum intr_polarity pol) { @@ -313,8 +330,10 @@ openpic_ipi(device_t dev, u_int cpu) struct openpic_softc *sc; sc = device_get_softc(dev); + sched_pin(); openpic_write(sc, OPENPIC_PCPU_IPI_DISPATCH(PCPU_GET(cpuid), 0), 1u << cpu); + sched_unpin(); } void Modified: head/sys/powerpc/powerpc/pic_if.m ============================================================================== --- head/sys/powerpc/powerpc/pic_if.m Wed Jun 23 22:25:52 2010 (r209485) +++ head/sys/powerpc/powerpc/pic_if.m Wed Jun 23 22:33:03 2010 (r209486) @@ -32,6 +32,12 @@ INTERFACE pic; +METHOD void bind { + device_t dev; + u_int irq; + cpumask_t cpumask; +}; + METHOD void config { device_t dev; u_int irq; @@ -73,3 +79,4 @@ METHOD void unmask { device_t dev; u_int irq; }; +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006232233.o5NMX3w4099776>