mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 01:03:07 +00:00
contrib/slabinfo: add scripts to dump slabinfo
Sample output: python3 drgn -s vmlinux -c vmcore contrib/slabinfo.py struct kmem_cache * | name | active_objs | num_objs | objsize | objperslab | pagesperslab -------------------- | -------------------- | ------------ | ------------ | -------- | ----------- | ------------- 0xffff00000632cf40 | 9p-fcall-cache | 0 | 0 | 131192 | 1 | 64 0xffff00000632cdc0 | p9_req_t | 0 | 33 | 248 | 33 | 2 0xffff00000632cc40 | isp1760_qh | 0 | 0 | 144 | 28 | 1 0xffff00000632cac0 | isp1760_qtd | 0 | 0 | 168 | 24 | 1 0xffff00000632c940 | isp1760_urb_listite | 0 | 0 | 120 | 34 | 1 0xffff00000632c7c0 | asd_sas_event | 0 | 0 | 256 | 32 | 2 0xffff00000632c640 | sas_task | 0 | 0 | 448 | 36 | 4 0xffff00000632c4c0 | bio-120 | 50 | 50 | 320 | 25 | 2 0xffff00000632c340 | io_buffer | 0 | 0 | 160 | 25 | 1 0xffff00000632c1c0 | io_kiocb | 0 | 0 | 448 | 36 | 4 0xffff00000632c040 | bfq_io_cq | 0 | 0 | 1456 | 22 | 8 0xffff000006321e40 | bfq_queue | 0 | 0 | 672 | 24 | 4 0xffff000006321cc0 | bio-248 | 4 | 36 | 448 | 36 | 4 0xffff000006321b40 | mqueue_inode_cache | 1 | 30 | 1088 | 30 | 8 0xffff0000063219c0 | v9fs_inode_cache | 1 | 39 | 832 | 39 | 8 0xffff000006321840 | nfs4_xattr_cache_ca | 0 | 0 | 2216 | 14 | 8 ... Signed-off-by: Kuan-Ying Lee <kuan-ying.lee@canonical.com>
This commit is contained in:
parent
f8168da4e2
commit
3540cfa992
91
contrib/slabinfo.py
Executable file
91
contrib/slabinfo.py
Executable file
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env drgn
|
||||
# Copyright (c) Canonical Ltd.
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
""" Script to dump slabinfo status using drgn"""
|
||||
|
||||
from typing import Iterator, Optional
|
||||
|
||||
from drgn import Object
|
||||
from drgn.helpers.common.format import escape_ascii_string
|
||||
from drgn.helpers.linux.list import list_for_each_entry, list_for_each_entry_reverse
|
||||
from drgn.helpers.linux.slab import for_each_slab_cache
|
||||
|
||||
MAX_PARTIAL_TO_SCAN = 10000
|
||||
OO_SHIFT = 16
|
||||
OO_MASK = (1 << OO_SHIFT) - 1
|
||||
|
||||
|
||||
def for_each_kmem_cache_node(slab_cache: Object) -> Iterator[Object]:
|
||||
"""
|
||||
Iterate over all kmem_cache_node of specific slab cache.
|
||||
|
||||
:return: Iterator of ``struct kmem_cache_node *`` objects.
|
||||
"""
|
||||
for nid in range(0, prog["nr_node_ids"].value_()):
|
||||
yield slab_cache.node[nid]
|
||||
|
||||
|
||||
def count_partial_free_approx(kmem_cache_node: Object) -> Optional[Object]:
|
||||
x = Object(prog, "unsigned long", 0)
|
||||
n = kmem_cache_node
|
||||
if n.nr_partial <= MAX_PARTIAL_TO_SCAN:
|
||||
for slab in list_for_each_entry(
|
||||
"struct slab", n.partial.address_of_(), "slab_list"
|
||||
):
|
||||
x += slab.objects - slab.inuse
|
||||
else:
|
||||
scanned = 0
|
||||
for slab in list_for_each_entry(
|
||||
"struct slab", n.partial.address_of_(), "slab_list"
|
||||
):
|
||||
x += slab.objects - slab.inuse
|
||||
scanned += 1
|
||||
if scanned == MAX_PARTIAL_TO_SCAN / 2:
|
||||
break
|
||||
for slab in list_for_each_entry_reverse(
|
||||
"struct slab", n.partial.address_of_(), "slab_list"
|
||||
):
|
||||
x += slab.objects - slab.inuse
|
||||
scanned += 1
|
||||
if scanned == MAX_PARTIAL_TO_SCAN / 2:
|
||||
break
|
||||
x = x * n.nr_partial / scanned
|
||||
x = min(x, n.total_objects)
|
||||
return x
|
||||
|
||||
|
||||
def oo_objects(kmem_cache_order_objects: Object) -> Optional[Object]:
|
||||
return kmem_cache_order_objects.x & OO_MASK
|
||||
|
||||
|
||||
def oo_order(kmem_cache_order_objects: Object) -> Optional[Object]:
|
||||
return kmem_cache_order_objects.x >> OO_SHIFT
|
||||
|
||||
|
||||
print(
|
||||
f"{'struct kmem_cache *':^20} | {'name':^20} | {'active_objs':^12} | {'num_objs':^12} | {'objsize':^8} | {'objperslab':^11} | {'pageperslab':^13}"
|
||||
)
|
||||
print(
|
||||
f"{'':-^20} | {'':-^20} | {'':-^12} | {'':-^12} | {'':-^8} | {'':-^11} | {'':-^13}"
|
||||
)
|
||||
|
||||
for s in for_each_slab_cache(prog):
|
||||
nr_slabs = 0
|
||||
nr_objs = 0
|
||||
nr_free = 0
|
||||
for node in for_each_kmem_cache_node(s):
|
||||
nr_slabs += node.nr_slabs.counter.value_()
|
||||
nr_objs += node.total_objects.counter.value_()
|
||||
nr_free += count_partial_free_approx(node).value_()
|
||||
active_objs = nr_objs - nr_free
|
||||
num_objs = nr_objs
|
||||
active_slab = nr_slabs
|
||||
num_slabs = nr_slabs
|
||||
objects_per_slab = oo_objects(s.oo).value_()
|
||||
cache_order = oo_order(s.oo).value_()
|
||||
name = escape_ascii_string(s.name.string_(), escape_backslash=True)
|
||||
|
||||
print(
|
||||
f"0x{s.value_():<18x} | {name:20.19s} | {active_objs:12} | {num_objs:12} | {s.size.value_():8} | {objects_per_slab:11} | {1<<cache_order:13}"
|
||||
)
|
Loading…
Reference in New Issue
Block a user