Source code for crash.types.vmstat

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

from typing import List, Tuple

from crash.util.symbols import Types, TypeCallbacks, Symbols
from crash.types.percpu import get_percpu_var
from crash.types.cpu import for_each_online_cpu

import gdb

[docs]class VmStat: types = Types(['enum zone_stat_item', 'enum vm_event_item']) symbols = Symbols(['vm_event_states']) nr_stat_items = -1 nr_event_items = -1 vm_stat_names: List[str] = list() vm_event_names: List[str] = list()
[docs] @classmethod def check_enum_type(cls, gdbtype: gdb.Type) -> None: if gdbtype == cls.types.enum_zone_stat_item_type: (items, names) = cls.__populate_names(gdbtype, 'NR_VM_ZONE_STAT_ITEMS') cls.nr_stat_items = items cls.vm_stat_names = names elif gdbtype == cls.types.enum_vm_event_item_type: (items, names) = cls.__populate_names(gdbtype, 'NR_VM_EVENT_ITEMS') cls.nr_event_items = items cls.vm_event_names = names else: raise TypeError("Unexpected type {}".format(gdbtype.name))
@classmethod def __populate_names(cls, enum_type: gdb.Type, items_name: str) -> Tuple[int, List[str]]: nr_items = enum_type[items_name].enumval names = ["__UNKNOWN__"] * nr_items for field in enum_type.fields(): if field.enumval < nr_items: names[field.enumval] = field.name return (nr_items, names)
[docs] @classmethod def get_stat_names(cls) -> List[str]: return cls.vm_stat_names
[docs] @classmethod def get_event_names(cls) -> List[str]: return cls.vm_event_names
[docs] @classmethod def get_events(cls) -> List[int]: nr = cls.nr_event_items events = [0] * nr for cpu in for_each_online_cpu(): states = get_percpu_var(cls.symbols.vm_event_states, cpu) for item in range(0, nr): events[item] += int(states["event"][item]) return events
type_cbs = TypeCallbacks([('enum zone_stat_item', VmStat.check_enum_type), ('enum vm_event_item', VmStat.check_enum_type)])