mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-12 02:18:40 +00:00
Originally, we don't format the output of analyser well. It is hard to read the result. This patch make every entry of the result align with the corresponding title to make it easier for users to read. Without patch: Event NR_Exit NR_Exit/Sec Time Consumed(cycles) Time Percentage VMEXIT_INTERRUPT_WINDOW 78090 130.15 40 0.01 VMEXIT_CR_ACCESS 0 0.00 0 0.00 VMEXIT_APICV_ACCESS 0 0.00 0 0.00 VMEXIT_EXCEPTION_OR_NMI 0 0.00 0 0.00 VMEXIT_RDTSC 0 0.00 0 0.00 ... Vector Count NR_Exit/Sec 0x000000f0 82337 137.23 0x000000ef 247713 412.85 With patch: Event NR_Exit NR_Exit/Sec Time Consumed(cycles) Time percentage VMEXIT_APICV_WRITE 13352 22.25 14331304 0.00 VMEXIT_WRMSR 309085 515.14 241166212 0.02 VMEXIT_INTERRUPT_WINDOW 78090 130.15 76841734 0.01 ... Vector Count NR_Exit/Sec 0x000000f0 82337 137.23 0x000000ef 247713 412.85 Signed-off-by: Kaige Fu <kaige.fu@intel.com> Reviewed-by: Eddie Dong <eddie.dong@intel.com> Acked-by: Yan, Like <like.yan@intel.com>
108 lines
2.6 KiB
Python
Executable File
108 lines
2.6 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# -*- coding: UTF-8 -*-
|
|
|
|
"""
|
|
This script defines the function to do the irq related analysis
|
|
"""
|
|
|
|
import csv
|
|
import struct
|
|
from config import TSC_FREQ
|
|
|
|
TSC_BEGIN = 0
|
|
TSC_END = 0
|
|
|
|
VMEXIT_ENTRY = 0x10000
|
|
|
|
LIST_EVENTS = {
|
|
'VMEXIT_EXTERNAL_INTERRUPT': VMEXIT_ENTRY + 0x00000001,
|
|
}
|
|
|
|
IRQ_EXITS = {}
|
|
|
|
# 4 * 64bit per trace entry
|
|
TRCREC = "QQQQ"
|
|
|
|
def parse_trace(ifile):
|
|
"""parse the trace data file
|
|
Args:
|
|
ifile: input trace data file
|
|
Return:
|
|
None
|
|
"""
|
|
|
|
fd = open(ifile, 'rb')
|
|
|
|
while True:
|
|
global TSC_BEGIN, TSC_END
|
|
try:
|
|
line = fd.read(struct.calcsize(TRCREC))
|
|
if not line:
|
|
break
|
|
(tsc, event, vec, d2) = struct.unpack(TRCREC, line)
|
|
|
|
event = event & 0xffffffffffff
|
|
|
|
if TSC_BEGIN == 0:
|
|
TSC_BEGIN = tsc
|
|
|
|
TSC_END = tsc
|
|
|
|
for key in LIST_EVENTS.keys():
|
|
if event == LIST_EVENTS.get(key):
|
|
if vec in IRQ_EXITS.keys():
|
|
IRQ_EXITS[vec] += 1
|
|
else:
|
|
IRQ_EXITS[vec] = 1
|
|
|
|
except struct.error:
|
|
sys.exit()
|
|
|
|
def generate_report(ofile, freq):
|
|
""" generate analysis report
|
|
Args:
|
|
ofile: output report
|
|
freq: TSC frequency of the device trace data from
|
|
Return:
|
|
None
|
|
"""
|
|
global TSC_BEGIN, TSC_END
|
|
|
|
csv_name = ofile + '.csv'
|
|
try:
|
|
with open(csv_name, 'a') as filep:
|
|
f_csv = csv.writer(filep)
|
|
|
|
rt_cycle = TSC_END - TSC_BEGIN
|
|
assert rt_cycle != 0, "Total run time in cycle is 0, \
|
|
TSC end %d, TSC begin %d" \
|
|
% (TSC_END, TSC_BEGIN)
|
|
|
|
rt_sec = float(rt_cycle) / (float(freq) * 1000 * 1000)
|
|
|
|
print ("%-8s\t%-8s\t%-8s" % ("Vector", "Count", "NR_Exit/Sec"))
|
|
f_csv.writerow(['Vector', 'NR_Exit', 'NR_Exit/Sec'])
|
|
for e in IRQ_EXITS.keys():
|
|
pct = float(IRQ_EXITS[e]) / rt_sec
|
|
print ("0x%08x\t%-8d\t%-8.2f" % (e, IRQ_EXITS[e], pct))
|
|
f_csv.writerow(['0x%08x' % e, IRQ_EXITS[e], '%.2f' % pct])
|
|
|
|
except IOError as err:
|
|
print ("Output File Error: " + str(err))
|
|
|
|
def analyze_irq(ifile, ofile):
|
|
"""do the vm exits analysis
|
|
Args:
|
|
ifile: input trace data file
|
|
ofile: output report file
|
|
Return:
|
|
None
|
|
"""
|
|
|
|
print("IRQ analysis started... \n\tinput file: %s\n"
|
|
"\toutput file: %s.csv" % (ifile, ofile))
|
|
|
|
parse_trace(ifile)
|
|
# save report to the output file
|
|
generate_report(ofile, TSC_FREQ)
|