Extract and store memory watermark information
This commit is contained in:
parent
fd3acbb16d
commit
17536301d6
@ -520,6 +520,13 @@ class BaseKernelConfig:
|
|||||||
rec_oom_end = re.compile(r"^Killed process \d+", re.MULTILINE)
|
rec_oom_end = re.compile(r"^Killed process \d+", re.MULTILINE)
|
||||||
"""RE to match the last line of an OOM block"""
|
"""RE to match the last line of an OOM block"""
|
||||||
|
|
||||||
|
watermark_start = "Node 0 DMA free:"
|
||||||
|
"""
|
||||||
|
Pattern to find the start of the memory watermark information
|
||||||
|
|
||||||
|
:type: str
|
||||||
|
"""
|
||||||
|
|
||||||
zoneinfo_start = "Node 0 DMA: "
|
zoneinfo_start = "Node 0 DMA: "
|
||||||
"""
|
"""
|
||||||
Pattern to find the start of the memory chunk information (buddyinfo)
|
Pattern to find the start of the memory chunk information (buddyinfo)
|
||||||
@ -2702,7 +2709,17 @@ class OOMAnalyser:
|
|||||||
REC_FREE_MEMORY_CHUNKS = re.compile(
|
REC_FREE_MEMORY_CHUNKS = re.compile(
|
||||||
"Node (?P<node>\d+) (?P<zone>DMA|DMA32|Normal): (?P<zone_usage>.*) = (?P<total_free_kb_per_node>\d+)kB"
|
"Node (?P<node>\d+) (?P<zone>DMA|DMA32|Normal): (?P<zone_usage>.*) = (?P<total_free_kb_per_node>\d+)kB"
|
||||||
)
|
)
|
||||||
"""RE to extract free memory chunks in a zone"""
|
"""RE to extract free memory chunks of a memor zone"""
|
||||||
|
|
||||||
|
REC_WATERMARK = re.compile(
|
||||||
|
"Node (?P<node>\d+) (?P<zone>DMA|DMA32|Normal) "
|
||||||
|
"free:(?P<free>\d+)kB "
|
||||||
|
"min:(?P<min>\d+)kB "
|
||||||
|
"low:(?P<low>\d+)kB "
|
||||||
|
"high:(?P<high>\d+)kB "
|
||||||
|
".*"
|
||||||
|
)
|
||||||
|
"""RE to extract watermark information in a memory zone"""
|
||||||
|
|
||||||
def __init__(self, oom):
|
def __init__(self, oom):
|
||||||
self.oom_entity = oom
|
self.oom_entity = oom
|
||||||
@ -2913,6 +2930,7 @@ class OOMAnalyser:
|
|||||||
self._extract_pstable()
|
self._extract_pstable()
|
||||||
self._extract_gpf_mask()
|
self._extract_gpf_mask()
|
||||||
self._extract_buddyinfo()
|
self._extract_buddyinfo()
|
||||||
|
self._extract_watermarks()
|
||||||
|
|
||||||
def _extract_pstable(self):
|
def _extract_pstable(self):
|
||||||
"""Extract process table"""
|
"""Extract process table"""
|
||||||
@ -2991,6 +3009,37 @@ class OOMAnalyser:
|
|||||||
size = size[:-2] # strip "kB"
|
size = size[:-2] # strip "kB"
|
||||||
self.oom_result.details["_buddyinfo_pagesize_kb"] = int(size)
|
self.oom_result.details["_buddyinfo_pagesize_kb"] = int(size)
|
||||||
|
|
||||||
|
def _extract_watermarks(self):
|
||||||
|
"""
|
||||||
|
Extract memory watermark information from all zones
|
||||||
|
|
||||||
|
This function fills:
|
||||||
|
* OOMResult.details["_watermarks"] with [<zone>][<node>][(free|min|low|high)] = <XXX>
|
||||||
|
"""
|
||||||
|
self.oom_result.details["_watermarks"] = {}
|
||||||
|
watermark_info = self.oom_result.details["_watermarks"]
|
||||||
|
self.oom_entity.find_text(self.oom_result.kconfig.watermark_start)
|
||||||
|
|
||||||
|
# Currently omm_entity point to the first line of the watermark information.
|
||||||
|
# The iterator protocol uses the next() call. However, this will cause the
|
||||||
|
# current line to be skipped.
|
||||||
|
# Therefore, we reset the counter by one line.
|
||||||
|
self.oom_entity.back()
|
||||||
|
|
||||||
|
for line in self.oom_entity:
|
||||||
|
match = self.REC_WATERMARK.match(line)
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
|
||||||
|
node = int(match.group("node"))
|
||||||
|
zone = match.group("zone")
|
||||||
|
if zone not in watermark_info:
|
||||||
|
watermark_info[zone] = {}
|
||||||
|
if node not in watermark_info[zone]:
|
||||||
|
watermark_info[zone][node] = {}
|
||||||
|
for i in ["free", "min", "low", "high"]:
|
||||||
|
watermark_info[zone][node][i] = int(match.group(i))
|
||||||
|
|
||||||
def _gfp_hex2flags(self, hexvalue):
|
def _gfp_hex2flags(self, hexvalue):
|
||||||
"""\
|
"""\
|
||||||
Convert the hexadecimal value into flags specified by definition
|
Convert the hexadecimal value into flags specified by definition
|
||||||
|
42
test.py
42
test.py
@ -896,6 +896,48 @@ Hardware name: HP ProLiant DL385 G7, BIOS A18 12/08/2012
|
|||||||
% (order, zone, node, count, except_count),
|
% (order, zone, node, count, except_count),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_010_extract_zoneinfo(self):
|
||||||
|
"""Test extracting watermark information"""
|
||||||
|
oom = OOMAnalyser.OOMEntity(OOMAnalyser.OOMDisplay.example_rhel7)
|
||||||
|
analyser = OOMAnalyser.OOMAnalyser(oom)
|
||||||
|
success = analyser.analyse()
|
||||||
|
self.assertTrue(success, "OOM analysis failed")
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
analyser.oom_result.kconfig.release,
|
||||||
|
(3, 10, ".el7."),
|
||||||
|
"Wrong KernelConfig release",
|
||||||
|
)
|
||||||
|
watermarks = analyser.oom_result.details["_watermarks"]
|
||||||
|
for zone, node, level, except_level in [
|
||||||
|
("Normal", 0, "free", 36692),
|
||||||
|
("Normal", 0, "min", 36784),
|
||||||
|
("Normal", 1, "low", 56804),
|
||||||
|
("Normal", 1, "high", 68164),
|
||||||
|
("DMA", 0, "free", 15872),
|
||||||
|
("DMA", 0, "high", 60),
|
||||||
|
("DMA32", 0, "free", 59728),
|
||||||
|
("DMA32", 0, "low", 9788),
|
||||||
|
]:
|
||||||
|
self.assertTrue(
|
||||||
|
zone in watermarks,
|
||||||
|
"Missing details for zone %s in memory watermarks" % zone,
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
node in watermarks[zone],
|
||||||
|
'Missing details for node "%s" in memory watermarks' % node,
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
level in watermarks[zone][node],
|
||||||
|
'Missing details for level "%s" in memory watermarks' % level,
|
||||||
|
)
|
||||||
|
level = watermarks[zone][node][level]
|
||||||
|
self.assertTrue(
|
||||||
|
level == except_level,
|
||||||
|
'Wrong watermark level for node %s in zone "%s" (got: %d, expect %d)'
|
||||||
|
% (node, zone, level, except_level),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main(verbosity=2)
|
unittest.main(verbosity=2)
|
||||||
|
Loading…
Reference in New Issue
Block a user