Source code for crash.types.zone

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

from typing import List

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

import gdb

[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 list_array_name = "lists" if is_pcp else "free_list" for free_list in array_for_each(area[list_array_name]): 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("page {:#x} misplaced on {} of zone {}:{}, has flags for zone {}:{}". format(int(page_obj.address), "pcplist" if is_pcp else "freelist", self.nid, self.zid, page.get_nid(), page.get_zid())) nr_expected = area["count"] if is_pcp else area["nr_free"] if nr_free != nr_expected: print("nr_free mismatch in {} {}: expected {}, counted {}". format("pcplist" if is_pcp else "area", area.address, nr_expected, 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)