xref: /aosp_15_r20/external/bcc/tools/ppchcalls.py (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/python
2*387f9dfdSAndroid Build Coastguard Worker#
3*387f9dfdSAndroid Build Coastguard Worker# ppchcalls   Summarize ppc hcalls stats.
4*387f9dfdSAndroid Build Coastguard Worker#
5*387f9dfdSAndroid Build Coastguard Worker# Initial version migrating perf based tool to ebpf with additional hcalls,
6*387f9dfdSAndroid Build Coastguard Worker# inspired by existing bcc tool for syscalls.
7*387f9dfdSAndroid Build Coastguard Worker#
8*387f9dfdSAndroid Build Coastguard Worker#
9*387f9dfdSAndroid Build Coastguard Worker
10*387f9dfdSAndroid Build Coastguard Workerfrom time import sleep, strftime
11*387f9dfdSAndroid Build Coastguard Workerimport argparse
12*387f9dfdSAndroid Build Coastguard Workerimport errno
13*387f9dfdSAndroid Build Coastguard Workerimport itertools
14*387f9dfdSAndroid Build Coastguard Workerimport sys
15*387f9dfdSAndroid Build Coastguard Workerimport signal
16*387f9dfdSAndroid Build Coastguard Workerfrom bcc import BPF
17*387f9dfdSAndroid Build Coastguard Worker
18*387f9dfdSAndroid Build Coastguard Workerhcall_table = {
19*387f9dfdSAndroid Build Coastguard Worker    4: 'H_REMOVE',
20*387f9dfdSAndroid Build Coastguard Worker    8: 'H_ENTER',
21*387f9dfdSAndroid Build Coastguard Worker    12: 'H_READ',
22*387f9dfdSAndroid Build Coastguard Worker    16: 'H_CLEAR_MOD',
23*387f9dfdSAndroid Build Coastguard Worker    20: 'H_CLEAR_REF',
24*387f9dfdSAndroid Build Coastguard Worker    24: 'H_PROTECT',
25*387f9dfdSAndroid Build Coastguard Worker    28: 'H_GET_TCE',
26*387f9dfdSAndroid Build Coastguard Worker    32: 'H_PUT_TCE',
27*387f9dfdSAndroid Build Coastguard Worker    36: 'H_SET_SPRG0',
28*387f9dfdSAndroid Build Coastguard Worker    40: 'H_SET_DABR',
29*387f9dfdSAndroid Build Coastguard Worker    44: 'H_PAGE_INIT',
30*387f9dfdSAndroid Build Coastguard Worker    48: 'H_SET_ASR',
31*387f9dfdSAndroid Build Coastguard Worker    52: 'H_ASR_ON',
32*387f9dfdSAndroid Build Coastguard Worker    56: 'H_ASR_OFF',
33*387f9dfdSAndroid Build Coastguard Worker    60: 'H_LOGICAL_CI_LOAD',
34*387f9dfdSAndroid Build Coastguard Worker    64: 'H_LOGICAL_CI_STORE',
35*387f9dfdSAndroid Build Coastguard Worker    68: 'H_LOGICAL_CACHE_LOAD',
36*387f9dfdSAndroid Build Coastguard Worker    72: 'H_LOGICAL_CACHE_STORE',
37*387f9dfdSAndroid Build Coastguard Worker    76: 'H_LOGICAL_ICBI',
38*387f9dfdSAndroid Build Coastguard Worker    80: 'H_LOGICAL_DCBF',
39*387f9dfdSAndroid Build Coastguard Worker    84: 'H_GET_TERM_CHAR',
40*387f9dfdSAndroid Build Coastguard Worker    88: 'H_PUT_TERM_CHAR',
41*387f9dfdSAndroid Build Coastguard Worker    92: 'H_REAL_TO_LOGICAL',
42*387f9dfdSAndroid Build Coastguard Worker    96: 'H_HYPERVISOR_DATA',
43*387f9dfdSAndroid Build Coastguard Worker    100: 'H_EOI',
44*387f9dfdSAndroid Build Coastguard Worker    104: 'H_CPPR',
45*387f9dfdSAndroid Build Coastguard Worker    108: 'H_IPI',
46*387f9dfdSAndroid Build Coastguard Worker    112: 'H_IPOLL',
47*387f9dfdSAndroid Build Coastguard Worker    116: 'H_XIRR',
48*387f9dfdSAndroid Build Coastguard Worker    120: 'H_MIGRATE_DMA',
49*387f9dfdSAndroid Build Coastguard Worker    124: 'H_PERFMON',
50*387f9dfdSAndroid Build Coastguard Worker    220: 'H_REGISTER_VPA',
51*387f9dfdSAndroid Build Coastguard Worker    224: 'H_CEDE',
52*387f9dfdSAndroid Build Coastguard Worker    228: 'H_CONFER',
53*387f9dfdSAndroid Build Coastguard Worker    232: 'H_PROD',
54*387f9dfdSAndroid Build Coastguard Worker    236: 'H_GET_PPP',
55*387f9dfdSAndroid Build Coastguard Worker    240: 'H_SET_PPP',
56*387f9dfdSAndroid Build Coastguard Worker    244: 'H_PURR',
57*387f9dfdSAndroid Build Coastguard Worker    248: 'H_PIC',
58*387f9dfdSAndroid Build Coastguard Worker    252: 'H_REG_CRQ',
59*387f9dfdSAndroid Build Coastguard Worker    256: 'H_FREE_CRQ',
60*387f9dfdSAndroid Build Coastguard Worker    260: 'H_VIO_SIGNAL',
61*387f9dfdSAndroid Build Coastguard Worker    264: 'H_SEND_CRQ',
62*387f9dfdSAndroid Build Coastguard Worker    272: 'H_COPY_RDMA',
63*387f9dfdSAndroid Build Coastguard Worker    276: 'H_REGISTER_LOGICAL_LAN',
64*387f9dfdSAndroid Build Coastguard Worker    280: 'H_FREE_LOGICAL_LAN',
65*387f9dfdSAndroid Build Coastguard Worker    284: 'H_ADD_LOGICAL_LAN_BUFFER',
66*387f9dfdSAndroid Build Coastguard Worker    288: 'H_SEND_LOGICAL_LAN',
67*387f9dfdSAndroid Build Coastguard Worker    292: 'H_BULK_REMOVE',
68*387f9dfdSAndroid Build Coastguard Worker    304: 'H_MULTICAST_CTRL',
69*387f9dfdSAndroid Build Coastguard Worker    308: 'H_SET_XDABR',
70*387f9dfdSAndroid Build Coastguard Worker    312: 'H_STUFF_TCE',
71*387f9dfdSAndroid Build Coastguard Worker    316: 'H_PUT_TCE_INDIRECT',
72*387f9dfdSAndroid Build Coastguard Worker    332: 'H_CHANGE_LOGICAL_LAN_MAC',
73*387f9dfdSAndroid Build Coastguard Worker    336: 'H_VTERM_PARTNER_INFO',
74*387f9dfdSAndroid Build Coastguard Worker    340: 'H_REGISTER_VTERM',
75*387f9dfdSAndroid Build Coastguard Worker    344: 'H_FREE_VTERM',
76*387f9dfdSAndroid Build Coastguard Worker    348: 'H_RESET_EVENTS',
77*387f9dfdSAndroid Build Coastguard Worker    352: 'H_ALLOC_RESOURCE',
78*387f9dfdSAndroid Build Coastguard Worker    356: 'H_FREE_RESOURCE',
79*387f9dfdSAndroid Build Coastguard Worker    360: 'H_MODIFY_QP',
80*387f9dfdSAndroid Build Coastguard Worker    364: 'H_QUERY_QP',
81*387f9dfdSAndroid Build Coastguard Worker    368: 'H_REREGISTER_PMR',
82*387f9dfdSAndroid Build Coastguard Worker    372: 'H_REGISTER_SMR',
83*387f9dfdSAndroid Build Coastguard Worker    376: 'H_QUERY_MR',
84*387f9dfdSAndroid Build Coastguard Worker    380: 'H_QUERY_MW',
85*387f9dfdSAndroid Build Coastguard Worker    384: 'H_QUERY_HCA',
86*387f9dfdSAndroid Build Coastguard Worker    388: 'H_QUERY_PORT',
87*387f9dfdSAndroid Build Coastguard Worker    392: 'H_MODIFY_PORT',
88*387f9dfdSAndroid Build Coastguard Worker    396: 'H_DEFINE_AQP1',
89*387f9dfdSAndroid Build Coastguard Worker    400: 'H_GET_TRACE_BUFFER',
90*387f9dfdSAndroid Build Coastguard Worker    404: 'H_DEFINE_AQP0',
91*387f9dfdSAndroid Build Coastguard Worker    408: 'H_RESIZE_MR',
92*387f9dfdSAndroid Build Coastguard Worker    412: 'H_ATTACH_MCQP',
93*387f9dfdSAndroid Build Coastguard Worker    416: 'H_DETACH_MCQP',
94*387f9dfdSAndroid Build Coastguard Worker    420: 'H_CREATE_RPT',
95*387f9dfdSAndroid Build Coastguard Worker    424: 'H_REMOVE_RPT',
96*387f9dfdSAndroid Build Coastguard Worker    428: 'H_REGISTER_RPAGES',
97*387f9dfdSAndroid Build Coastguard Worker    432: 'H_DISABLE_AND_GET',
98*387f9dfdSAndroid Build Coastguard Worker    436: 'H_ERROR_DATA',
99*387f9dfdSAndroid Build Coastguard Worker    440: 'H_GET_HCA_INFO',
100*387f9dfdSAndroid Build Coastguard Worker    444: 'H_GET_PERF_COUNT',
101*387f9dfdSAndroid Build Coastguard Worker    448: 'H_MANAGE_TRACE',
102*387f9dfdSAndroid Build Coastguard Worker    456: 'H_GET_CPU_CHARACTERISTICS',
103*387f9dfdSAndroid Build Coastguard Worker    468: 'H_FREE_LOGICAL_LAN_BUFFER',
104*387f9dfdSAndroid Build Coastguard Worker    472: 'H_POLL_PENDING',
105*387f9dfdSAndroid Build Coastguard Worker    484: 'H_QUERY_INT_STATE',
106*387f9dfdSAndroid Build Coastguard Worker    580: 'H_ILLAN_ATTRIBUTES',
107*387f9dfdSAndroid Build Coastguard Worker    592: 'H_MODIFY_HEA_QP',
108*387f9dfdSAndroid Build Coastguard Worker    596: 'H_QUERY_HEA_QP',
109*387f9dfdSAndroid Build Coastguard Worker    600: 'H_QUERY_HEA',
110*387f9dfdSAndroid Build Coastguard Worker    604: 'H_QUERY_HEA_PORT',
111*387f9dfdSAndroid Build Coastguard Worker    608: 'H_MODIFY_HEA_PORT',
112*387f9dfdSAndroid Build Coastguard Worker    612: 'H_REG_BCMC',
113*387f9dfdSAndroid Build Coastguard Worker    616: 'H_DEREG_BCMC',
114*387f9dfdSAndroid Build Coastguard Worker    620: 'H_REGISTER_HEA_RPAGES',
115*387f9dfdSAndroid Build Coastguard Worker    624: 'H_DISABLE_AND_GET_HEA',
116*387f9dfdSAndroid Build Coastguard Worker    628: 'H_GET_HEA_INFO',
117*387f9dfdSAndroid Build Coastguard Worker    632: 'H_ALLOC_HEA_RESOURCE',
118*387f9dfdSAndroid Build Coastguard Worker    644: 'H_ADD_CONN',
119*387f9dfdSAndroid Build Coastguard Worker    648: 'H_DEL_CONN',
120*387f9dfdSAndroid Build Coastguard Worker    664: 'H_JOIN',
121*387f9dfdSAndroid Build Coastguard Worker    672: 'H_VASI_SIGNAL',
122*387f9dfdSAndroid Build Coastguard Worker    676: 'H_VASI_STATE',
123*387f9dfdSAndroid Build Coastguard Worker    680: 'H_VIOCTL',
124*387f9dfdSAndroid Build Coastguard Worker    688: 'H_ENABLE_CRQ',
125*387f9dfdSAndroid Build Coastguard Worker    696: 'H_GET_EM_PARMS',
126*387f9dfdSAndroid Build Coastguard Worker    720: 'H_SET_MPP',
127*387f9dfdSAndroid Build Coastguard Worker    724: 'H_GET_MPP',
128*387f9dfdSAndroid Build Coastguard Worker    732: 'H_REG_SUB_CRQ',
129*387f9dfdSAndroid Build Coastguard Worker    736: 'H_FREE_SUB_CRQ',
130*387f9dfdSAndroid Build Coastguard Worker    740: 'H_SEND_SUB_CRQ',
131*387f9dfdSAndroid Build Coastguard Worker    744: 'H_SEND_SUB_CRQ_INDIRECT',
132*387f9dfdSAndroid Build Coastguard Worker    748: 'H_HOME_NODE_ASSOCIATIVITY',
133*387f9dfdSAndroid Build Coastguard Worker    756: 'H_BEST_ENERGY',
134*387f9dfdSAndroid Build Coastguard Worker    764: 'H_XIRR_X',
135*387f9dfdSAndroid Build Coastguard Worker    768: 'H_RANDOM',
136*387f9dfdSAndroid Build Coastguard Worker    772: 'H_COP',
137*387f9dfdSAndroid Build Coastguard Worker    788: 'H_GET_MPP_X',
138*387f9dfdSAndroid Build Coastguard Worker    796: 'H_SET_MODE',
139*387f9dfdSAndroid Build Coastguard Worker    808: 'H_BLOCK_REMOVE',
140*387f9dfdSAndroid Build Coastguard Worker    856: 'H_CLEAR_HPT',
141*387f9dfdSAndroid Build Coastguard Worker    864: 'H_REQUEST_VMC',
142*387f9dfdSAndroid Build Coastguard Worker    876: 'H_RESIZE_HPT_PREPARE',
143*387f9dfdSAndroid Build Coastguard Worker    880: 'H_RESIZE_HPT_COMMIT',
144*387f9dfdSAndroid Build Coastguard Worker    892: 'H_REGISTER_PROC_TBL',
145*387f9dfdSAndroid Build Coastguard Worker    896: 'H_SIGNAL_SYS_RESET',
146*387f9dfdSAndroid Build Coastguard Worker    904: 'H_ALLOCATE_VAS_WINDOW',
147*387f9dfdSAndroid Build Coastguard Worker    908: 'H_MODIFY_VAS_WINDOW',
148*387f9dfdSAndroid Build Coastguard Worker    912: 'H_DEALLOCATE_VAS_WINDOW',
149*387f9dfdSAndroid Build Coastguard Worker    916: 'H_QUERY_VAS_WINDOW',
150*387f9dfdSAndroid Build Coastguard Worker    920: 'H_QUERY_VAS_CAPABILITIES',
151*387f9dfdSAndroid Build Coastguard Worker    924: 'H_QUERY_NX_CAPABILITIES',
152*387f9dfdSAndroid Build Coastguard Worker    928: 'H_GET_NX_FAULT',
153*387f9dfdSAndroid Build Coastguard Worker    936: 'H_INT_GET_SOURCE_INFO',
154*387f9dfdSAndroid Build Coastguard Worker    940: 'H_INT_SET_SOURCE_CONFIG',
155*387f9dfdSAndroid Build Coastguard Worker    944: 'H_INT_GET_SOURCE_CONFIG',
156*387f9dfdSAndroid Build Coastguard Worker    948: 'H_INT_GET_QUEUE_INFO',
157*387f9dfdSAndroid Build Coastguard Worker    952: 'H_INT_SET_QUEUE_CONFIG',
158*387f9dfdSAndroid Build Coastguard Worker    956: 'H_INT_GET_QUEUE_CONFIG',
159*387f9dfdSAndroid Build Coastguard Worker    960: 'H_INT_SET_OS_REPORTING_LINE',
160*387f9dfdSAndroid Build Coastguard Worker    964: 'H_INT_GET_OS_REPORTING_LINE',
161*387f9dfdSAndroid Build Coastguard Worker    968: 'H_INT_ESB',
162*387f9dfdSAndroid Build Coastguard Worker    972: 'H_INT_SYNC',
163*387f9dfdSAndroid Build Coastguard Worker    976: 'H_INT_RESET',
164*387f9dfdSAndroid Build Coastguard Worker    996: 'H_SCM_READ_METADATA',
165*387f9dfdSAndroid Build Coastguard Worker    1000: 'H_SCM_WRITE_METADATA',
166*387f9dfdSAndroid Build Coastguard Worker    1004: 'H_SCM_BIND_MEM',
167*387f9dfdSAndroid Build Coastguard Worker    1008: 'H_SCM_UNBIND_MEM',
168*387f9dfdSAndroid Build Coastguard Worker    1012: 'H_SCM_QUERY_BLOCK_MEM_BINDING',
169*387f9dfdSAndroid Build Coastguard Worker    1016: 'H_SCM_QUERY_LOGICAL_MEM_BINDING',
170*387f9dfdSAndroid Build Coastguard Worker    1020: 'H_SCM_UNBIND_ALL',
171*387f9dfdSAndroid Build Coastguard Worker    1024: 'H_SCM_HEALTH',
172*387f9dfdSAndroid Build Coastguard Worker    1048: 'H_SCM_PERFORMANCE_STATS',
173*387f9dfdSAndroid Build Coastguard Worker    1052: 'H_PKS_GET_CONFIG',
174*387f9dfdSAndroid Build Coastguard Worker    1056: 'H_PKS_SET_PASSWORD',
175*387f9dfdSAndroid Build Coastguard Worker    1060: 'H_PKS_GEN_PASSWORD',
176*387f9dfdSAndroid Build Coastguard Worker    1068: 'H_PKS_WRITE_OBJECT',
177*387f9dfdSAndroid Build Coastguard Worker    1072: 'H_PKS_GEN_KEY',
178*387f9dfdSAndroid Build Coastguard Worker    1076: 'H_PKS_READ_OBJECT',
179*387f9dfdSAndroid Build Coastguard Worker    1080: 'H_PKS_REMOVE_OBJECT',
180*387f9dfdSAndroid Build Coastguard Worker    1084: 'H_PKS_CONFIRM_OBJECT_FLUSHED',
181*387f9dfdSAndroid Build Coastguard Worker    1096: 'H_RPT_INVALIDATE',
182*387f9dfdSAndroid Build Coastguard Worker    1100: 'H_SCM_FLUSH',
183*387f9dfdSAndroid Build Coastguard Worker    1104: 'H_GET_ENERGY_SCALE_INFO',
184*387f9dfdSAndroid Build Coastguard Worker    1108: 'H_PKS_SIGNED_UPDATE',
185*387f9dfdSAndroid Build Coastguard Worker    1116: 'H_WATCHDOG',
186*387f9dfdSAndroid Build Coastguard Worker    # Platform specific hcalls used by KVM on PowerVM
187*387f9dfdSAndroid Build Coastguard Worker    1120: 'H_GUEST_GET_CAPABILITIES',
188*387f9dfdSAndroid Build Coastguard Worker    1124: 'H_GUEST_SET_CAPABILITIES',
189*387f9dfdSAndroid Build Coastguard Worker    1136: 'H_GUEST_CREATE',
190*387f9dfdSAndroid Build Coastguard Worker    1140: 'H_GUEST_CREATE_VCPU',
191*387f9dfdSAndroid Build Coastguard Worker    1144: 'H_GUEST_GET_STATE',
192*387f9dfdSAndroid Build Coastguard Worker    1148: 'H_GUEST_SET_STATE',
193*387f9dfdSAndroid Build Coastguard Worker    1152: 'H_GUEST_RUN_VCPU',
194*387f9dfdSAndroid Build Coastguard Worker    1156: 'H_GUEST_COPY_MEMORY',
195*387f9dfdSAndroid Build Coastguard Worker    1160: 'H_GUEST_DELETE',
196*387f9dfdSAndroid Build Coastguard Worker    # Platform-specific hcalls used by the Ultravisor
197*387f9dfdSAndroid Build Coastguard Worker    61184: 'H_SVM_PAGE_IN',
198*387f9dfdSAndroid Build Coastguard Worker    61188: 'H_SVM_PAGE_OUT',
199*387f9dfdSAndroid Build Coastguard Worker    61192: 'H_SVM_INIT_START',
200*387f9dfdSAndroid Build Coastguard Worker    61196: 'H_SVM_INIT_DONE',
201*387f9dfdSAndroid Build Coastguard Worker    61204: 'H_SVM_INIT_ABORT',
202*387f9dfdSAndroid Build Coastguard Worker    # Platform specific hcalls used by KVM
203*387f9dfdSAndroid Build Coastguard Worker    61440: 'H_RTAS',
204*387f9dfdSAndroid Build Coastguard Worker    # Platform specific hcalls used by QEMU/SLOF
205*387f9dfdSAndroid Build Coastguard Worker    61441: 'H_LOGICAL_MEMOP',
206*387f9dfdSAndroid Build Coastguard Worker    61442: 'H_CAS',
207*387f9dfdSAndroid Build Coastguard Worker    61443: 'H_UPDATE_DT',
208*387f9dfdSAndroid Build Coastguard Worker    # Platform specific hcalls provided by PHYP
209*387f9dfdSAndroid Build Coastguard Worker    61560: 'H_GET_24X7_CATALOG_PAGE',
210*387f9dfdSAndroid Build Coastguard Worker    61564: 'H_GET_24X7_DATA',
211*387f9dfdSAndroid Build Coastguard Worker    61568: 'H_GET_PERF_COUNTER_INFO',
212*387f9dfdSAndroid Build Coastguard Worker    # Platform-specific hcalls used for nested HV KVM
213*387f9dfdSAndroid Build Coastguard Worker    63488: 'H_SET_PARTITION_TABLE',
214*387f9dfdSAndroid Build Coastguard Worker    63492: 'H_ENTER_NESTED',
215*387f9dfdSAndroid Build Coastguard Worker    63496: 'H_TLB_INVALIDATE',
216*387f9dfdSAndroid Build Coastguard Worker    63500: 'H_COPY_TOFROM_GUEST',
217*387f9dfdSAndroid Build Coastguard Worker}
218*387f9dfdSAndroid Build Coastguard Worker
219*387f9dfdSAndroid Build Coastguard Workerdef hcall_table_lookup(opcode):
220*387f9dfdSAndroid Build Coastguard Worker        if (opcode in hcall_table):
221*387f9dfdSAndroid Build Coastguard Worker                return hcall_table[opcode]
222*387f9dfdSAndroid Build Coastguard Worker        else:
223*387f9dfdSAndroid Build Coastguard Worker                return opcode
224*387f9dfdSAndroid Build Coastguard Worker
225*387f9dfdSAndroid Build Coastguard Workerif sys.version_info.major < 3:
226*387f9dfdSAndroid Build Coastguard Worker    izip_longest = itertools.izip_longest
227*387f9dfdSAndroid Build Coastguard Workerelse:
228*387f9dfdSAndroid Build Coastguard Worker    izip_longest = itertools.zip_longest
229*387f9dfdSAndroid Build Coastguard Worker
230*387f9dfdSAndroid Build Coastguard Worker# signal handler
231*387f9dfdSAndroid Build Coastguard Workerdef signal_ignore(signal, frame):
232*387f9dfdSAndroid Build Coastguard Worker    print()
233*387f9dfdSAndroid Build Coastguard Worker
234*387f9dfdSAndroid Build Coastguard Workerdef handle_errno(errstr):
235*387f9dfdSAndroid Build Coastguard Worker    try:
236*387f9dfdSAndroid Build Coastguard Worker        return abs(int(errstr))
237*387f9dfdSAndroid Build Coastguard Worker    except ValueError:
238*387f9dfdSAndroid Build Coastguard Worker        pass
239*387f9dfdSAndroid Build Coastguard Worker
240*387f9dfdSAndroid Build Coastguard Worker    try:
241*387f9dfdSAndroid Build Coastguard Worker        return getattr(errno, errstr)
242*387f9dfdSAndroid Build Coastguard Worker    except AttributeError:
243*387f9dfdSAndroid Build Coastguard Worker        raise argparse.ArgumentTypeError("couldn't map %s to an errno" % errstr)
244*387f9dfdSAndroid Build Coastguard Worker
245*387f9dfdSAndroid Build Coastguard Worker
246*387f9dfdSAndroid Build Coastguard Workerparser = argparse.ArgumentParser(
247*387f9dfdSAndroid Build Coastguard Worker    description="Summarize ppc hcall counts and latencies.")
248*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-p", "--pid", type=int,
249*387f9dfdSAndroid Build Coastguard Worker    help="trace only this pid")
250*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-t", "--tid", type=int,
251*387f9dfdSAndroid Build Coastguard Worker    help="trace only this tid")
252*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-i", "--interval", type=int,
253*387f9dfdSAndroid Build Coastguard Worker    help="print summary at this interval (seconds)")
254*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-d", "--duration", type=int,
255*387f9dfdSAndroid Build Coastguard Worker    help="total duration of trace, in seconds")
256*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-T", "--top", type=int, default=10,
257*387f9dfdSAndroid Build Coastguard Worker    help="print only the top hcalls by count or latency")
258*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-x", "--failures", action="store_true",
259*387f9dfdSAndroid Build Coastguard Worker    help="trace only failed hcalls (return < 0)")
260*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-e", "--errno", type=handle_errno,
261*387f9dfdSAndroid Build Coastguard Worker    help="trace only hcalls that return this error (numeric or EPERM, etc.)")
262*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-L", "--latency", action="store_true",
263*387f9dfdSAndroid Build Coastguard Worker    help="collect hcall latency")
264*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-m", "--milliseconds", action="store_true",
265*387f9dfdSAndroid Build Coastguard Worker    help="display latency in milliseconds (default: microseconds)")
266*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-P", "--process", action="store_true",
267*387f9dfdSAndroid Build Coastguard Worker    help="count by process and not by hcall")
268*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("-l", "--list", action="store_true",
269*387f9dfdSAndroid Build Coastguard Worker    help="print list of recognized hcalls and exit")
270*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--hcall", type=str,
271*387f9dfdSAndroid Build Coastguard Worker    help="trace this hcall only (use option -l to get all recognized hcalls)")
272*387f9dfdSAndroid Build Coastguard Workerparser.add_argument("--ebpf", action="store_true",
273*387f9dfdSAndroid Build Coastguard Worker    help=argparse.SUPPRESS)
274*387f9dfdSAndroid Build Coastguard Workerargs = parser.parse_args()
275*387f9dfdSAndroid Build Coastguard Workerif args.duration and not args.interval:
276*387f9dfdSAndroid Build Coastguard Worker    args.interval = args.duration
277*387f9dfdSAndroid Build Coastguard Workerif not args.interval:
278*387f9dfdSAndroid Build Coastguard Worker    args.interval = 99999999
279*387f9dfdSAndroid Build Coastguard Worker
280*387f9dfdSAndroid Build Coastguard Workerhcall_nr = -1
281*387f9dfdSAndroid Build Coastguard Workerif args.hcall is not None:
282*387f9dfdSAndroid Build Coastguard Worker    for key, value in hcall_table.items():
283*387f9dfdSAndroid Build Coastguard Worker        if args.hcall == value:
284*387f9dfdSAndroid Build Coastguard Worker            hcall_nr = key
285*387f9dfdSAndroid Build Coastguard Worker            print("hcall %s , hcall_nr =%d" % (args.hcall, hcall_nr))
286*387f9dfdSAndroid Build Coastguard Worker            break
287*387f9dfdSAndroid Build Coastguard Worker    if hcall_nr == -1:
288*387f9dfdSAndroid Build Coastguard Worker        print("Error: hcall '%s' not found. Exiting." % args.hcall)
289*387f9dfdSAndroid Build Coastguard Worker        sys.exit(1)
290*387f9dfdSAndroid Build Coastguard Worker
291*387f9dfdSAndroid Build Coastguard Workerif args.list:
292*387f9dfdSAndroid Build Coastguard Worker    for grp in izip_longest(*(iter(sorted(hcall_table.values())),) * 4):
293*387f9dfdSAndroid Build Coastguard Worker        print("   ".join(["%-25s" % s for s in grp if s is not None]))
294*387f9dfdSAndroid Build Coastguard Worker    sys.exit(0)
295*387f9dfdSAndroid Build Coastguard Worker
296*387f9dfdSAndroid Build Coastguard Workertext = """
297*387f9dfdSAndroid Build Coastguard Worker#ifdef LATENCY
298*387f9dfdSAndroid Build Coastguard Workerstruct data_t {
299*387f9dfdSAndroid Build Coastguard Worker    u64 count;
300*387f9dfdSAndroid Build Coastguard Worker    u64 min;
301*387f9dfdSAndroid Build Coastguard Worker    u64 max;
302*387f9dfdSAndroid Build Coastguard Worker    u64 total_ns;
303*387f9dfdSAndroid Build Coastguard Worker};
304*387f9dfdSAndroid Build Coastguard Worker
305*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(start, u64, u64);
306*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(ppc_data, u32, struct data_t);
307*387f9dfdSAndroid Build Coastguard Worker#else
308*387f9dfdSAndroid Build Coastguard WorkerBPF_HASH(ppc_data, u32, u64);
309*387f9dfdSAndroid Build Coastguard Worker#endif
310*387f9dfdSAndroid Build Coastguard Worker
311*387f9dfdSAndroid Build Coastguard Worker#ifdef LATENCY
312*387f9dfdSAndroid Build Coastguard WorkerRAW_TRACEPOINT_PROBE(hcall_entry) {
313*387f9dfdSAndroid Build Coastguard Worker    // TP_PROTO(unsigned long opcode, unsigned long *args),
314*387f9dfdSAndroid Build Coastguard Worker    u64 pid_tgid = bpf_get_current_pid_tgid();
315*387f9dfdSAndroid Build Coastguard Worker    u32 pid = pid_tgid >> 32;
316*387f9dfdSAndroid Build Coastguard Worker    u32 tid = (u32)pid_tgid;
317*387f9dfdSAndroid Build Coastguard Worker
318*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_HCALL_NR
319*387f9dfdSAndroid Build Coastguard Workerif (ctx->args[0] != FILTER_HCALL_NR)
320*387f9dfdSAndroid Build Coastguard Worker    return 0;
321*387f9dfdSAndroid Build Coastguard Worker#endif
322*387f9dfdSAndroid Build Coastguard Worker
323*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_PID
324*387f9dfdSAndroid Build Coastguard Worker    if (pid != FILTER_PID)
325*387f9dfdSAndroid Build Coastguard Worker        return 0;
326*387f9dfdSAndroid Build Coastguard Worker#endif
327*387f9dfdSAndroid Build Coastguard Worker
328*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_TID
329*387f9dfdSAndroid Build Coastguard Worker    if (tid != FILTER_TID)
330*387f9dfdSAndroid Build Coastguard Worker        return 0;
331*387f9dfdSAndroid Build Coastguard Worker#endif
332*387f9dfdSAndroid Build Coastguard Worker
333*387f9dfdSAndroid Build Coastguard Worker    u64 t = bpf_ktime_get_ns();
334*387f9dfdSAndroid Build Coastguard Worker    start.update(&pid_tgid, &t);
335*387f9dfdSAndroid Build Coastguard Worker    return 0;
336*387f9dfdSAndroid Build Coastguard Worker}
337*387f9dfdSAndroid Build Coastguard Worker#endif
338*387f9dfdSAndroid Build Coastguard Worker
339*387f9dfdSAndroid Build Coastguard WorkerRAW_TRACEPOINT_PROBE(hcall_exit) {
340*387f9dfdSAndroid Build Coastguard Worker    // TP_PROTO(unsigned long opcode, long retval, unsigned long *retbuf)
341*387f9dfdSAndroid Build Coastguard Worker    u64 pid_tgid = bpf_get_current_pid_tgid();
342*387f9dfdSAndroid Build Coastguard Worker    u32 pid = pid_tgid >> 32;
343*387f9dfdSAndroid Build Coastguard Worker    u32 tid = (u32)pid_tgid;
344*387f9dfdSAndroid Build Coastguard Worker
345*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_HCALL_NR
346*387f9dfdSAndroid Build Coastguard Worker    if (ctx->args[0] != FILTER_HCALL_NR)
347*387f9dfdSAndroid Build Coastguard Worker        return 0;
348*387f9dfdSAndroid Build Coastguard Worker#endif
349*387f9dfdSAndroid Build Coastguard Worker
350*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_PID
351*387f9dfdSAndroid Build Coastguard Worker    if (pid != FILTER_PID)
352*387f9dfdSAndroid Build Coastguard Worker        return 0;
353*387f9dfdSAndroid Build Coastguard Worker#endif
354*387f9dfdSAndroid Build Coastguard Worker
355*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_TID
356*387f9dfdSAndroid Build Coastguard Worker    if (tid != FILTER_TID)
357*387f9dfdSAndroid Build Coastguard Worker        return 0;
358*387f9dfdSAndroid Build Coastguard Worker#endif
359*387f9dfdSAndroid Build Coastguard Worker
360*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_FAILED
361*387f9dfdSAndroid Build Coastguard Worker    if (ctx->args[1] >= 0)
362*387f9dfdSAndroid Build Coastguard Worker        return 0;
363*387f9dfdSAndroid Build Coastguard Worker#endif
364*387f9dfdSAndroid Build Coastguard Worker
365*387f9dfdSAndroid Build Coastguard Worker#ifdef FILTER_ERRNO
366*387f9dfdSAndroid Build Coastguard Worker    if (ctx->args[1] != -FILTER_ERRNO)
367*387f9dfdSAndroid Build Coastguard Worker        return 0;
368*387f9dfdSAndroid Build Coastguard Worker#endif
369*387f9dfdSAndroid Build Coastguard Worker
370*387f9dfdSAndroid Build Coastguard Worker#ifdef BY_PROCESS
371*387f9dfdSAndroid Build Coastguard Worker    u32 key = pid_tgid >> 32;
372*387f9dfdSAndroid Build Coastguard Worker#else
373*387f9dfdSAndroid Build Coastguard Worker    u32 key = (unsigned long) ctx->args[0];
374*387f9dfdSAndroid Build Coastguard Worker#endif
375*387f9dfdSAndroid Build Coastguard Worker
376*387f9dfdSAndroid Build Coastguard Worker#ifdef LATENCY
377*387f9dfdSAndroid Build Coastguard Worker    struct data_t *val, zero = {};
378*387f9dfdSAndroid Build Coastguard Worker    u64 delta = 0;
379*387f9dfdSAndroid Build Coastguard Worker    u64 *start_ns = start.lookup(&pid_tgid);
380*387f9dfdSAndroid Build Coastguard Worker    if (!start_ns)
381*387f9dfdSAndroid Build Coastguard Worker        return 0;
382*387f9dfdSAndroid Build Coastguard Worker
383*387f9dfdSAndroid Build Coastguard Worker    val = ppc_data.lookup_or_try_init(&key, &zero);
384*387f9dfdSAndroid Build Coastguard Worker    if (val) {
385*387f9dfdSAndroid Build Coastguard Worker        val->count++;
386*387f9dfdSAndroid Build Coastguard Worker        delta = bpf_ktime_get_ns() - *start_ns;
387*387f9dfdSAndroid Build Coastguard Worker        if (val->min) {
388*387f9dfdSAndroid Build Coastguard Worker            if(val->min > delta)
389*387f9dfdSAndroid Build Coastguard Worker                val->min = delta;
390*387f9dfdSAndroid Build Coastguard Worker        } else {
391*387f9dfdSAndroid Build Coastguard Worker                val->min = delta;
392*387f9dfdSAndroid Build Coastguard Worker        }
393*387f9dfdSAndroid Build Coastguard Worker        if (val->max) {
394*387f9dfdSAndroid Build Coastguard Worker            if(val->max < delta)
395*387f9dfdSAndroid Build Coastguard Worker                val->max = delta;
396*387f9dfdSAndroid Build Coastguard Worker        } else {
397*387f9dfdSAndroid Build Coastguard Worker                val->max = delta;
398*387f9dfdSAndroid Build Coastguard Worker        }
399*387f9dfdSAndroid Build Coastguard Worker        val->total_ns += delta;
400*387f9dfdSAndroid Build Coastguard Worker    }
401*387f9dfdSAndroid Build Coastguard Worker#else
402*387f9dfdSAndroid Build Coastguard Worker    u64 *val, zero = 0;
403*387f9dfdSAndroid Build Coastguard Worker    val = ppc_data.lookup_or_try_init(&key, &zero);
404*387f9dfdSAndroid Build Coastguard Worker    if (val) {
405*387f9dfdSAndroid Build Coastguard Worker        ++(*val);
406*387f9dfdSAndroid Build Coastguard Worker    }
407*387f9dfdSAndroid Build Coastguard Worker#endif
408*387f9dfdSAndroid Build Coastguard Worker    return 0;
409*387f9dfdSAndroid Build Coastguard Worker}
410*387f9dfdSAndroid Build Coastguard Worker"""
411*387f9dfdSAndroid Build Coastguard Worker
412*387f9dfdSAndroid Build Coastguard Workerif args.pid:
413*387f9dfdSAndroid Build Coastguard Worker    text = ("#define FILTER_PID %d\n" % args.pid) + text
414*387f9dfdSAndroid Build Coastguard Workerelif args.tid:
415*387f9dfdSAndroid Build Coastguard Worker    text = ("#define FILTER_TID %d\n" % args.tid) + text
416*387f9dfdSAndroid Build Coastguard Workerif args.failures:
417*387f9dfdSAndroid Build Coastguard Worker    text = "#define FILTER_FAILED\n" + text
418*387f9dfdSAndroid Build Coastguard Workerif args.errno:
419*387f9dfdSAndroid Build Coastguard Worker    text = "#define FILTER_ERRNO %d\n" % abs(args.errno) + text
420*387f9dfdSAndroid Build Coastguard Workerif args.latency:
421*387f9dfdSAndroid Build Coastguard Worker    text = "#define LATENCY\n" + text
422*387f9dfdSAndroid Build Coastguard Workerif args.process:
423*387f9dfdSAndroid Build Coastguard Worker    text = "#define BY_PROCESS\n" + text
424*387f9dfdSAndroid Build Coastguard Workerif args.hcall is not None:
425*387f9dfdSAndroid Build Coastguard Worker    text = ("#define FILTER_HCALL_NR %d\n" % hcall_nr) + text
426*387f9dfdSAndroid Build Coastguard Workerif args.ebpf:
427*387f9dfdSAndroid Build Coastguard Worker    print(text)
428*387f9dfdSAndroid Build Coastguard Worker    exit()
429*387f9dfdSAndroid Build Coastguard Worker
430*387f9dfdSAndroid Build Coastguard Workerbpf = BPF(text=text)
431*387f9dfdSAndroid Build Coastguard Worker
432*387f9dfdSAndroid Build Coastguard Workerdef print_stats():
433*387f9dfdSAndroid Build Coastguard Worker    if args.latency:
434*387f9dfdSAndroid Build Coastguard Worker        ppc_print_latency_stats()
435*387f9dfdSAndroid Build Coastguard Worker    else:
436*387f9dfdSAndroid Build Coastguard Worker        print_ppc_count_stats()
437*387f9dfdSAndroid Build Coastguard Worker
438*387f9dfdSAndroid Build Coastguard Workerppc_agg_colname = "PID    COMM" if args.process else "PPC HCALL"
439*387f9dfdSAndroid Build Coastguard Workermin_time_colname = "MIN (ms)" if args.milliseconds else "MIN (us)"
440*387f9dfdSAndroid Build Coastguard Workermax_time_colname = "MAX (ms)" if args.milliseconds else "MAX (us)"
441*387f9dfdSAndroid Build Coastguard Workeravg_time_colname = "AVG (ms)" if args.milliseconds else "AVG (us)"
442*387f9dfdSAndroid Build Coastguard Worker
443*387f9dfdSAndroid Build Coastguard Workerdef comm_for_pid(pid):
444*387f9dfdSAndroid Build Coastguard Worker    try:
445*387f9dfdSAndroid Build Coastguard Worker        return open("/proc/%d/comm" % pid, "r").read().strip()
446*387f9dfdSAndroid Build Coastguard Worker    except Exception:
447*387f9dfdSAndroid Build Coastguard Worker        return "[unknown]"
448*387f9dfdSAndroid Build Coastguard Worker
449*387f9dfdSAndroid Build Coastguard Workerdef agg_colval(key):
450*387f9dfdSAndroid Build Coastguard Worker    if args.process:
451*387f9dfdSAndroid Build Coastguard Worker        return "%-6d %-15s" % (key.value, comm_for_pid(key.value))
452*387f9dfdSAndroid Build Coastguard Worker    else:
453*387f9dfdSAndroid Build Coastguard Worker        return hcall_table_lookup(key.value)
454*387f9dfdSAndroid Build Coastguard Worker
455*387f9dfdSAndroid Build Coastguard Workerdef print_ppc_count_stats():
456*387f9dfdSAndroid Build Coastguard Worker    data = bpf["ppc_data"]
457*387f9dfdSAndroid Build Coastguard Worker    print("[%s]" % strftime("%H:%M:%S"))
458*387f9dfdSAndroid Build Coastguard Worker    print("%-45s %8s" % (ppc_agg_colname, "COUNT"))
459*387f9dfdSAndroid Build Coastguard Worker    for k, v in sorted(data.items(), key=lambda kv: -kv[1].value)[:args.top]:
460*387f9dfdSAndroid Build Coastguard Worker        if k.value == 0xFFFFFFFF:
461*387f9dfdSAndroid Build Coastguard Worker            continue    # happens occasionally, we don't need it
462*387f9dfdSAndroid Build Coastguard Worker        print("%-45s %8d" % (agg_colval(k), v.value))
463*387f9dfdSAndroid Build Coastguard Worker    print("")
464*387f9dfdSAndroid Build Coastguard Worker    data.clear()
465*387f9dfdSAndroid Build Coastguard Worker
466*387f9dfdSAndroid Build Coastguard Workerdef ppc_print_latency_stats():
467*387f9dfdSAndroid Build Coastguard Worker    data = bpf["ppc_data"]
468*387f9dfdSAndroid Build Coastguard Worker    print("[%s]" % strftime("%H:%M:%S"))
469*387f9dfdSAndroid Build Coastguard Worker    print("%-45s %8s %17s %17s %17s" % (ppc_agg_colname, "COUNT",
470*387f9dfdSAndroid Build Coastguard Worker          min_time_colname, max_time_colname, avg_time_colname))
471*387f9dfdSAndroid Build Coastguard Worker    for k, v in sorted(data.items(),
472*387f9dfdSAndroid Build Coastguard Worker                       key=lambda kv: -kv[1].count)[:args.top]:
473*387f9dfdSAndroid Build Coastguard Worker        if k.value == 0xFFFFFFFF:
474*387f9dfdSAndroid Build Coastguard Worker            continue    # happens occasionally, we don't need it
475*387f9dfdSAndroid Build Coastguard Worker        print(("%-45s %8d " + ("%17.6f" if args.milliseconds else "%17.3f ") +
476*387f9dfdSAndroid Build Coastguard Worker                              ("%17.6f" if args.milliseconds else "%17.3f ") +
477*387f9dfdSAndroid Build Coastguard Worker                              ("%17.6f" if args.milliseconds else "%17.3f")) %
478*387f9dfdSAndroid Build Coastguard Worker               (agg_colval(k), v.count,
479*387f9dfdSAndroid Build Coastguard Worker                v.min / (1e6 if args.milliseconds else 1e3),
480*387f9dfdSAndroid Build Coastguard Worker                v.max / (1e6 if args.milliseconds else 1e3),
481*387f9dfdSAndroid Build Coastguard Worker                (v.total_ns / v.count) / (1e6 if args.milliseconds else 1e3)))
482*387f9dfdSAndroid Build Coastguard Worker    print("")
483*387f9dfdSAndroid Build Coastguard Worker    data.clear()
484*387f9dfdSAndroid Build Coastguard Worker
485*387f9dfdSAndroid Build Coastguard Workerif args.hcall is not None:
486*387f9dfdSAndroid Build Coastguard Worker    print("Tracing %sppc hcall '%s'... Ctrl+C to quit." %
487*387f9dfdSAndroid Build Coastguard Worker        ("failed " if args.failures else "", args.hcall))
488*387f9dfdSAndroid Build Coastguard Workerelse:
489*387f9dfdSAndroid Build Coastguard Worker    print("Tracing %sppc hcalls, printing top %d... Ctrl+C to quit." %
490*387f9dfdSAndroid Build Coastguard Worker        ("failed " if args.failures else "", args.top))
491*387f9dfdSAndroid Build Coastguard Workerexiting = 0 if args.interval else 1
492*387f9dfdSAndroid Build Coastguard Workerseconds = 0
493*387f9dfdSAndroid Build Coastguard Workerwhile True:
494*387f9dfdSAndroid Build Coastguard Worker    try:
495*387f9dfdSAndroid Build Coastguard Worker        sleep(args.interval)
496*387f9dfdSAndroid Build Coastguard Worker        seconds += args.interval
497*387f9dfdSAndroid Build Coastguard Worker    except KeyboardInterrupt:
498*387f9dfdSAndroid Build Coastguard Worker        exiting = 1
499*387f9dfdSAndroid Build Coastguard Worker        signal.signal(signal.SIGINT, signal_ignore)
500*387f9dfdSAndroid Build Coastguard Worker    if args.duration and seconds >= args.duration:
501*387f9dfdSAndroid Build Coastguard Worker        exiting = 1
502*387f9dfdSAndroid Build Coastguard Worker
503*387f9dfdSAndroid Build Coastguard Worker    print_stats()
504*387f9dfdSAndroid Build Coastguard Worker
505*387f9dfdSAndroid Build Coastguard Worker    if exiting:
506*387f9dfdSAndroid Build Coastguard Worker        print("Detaching...")
507*387f9dfdSAndroid Build Coastguard Worker        exit()
508