Skip to content
Snippets Groups Projects
Commit 714710cb authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "lrdp_V2 : Add range feature in pagetracking.py"

parents a2583fc2 c64a912a
No related branches found
No related tags found
No related merge requests found
...@@ -12,30 +12,52 @@ ...@@ -12,30 +12,52 @@
from print_out import print_out_str from print_out import print_out_str
from parser_util import register_parser, RamParser from parser_util import register_parser, RamParser
from mm import pfn_to_page, page_buddy, page_count, for_each_pfn from mm import pfn_to_page, page_buddy, page_count, for_each_pfn
from mm import page_to_pfn
import sys
@register_parser('--print-pagetracking', 'print page tracking information (if available)') @register_parser('--print-pagetracking', 'print page tracking information (if available)')
class PageTracking(RamParser): class PageTracking(RamParser):
def parse(self): def __init__(self, *args):
if not self.ramdump.is_config_defined('CONFIG_PAGE_OWNER'): super(PageTracking, self).__init__(*args)
print_out_str('CONFIG_PAGE_OWNER not defined') self.trace_entry_size = self.ramdump.sizeof('unsigned long')
return if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'):
self.page_ext_offset = self.ramdump.field_offset(
'struct mem_section', 'page_ext')
else:
self.page_ext_offset = self.ramdump.field_offset(
'struct pglist_data', 'node_page_ext')
if (self.ramdump.kernel_version >= (3, 19, 0)): if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'):
if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'): self.mem_section_size = self.ramdump.sizeof("struct mem_section")
mem_section = self.ramdump.read_word('mem_section') else:
if self.ramdump.kernel_version >= (4, 14): self.mem_section_size = 0
mem_section = self.ramdump.read_word(mem_section)
else: '''
mem_section = self.ramdump.address_of('contig_page_data') Following based upon definition in include/linux/mmzone.h
#ifndef CONFIG_FORCE_MAX_ZONEORDER
#define MAX_ORDER 11
#else
#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
#endif
'''
try:
self.max_order = int(self.ramdump.get_config_val(
"CONFIG_FORCE_MAX_ZONEORDER"))
except:
self.max_order = 11
self.stack_slabs = self.ramdump.address_of('stack_slabs')
self.stack_slabs_size = self.ramdump.sizeof('void *')
def page_trace(self, pfn, mem_section):
trace_offset = 0 trace_offset = 0
nr_entries_offset = 0 nr_entries_offset = 0
trace_entries_offset = 0 trace_entries_offset = 0
offset = 0 offset = 0
struct_holding_trace_entries = 0 struct_holding_trace_entries = 0
trace_entry_size = self.ramdump.sizeof("unsigned long")
if (self.ramdump.kernel_version <= (3, 19, 0)): if (self.ramdump.kernel_version <= (3, 19, 0)):
trace_offset = self.ramdump.field_offset('struct page', 'trace') trace_offset = self.ramdump.field_offset('struct page', 'trace')
...@@ -43,166 +65,192 @@ class PageTracking(RamParser): ...@@ -43,166 +65,192 @@ class PageTracking(RamParser):
'struct stack_trace', 'nr_entries') 'struct stack_trace', 'nr_entries')
trace_entries_offset = self.ramdump.field_offset( trace_entries_offset = self.ramdump.field_offset(
'struct page', 'trace_entries') 'struct page', 'trace_entries')
else:
if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'):
page_ext_offset = self.ramdump.field_offset(
'struct mem_section', 'page_ext')
else:
page_ext_offset = self.ramdump.field_offset(
'struct pglist_data', 'node_page_ext')
else:
trace_offset = self.ramdump.field_offset( trace_offset = self.ramdump.field_offset(
'struct page_ext', 'trace') 'struct page_ext', 'trace')
if self.ramdump.is_config_defined('CONFIG_STACKDEPOT'): if self.ramdump.is_config_defined('CONFIG_STACKDEPOT'):
trace_entries_offset = self.ramdump.field_offset( trace_entries_offset = self.ramdump.field_offset(
'struct stack_record', 'entries') 'struct stack_record', 'entries')
else: else:
trace_entries_offset = self.ramdump.field_offset( trace_entries_offset = self.ramdump.field_offset(
'struct page_ext', 'trace_entries') 'struct page_ext', 'trace_entries')
nr_entries_offset = self.ramdump.field_offset( nr_entries_offset = self.ramdump.field_offset(
'struct page_ext', 'nr_entries') 'struct page_ext', 'nr_entries')
if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'):
mem_section_size = self.ramdump.sizeof("struct mem_section")
else:
mem_section_size = 0;
page_ext_size = self.ramdump.sizeof("struct page_ext") page_ext_size = self.ramdump.sizeof("struct page_ext")
if self.ramdump.kernel_version >= (4,9,0): if self.ramdump.kernel_version >= (4, 9, 0):
page_owner_size = self.ramdump.sizeof("struct page_owner") page_owner_size = self.ramdump.sizeof("struct page_owner")
page_ext_size = page_ext_size + page_owner_size page_ext_size = page_ext_size + page_owner_size
page_owner_ops_offset = self.ramdump.read_structure_field( page_owner_ops_offset = self.ramdump.read_structure_field(
'page_owner_ops', 'struct page_ext_operations', 'offset') 'page_owner_ops', 'struct page_ext_operations', 'offset')
page = pfn_to_page(self.ramdump, pfn)
order = 0
out_tracking = self.ramdump.open_file('page_tracking.txt') if (self.ramdump.kernel_version <= (3, 19, 0)):
out_frequency = self.ramdump.open_file('page_frequency.txt') nr_trace_entries = self.ramdump.read_int(
sorted_pages = {} page + trace_offset + nr_entries_offset)
struct_holding_trace_entries = page
''' order = self.ramdump.read_structure_field(
Following based upon definition in include/linux/mmzone.h page, 'struct page', 'order')
else:
phys = pfn << 12
if phys is None or phys == 0:
return
if self.ramdump.is_config_defined('CONFIG_MEMORY_HOTPLUG'):
section_size_bits = int(self.ramdump.get_config_val(
'CONFIG_HOTPLUG_SIZE_BITS'))
offset = phys >> section_size_bits
else:
offset = phys >> 30
if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'):
mem_section_0_offset = (
mem_section + offset * self.mem_section_size)
page_ext = self.ramdump.read_word(
mem_section_0_offset + self.page_ext_offset)
else:
page_ext = self.ramdump.read_word(
mem_section + self.page_ext_offset)
#ifndef CONFIG_FORCE_MAX_ZONEORDER if self.ramdump.arm64:
#define MAX_ORDER 11 temp_page_ext = page_ext + (pfn * page_ext_size)
#else else:
#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER pfn_index = pfn - (self.ramdump.phys_offset >> 12)
#endif temp_page_ext = page_ext + (pfn_index * page_ext_size)
'''
try:
max_order = int(self.ramdump.get_config_val("CONFIG_FORCE_MAX_ZONEORDER"))
except:
max_order = 11
for pfn in for_each_pfn(self.ramdump): if self.ramdump.kernel_version >= (4, 9, 0):
page = pfn_to_page(self.ramdump, pfn) temp_page_ext = temp_page_ext + page_owner_ops_offset
order = 0 order = self.ramdump.read_structure_field(
temp_page_ext, 'struct page_owner', 'order')
else:
order = self.ramdump.read_structure_field(
temp_page_ext, 'struct page_ext', 'order')
"""must be allocated, and the first pfn of an order > 0 page""" if not self.ramdump.is_config_defined('CONFIG_STACKDEPOT'):
if (page_buddy(self.ramdump, page) or
page_count(self.ramdump, page) == 0):
continue
if (self.ramdump.kernel_version <= (3, 19, 0)):
nr_trace_entries = self.ramdump.read_int( nr_trace_entries = self.ramdump.read_int(
page + trace_offset + nr_entries_offset) temp_page_ext + nr_entries_offset)
struct_holding_trace_entries = page struct_holding_trace_entries = temp_page_ext
order = self.ramdump.read_structure_field(
page, 'struct page', 'order')
else: else:
phys = pfn << 12 if self.ramdump.kernel_version >= (4, 9, 0):
if phys is None or phys is 0: handle = self.ramdump.read_structure_field(
continue temp_page_ext, 'struct page_owner', 'handle')
if self.ramdump.is_config_defined('CONFIG_MEMORY_HOTPLUG'):
section_size_bits = int(self.ramdump.get_config_val(
'CONFIG_HOTPLUG_SIZE_BITS'))
offset = phys >> section_size_bits
else: else:
offset = phys >> 30 handle = self.ramdump.read_structure_field(
temp_page_ext, 'struct page_ext', 'handle')
if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'): slabindex = handle & 0x1fffff
mem_section_0_offset = ( handle_offset = (handle >> 0x15) & 0x3ff
mem_section + (offset * mem_section_size)) handle_offset = handle_offset << 4
page_ext = self.ramdump.read_word(
mem_section_0_offset + page_ext_offset)
else:
page_ext = self.ramdump.read_word(
mem_section + page_ext_offset)
slab = self.ramdump.read_word(
self.stack_slabs + (self.stack_slabs_size * slabindex))
stack = slab + handle_offset
if self.ramdump.arm64: nr_trace_entries = self.ramdump.read_structure_field(
temp_page_ext = page_ext + (pfn * page_ext_size) stack, 'struct stack_record', 'size')
else:
pfn_index = pfn - (self.ramdump.phys_offset >> 12)
temp_page_ext = page_ext + (pfn_index * page_ext_size)
if self.ramdump.kernel_version >= (4,9,0): struct_holding_trace_entries = stack
temp_page_ext = temp_page_ext + page_owner_ops_offset
order = self.ramdump.read_structure_field(
temp_page_ext, 'struct page_owner', 'order')
else:
order = self.ramdump.read_structure_field(
temp_page_ext, 'struct page_ext', 'order')
if not self.ramdump.is_config_defined('CONFIG_STACKDEPOT'):
nr_trace_entries = self.ramdump.read_int( if nr_trace_entries <= 0 or nr_trace_entries > 16:
temp_page_ext + nr_entries_offset) return
struct_holding_trace_entries = temp_page_ext if order >= self.max_order:
return
else: alloc_str = ''
if self.ramdump.kernel_version >= (4,9,0): for i in range(0, nr_trace_entries):
handle = self.ramdump.read_structure_field( addr = self.ramdump.read_word(
temp_page_ext, 'struct page_owner', 'handle') struct_holding_trace_entries + trace_entries_offset + i *
else: self.trace_entry_size)
handle = self.ramdump.read_structure_field(
temp_page_ext, 'struct page_ext', 'handle') if not addr:
break
slabindex = handle & 0x1fffff look = self.ramdump.unwind_lookup(addr)
handle_offset = (handle >> 0x15) & 0x3ff if look is None:
handle_offset = handle_offset << 4 break
symname, offset = look
stack_slabs = self.ramdump.address_of('stack_slabs') unwind_dat = ' [<{0:x}>] {1}+0x{2:x}\n'.format(
stack_slabs_size = self.ramdump.sizeof('void *') addr, symname, offset)
slab = self.ramdump.read_word(stack_slabs + ( stack_slabs_size * slabindex)) alloc_str = alloc_str + unwind_dat
stack = slab + handle_offset
return alloc_str, order
nr_trace_entries = self.ramdump.read_structure_field(
stack, 'struct stack_record', 'size') def parse(self):
ranges = None
struct_holding_trace_entries = stack for arg in sys.argv:
if "ranges=" in arg:
g_optimization = True
if nr_trace_entries <= 0 or nr_trace_entries > 16: k, ranges = arg.split("=")
continue start, end = ranges.split('-')
start_pfn = int(start, 16) >> 12
if order >= max_order: end_pfn = int(end, 16) >> 12
out_tracking.write('PFN 0x{:x} page 0x{:x} skip as order 0x{:x}\n'.format( break
pfn, page, order)) elif "page=" in arg:
continue g_optimization = True
k, page = arg.split('=')
out_tracking.write('PFN 0x{:x}-0x{:x} page 0x{:x}\n'.format( page = int(page, 16)
pfn, pfn + (1 << order) - 1, page)) start_pfn = page_to_pfn(self.ramdump, page)
end_pfn = start_pfn + 1
alloc_str = '' break
for i in range(0, nr_trace_entries): else:
addr = self.ramdump.read_word( g_optimization = False
struct_holding_trace_entries + trace_entries_offset + i * trace_entry_size) if not self.ramdump.is_config_defined('CONFIG_PAGE_OWNER'):
print_out_str('CONFIG_PAGE_OWNER not defined')
if addr == 0: return
break
look = self.ramdump.unwind_lookup(addr) if (self.ramdump.kernel_version >= (3, 19, 0)):
if look is None: if self.ramdump.is_config_defined('CONFIG_SPARSEMEM'):
break mem_section = self.ramdump.read_word('mem_section')
symname, offset = look if self.ramdump.kernel_version >= (4, 14):
unwind_dat = ' [<{0:x}>] {1}+0x{2:x}\n'.format( mem_section = self.ramdump.read_word(mem_section)
addr, symname, offset)
out_tracking.write(unwind_dat)
alloc_str = alloc_str + unwind_dat
if alloc_str in sorted_pages:
sorted_pages[alloc_str] = sorted_pages[alloc_str] + 1
else: else:
sorted_pages[alloc_str] = 1 mem_section = self.ramdump.address_of('contig_page_data')
out_tracking.write('\n') out_tracking = self.ramdump.open_file('page_tracking.txt')
out_frequency = self.ramdump.open_file('page_frequency.txt')
sorted_pages = {}
str = "PFN : 0x{0:x}-0x{1:x} Page : 0x{2:x}\n{3}\n"
if g_optimization is True:
for pfn in range(start_pfn, end_pfn):
page = pfn_to_page(self.ramdump, pfn)
order = 0
if (page_buddy(self.ramdump, page) or
page_count(self.ramdump, page) == 0):
continue
function_list, order = self.page_trace(pfn, mem_section)
if order >= self.max_order:
out_tracking.write('PFN 0x{:x} page 0x{:x} skip as order '
'0x{:x}\n'.format(pfn, page, order))
out_tracking.write(str.format(pfn, pfn + (1 << order) - 1,
page, function_list))
if function_list in sorted_pages:
sorted_pages[function_list] = sorted_pages[function_list]\
+ 1
else:
sorted_pages[function_list] = 1
else:
for pfn in for_each_pfn(self.ramdump):
page = pfn_to_page(self.ramdump, pfn)
order = 0
if (page_buddy(self.ramdump, page) or
page_count(self.ramdump, page) == 0):
continue
function_list, order = self.page_trace(pfn, mem_section)
if order >= self.max_order:
out_tracking.write('PFN 0x{:x} page 0x{:x} skip as order '
'0x{:x}\n'.format(pfn, page, order))
out_tracking.write(str.format(pfn, pfn + (1 << order) - 1,
page, function_list))
if function_list in sorted_pages:
sorted_pages[function_list] = sorted_pages[function_list]\
+ 1
else:
sorted_pages[function_list] = 1
sortlist = sorted(sorted_pages.iteritems(), sortlist = sorted(sorted_pages.iteritems(),
key=lambda(k, v): (v), reverse=True) key=lambda(k, v): (v), reverse=True)
......
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