Module Name: src Committed By: rmind Date: Mon May 19 22:47:54 UTC 2014
Modified Files: src/sys/arch/alpha/alpha: ipifuncs.c src/sys/arch/alpha/include: intr.h src/sys/arch/arm/arm32: arm32_machdep.c src/sys/arch/arm/cortex: gic.c src/sys/arch/arm/pic: pic.c picvar.h src/sys/arch/hppa/hppa: ipifuncs.c src/sys/arch/hppa/include: intrdefs.h src/sys/arch/mips/include: intr.h src/sys/arch/mips/mips: cpu_subr.c ipifuncs.c src/sys/arch/powerpc/booke: e500_intr.c src/sys/arch/powerpc/include/booke: intr.h src/sys/arch/powerpc/pic: ipi.c ipivar.h src/sys/arch/powerpc/powerpc: powerpc_machdep.c src/sys/arch/sparc/sparc: cpu.c src/sys/arch/sparc64/sparc64: ipifuncs.c src/sys/arch/vax/include: cpu.h src/sys/arch/vax/vax: multicpu.c src/sys/arch/x86/include: intrdefs.h src/sys/arch/x86/x86: ipi.c src/sys/arch/xen/include: intrdefs.h src/sys/arch/xen/x86: xen_ipi.c src/sys/conf: files src/sys/kern: init_main.c Added Files: src/sys/kern: subr_ipi.c src/sys/sys: ipi.h Log Message: Implement MI IPI interface with cross-call support. To generate a diff of this commit: cvs rdiff -u -r1.47 -r1.48 src/sys/arch/alpha/alpha/ipifuncs.c cvs rdiff -u -r1.70 -r1.71 src/sys/arch/alpha/include/intr.h cvs rdiff -u -r1.104 -r1.105 src/sys/arch/arm/arm32/arm32_machdep.c cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/cortex/gic.c cvs rdiff -u -r1.21 -r1.22 src/sys/arch/arm/pic/pic.c cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/pic/picvar.h cvs rdiff -u -r1.2 -r1.3 src/sys/arch/hppa/hppa/ipifuncs.c cvs rdiff -u -r1.1 -r1.2 src/sys/arch/hppa/include/intrdefs.h cvs rdiff -u -r1.7 -r1.8 src/sys/arch/mips/include/intr.h cvs rdiff -u -r1.16 -r1.17 src/sys/arch/mips/mips/cpu_subr.c cvs rdiff -u -r1.6 -r1.7 src/sys/arch/mips/mips/ipifuncs.c cvs rdiff -u -r1.23 -r1.24 src/sys/arch/powerpc/booke/e500_intr.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/powerpc/include/booke/intr.h cvs rdiff -u -r1.10 -r1.11 src/sys/arch/powerpc/pic/ipi.c cvs rdiff -u -r1.6 -r1.7 src/sys/arch/powerpc/pic/ipivar.h cvs rdiff -u -r1.69 -r1.70 src/sys/arch/powerpc/powerpc/powerpc_machdep.c cvs rdiff -u -r1.244 -r1.245 src/sys/arch/sparc/sparc/cpu.c cvs rdiff -u -r1.47 -r1.48 src/sys/arch/sparc64/sparc64/ipifuncs.c cvs rdiff -u -r1.98 -r1.99 src/sys/arch/vax/include/cpu.h cvs rdiff -u -r1.32 -r1.33 src/sys/arch/vax/vax/multicpu.c cvs rdiff -u -r1.19 -r1.20 src/sys/arch/x86/include/intrdefs.h cvs rdiff -u -r1.23 -r1.24 src/sys/arch/x86/x86/ipi.c cvs rdiff -u -r1.11 -r1.12 src/sys/arch/xen/include/intrdefs.h cvs rdiff -u -r1.17 -r1.18 src/sys/arch/xen/x86/xen_ipi.c cvs rdiff -u -r1.1090 -r1.1091 src/sys/conf/files cvs rdiff -u -r1.454 -r1.455 src/sys/kern/init_main.c cvs rdiff -u -r0 -r1.1 src/sys/kern/subr_ipi.c cvs rdiff -u -r0 -r1.1 src/sys/sys/ipi.h 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/alpha/alpha/ipifuncs.c diff -u src/sys/arch/alpha/alpha/ipifuncs.c:1.47 src/sys/arch/alpha/alpha/ipifuncs.c:1.48 --- src/sys/arch/alpha/alpha/ipifuncs.c:1.47 Tue Jun 14 15:34:22 2011 +++ src/sys/arch/alpha/alpha/ipifuncs.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipifuncs.c,v 1.47 2011/06/14 15:34:22 matt Exp $ */ +/* $NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.47 2011/06/14 15:34:22 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:53 rmind Exp $"); /* * Interprocessor interrupt handlers. @@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v #include <sys/reboot.h> #include <sys/atomic.h> #include <sys/cpu.h> +#include <sys/ipi.h> #include <sys/intr.h> #include <sys/xcall.h> #include <sys/bitops.h> @@ -59,12 +60,13 @@ __KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v typedef void (*ipifunc_t)(struct cpu_info *, struct trapframe *); -void alpha_ipi_halt(struct cpu_info *, struct trapframe *); -void alpha_ipi_microset(struct cpu_info *, struct trapframe *); -void alpha_ipi_imb(struct cpu_info *, struct trapframe *); -void alpha_ipi_ast(struct cpu_info *, struct trapframe *); -void alpha_ipi_pause(struct cpu_info *, struct trapframe *); -void alpha_ipi_xcall(struct cpu_info *, struct trapframe *); +static void alpha_ipi_halt(struct cpu_info *, struct trapframe *); +static void alpha_ipi_microset(struct cpu_info *, struct trapframe *); +static void alpha_ipi_imb(struct cpu_info *, struct trapframe *); +static void alpha_ipi_ast(struct cpu_info *, struct trapframe *); +static void alpha_ipi_pause(struct cpu_info *, struct trapframe *); +static void alpha_ipi_xcall(struct cpu_info *, struct trapframe *); +static void alpha_ipi_generic(struct cpu_info *, struct trapframe *); /* * NOTE: This table must be kept in order with the bit definitions @@ -77,7 +79,8 @@ const ipifunc_t ipifuncs[ALPHA_NIPIS] = [ilog2(ALPHA_IPI_IMB)] = alpha_ipi_imb, [ilog2(ALPHA_IPI_AST)] = alpha_ipi_ast, [ilog2(ALPHA_IPI_PAUSE)] = alpha_ipi_pause, - [ilog2(ALPHA_IPI_XCALL)] = alpha_ipi_xcall + [ilog2(ALPHA_IPI_XCALL)] = alpha_ipi_xcall, + [ilog2(ALPHA_IPI_GENERIC)] = alpha_ipi_generic }; const char * const ipinames[ALPHA_NIPIS] = { @@ -87,7 +90,8 @@ const char * const ipinames[ALPHA_NIPIS] [ilog2(ALPHA_IPI_IMB)] = "imb ipi", [ilog2(ALPHA_IPI_AST)] = "ast ipi", [ilog2(ALPHA_IPI_PAUSE)] = "pause ipi", - [ilog2(ALPHA_IPI_XCALL)] = "xcall ipi" + [ilog2(ALPHA_IPI_XCALL)] = "xcall ipi", + [ilog2(ALPHA_IPI_GENERIC)] = "generic ipi", }; /* @@ -208,7 +212,7 @@ alpha_multicast_ipi(u_long cpumask, u_lo } } -void +static void alpha_ipi_halt(struct cpu_info *ci, struct trapframe *framep) { u_long cpu_id = ci->ci_cpuid; @@ -241,21 +245,21 @@ alpha_ipi_halt(struct cpu_info *ci, stru /* NOTREACHED */ } -void +static void alpha_ipi_microset(struct cpu_info *ci, struct trapframe *framep) { cc_calibrate_cpu(ci); } -void +static void alpha_ipi_imb(struct cpu_info *ci, struct trapframe *framep) { alpha_pal_imb(); } -void +static void alpha_ipi_ast(struct cpu_info *ci, struct trapframe *framep) { @@ -263,7 +267,7 @@ alpha_ipi_ast(struct cpu_info *ci, struc aston(ci->ci_curlwp); } -void +static void alpha_ipi_pause(struct cpu_info *ci, struct trapframe *framep) { u_long cpumask = (1UL << ci->ci_cpuid); @@ -295,17 +299,15 @@ alpha_ipi_pause(struct cpu_info *ci, str * MD support for xcall(9) interface. */ -void +static void alpha_ipi_xcall(struct cpu_info *ci, struct trapframe *framep) { - xc_ipi_handler(); } void xc_send_ipi(struct cpu_info *ci) { - KASSERT(kpreempt_disabled()); KASSERT(curcpu() != ci); @@ -317,3 +319,24 @@ xc_send_ipi(struct cpu_info *ci) alpha_broadcast_ipi(ALPHA_IPI_XCALL); } } + +static void +alpha_ipi_generic(struct cpu_info *ci, struct trapframe *framep) +{ + ipi_cpu_handler(); +} + +void +cpu_ipi(struct cpu_info *ci) +{ + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != ci); + + if (ci) { + /* Unicast: remote CPU. */ + alpha_send_ipi(ci->ci_cpuid, ALPHA_IPI_GENERIC); + } else { + /* Broadcast: all, but local CPU (caller will handle it). */ + alpha_broadcast_ipi(ALPHA_IPI_GENERIC); + } +} Index: src/sys/arch/alpha/include/intr.h diff -u src/sys/arch/alpha/include/intr.h:1.70 src/sys/arch/alpha/include/intr.h:1.71 --- src/sys/arch/alpha/include/intr.h:1.70 Mon Feb 6 02:14:13 2012 +++ src/sys/arch/alpha/include/intr.h Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.70 2012/02/06 02:14:13 matt Exp $ */ +/* $NetBSD: intr.h,v 1.71 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc. @@ -164,8 +164,9 @@ _splraise(int s) #define ALPHA_IPI_AST (1UL << 4) #define ALPHA_IPI_PAUSE (1UL << 5) #define ALPHA_IPI_XCALL (1UL << 6) +#define ALPHA_IPI_GENERIC (1UL << 7) -#define ALPHA_NIPIS 7 /* must not exceed 64 */ +#define ALPHA_NIPIS 8 /* must not exceed 64 */ struct cpu_info; struct trapframe; Index: src/sys/arch/arm/arm32/arm32_machdep.c diff -u src/sys/arch/arm/arm32/arm32_machdep.c:1.104 src/sys/arch/arm/arm32/arm32_machdep.c:1.105 --- src/sys/arch/arm/arm32/arm32_machdep.c:1.104 Fri Apr 11 04:19:47 2014 +++ src/sys/arch/arm/arm32/arm32_machdep.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: arm32_machdep.c,v 1.104 2014/04/11 04:19:47 matt Exp $ */ +/* $NetBSD: arm32_machdep.c,v 1.105 2014/05/19 22:47:53 rmind Exp $ */ /* * Copyright (c) 1994-1998 Mark Brinicombe. @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.104 2014/04/11 04:19:47 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.105 2014/05/19 22:47:53 rmind Exp $"); #include "opt_modular.h" #include "opt_md.h" @@ -65,6 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: arm32_machde #include <sys/module.h> #include <sys/atomic.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <uvm/uvm_extern.h> @@ -706,6 +707,16 @@ xc_send_ipi(struct cpu_info *ci) intr_ipi_send(ci != NULL ? ci->ci_kcpuset : NULL, IPI_XCALL); } + +void +cpu_ipi(struct cpu_info *ci) +{ + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != ci); + + intr_ipi_send(ci != NULL ? ci->ci_kcpuset : NULL, IPI_GENERIC); +} + #endif /* MULTIPROCESSOR */ #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS Index: src/sys/arch/arm/cortex/gic.c diff -u src/sys/arch/arm/cortex/gic.c:1.9 src/sys/arch/arm/cortex/gic.c:1.10 --- src/sys/arch/arm/cortex/gic.c:1.9 Sun Apr 27 16:22:13 2014 +++ src/sys/arch/arm/cortex/gic.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: gic.c,v 1.9 2014/04/27 16:22:13 matt Exp $ */ +/* $NetBSD: gic.c,v 1.10 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. @@ -33,7 +33,7 @@ #define _INTR_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.9 2014/04/27 16:22:13 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.10 2014/05/19 22:47:53 rmind Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -42,7 +42,6 @@ __KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.9 #include <sys/intr.h> #include <sys/cpu.h> #include <sys/proc.h> -#include <sys/xcall.h> /* for xc_ipi_handler */ #include <arm/armreg.h> #include <arm/cpufunc.h> @@ -612,6 +611,8 @@ armgic_attach(device_t parent, device_t pic_ipi_nop, (void *)-1); intr_establish(ARMGIC_SGI_IPIBASE + IPI_XCALL, IPL_VM, IST_EDGE, pic_ipi_xcall, (void *)-1); + intr_establish(ARMGIC_SGI_IPIBASE + IPI_GENERIC, IPL_VM, IST_EDGE, + pic_ipi_generic, (void *)-1); intr_establish(ARMGIC_SGI_IPIBASE + IPI_NOP, IPL_VM, IST_EDGE, pic_ipi_nop, (void *)-1); intr_establish(ARMGIC_SGI_IPIBASE + IPI_SHOOTDOWN, IPL_VM, IST_EDGE, Index: src/sys/arch/arm/pic/pic.c diff -u src/sys/arch/arm/pic/pic.c:1.21 src/sys/arch/arm/pic/pic.c:1.22 --- src/sys/arch/arm/pic/pic.c:1.21 Thu Mar 13 23:47:53 2014 +++ src/sys/arch/arm/pic/pic.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: pic.c,v 1.21 2014/03/13 23:47:53 matt Exp $ */ +/* $NetBSD: pic.c,v 1.22 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. * All rights reserved. @@ -32,7 +32,7 @@ #include "opt_ddb.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.21 2014/03/13 23:47:53 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.22 2014/05/19 22:47:53 rmind Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.21 #include <sys/kernel.h> #include <sys/kmem.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <arm/armreg.h> #include <arm/cpufunc.h> @@ -107,6 +108,13 @@ pic_ipi_xcall(void *arg) return 1; } +int +pic_ipi_generic(void *arg) +{ + ipi_cpu_handler(); + return 1; +} + #ifdef DDB int pic_ipi_ddb(void *arg) Index: src/sys/arch/arm/pic/picvar.h diff -u src/sys/arch/arm/pic/picvar.h:1.9 src/sys/arch/arm/pic/picvar.h:1.10 --- src/sys/arch/arm/pic/picvar.h:1.9 Thu Mar 13 23:47:53 2014 +++ src/sys/arch/arm/pic/picvar.h Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: picvar.h,v 1.9 2014/03/13 23:47:53 matt Exp $ */ +/* $NetBSD: picvar.h,v 1.10 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. * All rights reserved. @@ -49,11 +49,12 @@ struct cpu_info; #define IPI_NOP 2 /* just get an interrupt (armv6) */ #define IPI_SHOOTDOWN 3 /* cause a tlb shootdown */ #define IPI_DDB 4 /* enter DDB */ +#define IPI_GENERIC 5 /* generic IPI */ #ifdef __HAVE_PREEMPTION -#define IPI_KPREEMPT 5 /* cause a preemption */ -#define NIPI 6 +#define IPI_KPREEMPT 6 /* cause a preemption */ +#define NIPI 7 #else -#define NIPI 5 +#define NIPI 6 #endif int pic_handle_intr(void *); @@ -160,6 +161,7 @@ void pic_do_pending_int(void); #ifdef MULTIPROCESSOR int pic_ipi_nop(void *); int pic_ipi_xcall(void *); +int pic_ipi_generic(void *); int pic_ipi_shootdown(void *); int pic_ipi_ddb(void *); #endif Index: src/sys/arch/hppa/hppa/ipifuncs.c diff -u src/sys/arch/hppa/hppa/ipifuncs.c:1.2 src/sys/arch/hppa/hppa/ipifuncs.c:1.3 --- src/sys/arch/hppa/hppa/ipifuncs.c:1.2 Thu Apr 5 16:16:01 2012 +++ src/sys/arch/hppa/hppa/ipifuncs.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipifuncs.c,v 1.2 2012/04/05 16:16:01 skrll Exp $ */ +/* $NetBSD: ipifuncs.c,v 1.3 2014/05/19 22:47:53 rmind Exp $ */ /* $OpenBSD: ipi.c,v 1.4 2011/01/14 13:20:06 jsing Exp $ */ /* @@ -24,6 +24,7 @@ #include <sys/device.h> #include <sys/atomic.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <machine/cpu.h> #include <machine/cpufunc.h> @@ -38,21 +39,22 @@ #include <hppa/hppa/cpuvar.h> -void hppa_ipi_nop(void); -void hppa_ipi_halt(void); -void hppa_ipi_xcall(void); +static void hppa_ipi_nop(void); +static void hppa_ipi_halt(void); void (*ipifunc[HPPA_NIPI])(void) = { hppa_ipi_nop, hppa_ipi_halt, - hppa_ipi_xcall + xc_ipi_handler, + ipi_cpu_handler, }; const char *ipinames[HPPA_NIPI] = { "nop ipi", "halt ipi", "xcall ipi" + "generic ipi" }; void @@ -130,16 +132,16 @@ hppa_ipi_broadcast(u_long ipi) return count; } -void +static void hppa_ipi_nop(void) { } -void +static void hppa_ipi_halt(void) { struct cpu_info *ci = curcpu(); - + /* Turn off interrupts and halt CPU. */ // hppa_intr_disable(); ci->ci_flags &= ~CPUF_RUNNING; @@ -149,24 +151,31 @@ hppa_ipi_halt(void) } void -hppa_ipi_xcall(void) +xc_send_ipi(struct cpu_info *ci) { - - xc_ipi_handler(); + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != ci); + + if (ci) { + /* Unicast: remote CPU. */ + hppa_ipi_send(ci, HPPA_IPI_XCALL); + } else { + /* Broadcast: all, but local CPU (caller will handle it). */ + hppa_ipi_broadcast(HPPA_IPI_XCALL); + } } void -xc_send_ipi(struct cpu_info *ci) +cpu_ipi(struct cpu_info *) { - KASSERT(kpreempt_disabled()); KASSERT(curcpu() != ci); if (ci) { /* Unicast: remote CPU. */ - hppa_ipi_send(ci, HPPA_IPI_XCALL); + hppa_ipi_send(ci, HPPA_IPI_GENERIC); } else { /* Broadcast: all, but local CPU (caller will handle it). */ - hppa_ipi_broadcast(HPPA_IPI_XCALL); + hppa_ipi_broadcast(HPPA_IPI_GENERIC); } } Index: src/sys/arch/hppa/include/intrdefs.h diff -u src/sys/arch/hppa/include/intrdefs.h:1.1 src/sys/arch/hppa/include/intrdefs.h:1.2 --- src/sys/arch/hppa/include/intrdefs.h:1.1 Mon Feb 24 07:23:43 2014 +++ src/sys/arch/hppa/include/intrdefs.h Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: intrdefs.h,v 1.1 2014/02/24 07:23:43 skrll Exp $ */ +/* $NetBSD: intrdefs.h,v 1.2 2014/05/19 22:47:53 rmind Exp $ */ #ifndef _HPPA_INTRDEFS_H_ #define _HPPA_INTRDEFS_H_ @@ -24,7 +24,8 @@ #define HPPA_IPI_NOP 0 #define HPPA_IPI_HALT 1 #define HPPA_IPI_XCALL 2 -#define HPPA_NIPI 3 +#define HPPA_IPI_GENERIC 3 +#define HPPA_NIPI 4 #endif #endif Index: src/sys/arch/mips/include/intr.h diff -u src/sys/arch/mips/include/intr.h:1.7 src/sys/arch/mips/include/intr.h:1.8 --- src/sys/arch/mips/include/intr.h:1.7 Sun Mar 11 00:02:05 2012 +++ src/sys/arch/mips/include/intr.h Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.7 2012/03/11 00:02:05 mrg Exp $ */ +/* $NetBSD: intr.h,v 1.8 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc. @@ -72,7 +72,8 @@ #define IPI_SUSPEND 5 /* DDB suspend signaling */ #define IPI_HALT 6 /* halt cpu */ #define IPI_XCALL 7 /* xcall */ -#define NIPIS 8 +#define IPI_GENERIC 8 /* generic IPI */ +#define NIPIS 9 #ifdef __INTR_PRIVATE struct splsw { Index: src/sys/arch/mips/mips/cpu_subr.c diff -u src/sys/arch/mips/mips/cpu_subr.c:1.16 src/sys/arch/mips/mips/cpu_subr.c:1.17 --- src/sys/arch/mips/mips/cpu_subr.c:1.16 Mon May 21 14:15:18 2012 +++ src/sys/arch/mips/mips/cpu_subr.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu_subr.c,v 1.16 2012/05/21 14:15:18 martin Exp $ */ +/* $NetBSD: cpu_subr.c,v 1.17 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.16 2012/05/21 14:15:18 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.17 2014/05/19 22:47:53 rmind Exp $"); #include "opt_ddb.h" #include "opt_multiprocessor.h" @@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v #include <sys/bitops.h> #include <sys/idle.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <uvm/uvm.h> @@ -928,6 +929,13 @@ xc_send_ipi(struct cpu_info *ci) (*mips_locoresw.lsw_send_ipi)(ci, IPI_XCALL); } + +void +cpu_ipi(struct cpu_info *ci) +{ + (*mips_locoresw.lsw_send_ipi)(ci, IPI_GENERIC); +} + #endif /* MULTIPROCESSOR */ void Index: src/sys/arch/mips/mips/ipifuncs.c diff -u src/sys/arch/mips/mips/ipifuncs.c:1.6 src/sys/arch/mips/mips/ipifuncs.c:1.7 --- src/sys/arch/mips/mips/ipifuncs.c:1.6 Mon May 2 00:17:35 2011 +++ src/sys/arch/mips/mips/ipifuncs.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipifuncs.c,v 1.6 2011/05/02 00:17:35 matt Exp $ */ +/* $NetBSD: ipifuncs.c,v 1.7 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -32,13 +32,14 @@ #include "opt_ddb.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.6 2011/05/02 00:17:35 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.7 2014/05/19 22:47:53 rmind Exp $"); #include <sys/param.h> #include <sys/cpu.h> #include <sys/device.h> #include <sys/intr.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <uvm/uvm_extern.h> @@ -59,6 +60,7 @@ static const char * const ipi_names[] = [IPI_SUSPEND] = "ipi suspend", [IPI_HALT] = "ipi halt", [IPI_XCALL] = "ipi xcall", + [IPI_GENERIC] = "ipi generic", }; static void @@ -139,6 +141,10 @@ ipi_process(struct cpu_info *ci, uint64_ ci->ci_evcnt_per_ipi[IPI_XCALL].ev_count++; xc_ipi_handler(); } + if (ipi_mask & __BIT(IPI_GENERIC)) { + ci->ci_evcnt_per_ipi[IPI_GENERIC].ev_count++; + ipi_cpu_handler(); + } } void Index: src/sys/arch/powerpc/booke/e500_intr.c diff -u src/sys/arch/powerpc/booke/e500_intr.c:1.23 src/sys/arch/powerpc/booke/e500_intr.c:1.24 --- src/sys/arch/powerpc/booke/e500_intr.c:1.23 Sat Mar 29 19:28:29 2014 +++ src/sys/arch/powerpc/booke/e500_intr.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: e500_intr.c,v 1.23 2014/03/29 19:28:29 christos Exp $ */ +/* $NetBSD: e500_intr.c,v 1.24 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -39,7 +39,7 @@ #define __INTR_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.23 2014/03/29 19:28:29 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.24 2014/05/19 22:47:53 rmind Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: e500_intr.c, #include <sys/atomic.h> #include <sys/bus.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <sys/bitops.h> #include <uvm/uvm_extern.h> @@ -1217,6 +1218,7 @@ e500_ipi_kpreempt(void) static const ipifunc_t e500_ipifuncs[] = { [ilog2(IPI_XCALL)] = xc_ipi_handler, + [ilog2(IPI_GENERIC)] = ipi_cpu_handler, [ilog2(IPI_HALT)] = e500_ipi_halt, #ifdef __HAVE_PREEMPTION [ilog2(IPI_KPREEMPT)] = e500_ipi_kpreempt, Index: src/sys/arch/powerpc/include/booke/intr.h diff -u src/sys/arch/powerpc/include/booke/intr.h:1.7 src/sys/arch/powerpc/include/booke/intr.h:1.8 --- src/sys/arch/powerpc/include/booke/intr.h:1.7 Sat Mar 29 19:28:29 2014 +++ src/sys/arch/powerpc/include/booke/intr.h Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.h,v 1.7 2014/03/29 19:28:29 christos Exp $ */ +/* $NetBSD: intr.h,v 1.8 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -73,6 +73,7 @@ #define IPI_XCALL 0x0002 #define IPI_KPREEMPT 0x0004 #define IPI_TLB1SYNC 0x0008 +#define IPI_GENERIC 0x0010 #define __HAVE_FAST_SOFTINTS 1 #define SOFTINT_KPREEMPT SOFTINT_COUNT Index: src/sys/arch/powerpc/pic/ipi.c diff -u src/sys/arch/powerpc/pic/ipi.c:1.10 src/sys/arch/powerpc/pic/ipi.c:1.11 --- src/sys/arch/powerpc/pic/ipi.c:1.10 Mon Jun 20 06:23:52 2011 +++ src/sys/arch/powerpc/pic/ipi.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipi.c,v 1.10 2011/06/20 06:23:52 matt Exp $ */ +/* $NetBSD: ipi.c,v 1.11 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. * All rights reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.10 2011/06/20 06:23:52 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.11 2014/05/19 22:47:53 rmind Exp $"); #include "opt_multiprocessor.h" #include "opt_pic.h" @@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.10 #include <sys/param.h> #include <sys/kernel.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <sys/atomic.h> #include <sys/cpu.h> @@ -71,6 +72,9 @@ ipi_intr(void *v) if (ipi & IPI_XCALL) xc_ipi_handler(); + if (ipi & IPI_GENERIC) + ipi_cpu_handler(); + if (ipi & IPI_HALT) { aprint_normal("halting CPU %d\n", cpu_id); msr = (mfmsr() & ~PSL_EE) | PSL_POW; Index: src/sys/arch/powerpc/pic/ipivar.h diff -u src/sys/arch/powerpc/pic/ipivar.h:1.6 src/sys/arch/powerpc/pic/ipivar.h:1.7 --- src/sys/arch/powerpc/pic/ipivar.h:1.6 Thu Oct 13 19:49:50 2011 +++ src/sys/arch/powerpc/pic/ipivar.h Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipivar.h,v 1.6 2011/10/13 19:49:50 matt Exp $ */ +/* $NetBSD: ipivar.h,v 1.7 2014/05/19 22:47:53 rmind Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. * All rights reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipivar.h,v 1.6 2011/10/13 19:49:50 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipivar.h,v 1.7 2014/05/19 22:47:53 rmind Exp $"); #ifndef _IPI_VAR_H_ #define _IPI_VAR_H_ @@ -54,6 +54,7 @@ struct ipi_ops { #define IPI_HALT 0x0001 #define IPI_XCALL 0x0002 #define IPI_KPREEMPT 0x0004 +#define IPI_GENERIC 0x0008 /* OpenPIC */ void setup_openpic_ipi(void); Index: src/sys/arch/powerpc/powerpc/powerpc_machdep.c diff -u src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.69 src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.70 --- src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.69 Mon Mar 24 19:14:31 2014 +++ src/sys/arch/powerpc/powerpc/powerpc_machdep.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: powerpc_machdep.c,v 1.69 2014/03/24 19:14:31 christos Exp $ */ +/* $NetBSD: powerpc_machdep.c,v 1.70 2014/05/19 22:47:53 rmind Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.69 2014/03/24 19:14:31 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.70 2014/05/19 22:47:53 rmind Exp $"); #include "opt_altivec.h" #include "opt_modular.h" @@ -56,6 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: powerpc_mach #include <sys/atomic.h> #include <sys/kmem.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <dev/mm.h> @@ -488,6 +489,20 @@ xc_send_ipi(struct cpu_info *ci) /* Broadcast: all, but local CPU (caller will handle it). */ cpu_send_ipi(target, IPI_XCALL); } + +void +cpu_ipi(struct cpu_info *ci) +{ + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != ci); + + cpuid_t target = (ci != NULL ? cpu_index(ci) : IPI_DST_NOTME); + + /* Unicast: remote CPU. */ + /* Broadcast: all, but local CPU (caller will handle it). */ + cpu_send_ipi(target, IPI_GENERIC); +} + #endif /* MULTIPROCESSOR */ #ifdef MODULAR Index: src/sys/arch/sparc/sparc/cpu.c diff -u src/sys/arch/sparc/sparc/cpu.c:1.244 src/sys/arch/sparc/sparc/cpu.c:1.245 --- src/sys/arch/sparc/sparc/cpu.c:1.244 Tue Apr 15 10:39:44 2014 +++ src/sys/arch/sparc/sparc/cpu.c Mon May 19 22:47:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.244 2014/04/15 10:39:44 macallan Exp $ */ +/* $NetBSD: cpu.c,v 1.245 2014/05/19 22:47:53 rmind Exp $ */ /* * Copyright (c) 1996 @@ -52,7 +52,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.244 2014/04/15 10:39:44 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.245 2014/05/19 22:47:53 rmind Exp $"); #include "opt_multiprocessor.h" #include "opt_lockdebug.h" @@ -62,10 +62,10 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.24 #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> -#include <sys/malloc.h> #include <sys/kernel.h> #include <sys/evcnt.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <sys/cpu.h> #include <uvm/uvm.h> @@ -814,6 +814,21 @@ xc_send_ipi(struct cpu_info *target) XCALL0(xc_ipi_handler, cpuset); } +void +cpu_ipi(struct cpu_info *target) +{ + u_int cpuset; + + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != target); + + if (target) + cpuset = 1 << target->ci_cpuid; + else + cpuset = CPUSET_ALL & ~(1 << cpuinfo.ci_cpuid); + XCALL0(ipi_cpu_handler, cpuset); +} + /* * Tell all CPUs other than the current one to enter the PROM idle loop. */ Index: src/sys/arch/sparc64/sparc64/ipifuncs.c diff -u src/sys/arch/sparc64/sparc64/ipifuncs.c:1.47 src/sys/arch/sparc64/sparc64/ipifuncs.c:1.48 --- src/sys/arch/sparc64/sparc64/ipifuncs.c:1.47 Thu Nov 8 16:36:53 2012 +++ src/sys/arch/sparc64/sparc64/ipifuncs.c Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipifuncs.c,v 1.47 2012/11/08 16:36:53 nakayama Exp $ */ +/* $NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:54 rmind Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -27,14 +27,14 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.47 2012/11/08 16:36:53 nakayama Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:54 rmind Exp $"); #include "opt_ddb.h" #include <sys/param.h> #include <sys/systm.h> -#include <sys/malloc.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <machine/db_machdep.h> @@ -507,3 +507,10 @@ xc_send_ipi(struct cpu_info *target) sparc64_generic_xcall(target, (ipi_c_call_func_t)xc_ipi_handler, NULL); } + +void +cpu_send_ipi(struct cpu_info *target) +{ + + sparc64_generic_xcall(target, (ipi_c_call_func_t)ipi_cpu_handler, NULL); +} Index: src/sys/arch/vax/include/cpu.h diff -u src/sys/arch/vax/include/cpu.h:1.98 src/sys/arch/vax/include/cpu.h:1.99 --- src/sys/arch/vax/include/cpu.h:1.98 Sun Nov 10 00:50:13 2013 +++ src/sys/arch/vax/include/cpu.h Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.98 2013/11/10 00:50:13 christos Exp $ */ +/* $NetBSD: cpu.h,v 1.99 2014/05/19 22:47:54 rmind Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden @@ -101,6 +101,7 @@ struct cpu_mp_dep { #define IPI_TBIA 4 /* Flush the TLB */ #define IPI_DDB 5 /* Jump into the DDB loop */ #define IPI_XCALL 6 /* Helper for xcall(9) */ +#define IPI_GENERIC 7 /* Generic ipi(9) call */ #define IPI_DEST_MASTER -1 /* Destination is mastercpu */ #define IPI_DEST_ALL -2 /* Broadcast */ Index: src/sys/arch/vax/vax/multicpu.c diff -u src/sys/arch/vax/vax/multicpu.c:1.32 src/sys/arch/vax/vax/multicpu.c:1.33 --- src/sys/arch/vax/vax/multicpu.c:1.32 Sun Jun 5 16:59:21 2011 +++ src/sys/arch/vax/vax/multicpu.c Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: multicpu.c,v 1.32 2011/06/05 16:59:21 matt Exp $ */ +/* $NetBSD: multicpu.c,v 1.33 2014/05/19 22:47:54 rmind Exp $ */ /* * Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: multicpu.c,v 1.32 2011/06/05 16:59:21 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: multicpu.c,v 1.33 2014/05/19 22:47:54 rmind Exp $"); #include "opt_multiprocessor.h" @@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: multicpu.c,v #include <sys/malloc.h> #include <sys/proc.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <uvm/uvm_extern.h> @@ -198,6 +199,9 @@ cpu_handle_ipi(void) case IPI_XCALL: xc_ipi_handler(); break; + case IPI_GENERIC: + ipi_cpu_handler(); + break; default: panic("cpu_handle_ipi: bad bit %x", bitno); } @@ -212,7 +216,6 @@ cpu_handle_ipi(void) void xc_send_ipi(struct cpu_info *ci) { - KASSERT(kpreempt_disabled()); KASSERT(curcpu() != ci); @@ -224,3 +227,18 @@ xc_send_ipi(struct cpu_info *ci) cpu_send_ipi(IPI_DEST_ALL, IPI_XCALL); } } + +void +cpu_ipi(struct cpu_info *ci) +{ + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != ci); + + if (ci) { + /* Unicast: remote CPU. */ + cpu_send_ipi(ci->ci_cpuid, IPI_GENERIC); + } else { + /* Broadcast: all, but local CPU (caller will handle it). */ + cpu_send_ipi(IPI_DEST_ALL, IPI_GENERIC); + } +} Index: src/sys/arch/x86/include/intrdefs.h diff -u src/sys/arch/x86/include/intrdefs.h:1.19 src/sys/arch/x86/include/intrdefs.h:1.20 --- src/sys/arch/x86/include/intrdefs.h:1.19 Sun Dec 1 01:05:16 2013 +++ src/sys/arch/x86/include/intrdefs.h Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: intrdefs.h,v 1.19 2013/12/01 01:05:16 christos Exp $ */ +/* $NetBSD: intrdefs.h,v 1.20 2014/05/19 22:47:54 rmind Exp $ */ #ifndef _X86_INTRDEFS_H_ #define _X86_INTRDEFS_H_ @@ -60,7 +60,7 @@ #define X86_IPI_HALT 0x00000001 #define X86_IPI_MICROSET 0x00000002 -#define X86_IPI__UNUSED1 0x00000004 +#define X86_IPI_GENERIC 0x00000004 #define X86_IPI_SYNCH_FPU 0x00000008 #define X86_IPI_MTRR 0x00000010 #define X86_IPI_GDT 0x00000020 @@ -70,7 +70,7 @@ #define X86_NIPI 9 -#define X86_IPI_NAMES { "halt IPI", "timeset IPI", "unused", \ +#define X86_IPI_NAMES { "halt IPI", "timeset IPI", "generic IPI", \ "FPU synch IPI", "MTRR update IPI", \ "GDT update IPI", "xcall IPI", \ "ACPI CPU sleep IPI", "kpreempt IPI" } Index: src/sys/arch/x86/x86/ipi.c diff -u src/sys/arch/x86/x86/ipi.c:1.23 src/sys/arch/x86/x86/ipi.c:1.24 --- src/sys/arch/x86/x86/ipi.c:1.23 Wed Feb 19 21:23:02 2014 +++ src/sys/arch/x86/x86/ipi.c Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipi.c,v 1.23 2014/02/19 21:23:02 dsl Exp $ */ +/* $NetBSD: ipi.c,v 1.24 2014/05/19 22:47:54 rmind Exp $ */ /*- * Copyright (c) 2000, 2008, 2009 The NetBSD Foundation, Inc. @@ -32,18 +32,19 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.23 2014/02/19 21:23:02 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.24 2014/05/19 22:47:54 rmind Exp $"); #include "opt_mtrr.h" -#include <sys/param.h> +#include <sys/param.h> #include <sys/device.h> #include <sys/systm.h> #include <sys/atomic.h> #include <sys/intr.h> +#include <sys/ipi.h> #include <sys/cpu.h> #include <sys/xcall.h> - + #ifdef MULTIPROCESSOR #include <machine/cpufunc.h> @@ -61,6 +62,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.23 static void x86_ipi_halt(struct cpu_info *); static void x86_ipi_kpreempt(struct cpu_info *); static void x86_ipi_xcall(struct cpu_info *); +static void x86_ipi_generic(struct cpu_info *); #ifdef MTRR static void x86_ipi_reload_mtrr(struct cpu_info *); @@ -80,7 +82,7 @@ void (*ipifunc[X86_NIPI])(struct cpu_inf { x86_ipi_halt, NULL, - NULL, + x86_ipi_generic, x86_ipi_synch_fpu, x86_ipi_reload_mtrr, gdt_reload_cpu, @@ -206,10 +208,15 @@ x86_ipi_kpreempt(struct cpu_info *ci) static void x86_ipi_xcall(struct cpu_info *ci) { - xc_ipi_handler(); } +static void +x86_ipi_generic(struct cpu_info *ci) +{ + ipi_cpu_handler(); +} + void xc_send_ipi(struct cpu_info *ci) { @@ -226,6 +233,21 @@ xc_send_ipi(struct cpu_info *ci) } } +void +cpu_ipi(struct cpu_info *ci) +{ + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != ci); + + if (ci) { + /* Unicast: remote CPU. */ + x86_send_ipi(ci, X86_IPI_GENERIC); + } else { + /* Broadcast: all, but local CPU (caller will handle it). */ + x86_broadcast_ipi(X86_IPI_GENERIC); + } +} + #else int @@ -241,4 +263,9 @@ x86_broadcast_ipi(int ipimask) } +void +cpu_ipi(struct cpu_info *ci) +{ +} + #endif Index: src/sys/arch/xen/include/intrdefs.h diff -u src/sys/arch/xen/include/intrdefs.h:1.11 src/sys/arch/xen/include/intrdefs.h:1.12 --- src/sys/arch/xen/include/intrdefs.h:1.11 Mon Nov 7 15:51:31 2011 +++ src/sys/arch/xen/include/intrdefs.h Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: intrdefs.h,v 1.11 2011/11/07 15:51:31 cherry Exp $ */ +/* $NetBSD: intrdefs.h,v 1.12 2014/05/19 22:47:54 rmind Exp $ */ /* This file co-exists, and is included via machine/intrdefs.h */ @@ -12,7 +12,9 @@ #define XEN_IPI_DDB 0x00000004 #define XEN_IPI_XCALL 0x00000008 #define XEN_IPI_HVCB 0x00000010 +#define XEN_IPI_GENERIC 0x00000020 -#define XEN_NIPIS 5 /* IPI_KICK doesn't have a handler */ +/* Note: IPI_KICK does not have a handler. */ +#define XEN_NIPIS 6 #endif /* _XEN_INTRDEFS_H_ */ Index: src/sys/arch/xen/x86/xen_ipi.c diff -u src/sys/arch/xen/x86/xen_ipi.c:1.17 src/sys/arch/xen/x86/xen_ipi.c:1.18 --- src/sys/arch/xen/x86/xen_ipi.c:1.17 Wed Feb 12 23:24:09 2014 +++ src/sys/arch/xen/x86/xen_ipi.c Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $ */ +/* $NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -33,10 +33,10 @@ /* * Based on: x86/ipi.c - * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $"); + * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $"); */ -__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $"); #include <sys/types.h> @@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v #include <sys/mutex.h> #include <sys/device.h> #include <sys/xcall.h> +#include <sys/ipi.h> #include <sys/errno.h> #include <sys/systm.h> @@ -69,6 +70,7 @@ static void xen_ipi_synch_fpu(struct cpu static void xen_ipi_ddb(struct cpu_info *, struct intrframe *); static void xen_ipi_xcall(struct cpu_info *, struct intrframe *); static void xen_ipi_hvcb(struct cpu_info *, struct intrframe *); +static void xen_ipi_generic(struct cpu_info *, struct intrframe *); static void (*ipifunc[XEN_NIPIS])(struct cpu_info *, struct intrframe *) = { /* In order of priority (see: xen/include/intrdefs.h */ @@ -76,7 +78,8 @@ static void (*ipifunc[XEN_NIPIS])(struct xen_ipi_synch_fpu, xen_ipi_ddb, xen_ipi_xcall, - xen_ipi_hvcb + xen_ipi_hvcb, + xen_ipi_generic, }; static void @@ -131,7 +134,7 @@ xen_ipi_init(void) static inline bool /* helper */ valid_ipimask(uint32_t ipimask) { - uint32_t masks = XEN_IPI_HVCB | XEN_IPI_XCALL | + uint32_t masks = XEN_IPI_GENERIC | XEN_IPI_HVCB | XEN_IPI_XCALL | XEN_IPI_DDB | XEN_IPI_SYNCH_FPU | XEN_IPI_HALT | XEN_IPI_KICK; @@ -285,6 +288,29 @@ xc_send_ipi(struct cpu_info *ci) } static void +xen_ipi_generic(struct cpu_info *ci, struct intrframe *intrf) +{ + KASSERT(ci != NULL); + KASSERT(intrf != NULL); + + ipi_cpu_handler(); +} + +void +cpu_ipi(struct cpu_info *ci) +{ + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != ci); + if (ci) { + if (0 != xen_send_ipi(ci, XEN_IPI_GENERIC)) { + panic("xen_send_ipi(XEN_IPI_GENERIC) failed\n"); + } + } else { + xen_broadcast_ipi(XEN_IPI_GENERIC); + } +} + +static void xen_ipi_hvcb(struct cpu_info *ci, struct intrframe *intrf) { KASSERT(ci != NULL); Index: src/sys/conf/files diff -u src/sys/conf/files:1.1090 src/sys/conf/files:1.1091 --- src/sys/conf/files:1.1090 Tue Apr 1 17:49:30 2014 +++ src/sys/conf/files Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.1090 2014/04/01 17:49:30 riastradh Exp $ +# $NetBSD: files,v 1.1091 2014/05/19 22:47:54 rmind Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20100430 @@ -1598,6 +1598,7 @@ file kern/subr_extent.c file kern/subr_hash.c file kern/subr_humanize.c file kern/subr_iostat.c +file kern/subr_ipi.c file kern/subr_kcpuset.c file kern/subr_kmem.c file kern/subr_kobj.c Index: src/sys/kern/init_main.c diff -u src/sys/kern/init_main.c:1.454 src/sys/kern/init_main.c:1.455 --- src/sys/kern/init_main.c:1.454 Wed Oct 2 21:38:55 2013 +++ src/sys/kern/init_main.c Mon May 19 22:47:54 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.454 2013/10/02 21:38:55 apb Exp $ */ +/* $NetBSD: init_main.c,v 1.455 2014/05/19 22:47:54 rmind Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.454 2013/10/02 21:38:55 apb Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.455 2014/05/19 22:47:54 rmind Exp $"); #include "opt_ddb.h" #include "opt_ipsec.h" @@ -157,6 +157,7 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c, #include <sys/mbuf.h> #include <sys/sched.h> #include <sys/sleepq.h> +#include <sys/ipi.h> #include <sys/iostat.h> #include <sys/vmem.h> #include <sys/uuid.h> @@ -307,6 +308,7 @@ main(void) uvm_init(); kcpuset_sysinit(); + ipi_sysinit(); prop_kern_init(); Added files: Index: src/sys/kern/subr_ipi.c diff -u /dev/null src/sys/kern/subr_ipi.c:1.1 --- /dev/null Mon May 19 22:47:54 2014 +++ src/sys/kern/subr_ipi.c Mon May 19 22:47:54 2014 @@ -0,0 +1,238 @@ +/* $NetBSD: subr_ipi.c,v 1.1 2014/05/19 22:47:54 rmind Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Mindaugas Rasiukevicius. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Inter-processor interrupt (IPI) interface with cross-call support. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: subr_ipi.c,v 1.1 2014/05/19 22:47:54 rmind Exp $"); + +#include <sys/param.h> +#include <sys/types.h> + +#include <sys/atomic.h> +#include <sys/evcnt.h> +#include <sys/cpu.h> +#include <sys/ipi.h> +#include <sys/kcpuset.h> +#include <sys/kmem.h> +#include <sys/lock.h> + +/* + * Per-CPU mailbox for IPI messages: it is a single cache line storing + * up to IPI_MSG_MAX messages. + */ + +#define IPI_MSG_SLOTS (CACHE_LINE_SIZE / sizeof(ipi_msg_t *)) +#define IPI_MSG_MAX IPI_MSG_SLOTS + +typedef struct { + ipi_msg_t * msg[IPI_MSG_SLOTS]; +} ipi_mbox_t; + +static ipi_mbox_t * ipi_mboxes __read_mostly; +static struct evcnt ipi_mboxfull_ev __cacheline_aligned; + +#ifndef MULTIPROCESSOR +#define cpu_ipi(ci) KASSERT(ci == NULL) +#endif + +void +ipi_sysinit(void) +{ + const size_t len = ncpu * sizeof(ipi_mbox_t); + + /* Allocate per-CPU IPI mailboxes. */ + ipi_mboxes = kmem_zalloc(len, KM_SLEEP); + KASSERT(ipi_mboxes != NULL); + + evcnt_attach_dynamic(&ipi_mboxfull_ev, EVCNT_TYPE_MISC, NULL, + "ipi", "full"); +} + +/* + * put_msg: insert message into the mailbox. + */ +static inline void +put_msg(ipi_mbox_t *mbox, ipi_msg_t *msg) +{ + int count = SPINLOCK_BACKOFF_MIN; +again: + for (u_int i = 0; i < IPI_MSG_MAX; i++) { + if (__predict_true(mbox->msg[i] == NULL) && + atomic_cas_ptr(&mbox->msg[i], NULL, msg) == NULL) { + return; + } + } + + /* All slots are full: we have to spin-wait. */ + ipi_mboxfull_ev.ev_count++; + SPINLOCK_BACKOFF(count); + goto again; +} + +/* + * ipi_cpu_handler: the IPI handler. + */ +void +ipi_cpu_handler(void) +{ + const struct cpu_info * const ci = curcpu(); + ipi_mbox_t *mbox = &ipi_mboxes[cpu_index(ci)]; + + KASSERT(curcpu() == ci); + + for (u_int i = 0; i < IPI_MSG_MAX; i++) { + ipi_msg_t *msg; + + /* Get the message. */ + if ((msg = mbox->msg[i]) == NULL) { + continue; + } + mbox->msg[i] = NULL; + + /* Execute the handler. */ + KASSERT(msg->func); + msg->func(msg->arg); + + /* Ack the request. */ + atomic_dec_uint(&msg->_pending); + } +} + +/* + * ipi_unicast: send an IPI to a single CPU. + * + * => The CPU must be remote; must not be local. + * => The caller must ipi_wait() on the message for completion. + */ +void +ipi_unicast(ipi_msg_t *msg, struct cpu_info *ci) +{ + const cpuid_t id = cpu_index(ci); + + KASSERT(msg->func != NULL); + KASSERT(kpreempt_disabled()); + KASSERT(curcpu() != ci); + + msg->_pending = 1; + membar_producer(); + + put_msg(&ipi_mboxes[id], msg); + cpu_ipi(ci); +} + +/* + * ipi_multicast: send an IPI to each CPU in the specified set. + * + * => The caller must ipi_wait() on the message for completion. + */ +void +ipi_multicast(ipi_msg_t *msg, const kcpuset_t *target) +{ + const struct cpu_info * const self = curcpu(); + CPU_INFO_ITERATOR cii; + struct cpu_info *ci; + u_int local; + + KASSERT(msg->func != NULL); + KASSERT(kpreempt_disabled()); + + local = !!kcpuset_isset(target, cpu_index(self)); + msg->_pending = kcpuset_countset(target) - local; + membar_producer(); + + for (CPU_INFO_FOREACH(cii, ci)) { + cpuid_t id; + + if (__predict_false(ci == self)) { + continue; + } + id = cpu_index(ci); + if (!kcpuset_isset(target, id)) { + continue; + } + put_msg(&ipi_mboxes[id], msg); + cpu_ipi(ci); + } + if (local) { + msg->func(msg->arg); + } +} + +/* + * ipi_broadcast: send an IPI to all CPUs. + * + * => The caller must ipi_wait() on the message for completion. + */ +void +ipi_broadcast(ipi_msg_t *msg) +{ + const struct cpu_info * const self = curcpu(); + CPU_INFO_ITERATOR cii; + struct cpu_info *ci; + + KASSERT(msg->func != NULL); + KASSERT(kpreempt_disabled()); + + msg->_pending = ncpu - 1; + membar_producer(); + + /* Broadcast IPIs for remote CPUs. */ + for (CPU_INFO_FOREACH(cii, ci)) { + cpuid_t id; + + if (__predict_false(ci == self)) { + continue; + } + id = cpu_index(ci); + put_msg(&ipi_mboxes[id], msg); + } + cpu_ipi(NULL); + + /* Finally, execute locally. */ + msg->func(msg->arg); +} + +/* + * ipi_wait: spin-wait until the message is processed. + */ +void +ipi_wait(ipi_msg_t *msg) +{ + int count = SPINLOCK_BACKOFF_MIN; + + while (msg->_pending) { + KASSERT(msg->_pending < ncpu); + SPINLOCK_BACKOFF(count); + } +} Index: src/sys/sys/ipi.h diff -u /dev/null src/sys/sys/ipi.h:1.1 --- /dev/null Mon May 19 22:47:54 2014 +++ src/sys/sys/ipi.h Mon May 19 22:47:54 2014 @@ -0,0 +1,62 @@ +/* $NetBSD: ipi.h,v 1.1 2014/05/19 22:47:54 rmind Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Mindaugas Rasiukevicius. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_IPI_H_ +#define _SYS_IPI_H_ + +#if !defined(_KERNEL) && !defined(_KMEMUSER) +#error "not supposed to be exposed to userland" +#endif + +typedef void (*ipi_func_t)(void *); + +typedef struct { + /* Public: function handler and an argument. */ + ipi_func_t func; + void * arg; + + /* Private (internal) elements. */ + volatile u_int _pending; +} ipi_msg_t; + +void ipi_sysinit(void); +void ipi_cpu_handler(void); +void cpu_ipi(struct cpu_info *); + +/* + * Public ipi(9) API. + */ +void ipi_unicast(ipi_msg_t *, struct cpu_info *); +void ipi_multicast(ipi_msg_t *, const kcpuset_t *); +void ipi_broadcast(ipi_msg_t *); +void ipi_wait(ipi_msg_t *); + +#endif