Restructure extraction of node with mem shortage

Watermark extraction is performed only once and the result is now
stored in OOMResult.details["trigger_proc_numa_node"].
This commit is contained in:
Carsten Grohmann 2023-03-08 17:34:33 +01:00
parent 91caad251e
commit 470e5acf55
2 changed files with 20 additions and 19 deletions

View File

@ -3144,31 +3144,28 @@ class OOMAnalyser:
for i in ["free", "min", "low", "high"]: for i in ["free", "min", "low", "high"]:
watermark_info[zone][node][i] = int(match.group(i)) watermark_info[zone][node][i] = int(match.group(i))
def _extract_node_from_watermarks(self, zone): def _search_node_with_memory_shortage(self):
""" """
Search node with memory shortage: watermark "free" < "min" Search NUMA node with memory shortage: watermark "free" < "min".
@param str zone: Requested zone This function fills:
@return: First node with memory shortage or None if no node found * OOMResult.details["trigger_proc_numa_node"] = <int(first node with memory shortage) | None>
@rtype: None|int
""" """
self.oom_result.details["trigger_proc_numa_node"] = None
zone = self.oom_result.details["trigger_proc_mem_zone"]
watermark_info = self.oom_result.details["_watermarks"] watermark_info = self.oom_result.details["_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)
) )
return None return
# __pragma__ ('jsiter') # __pragma__ ('jsiter')
for node in watermark_info[zone]: for node in watermark_info[zone]:
if watermark_info[zone][node]["free"] < watermark_info[zone][node]["min"]: if watermark_info[zone][node]["free"] < watermark_info[zone][node]["min"]:
return int(node) self.oom_result.details["trigger_proc_numa_node"] = int(node)
return
# __pragma__ ('nojsiter') # __pragma__ ('nojsiter')
return
debug(
"Node with current memory shortage cannot be determined - skip memory analysis"
)
return None
def _gfp_hex2flags(self, hexvalue): def _gfp_hex2flags(self, hexvalue):
"""\ """\
@ -3289,7 +3286,7 @@ class OOMAnalyser:
@rtype: None|bool @rtype: None|bool
""" """
zone = self.oom_result.details["trigger_proc_mem_zone"] zone = self.oom_result.details["trigger_proc_mem_zone"]
node = self._extract_node_from_watermarks(zone) 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.details["_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(
@ -3340,9 +3337,9 @@ class OOMAnalyser:
return return
# Search node with memory shortage: watermark "free" < "min" # Search node with memory shortage: watermark "free" < "min"
node = self._extract_node_from_watermarks(zone) node = self.oom_result.details["trigger_proc_numa_node"]
if node is None: if node is None:
return # error cause already shown as debug message return
# the remaining code is similar to mm/page_alloc.c:__zone_watermark_ok() # the remaining code is similar to mm/page_alloc.c:__zone_watermark_ok()
# ======================================================================= # =======================================================================
@ -3533,6 +3530,7 @@ class OOMAnalyser:
self._calc_system_values() self._calc_system_values()
self._calc_trigger_process_values() self._calc_trigger_process_values()
self._calc_killed_process_values() self._calc_killed_process_values()
self._search_node_with_memory_shortage()
self._analyse_alloc_failure() self._analyse_alloc_failure()
self._check_for_memory_fragmentation() self._check_for_memory_fragmentation()

View File

@ -955,7 +955,7 @@ Hardware name: HP ProLiant DL385 G7, BIOS A18 12/08/2012
'Wrong watermark level for node %s in zone "%s" (got: %d, expect %d)' 'Wrong watermark level for node %s in zone "%s" (got: %d, expect %d)'
% (node, zone, level, except_level), % (node, zone, level, except_level),
) )
node = analyser._extract_node_from_watermarks("Normal") node = analyser.oom_result.details["trigger_proc_numa_node"]
self.assertTrue( self.assertTrue(
node == 0, "Wrong node with memory shortage (got: %s, expect: 0)" % node node == 0, "Wrong node with memory shortage (got: %s, expect: 0)" % node
) )
@ -1021,7 +1021,10 @@ Hardware name: HP ProLiant DL385 G7, BIOS A18 12/08/2012
("DMA32", None), ("DMA32", None),
("Normal", 0), ("Normal", 0),
]: ]:
node = analyser._extract_node_from_watermarks(zone) # override zone with test data and trigger extracting node
analyser.oom_result.details["trigger_proc_mem_zone"] = zone
analyser._search_node_with_memory_shortage()
node = analyser.oom_result.details["trigger_proc_numa_node"]
self.assertEqual( self.assertEqual(
node, node,
expected_node, expected_node,
@ -1042,7 +1045,7 @@ Hardware name: HP ProLiant DL385 G7, BIOS A18 12/08/2012
success = analyser.analyse() success = analyser.analyse()
self.assertTrue(success, "OOM analysis failed") self.assertTrue(success, "OOM analysis failed")
zone = analyser.oom_result.details["trigger_proc_mem_zone"] zone = analyser.oom_result.details["trigger_proc_mem_zone"]
node = analyser._extract_node_from_watermarks(zone) node = analyser.oom_result.details["trigger_proc_numa_node"]
mem_fragmented = not analyser._check_free_chunks( mem_fragmented = not analyser._check_free_chunks(
analyser.oom_result.kconfig.PAGE_ALLOC_COSTLY_ORDER, zone, node analyser.oom_result.kconfig.PAGE_ALLOC_COSTLY_ORDER, zone, node
) )