From 75feef4e2bd89e9a39d5c5b09477f13d8836d2c8 Mon Sep 17 00:00:00 2001 From: Patrick Daly <pdaly@codeaurora.org> Date: Tue, 28 Mar 2017 14:04:43 -0700 Subject: [PATCH] lrdp-v2: mm: Add pfn iterator Add a utility function for iterating through all valid pages. Use it in --print-pagetracking to fix an issue where invalid pfn numbers are being used. Change-Id: Iea87fd9afe2515c0be47ae32fa19db0aff5f3403 --- linux-ramdump-parser-v2/mm.py | 27 +++++++++++++++++++ .../parsers/pagetracking.py | 11 ++------ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/linux-ramdump-parser-v2/mm.py b/linux-ramdump-parser-v2/mm.py index 538af9c..efca724 100644 --- a/linux-ramdump-parser-v2/mm.py +++ b/linux-ramdump-parser-v2/mm.py @@ -304,3 +304,30 @@ def page_address(ramdump, page): pam = ramdump.read_word(pam + lh_offset) if pam == start: return None + + +def for_each_pfn(ramdump): + """ creates a generator for looping through valid pfn + Example: + for i in for_each_pfn(ramdump): + page = pfn_to_page(i) + """ + page_size = (1 << 12) + cnt = ramdump.read_structure_field('memblock', 'struct memblock', + 'memory.cnt') + region = ramdump.read_structure_field('memblock', 'struct memblock', + 'memory.regions') + memblock_region_size = ramdump.sizeof('struct memblock_region') + for i in range(cnt): + start = ramdump.read_structure_field(region, 'struct memblock_region', + 'base') + end = start + ramdump.read_structure_field( + region, 'struct memblock_region', 'size') + + pfn = start / page_size + end /= page_size + while pfn < end: + yield pfn + pfn += 1 + + region += memblock_region_size diff --git a/linux-ramdump-parser-v2/parsers/pagetracking.py b/linux-ramdump-parser-v2/parsers/pagetracking.py index 1d37141..c627ac8 100644 --- a/linux-ramdump-parser-v2/parsers/pagetracking.py +++ b/linux-ramdump-parser-v2/parsers/pagetracking.py @@ -11,7 +11,7 @@ from print_out import print_out_str from parser_util import register_parser, RamParser -from mm import pfn_to_page, page_buddy, page_count +from mm import pfn_to_page, page_buddy, page_count, for_each_pfn @register_parser('--print-pagetracking', 'print page tracking information (if available)') @@ -22,13 +22,6 @@ class PageTracking(RamParser): print_out_str('CONFIG_PAGE_OWNER not defined') return - min_pfn_addr = self.ramdump.address_of('min_low_pfn') - max_pfn_addr = self.ramdump.address_of('max_pfn') - min_pfn = self.ramdump.read_word( - min_pfn_addr) + (self.ramdump.phys_offset >> 12) - max_pfn = self.ramdump.read_word( - max_pfn_addr) + (self.ramdump.phys_offset >> 12) - if (self.ramdump.kernel_version >= (3, 19, 0)): mem_section = self.ramdump.read_word('mem_section') @@ -61,7 +54,7 @@ class PageTracking(RamParser): out_frequency = self.ramdump.open_file('page_frequency.txt') sorted_pages = {} - for pfn in range(min_pfn, max_pfn): + for pfn in for_each_pfn(self.ramdump): page = pfn_to_page(self.ramdump, pfn) order = 0 -- GitLab