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
Showing the changes to tools/perf/scripts/python (3 of 3 files). Show all
Unified · Split
| @@ -0,0 +1,2 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +perf record -e "{powerpc:hcall_entry,powerpc:hcall_exit}" $@ | |
| @@ -0,0 +1,2 @@ | ||
| 1 | +#!/bin/bash | |
| 2 | +perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/powerpc-hcalls.py | |
| @@ -0,0 +1,200 @@ | ||
| 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)} | |