| @@ -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)} |