* [PATCH 0/3] powerpc: Instrument Hypervisor Calls @ 2006-06-22 22:56 Mike Kravetz 2006-06-22 22:57 ` [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers Mike Kravetz ` (4 more replies) 0 siblings, 5 replies; 10+ 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] 10+ messages in thread
* [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers 2006-06-22 22:56 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz @ 2006-06-22 22:57 ` Mike Kravetz 2006-06-22 22:58 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz ` (3 subsequent siblings) 4 siblings, 0 replies; 10+ messages in thread From: Mike Kravetz @ 2006-06-22 22:57 UTC (permalink / raw) To: linuxppc-dev Cc: Bryan Rosenburg, Christopher Yeoh, Nathan Lynch, Arnd Bergmann 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.1/drivers/net/ibmveth.h linux-2.6.17.1.work/drivers/net/ibmveth.h --- linux-2.6.17.1/drivers/net/ibmveth.h 2006-06-20 09:31:55.000000000 +0000 +++ linux-2.6.17.1.work/drivers/net/ibmveth.h 2006-06-22 22:54:28.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.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-20 09:31:55.000000000 +0000 +++ linux-2.6.17.1.work/include/asm-powerpc/hvcall.h 2006-06-22 22:54:28.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] 10+ 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:57 ` [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers Mike Kravetz @ 2006-06-22 22:58 ` Mike Kravetz 2006-06-22 23:00 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz ` (2 subsequent siblings) 4 siblings, 0 replies; 10+ 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] 10+ messages in thread
* [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files 2006-06-22 22:56 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz 2006-06-22 22:57 ` [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers Mike Kravetz 2006-06-22 22:58 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz @ 2006-06-22 23:00 ` Mike Kravetz 2006-06-23 0:28 ` [PATCH 0/3] powerpc: Instrument Hypervisor Calls Segher Boessenkool 2006-07-10 20:35 ` Mike Kravetz 4 siblings, 0 replies; 10+ messages in thread From: Mike Kravetz @ 2006-06-22 23:00 UTC (permalink / raw) To: linuxppc-dev Cc: Bryan Rosenburg, Christopher Yeoh, Nathan Lynch, Arnd Bergmann Make statistics available via files in debugfs. -- Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> 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 2006-06-22 23:02:50.000000000 +0000 +++ linux-2.6.17.1.work/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-06-22 23:03:55.000000000 +0000 @@ -217,3 +217,94 @@ long plpar_hcall_9arg_9ret(unsigned long preempt_enable(); 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\n", h_num<<2, hs[h_num].num_calls, + hs[h_num].total_time); + + 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] 10+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-06-22 22:56 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz ` (2 preceding siblings ...) 2006-06-22 23:00 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz @ 2006-06-23 0:28 ` Segher Boessenkool 2006-07-10 20:35 ` Mike Kravetz 4 siblings, 0 replies; 10+ messages in thread From: Segher Boessenkool @ 2006-06-23 0:28 UTC (permalink / raw) To: Mike Kravetz Cc: Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Arnd Bergmann, Christopher Yeoh > Statistic files are moved to debugfs, and remain split out by CPU. Having done some if this myself long ago, I really like to see these per-cpu statistics. "Not useful" in real life, but for most testcases they're invaluable. It would be useful to also add a "total" column as well, of course, but it can also be done in userland. Segher ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-06-22 22:56 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz ` (3 preceding siblings ...) 2006-06-23 0:28 ` [PATCH 0/3] powerpc: Instrument Hypervisor Calls Segher Boessenkool @ 2006-07-10 20:35 ` Mike Kravetz 2006-07-10 20:49 ` Arnd Bergmann 2006-07-12 18:05 ` Mike Kravetz 4 siblings, 2 replies; 10+ messages in thread From: Mike Kravetz @ 2006-07-10 20:35 UTC (permalink / raw) To: linuxppc-dev Cc: Bryan Rosenburg, Christopher Yeoh, Nathan Lynch, Arnd Bergmann On Thu, Jun 22, 2006 at 03:56:09PM -0700, Mike Kravetz wrote: > This version addresses all comments received except Arnd's issue > with an #ifdef for each function in the assembly file. I was thinking of changing the names of all the assembly routines from plpar_hcall_*() to plpar_hcall_*_asm(). The instrumented version of the routines would be named plpar_hcall_*_inst(). Then, the header file would contain definitions such as: #ifdef CONFIG_HCALL_STATS #define plpar_hcall_*() plpar_hcall_*_inst() . #else #define plpar_hcall_*() plpar_hcall_*_asm() . #endif Is that any better than all the individual #ifdefs in the .S file? Is it still too ugly? I'm open to any suggestions. Thanks, -- Mike ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-07-10 20:35 ` Mike Kravetz @ 2006-07-10 20:49 ` Arnd Bergmann 2006-07-12 18:05 ` Mike Kravetz 1 sibling, 0 replies; 10+ messages in thread From: Arnd Bergmann @ 2006-07-10 20:49 UTC (permalink / raw) To: Mike Kravetz Cc: Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Christopher Yeoh On Monday 10 July 2006 22:35, Mike Kravetz wrote: > On Thu, Jun 22, 2006 at 03:56:09PM -0700, Mike Kravetz wrote: > > This version addresses all comments received except Arnd's issue > > with an #ifdef for each function in the assembly file. > > I was thinking of changing the names of all the assembly routines from > plpar_hcall_*() to plpar_hcall_*_asm(). The instrumented version of the > routines would be named plpar_hcall_*_inst(). Then, the header file > would contain definitions such as: > > #ifdef CONFIG_HCALL_STATS > #define plpar_hcall_*() plpar_hcall_*_inst() > . > #else > #define plpar_hcall_*() plpar_hcall_*_asm() > . > #endif > > Is that any better than all the individual #ifdefs in the .S file? Is it > still too ugly? > I guess it's better to have the #ifdef in the header file, but then again, you could just as well save some source lines doing #ifndef CONFIG_HCALL_STATS #define plpar_hcalldef(x) plpar_call_ ## x ## _asm #else #define plpar_hcalldef(x) plpar_call_ ## x ## _inst #endif #define plpar_call_foo plpar_hcalldef(foo) Arnd <>< ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/3] powerpc: Instrument Hypervisor Calls 2006-07-10 20:35 ` Mike Kravetz 2006-07-10 20:49 ` Arnd Bergmann @ 2006-07-12 18:05 ` Mike Kravetz 1 sibling, 0 replies; 10+ messages in thread From: Mike Kravetz @ 2006-07-12 18:05 UTC (permalink / raw) To: linuxppc-dev Cc: Bryan Rosenburg, Christopher Yeoh, Nathan Lynch, Arnd Bergmann On Mon, Jul 10, 2006 at 01:35:10PM -0700, Mike Kravetz wrote: > #ifdef CONFIG_HCALL_STATS > #define plpar_hcall_*() plpar_hcall_*_inst() To answer my own question, this won't work because plpar_hcall_*() routines are exported. So, marcros can't be used. Still thinking about the best way to juggle function names for instrumentation. -- Mike ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 0/3] powerpc: Instrument Hypervisor Calls @ 2006-07-14 23:37 Mike Kravetz 2006-07-14 23:41 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz 0 siblings, 1 reply; 10+ 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] 10+ messages in thread
* [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files 2006-07-14 23:37 Mike Kravetz @ 2006-07-14 23:41 ` Mike Kravetz 0 siblings, 0 replies; 10+ messages in thread From: Mike Kravetz @ 2006-07-14 23:41 UTC (permalink / raw) To: Paul Mackerras Cc: Arnd Bergmann, Bryan Rosenburg, linuxppc-dev, Nathan Lynch, Christopher Yeoh Make statistics available via files in debugfs. -- Signed-off-by: Mike Kravetz <kravetz@us.ibm.com> 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 2006-07-14 23:32:01.000000000 +0000 +++ linux-2.6.17.4.work/arch/powerpc/platforms/pseries/hvCall_inst.c 2006-07-14 23:32:54.000000000 +0000 @@ -205,3 +205,94 @@ long plpar_hcall_9arg_9ret(unsigned long update_stats(opcode, t_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\n", h_num<<2, hs[h_num].num_calls, + hs[h_num].total_time); + + 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] 10+ messages in thread
* [PATCH 0/3] powerpc: Instrument Hypervisor Calls @ 2006-07-18 20:47 Mike Kravetz 2006-07-18 20:50 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz 0 siblings, 1 reply; 10+ 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] 10+ 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:50 ` Mike Kravetz 0 siblings, 0 replies; 10+ 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] 10+ messages in thread
end of thread, other threads:[~2006-07-18 20:50 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-06-22 22:56 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz 2006-06-22 22:57 ` [PATCH 1/3] powerpc: Instrument Hypervisor Calls: merge headers Mike Kravetz 2006-06-22 22:58 ` [PATCH 2/3] powerpc: Instrument Hypervisor Calls: add wrappers Mike Kravetz 2006-06-22 23:00 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz 2006-06-23 0:28 ` [PATCH 0/3] powerpc: Instrument Hypervisor Calls Segher Boessenkool 2006-07-10 20:35 ` Mike Kravetz 2006-07-10 20:49 ` Arnd Bergmann 2006-07-12 18:05 ` Mike Kravetz -- strict thread matches above, loose matches on Subject: below -- 2006-07-14 23:37 Mike Kravetz 2006-07-14 23:41 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files Mike Kravetz 2006-07-18 20:47 [PATCH 0/3] powerpc: Instrument Hypervisor Calls Mike Kravetz 2006-07-18 20:50 ` [PATCH 3/3] powerpc: Instrument Hypervisor Calls: add debugfs files 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).