Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf script powerpc: Python script for hypervisor call statistics

Add python script to show hypervisor call statistics. Ex,

# perf record -a -e "{powerpc:hcall_entry,powerpc:hcall_exit}"
# perf script -s scripts/python/powerpc-hcalls.py
hcall count min(ns) max(ns) avg(ns)
--------------------------------------------------------------------
H_RANDOM 82 838 1164 904
H_PUT_TCE 47 1078 5928 2003
H_EOI 266 1336 3546 1654
H_ENTER 28 1646 4038 1952
H_PUT_TCE_INDIRECT 230 2166 18168 6109
H_IPI 238 1072 3232 1688
H_SEND_LOGICAL_LAN 42 5488 21366 7694
H_STUFF_TCE 294 986 6210 3591
H_XIRR 266 2286 6990 3783
H_PROTECT 10 2196 3556 2555
H_VIO_SIGNAL 294 1028 2784 1311
H_ADD_LOGICAL_LAN_BUFFER 53 1978 3450 2600
H_SEND_CRQ 77 1762 7240 2447

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/20180605124801.17210-1-ravi.bangoria@linux.ibm.com
[ Fixup typo: table_loockup -> table_lookup ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ravi Bangoria and committed by
Arnaldo Carvalho de Melo
ec1e6e6a 005cc008

+204
+2
tools/perf/scripts/python/bin/powerpc-hcalls-record
··· 1 + #!/bin/bash 2 + perf record -e "{powerpc:hcall_entry,powerpc:hcall_exit}" $@
+2
tools/perf/scripts/python/bin/powerpc-hcalls-report
··· 1 + #!/bin/bash 2 + perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/powerpc-hcalls.py
+200
tools/perf/scripts/python/powerpc-hcalls.py
··· 1 + # SPDX-License-Identifier: GPL-2.0+ 2 + # 3 + # Copyright (C) 2018 Ravi Bangoria, IBM Corporation 4 + # 5 + # Hypervisor call statisics 6 + 7 + import os 8 + import sys 9 + 10 + sys.path.append(os.environ['PERF_EXEC_PATH'] + \ 11 + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 12 + 13 + from perf_trace_context import * 14 + from Core import * 15 + from Util import * 16 + 17 + # output: { 18 + # opcode: { 19 + # 'min': minimum time nsec 20 + # 'max': maximum time nsec 21 + # 'time': average time nsec 22 + # 'cnt': counter 23 + # } ... 24 + # } 25 + output = {} 26 + 27 + # d_enter: { 28 + # cpu: { 29 + # opcode: nsec 30 + # } ... 31 + # } 32 + d_enter = {} 33 + 34 + hcall_table = { 35 + 4: 'H_REMOVE', 36 + 8: 'H_ENTER', 37 + 12: 'H_READ', 38 + 16: 'H_CLEAR_MOD', 39 + 20: 'H_CLEAR_REF', 40 + 24: 'H_PROTECT', 41 + 28: 'H_GET_TCE', 42 + 32: 'H_PUT_TCE', 43 + 36: 'H_SET_SPRG0', 44 + 40: 'H_SET_DABR', 45 + 44: 'H_PAGE_INIT', 46 + 48: 'H_SET_ASR', 47 + 52: 'H_ASR_ON', 48 + 56: 'H_ASR_OFF', 49 + 60: 'H_LOGICAL_CI_LOAD', 50 + 64: 'H_LOGICAL_CI_STORE', 51 + 68: 'H_LOGICAL_CACHE_LOAD', 52 + 72: 'H_LOGICAL_CACHE_STORE', 53 + 76: 'H_LOGICAL_ICBI', 54 + 80: 'H_LOGICAL_DCBF', 55 + 84: 'H_GET_TERM_CHAR', 56 + 88: 'H_PUT_TERM_CHAR', 57 + 92: 'H_REAL_TO_LOGICAL', 58 + 96: 'H_HYPERVISOR_DATA', 59 + 100: 'H_EOI', 60 + 104: 'H_CPPR', 61 + 108: 'H_IPI', 62 + 112: 'H_IPOLL', 63 + 116: 'H_XIRR', 64 + 120: 'H_MIGRATE_DMA', 65 + 124: 'H_PERFMON', 66 + 220: 'H_REGISTER_VPA', 67 + 224: 'H_CEDE', 68 + 228: 'H_CONFER', 69 + 232: 'H_PROD', 70 + 236: 'H_GET_PPP', 71 + 240: 'H_SET_PPP', 72 + 244: 'H_PURR', 73 + 248: 'H_PIC', 74 + 252: 'H_REG_CRQ', 75 + 256: 'H_FREE_CRQ', 76 + 260: 'H_VIO_SIGNAL', 77 + 264: 'H_SEND_CRQ', 78 + 272: 'H_COPY_RDMA', 79 + 276: 'H_REGISTER_LOGICAL_LAN', 80 + 280: 'H_FREE_LOGICAL_LAN', 81 + 284: 'H_ADD_LOGICAL_LAN_BUFFER', 82 + 288: 'H_SEND_LOGICAL_LAN', 83 + 292: 'H_BULK_REMOVE', 84 + 304: 'H_MULTICAST_CTRL', 85 + 308: 'H_SET_XDABR', 86 + 312: 'H_STUFF_TCE', 87 + 316: 'H_PUT_TCE_INDIRECT', 88 + 332: 'H_CHANGE_LOGICAL_LAN_MAC', 89 + 336: 'H_VTERM_PARTNER_INFO', 90 + 340: 'H_REGISTER_VTERM', 91 + 344: 'H_FREE_VTERM', 92 + 348: 'H_RESET_EVENTS', 93 + 352: 'H_ALLOC_RESOURCE', 94 + 356: 'H_FREE_RESOURCE', 95 + 360: 'H_MODIFY_QP', 96 + 364: 'H_QUERY_QP', 97 + 368: 'H_REREGISTER_PMR', 98 + 372: 'H_REGISTER_SMR', 99 + 376: 'H_QUERY_MR', 100 + 380: 'H_QUERY_MW', 101 + 384: 'H_QUERY_HCA', 102 + 388: 'H_QUERY_PORT', 103 + 392: 'H_MODIFY_PORT', 104 + 396: 'H_DEFINE_AQP1', 105 + 400: 'H_GET_TRACE_BUFFER', 106 + 404: 'H_DEFINE_AQP0', 107 + 408: 'H_RESIZE_MR', 108 + 412: 'H_ATTACH_MCQP', 109 + 416: 'H_DETACH_MCQP', 110 + 420: 'H_CREATE_RPT', 111 + 424: 'H_REMOVE_RPT', 112 + 428: 'H_REGISTER_RPAGES', 113 + 432: 'H_DISABLE_AND_GETC', 114 + 436: 'H_ERROR_DATA', 115 + 440: 'H_GET_HCA_INFO', 116 + 444: 'H_GET_PERF_COUNT', 117 + 448: 'H_MANAGE_TRACE', 118 + 468: 'H_FREE_LOGICAL_LAN_BUFFER', 119 + 472: 'H_POLL_PENDING', 120 + 484: 'H_QUERY_INT_STATE', 121 + 580: 'H_ILLAN_ATTRIBUTES', 122 + 592: 'H_MODIFY_HEA_QP', 123 + 596: 'H_QUERY_HEA_QP', 124 + 600: 'H_QUERY_HEA', 125 + 604: 'H_QUERY_HEA_PORT', 126 + 608: 'H_MODIFY_HEA_PORT', 127 + 612: 'H_REG_BCMC', 128 + 616: 'H_DEREG_BCMC', 129 + 620: 'H_REGISTER_HEA_RPAGES', 130 + 624: 'H_DISABLE_AND_GET_HEA', 131 + 628: 'H_GET_HEA_INFO', 132 + 632: 'H_ALLOC_HEA_RESOURCE', 133 + 644: 'H_ADD_CONN', 134 + 648: 'H_DEL_CONN', 135 + 664: 'H_JOIN', 136 + 676: 'H_VASI_STATE', 137 + 688: 'H_ENABLE_CRQ', 138 + 696: 'H_GET_EM_PARMS', 139 + 720: 'H_SET_MPP', 140 + 724: 'H_GET_MPP', 141 + 748: 'H_HOME_NODE_ASSOCIATIVITY', 142 + 756: 'H_BEST_ENERGY', 143 + 764: 'H_XIRR_X', 144 + 768: 'H_RANDOM', 145 + 772: 'H_COP', 146 + 788: 'H_GET_MPP_X', 147 + 796: 'H_SET_MODE', 148 + 61440: 'H_RTAS', 149 + } 150 + 151 + def hcall_table_lookup(opcode): 152 + if (hcall_table.has_key(opcode)): 153 + return hcall_table[opcode] 154 + else: 155 + return opcode 156 + 157 + print_ptrn = '%-28s%10s%10s%10s%10s' 158 + 159 + def trace_end(): 160 + print print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)') 161 + print '-' * 68 162 + for opcode in output: 163 + h_name = hcall_table_lookup(opcode) 164 + time = output[opcode]['time'] 165 + cnt = output[opcode]['cnt'] 166 + min_t = output[opcode]['min'] 167 + max_t = output[opcode]['max'] 168 + 169 + print print_ptrn % (h_name, cnt, min_t, max_t, time/cnt) 170 + 171 + def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain, 172 + opcode, retval): 173 + if (d_enter.has_key(cpu) and d_enter[cpu].has_key(opcode)): 174 + diff = nsecs(sec, nsec) - d_enter[cpu][opcode] 175 + 176 + if (output.has_key(opcode)): 177 + output[opcode]['time'] += diff 178 + output[opcode]['cnt'] += 1 179 + if (output[opcode]['min'] > diff): 180 + output[opcode]['min'] = diff 181 + if (output[opcode]['max'] < diff): 182 + output[opcode]['max'] = diff 183 + else: 184 + output[opcode] = { 185 + 'time': diff, 186 + 'cnt': 1, 187 + 'min': diff, 188 + 'max': diff, 189 + } 190 + 191 + del d_enter[cpu][opcode] 192 + # else: 193 + # print "Can't find matching hcall_enter event. Ignoring sample" 194 + 195 + def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm, 196 + callchain, opcode): 197 + if (d_enter.has_key(cpu)): 198 + d_enter[cpu][opcode] = nsecs(sec, nsec) 199 + else: 200 + d_enter[cpu] = {opcode: nsecs(sec, nsec)}