Source code for crash.types.zone

#!/usr/bin/python3
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

from typing import List

import gdb

from crash.util import array_for_each
from crash.util.symbols import Types
from crash.types.percpu import get_percpu_var
from crash.types.vmstat import VmStat
from crash.types.cpu import for_each_online_cpu
from crash.types.list import list_for_each_entry
import crash.types.page

[docs] class Zone: types = Types(['struct page']) def __init__(self, obj: gdb.Value, zid: int) -> None: self.gdb_obj = obj self.zid = zid self.nid = int(obj["node"])
[docs] def is_populated(self) -> bool: return self.gdb_obj["present_pages"] != 0
[docs] def get_vmstat(self) -> List[int]: stats = [0] * VmStat.nr_stat_items vm_stat = self.gdb_obj["vm_stat"] for item in range(0, VmStat.nr_stat_items): # TODO abstract atomic? stats[item] = int(vm_stat[item]["counter"]) return stats
[docs] def add_vmstat_diffs(self, diffs: List[int]) -> None: for cpu in for_each_online_cpu(): pageset = get_percpu_var(self.gdb_obj["pageset"], cpu) vmdiff = pageset["vm_stat_diff"] for item in range(0, VmStat.nr_stat_items): diffs[item] += int(vmdiff[item])
[docs] def get_vmstat_diffs(self) -> List[int]: diffs = [0] * VmStat.nr_stat_items self.add_vmstat_diffs(diffs) return diffs
def _check_free_area(self, area: gdb.Value, is_pcp: bool) -> None: nr_free = 0 if is_pcp: list_array_name = "lists" error_desc = "pcplist" else: list_array_name = "free_list" error_desc = "free area" for free_list in array_for_each(area[list_array_name]): try: for page_obj in list_for_each_entry(free_list, self.types.page_type, "lru"): page = crash.types.page.Page.from_obj(page_obj) nr_free += 1 if page.get_nid() != self.nid or page.get_zid() != self.zid: print(f"page 0x{int(page_obj.address):x} misplaced on " f"{error_desc} of node {self.nid} zone {self.zid}, " f"has flags for node {page.get_nid()} zone {page.get_zid()}") except BufferError as e: print(f"Error traversing free area: {e}") nr_expected = area["count"] if is_pcp else area["nr_free"] if nr_free != nr_expected: print(f"nr_free mismatch in {error_desc} 0x{int(area.address):x}: " f"expected {nr_expected}, counted {nr_free}")
[docs] def check_free_pages(self) -> None: for area in array_for_each(self.gdb_obj["free_area"]): self._check_free_area(area, False) for cpu in for_each_online_cpu(): pageset = get_percpu_var(self.gdb_obj["pageset"], cpu) self._check_free_area(pageset["pcp"], True)