Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
217 lines (151 sloc) 5.06 KB
# perf script event handlers, generated by perf script -g python
# Licensed under the terms of the GNU GPL License version 2
# The common_* event handler fields are the most useful fields common to
# all events. They don't necessarily correspond to the 'common_*' fields
# in the format files. Those fields not available as handler params can
# be retrieved using Python functions of the form common_*(context).
# See the perf-script-python Documentation for the list of available functions.
from __future__ import print_function
import os
import sys
import collections
sys.path.append(os.environ['PERF_EXEC_PATH'] + \
'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
from perf_trace_context import *
from Core import *
from Util import *
class QemuTrace:
APP_NAME = "qemu-system-x86"
# IO ports for different exit points
LINUX_EXIT_PORT = 0xf4
FW_EXIT_PORT = 0xf5
# Exit point values
EXIT_POINTS = { 1 : 'fw_start',
2 : 'linux_start_fwcfg',
3 : 'linux_start_boot',
4 : 'linux_start_pvhboot',
5 : 'fw_do_boot',
6 : 'linux_start_kernel',
7 : 'linux_start_user'}
def __init__(self):
self.start = 0
self.qemu_init_end = 0
self.probes = []
def print(self, div = 1):
print(" qemu_init_end: %f" % \
((self.qemu_init_end - float(self.start))/div))
pre_ep = 0
pre_ts = self.qemu_init_end
for ep, ts in self.probes:
if ep == pre_ep:
continue
if ep in QemuTrace.EXIT_POINTS:
ep_name = QemuTrace.EXIT_POINTS[ep]
else:
ep_name = "Exit point " + str(ep)
print(" {}: {} (+{})".format(ep_name, (ts - float(self.start))/div, (ts - float(pre_ts))/div))
pre_ts = ts
pre_ep = ep
@staticmethod
def stats(pids, traces, div):
avgQT = QemuTrace()
minQT = QemuTrace()
maxQT = QemuTrace()
count = 0
for pid in pids:
count += 1
print("%d) pid %d" % (count, pid))
traces[pid].print(div)
qit = traces[pid].qemu_init_end - traces[pid].start
avgQT.qemu_init_end += qit
maxQT.qemu_init_end = max(maxQT.qemu_init_end, qit)
if (count == 1):
minQT.qemu_init_end = qit
else:
minQT.qemu_init_end = min(minQT.qemu_init_end, qit)
i = 0
for ep, ts in traces[pid].probes:
rel_ts = ts - traces[pid].start
if (count == 1):
avgQT.probes.append((ep, rel_ts))
minQT.probes.append((ep, rel_ts))
maxQT.probes.append((ep, 0))
else:
avgQT.probes[i] = (ep, avgQT.probes[i][1] + rel_ts)
minQT.probes[i] = (ep, min(minQT.probes[i][1], rel_ts))
maxQT.probes[i] = (ep, max(maxQT.probes[i][1], rel_ts))
i+=1
if count > 1:
avgQT.qemu_init_end /= count
i = 0
for ep, ts in avgQT.probes:
avgQT.probes[i] = (ep, avgQT.probes[i][1] / count)
i+=1
print("\nAvg")
avgQT.print(div)
print("\nMin")
minQT.print(div)
print("\nMax")
maxQT.print(div)
class Events:
def __init__(self, ClassTrace):
self.ClassTrace = ClassTrace
self.app_name = ClassTrace.APP_NAME
self.pids = []
self.traces = autodict()
def stats(self, div):
self.ClassTrace.stats(self.pids, self.traces, div)
events = Events(QemuTrace)
def trace_begin():
print("in trace_begin")
def trace_end():
print("in trace_end")
print("Trace %s" % (events.app_name))
events.stats(1000000)
def sched__sched_process_exec(event_name, context, common_cpu,
common_secs, common_nsecs, common_pid, common_comm,
common_callchain, filename, pid, old_pid, perf_sample_dict):
if (events.app_name != common_comm):
return
events.traces[pid] = QemuTrace()
events.traces[pid].start = perf_sample_dict["sample"]["time"]
events.pids.append(pid)
print_header(event_name, common_cpu, common_secs, common_nsecs,
common_pid, common_comm)
print()
def kvm__kvm_pio(event_name, context, common_cpu,
common_secs, common_nsecs, common_pid, common_comm,
common_callchain, rw, port, size, count,
val, perf_sample_dict):
if (events.app_name != common_comm):
return
ts = perf_sample_dict["sample"]["time"]
pid = perf_sample_dict["sample"]["pid"]
if (port != QemuTrace.FW_EXIT_PORT and port != QemuTrace.LINUX_EXIT_PORT):
return
events.traces[pid].probes.append((val, ts))
print_header(event_name, common_cpu, common_secs, common_nsecs,
common_pid, common_comm)
print("rw=%u, port=0x%x, size=%u, count=%u, val=%u" % \
(rw, port, size, count, val))
print()
def kvm__kvm_entry(event_name, context, common_cpu,
common_secs, common_nsecs, common_pid, common_comm,
common_callchain, vcpu_id, perf_sample_dict):
if (events.app_name != common_comm):
return
ts = perf_sample_dict["sample"]["time"]
pid = perf_sample_dict["sample"]["pid"]
if (events.traces[pid].qemu_init_end != 0):
return
events.traces[pid].qemu_init_end = ts
print_header(event_name, common_cpu, common_secs, common_nsecs,
common_pid, common_comm)
print()
def trace_unhandled(event_name, context, event_fields_dict, perf_sample_dict):
pass
def print_header(event_name, cpu, secs, nsecs, pid, comm):
print("%-20s %5u %05u.%09u %8u %-20s " % \
(event_name, cpu, secs, nsecs, pid, comm), end="")
def get_dict_as_string(a_dict, delimiter=' '):
return delimiter.join(['%s=%s'%(k,str(v))for k,v in sorted(a_dict.items())])
You can’t perform that action at this time.