projects/linux·blob uaccess-cleanups · refs

335 lines · 7.9 KiB

1# SPDX-License-Identifier: GPL-2.0+
2#
3# Copyright (C) 2018 Ravi Bangoria, IBM Corporation
4#
5# Hypervisor call statisics
6
7from __future__ import print_function
8
9import os
10import sys
11
12sys.path.append(os.environ['PERF_EXEC_PATH'] + \
13 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
14
15from perf_trace_context import *
16from Core import *
17from Util import *
18
19# output: {
20# opcode: {
21# 'min': minimum time nsec
22# 'max': maximum time nsec
23# 'time': average time nsec
24# 'cnt': counter
25# } ...
26# }
27output = {}
28sort_key = 'count'
29
30# d_enter: {
31# cpu: {
32# opcode: nsec
33# } ...
34# }
35d_enter = {}
36
37hcall_table = {
38 4: 'H_REMOVE',
39 8: 'H_ENTER',
40 12: 'H_READ',
41 16: 'H_CLEAR_MOD',
42 20: 'H_CLEAR_REF',
43 24: 'H_PROTECT',
44 28: 'H_GET_TCE',
45 32: 'H_PUT_TCE',
46 36: 'H_SET_SPRG0',
47 40: 'H_SET_DABR',
48 44: 'H_PAGE_INIT',
49 48: 'H_SET_ASR',
50 52: 'H_ASR_ON',
51 56: 'H_ASR_OFF',
52 60: 'H_LOGICAL_CI_LOAD',
53 64: 'H_LOGICAL_CI_STORE',
54 68: 'H_LOGICAL_CACHE_LOAD',
55 72: 'H_LOGICAL_CACHE_STORE',
56 76: 'H_LOGICAL_ICBI',
57 80: 'H_LOGICAL_DCBF',
58 84: 'H_GET_TERM_CHAR',
59 88: 'H_PUT_TERM_CHAR',
60 92: 'H_REAL_TO_LOGICAL',
61 96: 'H_HYPERVISOR_DATA',
62 100: 'H_EOI',
63 104: 'H_CPPR',
64 108: 'H_IPI',
65 112: 'H_IPOLL',
66 116: 'H_XIRR',
67 120: 'H_MIGRATE_DMA',
68 124: 'H_PERFMON',
69 220: 'H_REGISTER_VPA',
70 224: 'H_CEDE',
71 228: 'H_CONFER',
72 232: 'H_PROD',
73 236: 'H_GET_PPP',
74 240: 'H_SET_PPP',
75 244: 'H_PURR',
76 248: 'H_PIC',
77 252: 'H_REG_CRQ',
78 256: 'H_FREE_CRQ',
79 260: 'H_VIO_SIGNAL',
80 264: 'H_SEND_CRQ',
81 272: 'H_COPY_RDMA',
82 276: 'H_REGISTER_LOGICAL_LAN',
83 280: 'H_FREE_LOGICAL_LAN',
84 284: 'H_ADD_LOGICAL_LAN_BUFFER',
85 288: 'H_SEND_LOGICAL_LAN',
86 292: 'H_BULK_REMOVE',
87 304: 'H_MULTICAST_CTRL',
88 308: 'H_SET_XDABR',
89 312: 'H_STUFF_TCE',
90 316: 'H_PUT_TCE_INDIRECT',
91 332: 'H_CHANGE_LOGICAL_LAN_MAC',
92 336: 'H_VTERM_PARTNER_INFO',
93 340: 'H_REGISTER_VTERM',
94 344: 'H_FREE_VTERM',
95 348: 'H_RESET_EVENTS',
96 352: 'H_ALLOC_RESOURCE',
97 356: 'H_FREE_RESOURCE',
98 360: 'H_MODIFY_QP',
99 364: 'H_QUERY_QP',
100 368: 'H_REREGISTER_PMR',
101 372: 'H_REGISTER_SMR',
102 376: 'H_QUERY_MR',
103 380: 'H_QUERY_MW',
104 384: 'H_QUERY_HCA',
105 388: 'H_QUERY_PORT',
106 392: 'H_MODIFY_PORT',
107 396: 'H_DEFINE_AQP1',
108 400: 'H_GET_TRACE_BUFFER',
109 404: 'H_DEFINE_AQP0',
110 408: 'H_RESIZE_MR',
111 412: 'H_ATTACH_MCQP',
112 416: 'H_DETACH_MCQP',
113 420: 'H_CREATE_RPT',
114 424: 'H_REMOVE_RPT',
115 428: 'H_REGISTER_RPAGES',
116 432: 'H_DISABLE_AND_GET',
117 436: 'H_ERROR_DATA',
118 440: 'H_GET_HCA_INFO',
119 444: 'H_GET_PERF_COUNT',
120 448: 'H_MANAGE_TRACE',
121 456: 'H_GET_CPU_CHARACTERISTICS',
122 468: 'H_FREE_LOGICAL_LAN_BUFFER',
123 472: 'H_POLL_PENDING',
124 484: 'H_QUERY_INT_STATE',
125 580: 'H_ILLAN_ATTRIBUTES',
126 584: 'H_ADD_LOGICAL_LAN_BUFFERS',
127 592: 'H_MODIFY_HEA_QP',
128 596: 'H_QUERY_HEA_QP',
129 600: 'H_QUERY_HEA',
130 604: 'H_QUERY_HEA_PORT',
131 608: 'H_MODIFY_HEA_PORT',
132 612: 'H_REG_BCMC',
133 616: 'H_DEREG_BCMC',
134 620: 'H_REGISTER_HEA_RPAGES',
135 624: 'H_DISABLE_AND_GET_HEA',
136 628: 'H_GET_HEA_INFO',
137 632: 'H_ALLOC_HEA_RESOURCE',
138 644: 'H_ADD_CONN',
139 648: 'H_DEL_CONN',
140 664: 'H_JOIN',
141 672: 'H_VASI_SIGNAL',
142 676: 'H_VASI_STATE',
143 680: 'H_VIOCTL',
144 688: 'H_ENABLE_CRQ',
145 696: 'H_GET_EM_PARMS',
146 720: 'H_SET_MPP',
147 724: 'H_GET_MPP',
148 732: 'H_REG_SUB_CRQ',
149 736: 'H_FREE_SUB_CRQ',
150 740: 'H_SEND_SUB_CRQ',
151 744: 'H_SEND_SUB_CRQ_INDIRECT',
152 748: 'H_HOME_NODE_ASSOCIATIVITY',
153 756: 'H_BEST_ENERGY',
154 764: 'H_XIRR_X',
155 768: 'H_RANDOM',
156 772: 'H_COP',
157 788: 'H_GET_MPP_X',
158 796: 'H_SET_MODE',
159 808: 'H_BLOCK_REMOVE',
160 856: 'H_CLEAR_HPT',
161 864: 'H_REQUEST_VMC',
162 876: 'H_RESIZE_HPT_PREPARE',
163 880: 'H_RESIZE_HPT_COMMIT',
164 892: 'H_REGISTER_PROC_TBL',
165 896: 'H_SIGNAL_SYS_RESET',
166 904: 'H_ALLOCATE_VAS_WINDOW',
167 908: 'H_MODIFY_VAS_WINDOW',
168 912: 'H_DEALLOCATE_VAS_WINDOW',
169 916: 'H_QUERY_VAS_WINDOW',
170 920: 'H_QUERY_VAS_CAPABILITIES',
171 924: 'H_QUERY_NX_CAPABILITIES',
172 928: 'H_GET_NX_FAULT',
173 936: 'H_INT_GET_SOURCE_INFO',
174 940: 'H_INT_SET_SOURCE_CONFIG',
175 944: 'H_INT_GET_SOURCE_CONFIG',
176 948: 'H_INT_GET_QUEUE_INFO',
177 952: 'H_INT_SET_QUEUE_CONFIG',
178 956: 'H_INT_GET_QUEUE_CONFIG',
179 960: 'H_INT_SET_OS_REPORTING_LINE',
180 964: 'H_INT_GET_OS_REPORTING_LINE',
181 968: 'H_INT_ESB',
182 972: 'H_INT_SYNC',
183 976: 'H_INT_RESET',
184 996: 'H_SCM_READ_METADATA',
185 1000: 'H_SCM_WRITE_METADATA',
186 1004: 'H_SCM_BIND_MEM',
187 1008: 'H_SCM_UNBIND_MEM',
188 1012: 'H_SCM_QUERY_BLOCK_MEM_BINDING',
189 1016: 'H_SCM_QUERY_LOGICAL_MEM_BINDING',
190 1020: 'H_SCM_UNBIND_ALL',
191 1024: 'H_SCM_HEALTH',
192 1048: 'H_SCM_PERFORMANCE_STATS',
193 1052: 'H_PKS_GET_CONFIG',
194 1056: 'H_PKS_SET_PASSWORD',
195 1060: 'H_PKS_GEN_PASSWORD',
196 1068: 'H_PKS_WRITE_OBJECT',
197 1072: 'H_PKS_GEN_KEY',
198 1076: 'H_PKS_READ_OBJECT',
199 1080: 'H_PKS_REMOVE_OBJECT',
200 1084: 'H_PKS_CONFIRM_OBJECT_FLUSHED',
201 1096: 'H_RPT_INVALIDATE',
202 1100: 'H_SCM_FLUSH',
203 1104: 'H_GET_ENERGY_SCALE_INFO',
204 1108: 'H_PKS_SIGNED_UPDATE',
205 1112: 'H_HTM',
206 1116: 'H_WATCHDOG',
207 # Platform specific hcalls used by KVM on PowerVM
208 1120: 'H_GUEST_GET_CAPABILITIES',
209 1124: 'H_GUEST_SET_CAPABILITIES',
210 1136: 'H_GUEST_CREATE',
211 1140: 'H_GUEST_CREATE_VCPU',
212 1144: 'H_GUEST_GET_STATE',
213 1148: 'H_GUEST_SET_STATE',
214 1152: 'H_GUEST_RUN_VCPU',
215 1156: 'H_GUEST_COPY_MEMORY',
216 1160: 'H_GUEST_DELETE',
217 # Key wrapping hcalls
218 1168: 'H_PKS_WRAP_OBJECT',
219 1172: 'H_PKS_UNWRAP_OBJECT',
220 # Platform-specific hcalls used by the Ultravisor
221 61184: 'H_SVM_PAGE_IN',
222 61188: 'H_SVM_PAGE_OUT',
223 61192: 'H_SVM_INIT_START',
224 61196: 'H_SVM_INIT_DONE',
225 61204: 'H_SVM_INIT_ABORT',
226 # Platform specific hcalls used by KVM
227 61440: 'H_RTAS',
228 # Platform specific hcalls used by QEMU/SLOF
229 61441: 'H_LOGICAL_MEMOP',
230 61442: 'H_CAS',
231 61443: 'H_UPDATE_DT',
232 # Platform specific hcalls provided by PHYP
233 61560: 'H_GET_24X7_CATALOG_PAGE',
234 61564: 'H_GET_24X7_DATA',
235 61568: 'H_GET_PERF_COUNTER_INFO',
236 # Platform-specific hcalls used for nested HV KVM
237 63488: 'H_SET_PARTITION_TABLE',
238 63492: 'H_ENTER_NESTED',
239 63496: 'H_TLB_INVALIDATE',
240 63500: 'H_COPY_TOFROM_GUEST',
241}
242
243def hcall_table_lookup(opcode):
244 if (opcode in hcall_table):
245 return hcall_table[opcode]
246 else:
247 return opcode
248
249print_ptrn = '%-28s%10s%10s%10s%10s'
250
251def sort_output(opcode):
252 stats = output[opcode]
253
254 if sort_key == 'min':
255 return stats['min']
256 if sort_key == 'max':
257 return stats['max']
258 if sort_key == 'avg':
259 return stats['time'] // stats['cnt']
260
261 return stats['cnt']
262
263def trace_begin():
264 global sort_key
265
266 valid_sort_keys = ['count', 'min', 'max', 'avg']
267
268 i = 1
269 while i < len(sys.argv):
270 arg = sys.argv[i]
271
272 if arg == '-s' or arg == '--sort':
273 if i + 1 >= len(sys.argv):
274 print("Error: -s/--sort requires a sort key argument")
275 sys.exit(1)
276 sort_key = sys.argv[i + 1]
277 i += 2
278 continue
279
280 if arg.startswith('--sort='):
281 sort_key = arg.split('=', 1)[1]
282 i += 1
283 continue
284
285 i += 1
286
287 if sort_key not in valid_sort_keys:
288 print(f"Error: Invalid sort key '{sort_key}'. Valid options are: {', '.join(valid_sort_keys)}")
289 sys.exit(1)
290
291 print("SORT KEY =", sort_key)
292
293def trace_end():
294 print(print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)'))
295 print('-' * 68)
296 for opcode in sorted(output, key = sort_output,
297 reverse=True):
298 h_name = hcall_table_lookup(opcode)
299 time = output[opcode]['time']
300 cnt = output[opcode]['cnt']
301 min_t = output[opcode]['min']
302 max_t = output[opcode]['max']
303
304 print(print_ptrn % (h_name, cnt, min_t, max_t, time//cnt))
305
306def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain,
307 opcode, retval):
308 if (cpu in d_enter and opcode in d_enter[cpu]):
309 diff = nsecs(sec, nsec) - d_enter[cpu][opcode]
310
311 if (opcode in output):
312 output[opcode]['time'] += diff
313 output[opcode]['cnt'] += 1
314 if (output[opcode]['min'] > diff):
315 output[opcode]['min'] = diff
316 if (output[opcode]['max'] < diff):
317 output[opcode]['max'] = diff
318 else:
319 output[opcode] = {
320 'time': diff,
321 'cnt': 1,
322 'min': diff,
323 'max': diff,
324 }
325
326 del d_enter[cpu][opcode]
327# else:
328# print("Can't find matching hcall_enter event. Ignoring sample")
329
330def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm,
331 callchain, opcode):
332 if (cpu in d_enter):
333 d_enter[cpu][opcode] = nsecs(sec, nsec)
334 else:
335 d_enter[cpu] = {opcode: nsecs(sec, nsec)}