Skip to content
Snippets Groups Projects
Commit 61fbfd93 authored by Avinash Jain's avatar Avinash Jain
Browse files

lrdp_v2: slabinfo optimization and bug fixes.

flag for performance on/off, bug fixes.

Change-Id: I07b2086f5f3302c8514a1a8179dbe1605c93f8a2
parent b4fa595a
No related branches found
No related tags found
No related merge requests found
...@@ -26,7 +26,26 @@ SLUB_RED_ACTIVE = 0xcc ...@@ -26,7 +26,26 @@ SLUB_RED_ACTIVE = 0xcc
POISON_INUSE = 0x5a POISON_INUSE = 0x5a
POISON_FREE = 0x6b POISON_FREE = 0x6b
POISON_END = 0xa5 POISON_END = 0xa5
g_printfreeobjStack = False
FREQUENCY = 0
CALLSTACK_INDEX = 1
CALL_STACK = 2
TRACK_TYPE = 3
# g_Optimization - if false will print :
# 1. Free objects callstacks
# 2. Object address range of allocated and FREE objects
g_Optimization = True
# When optimization is true, below two parameters will be used
# 1. MAX_NO_OF_CALLSTACK_TO_PRINT : Maximum number of callstacks to print
# in a slab.
# 2. CALLSTACK_FREQ_IN_SLAB: Print callstack only if occurance of
# each unique callstack in a slab is more than particular
# value(CALLSTACK_FREQ_IN_SLAB)
MAX_NO_OF_CALLSTACK_TO_PRINT = 5
CALLSTACK_FREQ_IN_SLAB = 10
class kmem_cache(object): class kmem_cache(object):
...@@ -89,6 +108,8 @@ class struct_member_offset(object): ...@@ -89,6 +108,8 @@ class struct_member_offset(object):
'struct page', 'freelist') 'struct page', 'freelist')
self.sizeof_struct_track = ramdump.sizeof( self.sizeof_struct_track = ramdump.sizeof(
'struct track') 'struct track')
self.cpu_cache_page_offset = ramdump.field_offset(
'struct kmem_cache_cpu', 'page')
self.sizeof_void_pointer = ramdump.sizeof( self.sizeof_void_pointer = ramdump.sizeof(
"void *") "void *")
self.sizeof_unsignedlong = ramdump.sizeof( self.sizeof_unsignedlong = ramdump.sizeof(
...@@ -131,7 +152,7 @@ class Slabinfo(RamParser): ...@@ -131,7 +152,7 @@ class Slabinfo(RamParser):
p = obj + slab.inuse p = obj + slab.inuse
return p + track_type * track_size return p + track_type * track_size
def extract_callstack(self, ramdump, a, stack, out_file): def extract_callstack(self, ramdump, stack, out_file):
for a in stack: for a in stack:
look = ramdump.unwind_lookup(a) look = ramdump.unwind_lookup(a)
if look is None: if look is None:
...@@ -159,28 +180,17 @@ class Slabinfo(RamParser): ...@@ -159,28 +180,17 @@ class Slabinfo(RamParser):
if stackstr_len == 0: if stackstr_len == 0:
return return
try: try:
self.g_allstacks[stackstr][0] += 1 self.g_allstacks[stackstr][FREQUENCY] += 1
if self.g_allstacks[stackstr][0] > 1: if self.g_allstacks[stackstr][FREQUENCY] > 1:
return return
self.extract_callstack(self.ramdump, a, stack, out_file)
except KeyError: except KeyError:
if g_printfreeobjStack is False: if g_Optimization is True:
if track_type != 0: if track_type != 0:
# if free object and g_printfreeobjStack is False, # if free object and g_Optimization is True,
# ignore it for printing its call stack # ignore it for printing its call stack
return return
if track_type == 1: self.g_allstacks[stackstr] = [1, self.g_index, stack, track_type]
out_file.write(
"FREE Call stack index:{0}".format(
self.g_index))
else:
out_file.write(
"ALLOCATED Call stack index:{0}".format(
self.g_index))
self.extract_callstack(self.ramdump, a, stack, out_file)
self.g_allstacks[stackstr] = [1, self.g_index]
self.g_index += 1 self.g_index += 1
out_file.write('\n')
def print_slab( def print_slab(
self, ramdump, slab, page, self, ramdump, slab, page,
...@@ -206,13 +216,41 @@ class Slabinfo(RamParser): ...@@ -206,13 +216,41 @@ class Slabinfo(RamParser):
page, out_file, out_slabs_addrs) page, out_file, out_slabs_addrs)
p = p + slab.size p = p + slab.size
def printsummary(self, slabs_output_summary): def printsummary(self, slabs_output_summary, slab_out):
nCounter = 0
write_output = False
str = " Call stack index:{0} frequency: {1}\n"
sorted_val = sorted( sorted_val = sorted(
self.g_allstacks.items(), self.g_allstacks.items(),
key=operator.itemgetter(1), reverse=True) key=operator.itemgetter(1), reverse=True)
for key, value in sorted_val:
if g_Optimization is False:
write_output = True
for key, val in sorted_val:
if g_Optimization is True:
if nCounter >= MAX_NO_OF_CALLSTACK_TO_PRINT:
break
if(
(nCounter < MAX_NO_OF_CALLSTACK_TO_PRINT)
and (val[FREQUENCY] > CALLSTACK_FREQ_IN_SLAB)):
write_output = True
else:
write_output = False
nCounter = nCounter + 1
if write_output is True:
if val[TRACK_TYPE] == 1: # free object
slab_out.write(
"\nFREE" + str.format(
val[CALLSTACK_INDEX], val[FREQUENCY]))
else: # allocated object
slab_out.write(
"\nALLOCATED" + str.format(
val[CALLSTACK_INDEX], val[FREQUENCY]))
self.extract_callstack(self.ramdump, val[CALL_STACK], slab_out)
slabs_output_summary.write( slabs_output_summary.write(
" stack index:{0} frequency:{1}\n".format(value[1], value[0])) " stack index:{0} frequency:{1}\n".format(
val[CALLSTACK_INDEX], val[FREQUENCY]))
def print_slab_page_info( def print_slab_page_info(
self, ramdump, slab_obj, slab_node, start, self, ramdump, slab_obj, slab_node, start,
...@@ -239,29 +277,31 @@ class Slabinfo(RamParser): ...@@ -239,29 +277,31 @@ class Slabinfo(RamParser):
page = self.ramdump.read_word(page + g_offsetof.page_lru) page = self.ramdump.read_word(page + g_offsetof.page_lru)
def print_per_cpu_slab_info( def print_per_cpu_slab_info(
self, ramdump, slab, slab_node, start, out_file, map_fn): self, ramdump, slab, slab_node, start, out_file, map_fn,
out_slabs_addrs):
page = self.ramdump.read_word(start) page = self.ramdump.read_word(start)
if page == 0: if page == 0:
return return
if page is None: if page is None:
return return
page_addr = page_address(self.ramdump, page)
self.print_slab( self.print_slab(
self.ramdump, page_addr, slab, page, out_file, map_fn) self.ramdump, slab, page, out_file, map_fn, out_slabs_addrs)
def print_all_objects( def print_all_objects(
self, ramdump, p, free, slab, page, out_file, out_slabs_addrs): self, ramdump, p, free, slab, page,
out_file, out_slabs_addrs):
if free:
out_slabs_addrs.write( if g_Optimization is False:
'\n Object {0:x}-{1:x} FREE'.format( if free:
out_slabs_addrs.write(
'\n Object {0:x}-{1:x} FREE'.format(
p, p + slab.size))
else:
out_slabs_addrs.write(
'\n Object {0:x}-{1:x} ALLOCATED'.format(
p, p + slab.size)) p, p + slab.size))
else:
out_slabs_addrs.write(
'\n Object {0:x}-{1:x} ALLOCATED'.format(
p, p + slab.size))
if self.ramdump.is_config_defined('CONFIG_SLUB_DEBUG_ON'): if self.ramdump.is_config_defined('CONFIG_SLUB_DEBUG_ON'):
if g_printfreeobjStack is True: if g_Optimization is False:
self.print_track(ramdump, slab, p, 0, out_file) self.print_track(ramdump, slab, p, 0, out_file)
self.print_track(ramdump, slab, p, 1, out_file) self.print_track(ramdump, slab, p, 1, out_file)
else: else:
...@@ -285,6 +325,7 @@ class Slabinfo(RamParser): ...@@ -285,6 +325,7 @@ class Slabinfo(RamParser):
slab_name_found = False slab_name_found = False
original_slab = self.ramdump.address_of('slab_caches') original_slab = self.ramdump.address_of('slab_caches')
cpus = self.ramdump.get_num_cpus() cpus = self.ramdump.get_num_cpus()
offsetof = struct_member_offset(self.ramdump) offsetof = struct_member_offset(self.ramdump)
self.initializeOffset() self.initializeOffset()
slab_list_offset = g_offsetof.kmemcache_list slab_list_offset = g_offsetof.kmemcache_list
...@@ -296,6 +337,16 @@ class Slabinfo(RamParser): ...@@ -296,6 +337,16 @@ class Slabinfo(RamParser):
slab = self.ramdump.read_word(original_slab) slab = self.ramdump.read_word(original_slab)
slabs_output_summary = self.ramdump.open_file('slabs_output.txt') slabs_output_summary = self.ramdump.open_file('slabs_output.txt')
out_slabs_addrs = self.ramdump.open_file('out_slabs_addrs.txt') out_slabs_addrs = self.ramdump.open_file('out_slabs_addrs.txt')
if g_Optimization is True:
msg = (
"To optimize slab traverse time,"
"print of object address are skipped."
" Supply option perf_off in command"
"prompt to print object address as well."
)
out_slabs_addrs.write(msg)
while slab != original_slab: while slab != original_slab:
slab = slab - slab_list_offset slab = slab - slab_list_offset
slab_obj = kmem_cache(self.ramdump, slab) slab_obj = kmem_cache(self.ramdump, slab)
...@@ -322,6 +373,9 @@ class Slabinfo(RamParser): ...@@ -322,6 +373,9 @@ class Slabinfo(RamParser):
print_out_str( print_out_str(
'\nExtracting slab details of : {0}'.format( '\nExtracting slab details of : {0}'.format(
slab_name)) slab_name))
if g_Optimization is False:
out_slabs_addrs.write(
'\nslab address of : {0}'.format(slab_name))
cpu_slab_addr = self.ramdump.read_word( cpu_slab_addr = self.ramdump.read_word(
slab + cpu_slab_offset) slab + cpu_slab_offset)
nr_total_objects = self.ramdump.read_structure_field( nr_total_objects = self.ramdump.read_structure_field(
...@@ -352,8 +406,7 @@ class Slabinfo(RamParser): ...@@ -352,8 +406,7 @@ class Slabinfo(RamParser):
self.ramdump, slab_obj, self.ramdump, slab_obj,
slab_node, cpu_slabn_addr + offsetof.cpu_cache_page_offset, slab_node, cpu_slabn_addr + offsetof.cpu_cache_page_offset,
slab_out, map_fn) slab_out, map_fn)
self.printsummary(slabs_output_summary, slab_out)
self.printsummary(slabs_output_summary)
self.g_allstacks.clear() self.g_allstacks.clear()
if slab_name_found is True: if slab_name_found is True:
break break
...@@ -362,13 +415,13 @@ class Slabinfo(RamParser): ...@@ -362,13 +415,13 @@ class Slabinfo(RamParser):
slabs_output_summary.close() slabs_output_summary.close()
def parse(self): def parse(self):
global g_printfreeobjStack global g_Optimization
slabname = None slabname = None
for arg in sys.argv: for arg in sys.argv:
if 'slabname=' in arg: if 'slabname=' in arg:
k, slabname = arg.split('=') k, slabname = arg.split('=')
if 'freeobj' in arg: if 'perf_off' in arg:
g_printfreeobjStack = True g_Optimization = False
slab_out = self.ramdump.open_file('slabs.txt') slab_out = self.ramdump.open_file('slabs.txt')
self.validate_slab_cache(slab_out, slabname, self.print_all_objects) self.validate_slab_cache(slab_out, slabname, self.print_all_objects)
slab_out.close() slab_out.close()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment