* [PATCH 0/3] powerpc: Instrument Hypervisor Calls @ 2006-07-18 20:47 Mike Kravetz 2006-07-18 20:48 ` [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers Mike Kravetz ` (4 more replies) 0 siblings, 5 replies; 28+ messages in thread From: Mike Kravetz @ 2006-07-18 20:47 UTC (permalink / raw) To: Paul Mackerras; +Cc: linuxppc-dev A small update from the last version. By popular demand, both wall time (mftb) and cpu cycles(PURR) are collected for each call. It is interesting to see these two values side by side in the output files. -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers 2006-07-18 20:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz @ 2006-07-18 20:48 ` Mike Kravetz 2006-07-18 20:49 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz ` (3 subsequent siblings) 4 siblings, 0 replies; 28+ messages in thread From: Mike Kravetz @ 2006-07-18 20:48 UTC (permalink / raw) To: Paul Mackerras; +Cc: linuxppc-dev Move all the Hypervisor call definitions to to a single header file. -- Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> diff -Naupr linux-2.6.17.6/drivers/net/ibmveth.h linux-2.6.17.6.work/drivers/net/ibmveth.h --- linux-2.6.17.6/drivers/net/ibmveth.h 2006-07-15 19:00:43.000000000 +0000 +++ linux-2.6.17.6.work/drivers/net/ibmveth.h 2006-07-18 19:33:47.000000000 +0000 @@ -41,16 +41,6 @@ #define IbmVethMcastRemoveFilter 0x2UL #define IbmVethMcastClearFilterTable 0x3UL -/* hcall numbers */ -#define H_VIO_SIGNAL 0x104 -#define H_REGISTER_LOGICAL_LAN 0x114 -#define H_FREE_LOGICAL_LAN 0x118 -#define H_ADD_LOGICAL_LAN_BUFFER 0x11C -#define H_SEND_LOGICAL_LAN 0x120 -#define H_MULTICAST_CTRL 0x130 -#define H_CHANGE_LOGICAL_LAN_MAC 0x14C -#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4 - /* hcall macros */ #define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \ plpar_hcall_norets(H_REGISTER_LOGICAL_LAN, ua, buflst, rxq, fltlst, mac) diff -Naupr linux-2.6.17.6/include/asm-powerpc/hvcall.h linux-2.6.17.6.work/include/asm-powerpc/hvcall.h --- linux-2.6.17.6/include/asm-powerpc/hvcall.h 2006-07-15 19:00:43.000000000 +0000 +++ linux-2.6.17.6.work/include/asm-powerpc/hvcall.h 2006-07-18 19:33:47.000000000 +0000 @@ -155,9 +155,15 @@ #define H_VIO_SIGNAL 0x104 #define H_SEND_CRQ 0x108 #define H_COPY_RDMA 0x110 +#define H_REGISTER_LOGICAL_LAN 0x114 +#define H_FREE_LOGICAL_LAN 0x118 +#define H_ADD_LOGICAL_LAN_BUFFER 0x11C +#define H_SEND_LOGICAL_LAN 0x120 +#define H_MULTICAST_CTRL 0x130 #define H_SET_XDABR 0x134 #define H_STUFF_TCE 0x138 #define H_PUT_TCE_INDIRECT 0x13C +#define H_CHANGE_LOGICAL_LAN_MAC 0x14C #define H_VTERM_PARTNER_INFO 0x150 #define H_REGISTER_VTERM 0x154 #define H_FREE_VTERM 0x158 @@ -187,11 +193,14 @@ #define H_GET_HCA_INFO 0x1B8 #define H_GET_PERF_COUNT 0x1BC #define H_MANAGE_TRACE 0x1C0 +#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4 #define H_QUERY_INT_STATE 0x1E4 #define H_POLL_PENDING 0x1D8 #define H_JOIN 0x298 #define H_ENABLE_CRQ 0x2B0 +#define MAX_HCALL_OPCODES (H_ENABLE_CRQ >> 2) + #ifndef __ASSEMBLY__ /* plpar_hcall() -- Generic call interface using above opcodes ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-18 20:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz 2006-07-18 20:48 ` [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers Mike Kravetz @ 2006-07-18 20:49 ` Mike Kravetz 2006-07-18 22:34 ` Olof Johansson 2006-07-18 20:50 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz ` (2 subsequent siblings) 4 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-07-18 20:49 UTC (permalink / raw) To: Paul Mackerras; +Cc: linuxppc-dev Add wrappers which perform the actual hypervisor call instrumentation. -- Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> diff -Naupr linux-2.6.17.6/arch/powerpc/Kconfig.debug linux-2.6.17.6.work/arch/powerpc/Kconfig.debug --- linux-2.6.17.6/arch/powerpc/Kconfig.debug 2006-07-15 19:00:43.000000000 +0000 +++ linux-2.6.17.6.work/arch/powerpc/Kconfig.debug 2006-07-18 19:56:20.000000000 +0000 @@ -18,6 +18,20 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. +config HCALL_STATS + bool "Hypervisor call instrumentation" + depends on PPC_PSERIES && DEBUG_FS + help + Adds code to keep track of the number of hypervisor calls made and + the amount of time spent in hypervisor calls: both wall time (based + on time base) and cpu time (based on PURR). A directory named + hcall_inst is added at the root of the debugfs filesystem. Within + the hcall_inst directory are files that contain CPU specific call + statistics. + + This option will add a small amount of overhead to all hypervisor + calls. + config DEBUGGER bool "Enable debugger hooks" depends on DEBUG_KERNEL diff -Naupr linux-2.6.17.6/arch/powerpc/platforms/pseries/Makefile linux-2.6.17.6.work/arch/powerpc/platforms/pseries/Makefile --- linux-2.6.17.6/arch/powerpc/platforms/pseries/Makefile 2006-07-15 19:00:43.000000000 +0000 +++ linux-2.6.17.6.work/arch/powerpc/platforms/pseries/Makefile 2006-07-18 19:56:20.000000000 +0000 @@ -9,3 +9,4 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o e obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o +obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o diff -Naupr linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall.S linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall.S --- linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall.S 2006-07-15 19:00:43.000000000 +0000 +++ linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall.S 2006-07-18 19:56:20.000000000 +0000 @@ -11,7 +11,35 @@ #include <asm/hvcall.h> #include <asm/processor.h> #include <asm/ppc_asm.h> - + +/* + * If hcall statistics are desired, all routines are wrapped with code + * that does the statistic gathering. + */ +#ifndef CONFIG_HCALL_STATS +#define PLPAR_HCALL plpar_hcall +#define PLPAR_HCALL_NORETS plpar_hcall_norets +#define PLPAR_HCALL_8ARG_2RET plpar_hcall_8arg_2ret +#define PLPAR_HCALL_4OUT plpar_hcall_4out +#define PLPAR_HCALL_7ARG_7RET plpar_hcall_7arg_7ret +#define PLPAR_HCALL_9ARG_9RET plpar_hcall_9arg_9ret +#else +#define PLPAR_HCALL plpar_hcall_base +#define PLPAR_HCALL_NORETS plpar_hcall_norets_base +#define PLPAR_HCALL_8ARG_2RET plpar_hcall_8arg_2ret_base +#define PLPAR_HCALL_4OUT plpar_hcall_4out_base +#define PLPAR_HCALL_7ARG_7RET plpar_hcall_7arg_7ret_base +#define PLPAR_HCALL_9ARG_9RET plpar_hcall_9arg_9ret_base + +/* + * A special 'indirect' call to a C based wrapper if statistics are desired. + * See plpar_hcall_norets_C function header for more details. + */ +_GLOBAL(plpar_hcall_norets) + b plpar_hcall_norets_C + +#endif + #define STK_PARM(i) (48 + ((i)-3)*8) .text @@ -25,7 +53,7 @@ unsigned long *out2, R9 unsigned long *out3); R10 */ -_GLOBAL(plpar_hcall) +_GLOBAL(PLPAR_HCALL) HMT_MEDIUM mfcr r0 @@ -52,7 +80,7 @@ _GLOBAL(plpar_hcall) /* Simple interface with no output values (other than status) */ -_GLOBAL(plpar_hcall_norets) +_GLOBAL(PLPAR_HCALL_NORETS) HMT_MEDIUM mfcr r0 @@ -76,7 +104,7 @@ _GLOBAL(plpar_hcall_norets) unsigned long arg8, 112(R1) unsigned long *out1); 120(R1) */ -_GLOBAL(plpar_hcall_8arg_2ret) +_GLOBAL(PLPAR_HCALL_8ARG_2RET) HMT_MEDIUM mfcr r0 @@ -102,7 +130,7 @@ _GLOBAL(plpar_hcall_8arg_2ret) unsigned long *out3, R10 unsigned long *out4); 112(R1) */ -_GLOBAL(plpar_hcall_4out) +_GLOBAL(PLPAR_HCALL_4OUT) HMT_MEDIUM mfcr r0 @@ -144,7 +172,7 @@ _GLOBAL(plpar_hcall_4out) unsigned long *out6, 102(R1) unsigned long *out7); 100(R1) */ -_GLOBAL(plpar_hcall_7arg_7ret) +_GLOBAL(PLPAR_HCALL_7ARG_7RET) HMT_MEDIUM mfcr r0 @@ -193,7 +221,7 @@ _GLOBAL(plpar_hcall_7arg_7ret) unsigned long *out8, 94(R1) unsigned long *out9, 92(R1) */ -_GLOBAL(plpar_hcall_9arg_9ret) +_GLOBAL(PLPAR_HCALL_9ARG_9RET) HMT_MEDIUM mfcr r0 diff -Naupr linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall_inst.c --- linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall_inst.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-07-18 19:57:44.000000000 +0000 @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2006 Mike Kravetz IBM Corporation + * + * Hypervisor Call Instrumentation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/percpu.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/cpumask.h> +#include <asm/hvcall.h> +#include <asm/firmware.h> + +DEFINE_PER_CPU(struct hcall_stats[MAX_HCALL_OPCODES+1], hcall_stats); + +/* + * Common update of the per-CPU/per-hcall statistics + */ +static inline void update_stats(unsigned long opcode, + unsigned long t_tb_before, + unsigned long t_cpu_before) +{ + unsigned long op_index = opcode >> 2; + struct hcall_stats *hs = &__get_cpu_var(hcall_stats[op_index]); + + hs->tb_total += (mftb() - t_tb_before); + hs->cpu_total += (mfspr(SPRN_PURR) - t_cpu_before); + hs->num_calls++; +} + +/* + * plpar_hcall wrapper + */ +long plpar_hcall(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3) +{ + long rc; + unsigned long t_tb_before, t_cpu_before; + + t_tb_before = mftb(); + t_cpu_before = mfspr(SPRN_PURR); + rc = plpar_hcall_base(opcode, arg1, arg2, arg3, arg4, out1, out2, out3); + + update_stats(opcode, t_tb_before, t_cpu_before); + return rc; +} + +/* + * A C based wrapper for plpar_hcall_norets + * The wrapper for plpar_hcall_norets is a special case because the function + * takes a variable number of arguments. It is almost impossible to write a + * wrapper for a function that takes a variable number of arguments in C. + * Therefore, there is an assembly routine in hvCall.S that simply branches + * to this C wrapper. This 'indirection' takes care of the variable arguments + * issue. This C wrapper has a fixed maximum number of arguments. + */ +long plpar_hcall_norets_C(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6) +{ + long rc; + unsigned long t_tb_before, t_cpu_before; + + t_tb_before = mftb(); + t_cpu_before = mfspr(SPRN_PURR); + rc = plpar_hcall_norets_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6); + + update_stats(opcode, t_tb_before, t_cpu_before); + return rc; +} + +/* + * plpar_hcall_8arg_2ret wrapper + */ +long plpar_hcall_8arg_2ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1) +{ + long rc; + unsigned long t_tb_before, t_cpu_before; + + t_tb_before = mftb(); + t_cpu_before = mfspr(SPRN_PURR); + rc = plpar_hcall_8arg_2ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, out1); + + update_stats(opcode, t_tb_before, t_cpu_before); + return rc; +} + +/* + * plpar_hcall_4out wrapper + */ +long plpar_hcall_4out(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4) +{ + long rc; + unsigned long t_tb_before, t_cpu_before; + + t_tb_before = mftb(); + t_cpu_before = mfspr(SPRN_PURR); + rc = plpar_hcall_4out_base(opcode, arg1, arg2, arg3, arg4, out1, + out2, out3, out4); + + update_stats(opcode, t_tb_before, t_cpu_before); + return rc; +} + +/* + * plpar_hcall_7arg_7ret wrapper + */ +long plpar_hcall_7arg_7ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7) +{ + long rc; + unsigned long t_tb_before, t_cpu_before; + + t_tb_before = mftb(); + t_cpu_before = mfspr(SPRN_PURR); + rc = plpar_hcall_7arg_7ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, out1, out2, out3, out4, + out5, out6, out7); + + update_stats(opcode, t_tb_before, t_cpu_before); + return rc; +} + +/* + * plpar_hcall_9arg_9ret wrapper + */ +long plpar_hcall_9arg_9ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long arg9, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7, + unsigned long *out8, + unsigned long *out9) +{ + long rc; + unsigned long t_tb_before, t_cpu_before; + + t_tb_before = mftb(); + t_cpu_before = mfspr(SPRN_PURR); + rc = plpar_hcall_9arg_9ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, out1, out2, + out3, out4, out5, out6, out7, out8, + out9); + + update_stats(opcode, t_tb_before, t_cpu_before); + return rc; +} diff -Naupr linux-2.6.17.6/include/asm-powerpc/hvcall.h linux-2.6.17.6.work/include/asm-powerpc/hvcall.h --- linux-2.6.17.6/include/asm-powerpc/hvcall.h 2006-07-18 19:35:00.000000000 +0000 +++ linux-2.6.17.6.work/include/asm-powerpc/hvcall.h 2006-07-18 19:56:20.000000000 +0000 @@ -292,6 +292,87 @@ long plpar_hcall_9arg_9ret(unsigned long unsigned long *out8, unsigned long *out9); + +/* For hcall instrumentation. One structure per-hcall, per-CPU */ +struct hcall_stats { + unsigned long num_calls; /* number of calls (on this CPU) */ + unsigned long tb_total; /* total wall time (mftb) of calls. */ + unsigned long cpu_total; /* total cpu time (PURR) of calls. */ +}; + +/* If Hypervisor call instrumentation is enabled, the assembly routine + * names are changed from 'plpar_hcall*' to 'plpar_hcall*_base' and + * 'plpar_hcall*' routines become instrumented wrappers. The following + * are declarations for the renamed 'plpar_hcall*_base' routines. + */ +long plpar_hcall_base (unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3); + +long plpar_hcall_norets_base(unsigned long opcode, ...); + +long plpar_hcall_8arg_2ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1); + +long plpar_hcall_4out_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4); + +long plpar_hcall_7arg_7ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7); + +long plpar_hcall_9arg_9ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long arg9, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7, + unsigned long *out8, + unsigned long *out9); + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HVCALL_H */ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-18 20:49 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz @ 2006-07-18 22:34 ` Olof Johansson 2006-07-18 23:18 ` Mike Kravetz 0 siblings, 1 reply; 28+ messages in thread From: Olof Johansson @ 2006-07-18 22:34 UTC (permalink / raw) To: Mike Kravetz; +Cc: linuxppc-dev, Paul Mackerras On Tue, Jul 18, 2006 at 01:49:46PM -0700, Mike Kravetz wrote: > Add wrappers which perform the actual hypervisor call instrumentation. > -- > Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> NACK. As I said before, SPRN_PURR doesn't exist on all architecture versions that supports hypervisor mode. Try booting on a JS20/21 or a POWER4 machine in LPAR mode and you'll see. (Unfortunately I don't have access to any such hardware myself, so I can't send you oops output to show it). -Olof > diff -Naupr linux-2.6.17.6/arch/powerpc/Kconfig.debug linux-2.6.17.6.work/arch/powerpc/Kconfig.debug > --- linux-2.6.17.6/arch/powerpc/Kconfig.debug 2006-07-15 19:00:43.000000000 +0000 > +++ linux-2.6.17.6.work/arch/powerpc/Kconfig.debug 2006-07-18 19:56:20.000000000 +0000 > @@ -18,6 +18,20 @@ config DEBUG_STACK_USAGE > > This option will slow down process creation somewhat. > > +config HCALL_STATS > + bool "Hypervisor call instrumentation" > + depends on PPC_PSERIES && DEBUG_FS > + help > + Adds code to keep track of the number of hypervisor calls made and > + the amount of time spent in hypervisor calls: both wall time (based > + on time base) and cpu time (based on PURR). A directory named > + hcall_inst is added at the root of the debugfs filesystem. Within > + the hcall_inst directory are files that contain CPU specific call > + statistics. > + > + This option will add a small amount of overhead to all hypervisor > + calls. > + > config DEBUGGER > bool "Enable debugger hooks" > depends on DEBUG_KERNEL > diff -Naupr linux-2.6.17.6/arch/powerpc/platforms/pseries/Makefile linux-2.6.17.6.work/arch/powerpc/platforms/pseries/Makefile > --- linux-2.6.17.6/arch/powerpc/platforms/pseries/Makefile 2006-07-15 19:00:43.000000000 +0000 > +++ linux-2.6.17.6.work/arch/powerpc/platforms/pseries/Makefile 2006-07-18 19:56:20.000000000 +0000 > @@ -9,3 +9,4 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o e > > obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o > obj-$(CONFIG_HVCS) += hvcserver.o > +obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o > diff -Naupr linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall.S linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall.S > --- linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall.S 2006-07-15 19:00:43.000000000 +0000 > +++ linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall.S 2006-07-18 19:56:20.000000000 +0000 > @@ -11,7 +11,35 @@ > #include <asm/hvcall.h> > #include <asm/processor.h> > #include <asm/ppc_asm.h> > - > + > +/* > + * If hcall statistics are desired, all routines are wrapped with code > + * that does the statistic gathering. > + */ > +#ifndef CONFIG_HCALL_STATS > +#define PLPAR_HCALL plpar_hcall > +#define PLPAR_HCALL_NORETS plpar_hcall_norets > +#define PLPAR_HCALL_8ARG_2RET plpar_hcall_8arg_2ret > +#define PLPAR_HCALL_4OUT plpar_hcall_4out > +#define PLPAR_HCALL_7ARG_7RET plpar_hcall_7arg_7ret > +#define PLPAR_HCALL_9ARG_9RET plpar_hcall_9arg_9ret > +#else > +#define PLPAR_HCALL plpar_hcall_base > +#define PLPAR_HCALL_NORETS plpar_hcall_norets_base > +#define PLPAR_HCALL_8ARG_2RET plpar_hcall_8arg_2ret_base > +#define PLPAR_HCALL_4OUT plpar_hcall_4out_base > +#define PLPAR_HCALL_7ARG_7RET plpar_hcall_7arg_7ret_base > +#define PLPAR_HCALL_9ARG_9RET plpar_hcall_9arg_9ret_base > + > +/* > + * A special 'indirect' call to a C based wrapper if statistics are desired. > + * See plpar_hcall_norets_C function header for more details. > + */ > +_GLOBAL(plpar_hcall_norets) > + b plpar_hcall_norets_C > + > +#endif > + > #define STK_PARM(i) (48 + ((i)-3)*8) > > .text > @@ -25,7 +53,7 @@ > unsigned long *out2, R9 > unsigned long *out3); R10 > */ > -_GLOBAL(plpar_hcall) > +_GLOBAL(PLPAR_HCALL) > HMT_MEDIUM > > mfcr r0 > @@ -52,7 +80,7 @@ _GLOBAL(plpar_hcall) > > > /* Simple interface with no output values (other than status) */ > -_GLOBAL(plpar_hcall_norets) > +_GLOBAL(PLPAR_HCALL_NORETS) > HMT_MEDIUM > > mfcr r0 > @@ -76,7 +104,7 @@ _GLOBAL(plpar_hcall_norets) > unsigned long arg8, 112(R1) > unsigned long *out1); 120(R1) > */ > -_GLOBAL(plpar_hcall_8arg_2ret) > +_GLOBAL(PLPAR_HCALL_8ARG_2RET) > HMT_MEDIUM > > mfcr r0 > @@ -102,7 +130,7 @@ _GLOBAL(plpar_hcall_8arg_2ret) > unsigned long *out3, R10 > unsigned long *out4); 112(R1) > */ > -_GLOBAL(plpar_hcall_4out) > +_GLOBAL(PLPAR_HCALL_4OUT) > HMT_MEDIUM > > mfcr r0 > @@ -144,7 +172,7 @@ _GLOBAL(plpar_hcall_4out) > unsigned long *out6, 102(R1) > unsigned long *out7); 100(R1) > */ > -_GLOBAL(plpar_hcall_7arg_7ret) > +_GLOBAL(PLPAR_HCALL_7ARG_7RET) > HMT_MEDIUM > > mfcr r0 > @@ -193,7 +221,7 @@ _GLOBAL(plpar_hcall_7arg_7ret) > unsigned long *out8, 94(R1) > unsigned long *out9, 92(R1) > */ > -_GLOBAL(plpar_hcall_9arg_9ret) > +_GLOBAL(PLPAR_HCALL_9ARG_9RET) > HMT_MEDIUM > > mfcr r0 > diff -Naupr linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall_inst.c > --- linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall_inst.c 1970-01-01 00:00:00.000000000 +0000 > +++ linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-07-18 19:57:44.000000000 +0000 > @@ -0,0 +1,216 @@ > +/* > + * Copyright (C) 2006 Mike Kravetz IBM Corporation > + * > + * Hypervisor Call Instrumentation > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +#include <linux/kernel.h> > +#include <linux/percpu.h> > +#include <linux/debugfs.h> > +#include <linux/seq_file.h> > +#include <linux/cpumask.h> > +#include <asm/hvcall.h> > +#include <asm/firmware.h> > + > +DEFINE_PER_CPU(struct hcall_stats[MAX_HCALL_OPCODES+1], hcall_stats); > + > +/* > + * Common update of the per-CPU/per-hcall statistics > + */ > +static inline void update_stats(unsigned long opcode, > + unsigned long t_tb_before, > + unsigned long t_cpu_before) > +{ > + unsigned long op_index = opcode >> 2; > + struct hcall_stats *hs = &__get_cpu_var(hcall_stats[op_index]); > + > + hs->tb_total += (mftb() - t_tb_before); > + hs->cpu_total += (mfspr(SPRN_PURR) - t_cpu_before); > + hs->num_calls++; > +} > + > +/* > + * plpar_hcall wrapper > + */ > +long plpar_hcall(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3) > +{ > + long rc; > + unsigned long t_tb_before, t_cpu_before; > + > + t_tb_before = mftb(); > + t_cpu_before = mfspr(SPRN_PURR); > + rc = plpar_hcall_base(opcode, arg1, arg2, arg3, arg4, out1, out2, out3); > + > + update_stats(opcode, t_tb_before, t_cpu_before); > + return rc; > +} > + > +/* > + * A C based wrapper for plpar_hcall_norets > + * The wrapper for plpar_hcall_norets is a special case because the function > + * takes a variable number of arguments. It is almost impossible to write a > + * wrapper for a function that takes a variable number of arguments in C. > + * Therefore, there is an assembly routine in hvCall.S that simply branches > + * to this C wrapper. This 'indirection' takes care of the variable arguments > + * issue. This C wrapper has a fixed maximum number of arguments. > + */ > +long plpar_hcall_norets_C(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long arg5, > + unsigned long arg6) > +{ > + long rc; > + unsigned long t_tb_before, t_cpu_before; > + > + t_tb_before = mftb(); > + t_cpu_before = mfspr(SPRN_PURR); > + rc = plpar_hcall_norets_base(opcode, arg1, arg2, arg3, arg4, arg5, > + arg6); > + > + update_stats(opcode, t_tb_before, t_cpu_before); > + return rc; > +} > + > +/* > + * plpar_hcall_8arg_2ret wrapper > + */ > +long plpar_hcall_8arg_2ret(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long arg5, > + unsigned long arg6, > + unsigned long arg7, > + unsigned long arg8, > + unsigned long *out1) > +{ > + long rc; > + unsigned long t_tb_before, t_cpu_before; > + > + t_tb_before = mftb(); > + t_cpu_before = mfspr(SPRN_PURR); > + rc = plpar_hcall_8arg_2ret_base(opcode, arg1, arg2, arg3, arg4, arg5, > + arg6, arg7, arg8, out1); > + > + update_stats(opcode, t_tb_before, t_cpu_before); > + return rc; > +} > + > +/* > + * plpar_hcall_4out wrapper > + */ > +long plpar_hcall_4out(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3, > + unsigned long *out4) > +{ > + long rc; > + unsigned long t_tb_before, t_cpu_before; > + > + t_tb_before = mftb(); > + t_cpu_before = mfspr(SPRN_PURR); > + rc = plpar_hcall_4out_base(opcode, arg1, arg2, arg3, arg4, out1, > + out2, out3, out4); > + > + update_stats(opcode, t_tb_before, t_cpu_before); > + return rc; > +} > + > +/* > + * plpar_hcall_7arg_7ret wrapper > + */ > +long plpar_hcall_7arg_7ret(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long arg5, > + unsigned long arg6, > + unsigned long arg7, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3, > + unsigned long *out4, > + unsigned long *out5, > + unsigned long *out6, > + unsigned long *out7) > +{ > + long rc; > + unsigned long t_tb_before, t_cpu_before; > + > + t_tb_before = mftb(); > + t_cpu_before = mfspr(SPRN_PURR); > + rc = plpar_hcall_7arg_7ret_base(opcode, arg1, arg2, arg3, arg4, arg5, > + arg6, arg7, out1, out2, out3, out4, > + out5, out6, out7); > + > + update_stats(opcode, t_tb_before, t_cpu_before); > + return rc; > +} > + > +/* > + * plpar_hcall_9arg_9ret wrapper > + */ > +long plpar_hcall_9arg_9ret(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long arg5, > + unsigned long arg6, > + unsigned long arg7, > + unsigned long arg8, > + unsigned long arg9, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3, > + unsigned long *out4, > + unsigned long *out5, > + unsigned long *out6, > + unsigned long *out7, > + unsigned long *out8, > + unsigned long *out9) > +{ > + long rc; > + unsigned long t_tb_before, t_cpu_before; > + > + t_tb_before = mftb(); > + t_cpu_before = mfspr(SPRN_PURR); > + rc = plpar_hcall_9arg_9ret_base(opcode, arg1, arg2, arg3, arg4, arg5, > + arg6, arg7, arg8, arg9, out1, out2, > + out3, out4, out5, out6, out7, out8, > + out9); > + > + update_stats(opcode, t_tb_before, t_cpu_before); > + return rc; > +} > diff -Naupr linux-2.6.17.6/include/asm-powerpc/hvcall.h linux-2.6.17.6.work/include/asm-powerpc/hvcall.h > --- linux-2.6.17.6/include/asm-powerpc/hvcall.h 2006-07-18 19:35:00.000000000 +0000 > +++ linux-2.6.17.6.work/include/asm-powerpc/hvcall.h 2006-07-18 19:56:20.000000000 +0000 > @@ -292,6 +292,87 @@ long plpar_hcall_9arg_9ret(unsigned long > unsigned long *out8, > unsigned long *out9); > > + > +/* For hcall instrumentation. One structure per-hcall, per-CPU */ > +struct hcall_stats { > + unsigned long num_calls; /* number of calls (on this CPU) */ > + unsigned long tb_total; /* total wall time (mftb) of calls. */ > + unsigned long cpu_total; /* total cpu time (PURR) of calls. */ > +}; > + > +/* If Hypervisor call instrumentation is enabled, the assembly routine > + * names are changed from 'plpar_hcall*' to 'plpar_hcall*_base' and > + * 'plpar_hcall*' routines become instrumented wrappers. The following > + * are declarations for the renamed 'plpar_hcall*_base' routines. > + */ > +long plpar_hcall_base (unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3); > + > +long plpar_hcall_norets_base(unsigned long opcode, ...); > + > +long plpar_hcall_8arg_2ret_base(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long arg5, > + unsigned long arg6, > + unsigned long arg7, > + unsigned long arg8, > + unsigned long *out1); > + > +long plpar_hcall_4out_base(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3, > + unsigned long *out4); > + > +long plpar_hcall_7arg_7ret_base(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long arg5, > + unsigned long arg6, > + unsigned long arg7, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3, > + unsigned long *out4, > + unsigned long *out5, > + unsigned long *out6, > + unsigned long *out7); > + > +long plpar_hcall_9arg_9ret_base(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long arg5, > + unsigned long arg6, > + unsigned long arg7, > + unsigned long arg8, > + unsigned long arg9, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3, > + unsigned long *out4, > + unsigned long *out5, > + unsigned long *out6, > + unsigned long *out7, > + unsigned long *out8, > + unsigned long *out9); > + > #endif /* __ASSEMBLY__ */ > #endif /* __KERNEL__ */ > #endif /* _ASM_POWERPC_HVCALL_H */ > _______________________________________________ > Linuxppc-dev mailing list > Linuxppc-dev@ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc-dev ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-18 22:34 ` Olof Johansson @ 2006-07-18 23:18 ` Mike Kravetz 2006-07-19 3:33 ` Olof Johansson 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-07-18 23:18 UTC (permalink / raw) To: Olof Johansson; +Cc: linuxppc-dev, Paul Mackerras On Tue, Jul 18, 2006 at 05:34:25PM -0500, Olof Johansson wrote: > As I said before, SPRN_PURR doesn't exist on all architecture versions > that supports hypervisor mode. Thanks! I assume checking must be done at run time via something like, if (cpu_has_feature(CPU_FTR_PURR)) Also assume that it would make sense to do this determination at initialization/boot time and put the result in the statistic data structure. In this way we would know it is in the same cache line we are updating with other stats. Or, should cur_cpu_spec->cpu_features be 'sufficiently hot' to make this a non-issue? -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-18 23:18 ` Mike Kravetz @ 2006-07-19 3:33 ` Olof Johansson 2006-07-19 3:50 ` Mike Kravetz 0 siblings, 1 reply; 28+ messages in thread From: Olof Johansson @ 2006-07-19 3:33 UTC (permalink / raw) To: Mike Kravetz; +Cc: Olof Johansson, linuxppc-dev, Paul Mackerras On Tue, Jul 18, 2006 at 04:18:15PM -0700, Mike Kravetz wrote: > I assume checking must be done at run time via something like, > if (cpu_has_feature(CPU_FTR_PURR)) If you do it in the hcall asm instead (like Paulus suggested), then it's better to use BEGIN_FTR_SECTION/END_FTR_SECTION() around it, that way the PURR reads just get nopped out instead of adding tests and branches. > Also assume that it would make sense to do this determination at > initialization/boot time and put the result in the statistic data > structure. In this way we would know it is in the same cache line > we are updating with other stats. Or, should cur_cpu_spec->cpu_features > be 'sufficiently hot' to make this a non-issue? If you use the FTR_SECTION stuff then it'll be taken care of automatically at boot time. Doing that from C is messy, I don't think anyone has had reason to do it before. -Olof ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-19 3:33 ` Olof Johansson @ 2006-07-19 3:50 ` Mike Kravetz 0 siblings, 0 replies; 28+ messages in thread From: Mike Kravetz @ 2006-07-19 3:50 UTC (permalink / raw) To: Olof Johansson; +Cc: linuxppc-dev, Paul Mackerras On Tue, Jul 18, 2006 at 10:33:00PM -0500, Olof Johansson wrote: > If you use the FTR_SECTION stuff then it'll be taken care of > automatically at boot time. Doing that from C is messy, I don't think > anyone has had reason to do it before. Ok, sounds like a good reason for assembly. I'll dust off the books. :) -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files 2006-07-18 20:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz 2006-07-18 20:48 ` [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers Mike Kravetz 2006-07-18 20:49 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz @ 2006-07-18 20:50 ` Mike Kravetz 2006-07-18 21:00 ` [PATCH 0/3] powerpc: Instrument Hypervisor Calls Paul Mackerras 2006-07-18 21:29 ` Mike Kravetz 4 siblings, 0 replies; 28+ messages in thread From: Mike Kravetz @ 2006-07-18 20:50 UTC (permalink / raw) To: Paul Mackerras; +Cc: linuxppc-dev Make statistics available via files in debugfs. -- Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> diff -Naupr linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall_inst.c --- linux-2.6.17.6/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-07-18 20:02:21.000000000 +0000 +++ linux-2.6.17.6.work/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-07-18 20:03:32.000000000 +0000 @@ -214,3 +214,96 @@ long plpar_hcall_9arg_9ret(unsigned long update_stats(opcode, t_tb_before, t_cpu_before); return rc; } + +/* + * Routines for displaying the statistics in debugfs + */ +static void *hc_start(struct seq_file *m, loff_t *pos) +{ + if ((int)*pos < MAX_HCALL_OPCODES) + return (void *)(unsigned long)(*pos + 1); + + return NULL; +} + +static void *hc_next(struct seq_file *m, void *p, loff_t * pos) +{ + ++*pos; + + return hc_start(m, pos); +} + +static void hc_stop(struct seq_file *m, void *p) +{ +} + +static int hc_show(struct seq_file *m, void *p) +{ + unsigned long h_num = (unsigned long)p; + struct hcall_stats *hs = (struct hcall_stats *)m->private; + + if (hs[h_num].num_calls) + seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2, + hs[h_num].num_calls, + hs[h_num].tb_total, + hs[h_num].cpu_total); + + return 0; +} + +static struct seq_operations hcall_inst_seq_ops = { + .start = hc_start, + .next = hc_next, + .stop = hc_stop, + .show = hc_show +}; + +static int hcall_inst_seq_open(struct inode *inode, struct file *file) +{ + int rc; + struct seq_file *seq; + + rc = seq_open(file, &hcall_inst_seq_ops); + seq = file->private_data; + seq->private = file->f_dentry->d_inode->u.generic_ip; + + return rc; +} + +static struct file_operations hcall_inst_seq_fops = { + .open = hcall_inst_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +#define HCALL_ROOT_DIR "hcall_inst" +#define CPU_NAME_BUF_SIZE 32 + +static int __init hcall_inst_init(void) +{ + struct dentry *hcall_root; + struct dentry *hcall_file; + char cpu_name_buf[CPU_NAME_BUF_SIZE]; + int cpu; + + if (!firmware_has_feature(FW_FEATURE_LPAR)) + return 0; + + hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL); + if (!hcall_root) + return -ENOMEM; + + for_each_cpu(cpu) { + snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu); + hcall_file = debugfs_create_file(cpu_name_buf, S_IRUGO, + hcall_root, + per_cpu(hcall_stats, cpu), + &hcall_inst_seq_fops); + if (!hcall_file) + return -ENOMEM; + } + + return 0; +} +__initcall(hcall_inst_init); ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-07-18 20:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz ` (2 preceding siblings ...) 2006-07-18 20:50 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz @ 2006-07-18 21:00 ` Paul Mackerras 2006-07-19 3:36 ` Mike Kravetz 2006-07-18 21:29 ` Mike Kravetz 4 siblings, 1 reply; 28+ messages in thread From: Paul Mackerras @ 2006-07-18 21:00 UTC (permalink / raw) To: Mike Kravetz; +Cc: linuxppc-dev Mike Kravetz writes: > A small update from the last version. By popular demand, both > wall time (mftb) and cpu cycles(PURR) are collected for each call. > It is interesting to see these two values side by side in the > output files. Did you see the patch from Anton that I posted a week or so ago, which reduces the number of plpar_hcall_* functions? I'd rather the instrumentation stuff was based on that. My other comment is this: wouldn't it actually turn out simpler if we read the timebase (and PURR, if we really want to do that too) in the assembly code that implements plpar_hcall_*? Paul. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-07-18 21:00 ` [PATCH 0/3] powerpc: Instrument Hypervisor Calls Paul Mackerras @ 2006-07-19 3:36 ` Mike Kravetz 2006-07-19 22:11 ` Mike Kravetz 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-07-19 3:36 UTC (permalink / raw) To: Paul Mackerras; +Cc: linuxppc-dev On Wed, Jul 19, 2006 at 07:00:22AM +1000, Paul Mackerras wrote: > Mike Kravetz writes: > > A small update from the last version. By popular demand, both > > wall time (mftb) and cpu cycles(PURR) are collected for each call. > > It is interesting to see these two values side by side in the > > output files. > > Did you see the patch from Anton that I posted a week or so ago, which > reduces the number of plpar_hcall_* functions? I'd rather the > instrumentation stuff was based on that. Agreed. I missed the patch from last week, but saw the one from Anton that was posted today. Future instrumentation patches will assume this change. > My other comment is this: wouldn't it actually turn out simpler if we > read the timebase (and PURR, if we really want to do that too) in the > assembly code that implements plpar_hcall_*? I'll give that a try. My assembly skills are a bit rusty, so it may take a little longer to produce something. -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-07-19 3:36 ` Mike Kravetz @ 2006-07-19 22:11 ` Mike Kravetz 0 siblings, 0 replies; 28+ messages in thread From: Mike Kravetz @ 2006-07-19 22:11 UTC (permalink / raw) To: Paul Mackerras; +Cc: linuxppc-dev On Tue, Jul 18, 2006 at 08:36:18PM -0700, Mike Kravetz wrote: > > My other comment is this: wouldn't it actually turn out simpler if we > > read the timebase (and PURR, if we really want to do that too) in the > > assembly code that implements plpar_hcall_*? > > I'll give that a try. My assembly skills are a bit rusty, so it may > take a little longer to produce something. Getting the timebase and PURR in assembly is easy enough. So, I thought about updating the per-cpu statistics while in there. But, I couldn't find any other assembly code that does this. Sure there is asm code that updated fields in the PACA, but none that messes with paca.data_offset (that I could find). Should the statistic updates also be done in the assembly routines? Or, how about a call out to a C routine for this? -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-07-18 20:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz ` (3 preceding siblings ...) 2006-07-18 21:00 ` [PATCH 0/3] powerpc: Instrument Hypervisor Calls Paul Mackerras @ 2006-07-18 21:29 ` Mike Kravetz 2006-07-18 22:38 ` Olof Johansson 4 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-07-18 21:29 UTC (permalink / raw) To: Paul Mackerras; +Cc: linuxppc-dev On Tue, Jul 18, 2006 at 01:47:23PM -0700, Mike Kravetz wrote: > A small update from the last version. By popular demand, both > wall time (mftb) and cpu cycles(PURR) are collected for each call. > It is interesting to see these two values side by side in the > output files. Arnd asked on IRC, so I thought others may be interested in a sample output file. Remember, there is one file per CPU. All values are decimal. First number is hcall # (in decimal), second is number of calls, third is total time (mftb) and fourth is cpu time (PURR). Note that 'total times' are still in cycles and can be converted to another format in user space. [elm3b125]/sys/kernel/debug/hcall_inst >cat cpu0 4 140651 21538230 14456409 8 130064 11855094 9459178 24 14259 1496316 986702 32 1809 354584 315399 84 103 27196 17763 88 1046 108106 109322 100 2596 251229 205154 104 1 1040 1061 108 2208 320491 242708 116 2669 1030894 713272 220 2 532 510 224 130662 47508588184 169383891 228 5 2689902 4622 260 3018 261893 230753 -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-07-18 21:29 ` Mike Kravetz @ 2006-07-18 22:38 ` Olof Johansson 0 siblings, 0 replies; 28+ messages in thread From: Olof Johansson @ 2006-07-18 22:38 UTC (permalink / raw) To: Mike Kravetz; +Cc: linuxppc-dev, Paul Mackerras On Tue, Jul 18, 2006 at 02:29:13PM -0700, Mike Kravetz wrote: > 88 1046 108106 109322 [...] > 104 1 1040 1061 Heh. Shouldn't PURR/TB be <= 1 at all times? :-) I bet this is because they're not sampled at exactly the same time, etc. Maybe recoding it to assembly so you can do mftb and mfspr right after each other, and do the arithmetics/stores later could help. Inline asm might be sufficient. -Olof ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 0/3] powerpc: Instrument Hypervisor Calls @ 2006-07-14 23:37 Mike Kravetz 2006-07-14 23:40 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-07-14 23:37 UTC (permalink / raw) To: Paul Mackerras Cc: Arnd Bergmann, Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Christopher Yeoh Hi Paul, Here is an updated version of the patch(es) to instrument hcalls. All issues from the previous versions have been addressed. Although, I haven't really discovered an elegant solution to the assembly routine name juggling. In addition, there has been some discussion of these patches on IRC. Some remaining issues/questions are: - Exactly how much overhead does the statistic gathering introduce? - What would be the cost of disabling preemption for more accurate statistics? - What would be the cost of disabling interrupts for more accurate statistics? - Should we extend this statistic gathering to RTAS calls? I would like to get this basic code integrated and then start to address some of these questions. The IBM performance group will help in benchmarking to determine overhead. Please note that all code is behind a config option (off by default) with zero impact unless enabled. -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-14 23:37 Mike Kravetz @ 2006-07-14 23:40 ` Mike Kravetz 2006-07-15 0:15 ` Nathan Lynch 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-07-14 23:40 UTC (permalink / raw) To: Paul Mackerras Cc: Arnd Bergmann, Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Christopher Yeoh Add wrappers which perform the actual hypervisor call instrumentation. -- Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> diff -Naupr linux-2.6.17.4/arch/powerpc/Kconfig.debug linux-2.6.17.4.work/arch/powerpc/Kconfig.debug --- linux-2.6.17.4/arch/powerpc/Kconfig.debug 2006-07-06 20:02:28.000000000 +0000 +++ linux-2.6.17.4.work/arch/powerpc/Kconfig.debug 2006-07-14 23:28:20.000000000 +0000 @@ -18,6 +18,19 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. +config HCALL_STATS + bool "Hypervisor call instrumentation" + depends on PPC_PSERIES && DEBUG_FS + help + Adds code to keep track of the number of hypervisor calls made and + the amount of time spent in hypervisor calls. A directory named + hcall_inst is added at the root of the debugfs filesystem. Within + the hcall_inst directory are files that contain CPU specific call + statistics. + + This option will add a small amount of overhead to all hypervisor + calls. + config DEBUGGER bool "Enable debugger hooks" depends on DEBUG_KERNEL diff -Naupr linux-2.6.17.4/arch/powerpc/platforms/pseries/Makefile linux-2.6.17.4.work/arch/powerpc/platforms/pseries/Makefile --- linux-2.6.17.4/arch/powerpc/platforms/pseries/Makefile 2006-07-06 20:02:28.000000000 +0000 +++ linux-2.6.17.4.work/arch/powerpc/platforms/pseries/Makefile 2006-07-14 23:28:20.000000000 +0000 @@ -9,3 +9,4 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o e obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o +obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o diff -Naupr linux-2.6.17.4/arch/powerpc/platforms/pseries/hvCall.S linux-2.6.17.4.work/arch/powerpc/platforms/pseries/hvCall.S --- linux-2.6.17.4/arch/powerpc/platforms/pseries/hvCall.S 2006-07-06 20:02:28.000000000 +0000 +++ linux-2.6.17.4.work/arch/powerpc/platforms/pseries/hvCall.S 2006-07-14 23:28:20.000000000 +0000 @@ -11,7 +11,35 @@ #include <asm/hvcall.h> #include <asm/processor.h> #include <asm/ppc_asm.h> - + +/* + * If hcall statistics are desired, all routines are wrapped with code + * that does the statistic gathering. + */ +#ifndef CONFIG_HCALL_STATS +#define PLPAR_HCALL plpar_hcall +#define PLPAR_HCALL_NORETS plpar_hcall_norets +#define PLPAR_HCALL_8ARG_2RET plpar_hcall_8arg_2ret +#define PLPAR_HCALL_4OUT plpar_hcall_4out +#define PLPAR_HCALL_7ARG_7RET plpar_hcall_7arg_7ret +#define PLPAR_HCALL_9ARG_9RET plpar_hcall_9arg_9ret +#else +#define PLPAR_HCALL plpar_hcall_base +#define PLPAR_HCALL_NORETS plpar_hcall_norets_base +#define PLPAR_HCALL_8ARG_2RET plpar_hcall_8arg_2ret_base +#define PLPAR_HCALL_4OUT plpar_hcall_4out_base +#define PLPAR_HCALL_7ARG_7RET plpar_hcall_7arg_7ret_base +#define PLPAR_HCALL_9ARG_9RET plpar_hcall_9arg_9ret_base + +/* + * A special 'indirect' call to a C based wrapper if statistics are desired. + * See plpar_hcall_norets_C function header for more details. + */ +_GLOBAL(plpar_hcall_norets) + b plpar_hcall_norets_C + +#endif + #define STK_PARM(i) (48 + ((i)-3)*8) .text @@ -25,7 +53,7 @@ unsigned long *out2, R9 unsigned long *out3); R10 */ -_GLOBAL(plpar_hcall) +_GLOBAL(PLPAR_HCALL) HMT_MEDIUM mfcr r0 @@ -52,7 +80,7 @@ _GLOBAL(plpar_hcall) /* Simple interface with no output values (other than status) */ -_GLOBAL(plpar_hcall_norets) +_GLOBAL(PLPAR_HCALL_NORETS) HMT_MEDIUM mfcr r0 @@ -76,7 +104,7 @@ _GLOBAL(plpar_hcall_norets) unsigned long arg8, 112(R1) unsigned long *out1); 120(R1) */ -_GLOBAL(plpar_hcall_8arg_2ret) +_GLOBAL(PLPAR_HCALL_8ARG_2RET) HMT_MEDIUM mfcr r0 @@ -102,7 +130,7 @@ _GLOBAL(plpar_hcall_8arg_2ret) unsigned long *out3, R10 unsigned long *out4); 112(R1) */ -_GLOBAL(plpar_hcall_4out) +_GLOBAL(PLPAR_HCALL_4OUT) HMT_MEDIUM mfcr r0 @@ -144,7 +172,7 @@ _GLOBAL(plpar_hcall_4out) unsigned long *out6, 102(R1) unsigned long *out7); 100(R1) */ -_GLOBAL(plpar_hcall_7arg_7ret) +_GLOBAL(PLPAR_HCALL_7ARG_7RET) HMT_MEDIUM mfcr r0 @@ -193,7 +221,7 @@ _GLOBAL(plpar_hcall_7arg_7ret) unsigned long *out8, 94(R1) unsigned long *out9, 92(R1) */ -_GLOBAL(plpar_hcall_9arg_9ret) +_GLOBAL(PLPAR_HCALL_9ARG_9RET) HMT_MEDIUM mfcr r0 diff -Naupr linux-2.6.17.4/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.17.4.work/arch/powerpc/platforms/pseries/hvCall_inst.c --- linux-2.6.17.4/arch/powerpc/platforms/pseries/hvCall_inst.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.17.4.work/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-07-14 23:28:44.000000000 +0000 @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2006 Mike Kravetz IBM Corporation + * + * Hypervisor Call Instrumentation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/percpu.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/cpumask.h> +#include <asm/hvcall.h> +#include <asm/firmware.h> + +DEFINE_PER_CPU(struct hcall_stats[MAX_HCALL_OPCODES+1], hcall_stats); + +/* + * Common update of the per-CPU/per-hcall statistics + */ +static inline void update_stats(unsigned long opcode, unsigned long t_before) +{ + unsigned long op_index = opcode >> 2; + struct hcall_stats *hs = &__get_cpu_var(hcall_stats[op_index]); + + hs->total_time += (mftb() - t_before); + hs->num_calls++; +} + +/* + * plpar_hcall wrapper + */ +long plpar_hcall(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3) +{ + long rc; + unsigned long t_before; + + t_before = mftb(); + rc = plpar_hcall_base(opcode, arg1, arg2, arg3, arg4, out1, out2, out3); + + update_stats(opcode, t_before); + return rc; +} + +/* + * A C based wrapper for plpar_hcall_norets + * The wrapper for plpar_hcall_norets is a special case because the function + * takes a variable number of arguments. It is almost impossible to write a + * wrapper for a function that takes a variable number of arguments in C. + * Therefore, there is an assembly routine in hvCall.S that simply branches + * to this C wrapper. This 'indirection' takes care of the variable arguments + * issue. This C wrapper has a fixed maximum number of arguments. + */ +long plpar_hcall_norets_C(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6) +{ + long rc; + unsigned long t_before; + + t_before = mftb(); + rc = plpar_hcall_norets_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6); + + update_stats(opcode, t_before); + return rc; +} + +/* + * plpar_hcall_8arg_2ret wrapper + */ +long plpar_hcall_8arg_2ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1) +{ + long rc; + unsigned long t_before; + + t_before = mftb(); + rc = plpar_hcall_8arg_2ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, out1); + + update_stats(opcode, t_before); + return rc; +} + +/* + * plpar_hcall_4out wrapper + */ +long plpar_hcall_4out(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4) +{ + long rc; + unsigned long t_before; + + t_before = mftb(); + rc = plpar_hcall_4out_base(opcode, arg1, arg2, arg3, arg4, out1, + out2, out3, out4); + + update_stats(opcode, t_before); + return rc; +} + +/* + * plpar_hcall_7arg_7ret wrapper + */ +long plpar_hcall_7arg_7ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7) +{ + long rc; + unsigned long t_before; + + t_before = mftb(); + rc = plpar_hcall_7arg_7ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, out1, out2, out3, out4, + out5, out6, out7); + + update_stats(opcode, t_before); + return rc; +} + +/* + * plpar_hcall_9arg_9ret wrapper + */ +long plpar_hcall_9arg_9ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long arg9, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7, + unsigned long *out8, + unsigned long *out9) +{ + long rc; + unsigned long t_before; + + t_before = mftb(); + rc = plpar_hcall_9arg_9ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, out1, out2, + out3, out4, out5, out6, out7, out8, + out9); + + update_stats(opcode, t_before); + return rc; +} diff -Naupr linux-2.6.17.4/include/asm-powerpc/hvcall.h linux-2.6.17.4.work/include/asm-powerpc/hvcall.h --- linux-2.6.17.4/include/asm-powerpc/hvcall.h 2006-07-14 23:27:52.000000000 +0000 +++ linux-2.6.17.4.work/include/asm-powerpc/hvcall.h 2006-07-14 23:28:20.000000000 +0000 @@ -292,6 +292,86 @@ long plpar_hcall_9arg_9ret(unsigned long unsigned long *out8, unsigned long *out9); + +/* For hcall instrumentation. One structure per-hcall, per-CPU */ +struct hcall_stats { + unsigned long num_calls; /* number of calls (on this CPU) */ + unsigned long total_time; /* total cputime (PURR) of calls. */ +}; + +/* If Hypervisor call instrumentation is enabled, the assembly routine + * names are changed from 'plpar_hcall*' to 'plpar_hcall*_base' and + * 'plpar_hcall*' routines become instrumented wrappers. The following + * are declarations for the renamed 'plpar_hcall*_base' routines. + */ +long plpar_hcall_base (unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3); + +long plpar_hcall_norets_base(unsigned long opcode, ...); + +long plpar_hcall_8arg_2ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1); + +long plpar_hcall_4out_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4); + +long plpar_hcall_7arg_7ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7); + +long plpar_hcall_9arg_9ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long arg9, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7, + unsigned long *out8, + unsigned long *out9); + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HVCALL_H */ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-14 23:40 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz @ 2006-07-15 0:15 ` Nathan Lynch 2006-07-15 0:41 ` Mike Kravetz 0 siblings, 1 reply; 28+ messages in thread From: Nathan Lynch @ 2006-07-15 0:15 UTC (permalink / raw) To: Mike Kravetz Cc: Bryan Rosenburg, linuxppc-dev, Paul Mackerras, Arnd Bergmann, Christopher Yeoh Mike Kravetz wrote: > +static inline void update_stats(unsigned long opcode, unsigned long t_before) > +{ > + unsigned long op_index = opcode >> 2; > + struct hcall_stats *hs = &__get_cpu_var(hcall_stats[op_index]); > + > + hs->total_time += (mftb() - t_before); > + hs->num_calls++; > +} > + > +/* > + * plpar_hcall wrapper > + */ > +long plpar_hcall(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3) > +{ > + long rc; > + unsigned long t_before; > + > + t_before = mftb(); > + rc = plpar_hcall_base(opcode, arg1, arg2, arg3, arg4, out1, out2, out3); > + > + update_stats(opcode, t_before); > + return rc; > +} Hmm, isn't it possible that the stats could be corrupted if we process an interrupt/softirq which does an hcall while the stats are being updated? Maybe it's not a show-stopper, but it seems to me that accuracy could suffer under some workloads. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-15 0:15 ` Nathan Lynch @ 2006-07-15 0:41 ` Mike Kravetz 2006-07-15 8:03 ` Nathan Lynch 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-07-15 0:41 UTC (permalink / raw) To: Nathan Lynch Cc: Bryan Rosenburg, linuxppc-dev, Paul Mackerras, Arnd Bergmann, Christopher Yeoh On Fri, Jul 14, 2006 at 07:15:45PM -0500, Nathan Lynch wrote: > Hmm, isn't it possible that the stats could be corrupted if we process > an interrupt/softirq which does an hcall while the stats are being > updated? Maybe it's not a show-stopper, but it seems to me that > accuracy could suffer under some workloads. Yes, they can become inaccurate. Is this what you mean by 'corrupted' or you thinking of something worse? There is going to be a trade off between accuracy and the overhead of the data gathering. What really needs to happen is some good benchmarking to measure the costs of different approaches. I'm pretty sure I can get someone to provide such data. In this patch, I have minimized the overhead in data collection at the cost of accuracy. -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-07-15 0:41 ` Mike Kravetz @ 2006-07-15 8:03 ` Nathan Lynch 0 siblings, 0 replies; 28+ messages in thread From: Nathan Lynch @ 2006-07-15 8:03 UTC (permalink / raw) To: Mike Kravetz Cc: Bryan Rosenburg, linuxppc-dev, Paul Mackerras, Arnd Bergmann, Christopher Yeoh Mike Kravetz wrote: > On Fri, Jul 14, 2006 at 07:15:45PM -0500, Nathan Lynch wrote: > > Hmm, isn't it possible that the stats could be corrupted if we process > > an interrupt/softirq which does an hcall while the stats are being > > updated? Maybe it's not a show-stopper, but it seems to me that > > accuracy could suffer under some workloads. > > Yes, they can become inaccurate. Is this what you mean by 'corrupted' or > you thinking of something worse? Yes, "corrupted" was perhaps too strong, but we could lose the accounting for hcalls from interrupts that we take at exactly the wrong time. I guess it's a pretty tiny risk. I just wanted to make sure this had been considered, but if you're comfortable with the overhead/accuracy tradeoff, then okay. ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 0/3] powerpc: Instrument Hypervisor Calls @ 2006-06-22 22:56 Mike Kravetz 2006-06-22 22:58 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-06-22 22:56 UTC (permalink / raw) To: linuxppc-dev Cc: Bryan Rosenburg, Christopher Yeoh, Nathan Lynch, Arnd Bergmann Here is an updated version of the hcall instrumentation patches. Unfortunately, I have not been able to spend as much time as I would like on this (and it seems that will continue). This version addresses all comments received except Arnd's issue with an #ifdef for each function in the assembly file. I like Jimi's suggestion for creating macros(which could also minimize the #ifdefs), but have not got around to implementing this. Suggestions of others way to accomplish this are welcome. Statistic files are moved to debugfs, and remain split out by CPU. After some thought, disable/enable of preemption was added around the statistic gathering(mostly for timing). -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-22 22:56 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz @ 2006-06-22 22:58 ` Mike Kravetz 0 siblings, 0 replies; 28+ messages in thread From: Mike Kravetz @ 2006-06-22 22:58 UTC (permalink / raw) To: linuxppc-dev Cc: Bryan Rosenburg, Christopher Yeoh, Nathan Lynch, Arnd Bergmann Add wrappers which perform the actual hypervisor call instrumentation. -- Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> diff -Naupr linux-2.6.17.1/arch/powerpc/Kconfig.debug linux-2.6.17.1.work/arch/powerpc/Kconfig.debug --- linux-2.6.17.1/arch/powerpc/Kconfig.debug 2006-06-20 09:31:55.000000000 +0000 +++ linux-2.6.17.1.work/arch/powerpc/Kconfig.debug 2006-06-22 22:58:58.000000000 +0000 @@ -18,6 +18,19 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. +config HCALL_STATS + bool "Hypervisor call instrumentation" + depends on PPC_PSERIES && DEBUG_FS + help + Adds code to keep track of the number of hypervisor calls made and + the amount of time spent in hypervisor calls. A directory named + hcall_inst is added at the root of the debugfs filesystem. Within + the hcall_inst directory are files that contain CPU specific call + statistics. + + This option will add a small amount of overhead to all hypervisor + calls. + config DEBUGGER bool "Enable debugger hooks" depends on DEBUG_KERNEL diff -Naupr linux-2.6.17.1/arch/powerpc/platforms/pseries/Makefile linux-2.6.17.1.work/arch/powerpc/platforms/pseries/Makefile --- linux-2.6.17.1/arch/powerpc/platforms/pseries/Makefile 2006-06-20 09:31:55.000000000 +0000 +++ linux-2.6.17.1.work/arch/powerpc/platforms/pseries/Makefile 2006-06-22 22:58:58.000000000 +0000 @@ -9,3 +9,4 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o e obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o +obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o diff -Naupr linux-2.6.17.1/arch/powerpc/platforms/pseries/hvCall.S linux-2.6.17.1.work/arch/powerpc/platforms/pseries/hvCall.S --- linux-2.6.17.1/arch/powerpc/platforms/pseries/hvCall.S 2006-06-20 09:31:55.000000000 +0000 +++ linux-2.6.17.1.work/arch/powerpc/platforms/pseries/hvCall.S 2006-06-22 22:58:58.000000000 +0000 @@ -25,7 +25,11 @@ unsigned long *out2, R9 unsigned long *out3); R10 */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_base) +#else _GLOBAL(plpar_hcall) +#endif HMT_MEDIUM mfcr r0 @@ -52,7 +56,19 @@ _GLOBAL(plpar_hcall) /* Simple interface with no output values (other than status) */ +#ifdef CONFIG_HCALL_STATS +/* + * A special 'indirect' call to a C based wrapper if statistics are desired. + * See plpar_hcall_norets_C function header for more details. + */ +_GLOBAL(plpar_hcall_norets) + b plpar_hcall_norets_C + + +_GLOBAL(plpar_hcall_norets_base) +#else _GLOBAL(plpar_hcall_norets) +#endif HMT_MEDIUM mfcr r0 @@ -76,7 +92,11 @@ _GLOBAL(plpar_hcall_norets) unsigned long arg8, 112(R1) unsigned long *out1); 120(R1) */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_8arg_2ret_base) +#else _GLOBAL(plpar_hcall_8arg_2ret) +#endif HMT_MEDIUM mfcr r0 @@ -102,7 +122,11 @@ _GLOBAL(plpar_hcall_8arg_2ret) unsigned long *out3, R10 unsigned long *out4); 112(R1) */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_4out_base) +#else _GLOBAL(plpar_hcall_4out) +#endif HMT_MEDIUM mfcr r0 @@ -144,7 +168,11 @@ _GLOBAL(plpar_hcall_4out) unsigned long *out6, 102(R1) unsigned long *out7); 100(R1) */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_7arg_7ret_base) +#else _GLOBAL(plpar_hcall_7arg_7ret) +#endif HMT_MEDIUM mfcr r0 @@ -193,7 +221,11 @@ _GLOBAL(plpar_hcall_7arg_7ret) unsigned long *out8, 94(R1) unsigned long *out9, 92(R1) */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_9arg_9ret_base) +#else _GLOBAL(plpar_hcall_9arg_9ret) +#endif HMT_MEDIUM mfcr r0 diff -Naupr linux-2.6.17.1/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.17.1.work/arch/powerpc/platforms/pseries/hvCall_inst.c --- linux-2.6.17.1/arch/powerpc/platforms/pseries/hvCall_inst.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.17.1.work/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-06-22 23:00:47.000000000 +0000 @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2006 Mike Kravetz IBM Corporation + * + * Hypervisor Call Instrumentation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/percpu.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include <linux/cpumask.h> +#include <asm/hvcall.h> +#include <asm/firmware.h> + +DEFINE_PER_CPU(struct hcall_stats[MAX_HCALL_OPCODES+1], hcall_stats); + +/* + * Common update of the per-CPU/per-hcall statistics + */ +static inline void update_stats(unsigned long opcode, unsigned long t_before) +{ + unsigned long op_index = opcode >> 2; + struct hcall_stats *hs = &__get_cpu_var(hcall_stats[op_index]); + + hs->total_time += (mfspr(SPRN_PURR) - t_before); + hs->num_calls++; +} + +/* + * plpar_hcall wrapper + */ +long plpar_hcall(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3) +{ + long rc; + unsigned long t_before; + + preempt_disable(); + t_before = mfspr(SPRN_PURR); + rc = plpar_hcall_base(opcode, arg1, arg2, arg3, arg4, out1, out2, out3); + + update_stats(opcode, t_before); + preempt_enable(); + return rc; +} + +/* + * A C based wrapper for plpar_hcall_norets + * The wrapper for plpar_hcall_norets is a special case because the function + * takes a variable number of arguments. It is almost impossible to write a + * wrapper for a function that takes a variable number of arguments in C. + * Therefore, there is an assembly routine in hvCall.S that simply branches + * to this C wrapper. This 'indirection' takes care of the variable arguments + * issue. This C wrapper has a fixed maximum number of arguments. + */ +long plpar_hcall_norets_C(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6) +{ + long rc; + unsigned long t_before; + + preempt_disable(); + t_before = mfspr(SPRN_PURR); + rc = plpar_hcall_norets_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6); + + update_stats(opcode, t_before); + preempt_enable(); + return rc; +} + +/* + * plpar_hcall_8arg_2ret wrapper + */ +long plpar_hcall_8arg_2ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1) +{ + long rc; + unsigned long t_before; + + preempt_disable(); + t_before = mfspr(SPRN_PURR); + rc = plpar_hcall_8arg_2ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, out1); + + update_stats(opcode, t_before); + preempt_enable(); + return rc; +} + +/* + * plpar_hcall_4out wrapper + */ +long plpar_hcall_4out(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4) +{ + long rc; + unsigned long t_before; + + preempt_disable(); + t_before = mfspr(SPRN_PURR); + rc = plpar_hcall_4out_base(opcode, arg1, arg2, arg3, arg4, out1, + out2, out3, out4); + + update_stats(opcode, t_before); + preempt_enable(); + return rc; +} + +/* + * plpar_hcall_7arg_7ret wrapper + */ +long plpar_hcall_7arg_7ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7) +{ + long rc; + unsigned long t_before; + + preempt_disable(); + t_before = mfspr(SPRN_PURR); + rc = plpar_hcall_7arg_7ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, out1, out2, out3, out4, + out5, out6, out7); + + update_stats(opcode, t_before); + preempt_enable(); + return rc; +} + +/* + * plpar_hcall_9arg_9ret wrapper + */ +long plpar_hcall_9arg_9ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long arg9, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7, + unsigned long *out8, + unsigned long *out9) +{ + long rc; + unsigned long t_before; + + preempt_disable(); + t_before = mfspr(SPRN_PURR); + rc = plpar_hcall_9arg_9ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, out1, out2, + out3, out4, out5, out6, out7, out8, + out9); + + update_stats(opcode, t_before); + preempt_enable(); + return rc; +} diff -Naupr linux-2.6.17.1/include/asm-powerpc/hvcall.h linux-2.6.17.1.work/include/asm-powerpc/hvcall.h --- linux-2.6.17.1/include/asm-powerpc/hvcall.h 2006-06-22 22:56:46.000000000 +0000 +++ linux-2.6.17.1.work/include/asm-powerpc/hvcall.h 2006-06-22 22:58:58.000000000 +0000 @@ -292,6 +292,86 @@ long plpar_hcall_9arg_9ret(unsigned long unsigned long *out8, unsigned long *out9); + +/* For hcall instrumentation. One structure per-hcall, per-CPU */ +struct hcall_stats { + unsigned long num_calls; /* number of calls (on this CPU) */ + unsigned long total_time; /* total cputime (PURR) of calls. */ +}; + +/* If Hypervisor call instrumentation is enabled, the assembly routine + * names are changed from 'plpar_hcall*' to 'plpar_hcall*_base' and + * 'plpar_hcall*' routines become instrumented wrappers. The following + * are declarations for the renamed 'plpar_hcall*_base' routines. + */ +long plpar_hcall_base (unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3); + +long plpar_hcall_norets_base(unsigned long opcode, ...); + +long plpar_hcall_8arg_2ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1); + +long plpar_hcall_4out_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4); + +long plpar_hcall_7arg_7ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7); + +long plpar_hcall_9arg_9ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long arg9, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7, + unsigned long *out8, + unsigned long *out9); + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HVCALL_H */ ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 0/3] powerpc: Instrument Hypervisor Calls @ 2006-06-14 3:47 Mike Kravetz 2006-06-14 3:52 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-06-14 3:47 UTC (permalink / raw) To: linuxppc-dev; +Cc: Bryan Rosenburg, Christopher Yeoh This patch series adds instrumentation to Hypervisor calls. Code and ideas were taken from the patch set provided by Christopher Yeoh. The idea is to put all instrumentation code behind a configuration option so that it can easily be added/removed. The instrumentation code is kept to a minimum in the hopes that it's impact to performance will not be noticed. Statistics are made available via files in sysfs. -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-14 3:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz @ 2006-06-14 3:52 ` Mike Kravetz 2006-06-14 7:23 ` Arnd Bergmann 2006-06-14 14:42 ` Nathan Lynch 0 siblings, 2 replies; 28+ messages in thread From: Mike Kravetz @ 2006-06-14 3:52 UTC (permalink / raw) To: linuxppc-dev; +Cc: Bryan Rosenburg, Christopher Yeoh Add wrappers which perform the actual hypervisor call instrumentation. -- Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> diff -Naupr linux-2.6.17-rc6/arch/powerpc/Kconfig.debug linux-2.6.17-rc6.work/arch/powerpc/Kconfig.debug --- linux-2.6.17-rc6/arch/powerpc/Kconfig.debug 2006-06-06 00:57:02.000000000 +0000 +++ linux-2.6.17-rc6.work/arch/powerpc/Kconfig.debug 2006-06-13 21:39:24.000000000 +0000 @@ -18,6 +18,16 @@ config DEBUG_STACK_USAGE This option will slow down process creation somewhat. +config HCALL_STATS + bool "Hypervisor call instrumentation" + depends on PPC_PSERIES + help + Adds code to keep track of number of hypervisor calls made and + the amount of time spent in hypervisor calls. + + This option will add a small amount of overhead to all hypervisor + calls. + config DEBUGGER bool "Enable debugger hooks" depends on DEBUG_KERNEL diff -Naupr linux-2.6.17-rc6/arch/powerpc/platforms/pseries/Makefile linux-2.6.17-rc6.work/arch/powerpc/platforms/pseries/Makefile --- linux-2.6.17-rc6/arch/powerpc/platforms/pseries/Makefile 2006-06-06 00:57:02.000000000 +0000 +++ linux-2.6.17-rc6.work/arch/powerpc/platforms/pseries/Makefile 2006-06-13 21:39:24.000000000 +0000 @@ -9,3 +9,4 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o e obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o +obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o diff -Naupr linux-2.6.17-rc6/arch/powerpc/platforms/pseries/hvCall.S linux-2.6.17-rc6.work/arch/powerpc/platforms/pseries/hvCall.S --- linux-2.6.17-rc6/arch/powerpc/platforms/pseries/hvCall.S 2006-06-06 00:57:02.000000000 +0000 +++ linux-2.6.17-rc6.work/arch/powerpc/platforms/pseries/hvCall.S 2006-06-13 21:39:24.000000000 +0000 @@ -25,7 +25,11 @@ unsigned long *out2, R9 unsigned long *out3); R10 */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_base) +#else _GLOBAL(plpar_hcall) +#endif HMT_MEDIUM mfcr r0 @@ -52,7 +56,15 @@ _GLOBAL(plpar_hcall) /* Simple interface with no output values (other than status) */ +#ifdef CONFIG_HCALL_STATS _GLOBAL(plpar_hcall_norets) + b plpar_hcall_norets_C + + +_GLOBAL(plpar_hcall_norets_base) +#else +_GLOBAL(plpar_hcall_norets) +#endif HMT_MEDIUM mfcr r0 @@ -76,7 +88,11 @@ _GLOBAL(plpar_hcall_norets) unsigned long arg8, 112(R1) unsigned long *out1); 120(R1) */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_8arg_2ret_base) +#else _GLOBAL(plpar_hcall_8arg_2ret) +#endif HMT_MEDIUM mfcr r0 @@ -102,7 +118,11 @@ _GLOBAL(plpar_hcall_8arg_2ret) unsigned long *out3, R10 unsigned long *out4); 112(R1) */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_4out_base) +#else _GLOBAL(plpar_hcall_4out) +#endif HMT_MEDIUM mfcr r0 @@ -144,7 +164,11 @@ _GLOBAL(plpar_hcall_4out) unsigned long *out6, 102(R1) unsigned long *out7); 100(R1) */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_7arg_7ret_base) +#else _GLOBAL(plpar_hcall_7arg_7ret) +#endif HMT_MEDIUM mfcr r0 @@ -193,7 +217,11 @@ _GLOBAL(plpar_hcall_7arg_7ret) unsigned long *out8, 94(R1) unsigned long *out9, 92(R1) */ +#ifdef CONFIG_HCALL_STATS +_GLOBAL(plpar_hcall_9arg_9ret_base) +#else _GLOBAL(plpar_hcall_9arg_9ret) +#endif HMT_MEDIUM mfcr r0 diff -Naupr linux-2.6.17-rc6/arch/powerpc/platforms/pseries/hvCall_inst.c linux-2.6.17-rc6.work/arch/powerpc/platforms/pseries/hvCall_inst.c --- linux-2.6.17-rc6/arch/powerpc/platforms/pseries/hvCall_inst.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.17-rc6.work/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-06-13 21:39:24.000000000 +0000 @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2006 Mike Kravetz IBM Corporation + * + * Hypervisor Call Instrumentation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/kernel.h> +#include <linux/percpu.h> +#include <asm/hvcall.h> + +DEFINE_PER_CPU(struct hcall_stats[MAX_HCALL_OPCODES+1], hcall_stats); + +static inline void update_stats(unsigned long opcode, unsigned long t_before) +{ + unsigned long op_index= opcode >> 2; + struct hcall_stats *hs = &__get_cpu_var(hcall_stats[op_index]); + + /* racey, but acceptable for non-critical stats */ + hs->total_time += (mfspr(SPRN_PURR) - t_before); + hs->num_calls++; +} + +extern long plpar_hcall_base (unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3); + +long plpar_hcall(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3) +{ + long rc; + unsigned long t_before = mfspr(SPRN_PURR); + + rc = plpar_hcall_base(opcode, arg1, arg2, arg3, arg4, out1, out2, out3); + + update_stats(opcode, t_before); + return rc; +} + +extern long plpar_hcall_norets_base(unsigned long opcode, ...); + +long plpar_hcall_norets_C(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6) +{ + long rc; + unsigned long t_before = mfspr(SPRN_PURR); + + rc = plpar_hcall_norets_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6); + + update_stats(opcode, t_before); + return rc; +} + +extern long plpar_hcall_8arg_2ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1); + +long plpar_hcall_8arg_2ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1) +{ + long rc; + unsigned long t_before = mfspr(SPRN_PURR); + + rc = plpar_hcall_8arg_2ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, out1); + + update_stats(opcode, t_before); + return rc; +} + +extern long plpar_hcall_4out_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4); + +long plpar_hcall_4out(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4) +{ + long rc; + unsigned long t_before = mfspr(SPRN_PURR); + + rc = plpar_hcall_4out_base(opcode, arg1, arg2, arg3, arg4, out1, + out2, out3, out4); + + update_stats(opcode, t_before); + return rc; +} + +extern long plpar_hcall_7arg_7ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7); + +long plpar_hcall_7arg_7ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7) +{ + long rc; + unsigned long t_before = mfspr(SPRN_PURR); + + rc = plpar_hcall_7arg_7ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, out1, out2, out3, out4, + out5, out6, out7); + + update_stats(opcode, t_before); + return rc; +} + +extern long plpar_hcall_9arg_9ret_base(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long arg9, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7, + unsigned long *out8, + unsigned long *out9); + +long plpar_hcall_9arg_9ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long arg9, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4, + unsigned long *out5, + unsigned long *out6, + unsigned long *out7, + unsigned long *out8, + unsigned long *out9) +{ + long rc; + unsigned long t_before = mfspr(SPRN_PURR); + + rc = plpar_hcall_9arg_9ret_base(opcode, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9, out1, out2, + out3, out4, out5, out6, out7, out8, + out9); + + update_stats(opcode, t_before); + return rc; +} diff -Naupr linux-2.6.17-rc6/include/asm-powerpc/hvcall.h linux-2.6.17-rc6.work/include/asm-powerpc/hvcall.h --- linux-2.6.17-rc6/include/asm-powerpc/hvcall.h 2006-06-13 21:38:45.000000000 +0000 +++ linux-2.6.17-rc6.work/include/asm-powerpc/hvcall.h 2006-06-13 21:39:24.000000000 +0000 @@ -292,6 +292,13 @@ long plpar_hcall_9arg_9ret(unsigned long unsigned long *out8, unsigned long *out9); +#ifdef CONFIG_HCALL_STATS +struct hcall_stats { + unsigned long num_calls; + unsigned long total_time; +}; +#endif /* CONFIG_HCALL_STATS */ + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HVCALL_H */ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-14 3:52 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz @ 2006-06-14 7:23 ` Arnd Bergmann 2006-06-14 14:42 ` Nathan Lynch 1 sibling, 0 replies; 28+ messages in thread From: Arnd Bergmann @ 2006-06-14 7:23 UTC (permalink / raw) To: linuxppc-dev; +Cc: Bryan Rosenburg, Christopher Yeoh T24gV2VkbmVzZGF5IDE0IEp1bmUgMjAwNiAwNTo1MiwgTWlrZSBLcmF2ZXR6IHdyb3RlOgoKPiCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB1bnNpZ25lZCBsb25nICpvdXQyLKCgoKCgoKCgoKCgoFI5 Cj4goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgdW5zaWduZWQgbG9uZyAqb3V0Myk7oKCgoKCgoKCg oKBSMTAKPiCgICovCj4gKyNpZmRlZiBDT05GSUdfSENBTExfU1RBVFMKPiArX0dMT0JBTChwbHBh cl9oY2FsbF9iYXNlKQo+ICsjZWxzZQo+IKBfR0xPQkFMKHBscGFyX2hjYWxsKQo+ICsjZW5kaWYK PiCgoKCgoKCgoEhNVF9NRURJVU0KPiCgCj4goKCgoKCgoKBtZmNyoKCgoHIwCgpUaGUgYXNzZW1i bHkgZmlsZXMgYXJlIGFscmVhZHkgaGFyZCB0byByZWFkLiBDYW4gd2UgZG8gdGhpcyB3aXRob3V0 CmFuIGV4dHJhICNpZmRlZiBpbiB0aGVyZSBmb3IgZXZlcnkgY2FsbD8KTW9yZW92ZXIsIHdoZW4g dXNpbmcgY3RhZ3Mgd2l0aCB5b3VyIHZlcnNpb24sIGxvb2tpbmcgZm9yIHBscGFyX2hjYWxsCndp bGwgZmluZCB0aGUgaW5zdHJ1bWVudGVkIHZlcnNpb24gb25seSwgd2hpY2ggbWF5IGJlIGV4dHJh IGNvbmZ1c2luZwp3aGVuIHRyeWluZyB0byB3b3JrIG91dCB0aGUgY2FsbCBjaGFpbi4KCj4gZGlm ZiAtTmF1cHIgbGludXgtMi42LjE3LXJjNi9hcmNoL3Bvd2VycGMvcGxhdGZvcm1zL3BzZXJpZXMv aHZDYWxsX2luc3QuYyBsaW51eC0yLjYuMTctcmM2LndvcmsvYXJjaC9wb3dlcnBjL3BsYXRmb3Jt cy9wc2VyaWVzL2h2Q2FsbF9pbnN0LmMKPiAtLS0gbGludXgtMi42LjE3LXJjNi9hcmNoL3Bvd2Vy cGMvcGxhdGZvcm1zL3BzZXJpZXMvaHZDYWxsX2luc3QuYyAgICAgICAxOTcwLTAxLTAxIDAwOjAw OjAwLjAwMDAwMDAwMCArMDAwMAo+ICsrKyBsaW51eC0yLjYuMTctcmM2LndvcmsvYXJjaC9wb3dl cnBjL3BsYXRmb3Jtcy9wc2VyaWVzL2h2Q2FsbF9pbnN0LmMgIDIwMDYtMDYtMTMgMjE6Mzk6MjQu MDAwMDAwMDAwICswMDAwCi4uLgo+ICtleHRlcm4gbG9uZyBwbHBhcl9oY2FsbF9iYXNlICh1bnNp Z25lZCBsb25nIG9wY29kZSwKPiArIKAgoCCgIKAgoCCgIKAgoCB1bnNpZ25lZCBsb25nIGFyZzEs Cj4gKyCgIKAgoCCgIKAgoCCgIKAgdW5zaWduZWQgbG9uZyBhcmcyLAo+ICsgoCCgIKAgoCCgIKAg oCCgIHVuc2lnbmVkIGxvbmcgYXJnMywKPiArIKAgoCCgIKAgoCCgIKAgoCB1bnNpZ25lZCBsb25n IGFyZzQsCj4gKyCgIKAgoCCgIKAgoCCgIKAgdW5zaWduZWQgbG9uZyAqb3V0MSwKPiArIKAgoCCg IKAgoCCgIKAgoCB1bnNpZ25lZCBsb25nICpvdXQyLAo+ICsgoCCgIKAgoCCgIKAgoCCgIHVuc2ln bmVkIGxvbmcgKm91dDMpOwoKQXQgdGhlIHNhbWUgdGltZSwgdGhlIGRlY2xhcmF0aW9ucyBzaG91 bGQgZ28gdG8gdGhlIGhlYWRlciBmaWxlLCBhcyB0aGV5CmFyZSBhbiBpbnRlcmZhY2UgYmV0d2Vl biB0d28gZmlsZXMuCgo+ICtleHRlcm4gbG9uZyBwbHBhcl9oY2FsbF9ub3JldHNfYmFzZSh1bnNp Z25lZCBsb25nIG9wY29kZSwgLi4uKTsKPiArCj4gK2xvbmcgcGxwYXJfaGNhbGxfbm9yZXRzX0Mo dW5zaWduZWQgbG9uZyBvcGNvZGUsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB1 bnNpZ25lZCBsb25nIGFyZzEsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB1bnNp Z25lZCBsb25nIGFyZzIsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB1bnNpZ25l ZCBsb25nIGFyZzMsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB1bnNpZ25lZCBs b25nIGFyZzQsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB1bnNpZ25lZCBsb25n IGFyZzUsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKB1bnNpZ25lZCBsb25nIGFy ZzYpCj4gK3sKPiAroKCgoKCgoGxvbmcgcmM7Cj4gK6CgoKCgoKB1bnNpZ25lZCBsb25nIHRfYmVm b3JlID0gbWZzcHIoU1BSTl9QVVJSKTsKPiArCj4gK6CgoKCgoKByYyA9IHBscGFyX2hjYWxsX25v cmV0c19iYXNlKG9wY29kZSwgYXJnMSwgYXJnMiwgYXJnMywgYXJnNCwgYXJnNSwKPiAroKCgoKCg oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCCgIKAgYXJnNik7Cj4gKwo+ICugoKCgoKCgdXBkYXRl X3N0YXRzKG9wY29kZSwgdF9iZWZvcmUpOwo+ICugoKCgoKCgcmV0dXJuIHJjOwo+ICt9CgpNYXli ZSBhIGxpdHRsZSBjb21tZW50IGhpbnRpbmcgYWJvdXQgdGhlIG1hZ2ljIGdvaW5nIG9uIHVuZGVy bmVhdGggdGhpcz8KCj4gZGlmZiAtTmF1cHIgbGludXgtMi42LjE3LXJjNi9pbmNsdWRlL2FzbS1w b3dlcnBjL2h2Y2FsbC5oIGxpbnV4LTIuNi4xNy1yYzYud29yay9pbmNsdWRlL2FzbS1wb3dlcnBj L2h2Y2FsbC5oCj4gLS0tIGxpbnV4LTIuNi4xNy1yYzYvaW5jbHVkZS9hc20tcG93ZXJwYy9odmNh bGwuaKCgoKCgoKAyMDA2LTA2LTEzIDIxOjM4OjQ1LjAwMDAwMDAwMCArMDAwMAo+ICsrKyBsaW51 eC0yLjYuMTctcmM2LndvcmsvaW5jbHVkZS9hc20tcG93ZXJwYy9odmNhbGwuaKCgMjAwNi0wNi0x MyAyMTozOToyNC4wMDAwMDAwMDAgKzAwMDAKPiBAQCAtMjkyLDYgKzI5MiwxMyBAQCBsb25nIHBs cGFyX2hjYWxsXzlhcmdfOXJldCh1bnNpZ25lZCBsb25nCj4goKCgoKCgoKCgoKCgoKCgoKCgoKCg oKCgIKAgdW5zaWduZWQgbG9uZyAqb3V0OCwKPiCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgoCB1 bnNpZ25lZCBsb25nICpvdXQ5KTsKPiCgCj4gKyNpZmRlZiBDT05GSUdfSENBTExfU1RBVFMKPiAr c3RydWN0IGhjYWxsX3N0YXRzIHsKPiAroKCgoKCgoHVuc2lnbmVkIGxvbmegoKBudW1fY2FsbHM7 Cj4gK6CgoKCgoKB1bnNpZ25lZCBsb25noKCgdG90YWxfdGltZTsKPiArfTsKPiArI2VuZGlmIC8q IENPTkZJR19IQ0FMTF9TVEFUUyAqLwo+ICsKClRoYXQgcmVhbGx5IHNob3VsZG4ndCBuZWVkICNp ZmRlZi4gWW91IGNvdWxkIG1vdmUgaXQgdG8gaHZDYWxsX2luc3QuYwp0aG91Z2gsIHNpbmNlIGl0 IGFwcGVhcnMgdG8gYmUgdXNlZCBvbmx5IGluIHRoZXJlIChwYXRjaCAzLzMgaGFzbid0CmNvbWUg dGhyb3VnaCB5ZXQsIGRvbid0IGtub3cgaWYgaXQncyB1c2VkIGVsc2V3aGVyZSBpbiB0aGF0KS4K CglBcm5kIDw+PAo= ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-14 3:52 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 2006-06-14 7:23 ` Arnd Bergmann @ 2006-06-14 14:42 ` Nathan Lynch 2006-06-14 22:33 ` Paul Mackerras 1 sibling, 1 reply; 28+ messages in thread From: Nathan Lynch @ 2006-06-14 14:42 UTC (permalink / raw) To: Mike Kravetz; +Cc: Bryan Rosenburg, linuxppc-dev, Christopher Yeoh Mike Kravetz wrote: > +config HCALL_STATS > + bool "Hypervisor call instrumentation" > + depends on PPC_PSERIES > + help > + Adds code to keep track of number of hypervisor calls made and > + the amount of time spent in hypervisor calls. > + > + This option will add a small amount of overhead to all hypervisor > + calls. Would be good to say how the stats are made available to userspace here. > +DEFINE_PER_CPU(struct hcall_stats[MAX_HCALL_OPCODES+1], hcall_stats); > + > +static inline void update_stats(unsigned long opcode, unsigned long t_before) > +{ > + unsigned long op_index= opcode >> 2; > + struct hcall_stats *hs = &__get_cpu_var(hcall_stats[op_index]); > + > + /* racey, but acceptable for non-critical stats */ > + hs->total_time += (mfspr(SPRN_PURR) - t_before); > + hs->num_calls++; > +} > + > +extern long plpar_hcall_base (unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3); > + > +long plpar_hcall(unsigned long opcode, > + unsigned long arg1, > + unsigned long arg2, > + unsigned long arg3, > + unsigned long arg4, > + unsigned long *out1, > + unsigned long *out2, > + unsigned long *out3) > +{ > + long rc; > + unsigned long t_before = mfspr(SPRN_PURR); > + > + rc = plpar_hcall_base(opcode, arg1, arg2, arg3, arg4, out1, out2, out3); > + > + update_stats(opcode, t_before); > + return rc; > +} Without disabling preemption around the mfspr ... update_stats section in these hcall wrappers, you risk updating the stats on the wrong cpu. > +struct hcall_stats { > + unsigned long num_calls; > + unsigned long total_time; > +}; A comment explaining the unit of time used for the total_time field would be nice. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-14 14:42 ` Nathan Lynch @ 2006-06-14 22:33 ` Paul Mackerras 2006-06-14 22:40 ` Nathan Lynch 2006-06-16 16:11 ` Mike Kravetz 0 siblings, 2 replies; 28+ messages in thread From: Paul Mackerras @ 2006-06-14 22:33 UTC (permalink / raw) To: Nathan Lynch; +Cc: Bryan Rosenburg, Christopher Yeoh, linuxppc-dev Nathan Lynch writes: > Without disabling preemption around the mfspr ... update_stats section > in these hcall wrappers, you risk updating the stats on the wrong cpu. I think we are only looking for total counts and times anyway, so it doesn't really matter which cpu updates the stats, as long as the time gets accounted on some cpu. The use of per-cpu counters is just for better cache behaviour. Paul. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-14 22:33 ` Paul Mackerras @ 2006-06-14 22:40 ` Nathan Lynch 2006-06-14 23:52 ` Mike Kravetz 2006-06-16 16:11 ` Mike Kravetz 1 sibling, 1 reply; 28+ messages in thread From: Nathan Lynch @ 2006-06-14 22:40 UTC (permalink / raw) To: Paul Mackerras; +Cc: Bryan Rosenburg, Christopher Yeoh, linuxppc-dev Paul Mackerras wrote: > Nathan Lynch writes: > > > Without disabling preemption around the mfspr ... update_stats section > > in these hcall wrappers, you risk updating the stats on the wrong cpu. > > I think we are only looking for total counts and times anyway, so it > doesn't really matter which cpu updates the stats, as long as the time > gets accounted on some cpu. The use of per-cpu counters is just for > better cache behaviour. Makes sense... then perhaps the stats shouldn't be exported in per-cpu files in sysfs, and the kernel should calculate and report the totals to userspace in some other form. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-14 22:40 ` Nathan Lynch @ 2006-06-14 23:52 ` Mike Kravetz 2006-06-15 11:09 ` Arnd Bergmann 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-06-14 23:52 UTC (permalink / raw) To: Nathan Lynch Cc: Bryan Rosenburg, linuxppc-dev, Paul Mackerras, Christopher Yeoh On Wed, Jun 14, 2006 at 05:40:40PM -0500, Nathan Lynch wrote: > Makes sense... then perhaps the stats shouldn't be exported in per-cpu > files in sysfs, and the kernel should calculate and report the totals > to userspace in some other form. I'm really wondering what would be the best way to make these stats available to userspace. As mentioned, putting them into sysfs would violate the one value/one file rule. The use of /proc is discouraged. debugfs was mentioned, but I have never used it. Noticed that debugfs was enabled in the default config (at least for pseries). Looks like that would be the best alternative. Agree? -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-14 23:52 ` Mike Kravetz @ 2006-06-15 11:09 ` Arnd Bergmann 2006-06-15 14:58 ` Mike Kravetz 0 siblings, 1 reply; 28+ messages in thread From: Arnd Bergmann @ 2006-06-15 11:09 UTC (permalink / raw) To: linuxppc-dev Cc: Bryan Rosenburg, Nathan Lynch, Paul Mackerras, Christopher Yeoh On Thursday 15 June 2006 01:52, Mike Kravetz wrote: > I'm really wondering what would be the best way to make these stats > available to userspace. =A0As mentioned, putting them into sysfs would > violate the one value/one file rule. =A0The use of /proc is discouraged. > debugfs was mentioned, but I have never used it. =A0Noticed that debugfs > was enabled in the default config (at least for pseries). =A0Looks like > that would be the best alternative. =A0Agree? Debugfs sounds good. If you use one file per hcall, it's probably as easy as static u64 hcall_stats_get(void *data) { unsigned long index =3D (unsigned long)data; return read_hcall_count(index); } DEFINE_SIMPLE_ATTRIBUTE(hcall_fops, hcall_stats_get, NULL, "%llu\n"); void hcall_stats_create(void) { unsigned long i; struct dentry *dir; dir =3D debugfs_create_dir("hcall_stats", NULL); for (i=3D0; i <=3D MAX_HCALL_OPCODES; i++) { char name[16]; sprintf(name, "%d", i << 2); debugfs_create_file(name, 0444, dir, (void *)i, &hcall_fops); } } Arnd <>< ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-15 11:09 ` Arnd Bergmann @ 2006-06-15 14:58 ` Mike Kravetz 2006-06-15 16:06 ` Arnd Bergmann 0 siblings, 1 reply; 28+ messages in thread From: Mike Kravetz @ 2006-06-15 14:58 UTC (permalink / raw) To: Arnd Bergmann Cc: Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Paul Mackerras, Christopher Yeoh On Thu, Jun 15, 2006 at 01:09:39PM +0200, Arnd Bergmann wrote: > On Thursday 15 June 2006 01:52, Mike Kravetz wrote: > > I'm really wondering what would be the best way to make these stats > > available to userspace. As mentioned, putting them into sysfs would > > violate the one value/one file rule. The use of /proc is discouraged. > > debugfs was mentioned, but I have never used it. Noticed that debugfs > > was enabled in the default config (at least for pseries). Looks like > > that would be the best alternative. Agree? > > Debugfs sounds good. If you use one file per hcall, it's probably as > easy as But does debugfs have the same one value/one file rule? Thought I could dump all the data in a single debugfs file. -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-15 14:58 ` Mike Kravetz @ 2006-06-15 16:06 ` Arnd Bergmann 0 siblings, 0 replies; 28+ messages in thread From: Arnd Bergmann @ 2006-06-15 16:06 UTC (permalink / raw) To: Mike Kravetz Cc: Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Paul Mackerras, Christopher Yeoh On Thursday 15 June 2006 16:58, Mike Kravetz wrote: > But does debugfs have the same one value/one file rule? =A0Thought I could > dump all the data in a single debugfs file. Sure, you could. It just makes it a little more complicated. You probably need to use a seq_file then. Arnd <>< ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers 2006-06-14 22:33 ` Paul Mackerras 2006-06-14 22:40 ` Nathan Lynch @ 2006-06-16 16:11 ` Mike Kravetz 1 sibling, 0 replies; 28+ messages in thread From: Mike Kravetz @ 2006-06-16 16:11 UTC (permalink / raw) To: Paul Mackerras Cc: Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Christopher Yeoh On Thu, Jun 15, 2006 at 08:33:55AM +1000, Paul Mackerras wrote: > Nathan Lynch writes: > > > Without disabling preemption around the mfspr ... update_stats section > > in these hcall wrappers, you risk updating the stats on the wrong cpu. > > I think we are only looking for total counts and times anyway, so it > doesn't really matter which cpu updates the stats, as long as the time > gets accounted on some cpu. The use of per-cpu counters is just for > better cache behaviour. Thought about this a little more. We do an mfspr to get a 'timestamp' before the actual hcall. Then, make the hcall and do another mfspr after. Isn't it possible to be preempted and perform the mfspr's on separate CPUs? Worse yet, wouldn't this possibly add 'time preempted' to the hcall time?. Do we have the same (skewed time) issue with interrupts? Thinking that enable/disable around the call might be worth the overhead. But, disabling interrupts would not be worth it. -- Mike ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2006-07-19 22:10 UTC | newest] Thread overview: 28+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-07-18 20:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz 2006-07-18 20:48 ` [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers Mike Kravetz 2006-07-18 20:49 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 2006-07-18 22:34 ` Olof Johansson 2006-07-18 23:18 ` Mike Kravetz 2006-07-19 3:33 ` Olof Johansson 2006-07-19 3:50 ` Mike Kravetz 2006-07-18 20:50 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz 2006-07-18 21:00 ` [PATCH 0/3] powerpc: Instrument Hypervisor Calls Paul Mackerras 2006-07-19 3:36 ` Mike Kravetz 2006-07-19 22:11 ` Mike Kravetz 2006-07-18 21:29 ` Mike Kravetz 2006-07-18 22:38 ` Olof Johansson -- strict thread matches above, loose matches on Subject: below -- 2006-07-14 23:37 Mike Kravetz 2006-07-14 23:40 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 2006-07-15 0:15 ` Nathan Lynch 2006-07-15 0:41 ` Mike Kravetz 2006-07-15 8:03 ` Nathan Lynch 2006-06-22 22:56 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz 2006-06-22 22:58 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 2006-06-14 3:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz 2006-06-14 3:52 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 2006-06-14 7:23 ` Arnd Bergmann 2006-06-14 14:42 ` Nathan Lynch 2006-06-14 22:33 ` Paul Mackerras 2006-06-14 22:40 ` Nathan Lynch 2006-06-14 23:52 ` Mike Kravetz 2006-06-15 11:09 ` Arnd Bergmann 2006-06-15 14:58 ` Mike Kravetz 2006-06-15 16:06 ` Arnd Bergmann 2006-06-16 16:11 ` Mike Kravetz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).