M7350/qcom-opensource/kernel/kernel-tests/memory_prof/hostscripts/stats.py

227 lines
7.9 KiB
Python
Raw Normal View History

2024-09-09 08:57:42 +00:00
#!/usr/bin/env python
# Copyright (c) 2013, The Linux Foundation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of The Linux Foundation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import string
import re
def create_dict(str):
"""
takes key-value pairs contained in string
and returns a dictionary of KVP's
"""
return dict(re.findall(r'(\S+)=(\S+)', str))
def return_ratio(prop, total):
"""
returns the percentage, or zero if denominator
is zero
"""
return str(round(((float(prop)/float(total))
*100), 3)) if (total != 0) else str(0)
class Incrementor(object):
"""
class for "counters" to simply
incrementing and retrieving values
"""
def __init__(self, start):
self.count=start
def __call__(self, jump=1):
self.count += jump
return self.count
class MapEntry(object):
def __init__(self, vals):
self.v_addr=vals['v_addr']
self.p_addr=vals['p_addr']
self.chunk_size=vals['chunk_size']
self.length=int(vals['len'])
class AllocEntry(object):
def __init__(self, vals):
self.gfp_flags=vals['gfp_flags']
self.order=int(vals['order'])
class MapStat(object):
def __init__(self):
self.total_calls = Incrementor(0)
self.size_sixteenm = Incrementor(0)
self.size_onem = Incrementor(0)
self.size_sixtyfourk = Incrementor(0)
self.size_fourk = Incrementor(0)
def total(self):
return str(self.total_calls(0))
def SM(self):
return str(self.size_sixteenm(0))
def OM(self):
return str(self.size_onem(0))
def SFK(self):
return str(self.size_sixtyfourk(0))
def fk(self):
return str(self.size_fourk(0))
def SM_ratio(self):
return return_ratio(self.size_sixteenm(0), self.total_calls(0))
def OM_ratio(self):
return return_ratio(self.size_onem(0), self.total_calls(0))
def SFK_ratio(self):
return return_ratio(self.size_sixtyfourk(0), self.total_calls(0))
def fk_ratio(self):
return return_ratio(self.size_fourk(0), self.total_calls(0))
class AllocStat(object):
def __init__(self):
self.total_heap_alloc_calls = Incrementor(0)
self.failed_heap_allocs = Incrementor(0)
self.heap_alloc_order_zero = Incrementor(0)
self.heap_alloc_order_four = Incrementor(0)
self.heap_alloc_order_eight = Incrementor(0)
def total(self):
return str(self.total_heap_alloc_calls(0))
def fail(self):
return str(self.failed_heap_allocs(0))
def zero(self):
return str(self.heap_alloc_order_zero(0))
def four(self):
return str(self.heap_alloc_order_four(0))
def eight(self):
return str(self.heap_alloc_order_eight(0))
def fail_ratio(self):
return return_ratio(self.failed_heap_allocs(0), self.total_heap_alloc_calls(0))
def zero_ratio(self):
return return_ratio(self.heap_alloc_order_zero(0), self.total_heap_alloc_calls(0))
def four_ratio(self):
return return_ratio(self.heap_alloc_order_four(0), self.total_heap_alloc_calls(0))
def eight_ratio(self):
return return_ratio(self.heap_alloc_order_eight(0), self.total_heap_alloc_calls(0))
class Stats(object):
def __init__(self):
self.map_calls = MapStat()
self.iommu = AllocStat()
self.sys = AllocStat()
with open('trace', 'r') as trace_file:
for line in trace_file:
self.process_line(line)
def process_line(self, line):
index=string.find(line, "iommu_map_range:")
if index >= 0:
return self.iommu_map_range(create_dict(line))
index=string.find(line, "alloc_pages_iommu_start:")
if index >= 0:
return self.alloc_pages_iommu_start(create_dict(line))
index=string.find(line, "alloc_pages_iommu_fail:")
if index >= 0:
return self.alloc_pages_iommu_fail(create_dict(line))
index=string.find(line, "alloc_pages_sys_start:")
if index >= 0:
return self.alloc_pages_sys_start(create_dict(line))
index=string.find(line, "alloc_pages_sys_fail:")
if index >= 0:
return self.alloc_pages_sys_fail(create_dict(line))
def iommu_map_range(self, vals):
stat = MapEntry(vals)
self.map_calls.total_calls()
if stat.length==(1 << 24):
self.map_calls.size_sixteenm()
elif stat.length==(1 << 20):
self.map_calls.size_onem()
elif stat.length==(1 << 16):
self.map_calls.size_sixtyfourk()
elif stat.length==(1 << 12):
self.map_calls.size_fourk()
else:
print "Unsupported Length: " + str(stat.length)
def alloc_pages_iommu_start(self, vals):
stat = AllocEntry(vals)
self.iommu.total_heap_alloc_calls()
if stat.order == 0:
self.iommu.heap_alloc_order_zero()
elif stat.order == 4:
self.iommu.heap_alloc_order_four()
elif stat.order == 8:
self.iommu.heap_alloc_order_eight()
else:
print "Unsupported Order: " + str(stat.order)
def alloc_pages_iommu_fail(self, vals):
stat = AllocEntry(vals)
self.iommu.failed_heap_allocs()
def alloc_pages_sys_start(self, vals):
stat = AllocEntry(vals)
self.sys.total_heap_alloc_calls()
if stat.order == 0:
self.sys.heap_alloc_order_zero()
elif stat.order == 4:
self.sys.heap_alloc_order_four()
else:
self.sys.heap_alloc_order_eight()
def alloc_pages_sys_fail(self, vals):
stat = AllocEntry(vals)
self.sys.failed_heap_allocs()
def return_results(self):
print ''.join(["Total Calls to Map Range: ", self.map_calls.total()])
print ''.join(["Mapped Pages of Size 16MB: ",
self.map_calls.SM(), "(", self.map_calls.SM_ratio(), "%)"])
print ''.join(["Mapped Pages of Size 1MB: ",
self.map_calls.OM(), "(", self.map_calls.OM_ratio(), "%)"])
print ''.join(["Mapped Pages of Size 64KB: ",
self.map_calls.SFK(), "(", self.map_calls.SFK_ratio(), "%)"])
print ''.join(["Mapped Pages of Size 4KB: ",
self.map_calls.fk(), "(", self.map_calls.fk_ratio(), "%)"])
print "---"
print ''.join(["Total Calls to Alloc in iommu Heap: ", self.iommu.total()])
print ''.join(["Failed iommu Heap Allocations: ",
self.iommu.fail(),"(", self.iommu.fail_ratio(),"%)"])
print ''.join(["iommu Heap Allocations of Order Zero: ",
self.iommu.zero(), "(", self.iommu.zero_ratio(), "%)"])
print ''.join(["iommu Heap Allocations of Order Four: ",
self.iommu.four(), "(", self.iommu.four_ratio(), "%)"])
print ''.join(["iommu Heap Allocations of Order Eight: ",
self.iommu.eight(), "(", self.iommu.eight_ratio(), "%)"])
print "---"
print ''.join(["Total Calls to Alloc in sys Heap: ", self.sys.total()])
print ''.join(["Failed sys Heap Allocations: ",
self.sys.fail(),"(", self.sys.fail_ratio(),"%)"])
print ''.join(["sys Heap Allocations of Order Zero: ",
self.sys.zero(), "(", self.sys.zero_ratio(), "%)"])
print ''.join(["sys Heap Allocations of Order Four: ",
self.sys.four(), "(", self.sys.four_ratio(), "%)"])
print ''.join(["sys Heap Allocations of Order Eight: ",
self.sys.eight(), "(", self.sys.eight_ratio(), "%)"])
if __name__ == '__main__':
stat = Stats()
stat.return_results()