Restructure storing buddyinfo and watermarks infos

This commit is contained in:
Carsten Grohmann 2023-03-14 20:23:34 +01:00
parent 72163cc7bc
commit 56d519cc8f
2 changed files with 26 additions and 30 deletions

View File

@ -2704,6 +2704,9 @@ class OOMEntity:
class OOMResult: class OOMResult:
"""Results of an OOM analysis""" """Results of an OOM analysis"""
buddyinfo = {}
"""Information about free areas in all zones"""
details = {} details = {}
"""Extracted result""" """Extracted result"""
@ -2765,6 +2768,9 @@ class OOMResult:
@type: bool @type: bool
""" """
watermarks = {}
"""Memory watermark information"""
class OOMAnalyser: class OOMAnalyser:
"""Analyse an OOM object and calculate additional values""" """Analyse an OOM object and calculate additional values"""
@ -3041,13 +3047,13 @@ class OOMAnalyser:
mm/page_alloc.c:show_migration_types(). mm/page_alloc.c:show_migration_types().
This function fills: This function fills:
* OOMResult.details["_buddyinfo"] with [<zone>][<order>][<node>] = <number of free chunks> * OOMResult.buddyinfo with [<zone>][<order>][<node>] = <number of free chunks>
* OOMResult.details["_buddyinfo"] with [zone]["total_free_kb_per_node"][node] = int(total_free_kb_per_node) * OOMResult.buddyinfo with [zone]["total_free_kb_per_node"][node] = int(total_free_kb_per_node)
* OOMResult.details["_buddyinfo_pagesize_kb"] with the extracted page size * OOMResult.details["_buddyinfo_pagesize_kb"] with the extracted page size
""" """
self.oom_result.details["_buddyinfo"] = {} self.oom_result.buddyinfo = {}
self.oom_result.details["_buddyinfo_pagesize_kb"] = None self.oom_result.details["_buddyinfo_pagesize_kb"] = None
buddy_info = self.oom_result.details["_buddyinfo"] buddy_info = self.oom_result.buddyinfo
self.oom_entity.find_text(self.oom_result.kconfig.zoneinfo_start) self.oom_entity.find_text(self.oom_result.kconfig.zoneinfo_start)
# Currently omm_entity point to the first line of the buddyinfo. # Currently omm_entity point to the first line of the buddyinfo.
@ -3098,7 +3104,7 @@ class OOMAnalyser:
# a value of 11 means that the largest free memory block is 2^10 pages. # a value of 11 means that the largest free memory block is 2^10 pages.
# __pragma__ ('jsiter') # __pragma__ ('jsiter')
max_order = 0 max_order = 0
for o in self.oom_result.details["_buddyinfo"]["DMA"]: for o in self.oom_result.buddyinfo["DMA"]:
# JS: integer is sometimes a string :-/ # JS: integer is sometimes a string :-/
if (isinstance(o, str) and o.isdigit()) or isinstance(o, int): if (isinstance(o, str) and o.isdigit()) or isinstance(o, int):
max_order += 1 max_order += 1
@ -3110,11 +3116,11 @@ class OOMAnalyser:
Extract memory watermark information from all zones Extract memory watermark information from all zones
This function fills: This function fills:
* OOMResult.details["_watermarks"] with [<zone>][<node>][(free|min|low|high)] = int * OOMResult.watermarks with [<zone>][<node>][(free|min|low|high)] = int
* OOMResult.details["_watermarks"] with [<zone>][<node>][(lowmem_reserve)] = List(int) * OOMResult.watermarks with [<zone>][<node>][(lowmem_reserve)] = List(int)
""" """
self.oom_result.details["_watermarks"] = {} self.oom_result.watermarks = {}
watermark_info = self.oom_result.details["_watermarks"] watermark_info = self.oom_result.watermarks
self.oom_entity.find_text(self.oom_result.kconfig.watermark_start) self.oom_entity.find_text(self.oom_result.kconfig.watermark_start)
# Currently omm_entity point to the first line of the watermark information. # Currently omm_entity point to the first line of the watermark information.
@ -3153,7 +3159,7 @@ class OOMAnalyser:
""" """
self.oom_result.details["trigger_proc_numa_node"] = None self.oom_result.details["trigger_proc_numa_node"] = None
zone = self.oom_result.details["trigger_proc_mem_zone"] zone = self.oom_result.details["trigger_proc_mem_zone"]
watermark_info = self.oom_result.details["_watermarks"] watermark_info = self.oom_result.watermarks
if zone not in watermark_info: if zone not in watermark_info:
debug( debug(
"Missing watermark info for zone {} - skip memory analysis".format(zone) "Missing watermark info for zone {} - skip memory analysis".format(zone)
@ -3259,9 +3265,9 @@ class OOMAnalyser:
@param int node: Node number @param int node: Node number
@rtype: None|bool @rtype: None|bool
""" """
if not self.oom_result.details["_buddyinfo"]: if not self.oom_result.buddyinfo:
return None return None
buddyinfo = self.oom_result.details["_buddyinfo"] buddyinfo = self.oom_result.buddyinfo
if zone not in buddyinfo: if zone not in buddyinfo:
return None return None
@ -3287,7 +3293,7 @@ class OOMAnalyser:
""" """
zone = self.oom_result.details["trigger_proc_mem_zone"] zone = self.oom_result.details["trigger_proc_mem_zone"]
node = self.oom_result.details["trigger_proc_numa_node"] node = self.oom_result.details["trigger_proc_numa_node"]
if zone not in self.oom_result.details["_buddyinfo"]: if zone not in self.oom_result.buddyinfo:
return None return None
self.oom_result.mem_fragmented = not self._check_free_chunks( self.oom_result.mem_fragmented = not self._check_free_chunks(
self.oom_result.kconfig.PAGE_ALLOC_COSTLY_ORDER, zone, node self.oom_result.kconfig.PAGE_ALLOC_COSTLY_ORDER, zone, node
@ -3307,12 +3313,9 @@ class OOMAnalyser:
if self.oom_result.oom_type == OOMEntityType.manual: if self.oom_result.oom_type == OOMEntityType.manual:
debug("OOM triggered manually - skip memory analysis") debug("OOM triggered manually - skip memory analysis")
return return
if "_buddyinfo" not in self.oom_result.details: if not self.oom_result.buddyinfo:
debug("Missing buddyinfo - skip memory analysis") debug("Missing buddyinfo - skip memory analysis")
return return
if not self.oom_result.details["_buddyinfo"]:
debug("Empty buddyinfo - skip memory analysis")
return
if ("trigger_proc_order" not in self.oom_result.details) or ( if ("trigger_proc_order" not in self.oom_result.details) or (
"trigger_proc_mem_zone" not in self.oom_result.details "trigger_proc_mem_zone" not in self.oom_result.details
): ):
@ -3320,13 +3323,13 @@ class OOMAnalyser:
"Missing trigger_proc_order and/or trigger_proc_mem_zone - skip memory analysis" "Missing trigger_proc_order and/or trigger_proc_mem_zone - skip memory analysis"
) )
return return
if "_watermarks" not in self.oom_result.details: if not self.oom_result.watermarks:
debug("Missing watermark information - skip memory analysis") debug("Missing watermark information - skip memory analysis")
return return
order = self.oom_result.details["trigger_proc_order"] order = self.oom_result.details["trigger_proc_order"]
zone = self.oom_result.details["trigger_proc_mem_zone"] zone = self.oom_result.details["trigger_proc_mem_zone"]
watermark_info = self.oom_result.details["_watermarks"] watermark_info = self.oom_result.watermarks
# "high order" requests don't trigger OOM # "high order" requests don't trigger OOM
if int(order) > self.oom_result.kconfig.PAGE_ALLOC_COSTLY_ORDER: if int(order) > self.oom_result.kconfig.PAGE_ALLOC_COSTLY_ORDER:
@ -4583,7 +4586,6 @@ Out of memory: Killed process 651 (unattended-upgr) total-vm:108020kB, anon-rss:
while swapped: while swapped:
swapped = False swapped = False
for i in range(len(ps_index) - 1): for i in range(len(ps_index) - 1):
v1 = getvalue(column_name, i) v1 = getvalue(column_name, i)
v2 = getvalue(column_name, i + 1) v2 = getvalue(column_name, i + 1)

14
test.py
View File

@ -885,7 +885,7 @@ Hardware name: HP ProLiant DL385 G7, BIOS A18 12/08/2012
(3, 10, ".el7."), (3, 10, ".el7."),
"Wrong KernelConfig release", "Wrong KernelConfig release",
) )
buddyinfo = analyser.oom_result.details["_buddyinfo"] buddyinfo = analyser.oom_result.buddyinfo
for zone, order, node, except_count in [ for zone, order, node, except_count in [
("Normal", 6, 0, 0), # order 6 - page size 256kB ("Normal", 6, 0, 0), # order 6 - page size 256kB
("Normal", 6, 1, 2), # order 6 - page size 256kB ("Normal", 6, 1, 2), # order 6 - page size 256kB
@ -926,7 +926,7 @@ Hardware name: HP ProLiant DL385 G7, BIOS A18 12/08/2012
(3, 10, ".el7."), (3, 10, ".el7."),
"Wrong KernelConfig release", "Wrong KernelConfig release",
) )
watermarks = analyser.oom_result.details["_watermarks"] watermarks = analyser.oom_result.watermarks
for zone, node, level, except_level in [ for zone, node, level, except_level in [
("Normal", 0, "free", 36692), ("Normal", 0, "free", 36692),
("Normal", 0, "min", 36784), ("Normal", 0, "min", 36784),
@ -978,19 +978,13 @@ Hardware name: HP ProLiant DL385 G7, BIOS A18 12/08/2012
OOMAnalyser.OOMEntityType.automatic, OOMAnalyser.OOMEntityType.automatic,
"OOM triggered manually", "OOM triggered manually",
) )
self.assertTrue( self.assertTrue(analyser.oom_result.buddyinfo, "Missing buddyinfo")
"_buddyinfo" in analyser.oom_result.details, "Missing buddyinfo"
)
self.assertTrue(analyser.oom_result.details["_buddyinfo"], "Empty buddyinfo")
self.assertTrue( self.assertTrue(
"trigger_proc_order" in analyser.oom_result.details "trigger_proc_order" in analyser.oom_result.details
and "trigger_proc_mem_zone" in analyser.oom_result.details, and "trigger_proc_mem_zone" in analyser.oom_result.details,
"Missing trigger_proc_order and/or trigger_proc_mem_zone", "Missing trigger_proc_order and/or trigger_proc_mem_zone",
) )
self.assertTrue( self.assertTrue(analyser.oom_result.watermarks, "Missing watermark information")
"_watermarks" in analyser.oom_result.details,
"Missing watermark information - skip memory analysis",
)
for zone, order, node, expected_result in [ for zone, order, node, expected_result in [
("DMA", 0, 0, True), ("DMA", 0, 0, True),