Skip to content

Commit b684d28

Browse files
committed
Print ioeventfd, iobus, vmstat and vcpustat information in kvm module.
Orabug: 37713468 Signed-off-by: Siddhi Katage <[email protected]>
1 parent 928e8ae commit b684d28

File tree

2 files changed

+236
-6
lines changed

2 files changed

+236
-6
lines changed

drgn_tools/kvm.py

Lines changed: 233 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
from drgn import cast
99
from drgn import Object
1010
from drgn import Program
11+
from drgn.helpers.common.type import enum_type_to_class
1112
from drgn.helpers.linux.list import list_for_each_entry
1213
from drgn.helpers.linux.pid import find_task
1314
from drgn.helpers.linux.sched import task_state_to_char
1415
from drgn.helpers.linux.xarray import xa_for_each
1516

1617
from drgn_tools.corelens import CorelensModule
1718
from drgn_tools.table import print_table
19+
from drgn_tools.util import enum_name_get
1820
from drgn_tools.util import has_member
1921

2022

@@ -268,6 +270,204 @@ def print_memslot_info(prog: Program) -> None:
268270
print("\n## Total Pages: %d ##" % (nr_pages))
269271

270272

273+
def print_ioeventfd_info(prog: Program) -> None:
274+
"""
275+
Print VM's ioeventfd information
276+
"""
277+
vm_list = for_each_vm(prog)
278+
279+
rows = [["KVM", "IOEVENTFD", "ADDR", "EVENTFD_CTX", "KVM_IO_DEV"]]
280+
nr_ioeventfds = 0
281+
282+
for vm in vm_list:
283+
iofd = list_for_each_entry(
284+
"struct _ioeventfd", vm.ioeventfds.address_of_(), "list"
285+
)
286+
for fd in iofd:
287+
addr = hex(fd.addr.value_())
288+
ioeventfd = hex(fd.eventfd.value_())
289+
dev = fd.dev.address_of_()
290+
nr_ioeventfds = nr_ioeventfds + 1
291+
rows.append(
292+
[hex(vm.value_()), hex(fd.value_()), addr, ioeventfd, hex(dev)]
293+
)
294+
print("=============<< IOEVENTFDS >>=============")
295+
print_table(rows)
296+
print("\n## Total ioeventfds: ##", nr_ioeventfds)
297+
298+
299+
def print_iobus_info(prog: Program) -> None:
300+
"""
301+
Print iobus information of VM
302+
"""
303+
rows = [
304+
["KVM", "IOBUS", "BUS", "DEV_COUNT", "EVTFD_COUNT", "KVM_IO_RANGE"]
305+
]
306+
vm_list = for_each_vm(prog)
307+
kvm_bus_type = enum_type_to_class(
308+
prog.type("enum kvm_bus"), "kvm_bus_type"
309+
)
310+
311+
for vm in vm_list:
312+
iobus_iterator = iter(vm.buses)
313+
i = 0
314+
for bus in iobus_iterator:
315+
iobus = hex(bus.value_())
316+
dev_count = bus.dev_count.value_()
317+
eventfd_count = bus.ioeventfd_count.value_()
318+
bus_name = enum_name_get(
319+
kvm_bus_type,
320+
i,
321+
"UNKNOWN",
322+
)
323+
range = hex(bus.range.address_of_())
324+
rows.append(
325+
[
326+
hex(vm.value_()),
327+
iobus,
328+
bus_name,
329+
dev_count,
330+
eventfd_count,
331+
range,
332+
]
333+
)
334+
i = i + 1
335+
print("=============<< IOBUS >>=============")
336+
print_table(rows)
337+
338+
339+
def print_kvmstat_info(prog: Program) -> None:
340+
"""
341+
print vmstat and vcpustat information of a VM
342+
"""
343+
vm_list = for_each_vm(prog)
344+
345+
for vm in vm_list:
346+
stat = vm.stat
347+
if has_member(stat, "generic"):
348+
rtlab_flush = stat.generic.remote_tlb_flush.value_()
349+
else:
350+
rtlab_flush = stat.remote_tlb_flush.value_()
351+
if has_member(stat, "lpages"):
352+
lpages = stat.lpages.value_()
353+
else:
354+
lpages = "NA"
355+
if has_member(stat, "pages_1g"):
356+
pages_1g = stat.pages_1g.counter.value_()
357+
else:
358+
pages_1g = "NA"
359+
if has_member(stat, "pages_2m"):
360+
pages_2m = stat.pages_2m.counter.value_()
361+
else:
362+
pages_2m = "NA"
363+
if has_member(stat, "pages_4k"):
364+
pages_4k = stat.pages_4k.counter.value_()
365+
else:
366+
pages_4k = "NA"
367+
368+
print("=============<< VMSTAT >>============= \n")
369+
rows_mm = [
370+
["KVM", hex(vm.value_())],
371+
["KVM_STAT", hex(vm.stat.address_of_())],
372+
["Remote TLB Flush", rtlab_flush],
373+
["MMU Shadow Zapped", stat.mmu_shadow_zapped.value_()],
374+
["MMU PTE Write", stat.mmu_pte_write.value_()],
375+
["MMU PDE Zapped", stat.mmu_pde_zapped.value_()],
376+
["MMU Floaded", stat.mmu_flooded.value_()],
377+
["MMU Recycled", stat.mmu_recycled.value_()],
378+
["MMU Cache Miss", stat.mmu_cache_miss.value_()],
379+
["MMU Unsync", stat.mmu_unsync.value_()],
380+
["Lpages", lpages],
381+
["NX Lpage Splits", stat.nx_lpage_splits.value_()],
382+
[
383+
"Max MMU Page Hash Collisions",
384+
stat.max_mmu_page_hash_collisions.value_(),
385+
],
386+
["Pages_1G", pages_1g],
387+
["Pgaes_2M", pages_2m],
388+
["Pages_4k", pages_4k],
389+
]
390+
print_table(rows_mm)
391+
392+
print("\n=============<< VCPU STAT >>============ \n")
393+
for vcpu in for_each_vcpu(vm):
394+
vcpu_stat = vcpu.stat
395+
rows_vcpu = [
396+
[
397+
"\nVCPU:",
398+
vcpu.vcpu_id.value_(),
399+
"HALT_SUC:",
400+
vcpu_stat.generic.halt_successful_poll.value_(),
401+
"HALT_ATTMPT:",
402+
vcpu_stat.generic.halt_attempted_poll.value_(),
403+
"HALT_INV:",
404+
vcpu_stat.generic.halt_poll_invalid.value_(),
405+
],
406+
[
407+
"PF_FIXED:",
408+
vcpu_stat.pf_fixed.value_(),
409+
"PF_GUEST:",
410+
vcpu_stat.pf_guest.value_(),
411+
"TLB_FLUSH:",
412+
vcpu_stat.tlb_flush.value_(),
413+
"INVLPG:",
414+
vcpu_stat.invlpg.value_(),
415+
],
416+
[
417+
"EXITS:",
418+
vcpu_stat.exits.value_(),
419+
"IO_EXIT:",
420+
vcpu_stat.io_exits.value_(),
421+
"MMIO_EXIT:",
422+
vcpu_stat.mmio_exits.value_(),
423+
"SIG_EXIT:",
424+
vcpu_stat.signal_exits.value_(),
425+
],
426+
[
427+
"IRQ_WIN_EXIT:",
428+
vcpu_stat.irq_window_exits.value_(),
429+
"NMI_WIN_EXIT:",
430+
vcpu_stat.nmi_window_exits.value_(),
431+
"L1D_FLUSH:",
432+
vcpu_stat.l1d_flush.value_(),
433+
"HALT_EXIT:",
434+
vcpu_stat.halt_exits.value_(),
435+
],
436+
[
437+
"REQ_IRQ_EXIT:",
438+
vcpu_stat.request_irq_exits.value_(),
439+
"IRQ_EXITS:",
440+
vcpu_stat.irq_exits.value_(),
441+
"HOST_STATE_RL:",
442+
vcpu_stat.host_state_reload.value_(),
443+
"FPU_RL:",
444+
vcpu_stat.fpu_reload.value_(),
445+
],
446+
[
447+
"INSN_EMUL:",
448+
vcpu_stat.insn_emulation.value_(),
449+
"INSN_EMUL_FAIL:",
450+
vcpu_stat.insn_emulation_fail.value_(),
451+
"HYPERCALLS:",
452+
vcpu_stat.hypercalls.value_(),
453+
"IRQ_INJ:",
454+
vcpu_stat.irq_injections.value_(),
455+
],
456+
[
457+
"NMI_INJ:",
458+
vcpu_stat.nmi_injections.value_(),
459+
"REQ_EVENT:",
460+
vcpu_stat.req_event.value_(),
461+
"PREEMPT_RPT:",
462+
vcpu_stat.preemption_reported.value_(),
463+
"PREEMT_OTH:",
464+
vcpu_stat.preemption_other.value_(),
465+
],
466+
]
467+
print()
468+
print_table(rows_vcpu)
469+
470+
271471
class KvmUtil(CorelensModule):
272472
"""
273473
Show all the VM related info from KVM host side
@@ -277,9 +477,7 @@ class KvmUtil(CorelensModule):
277477

278478
default_args = [
279479
[
280-
"--vms",
281-
"--vcpu",
282-
"--mmslot",
480+
"--all",
283481
]
284482
]
285483

@@ -302,12 +500,41 @@ def add_args(self, parser: argparse.ArgumentParser) -> None:
302500
action="store_true",
303501
help="show all memslot info",
304502
)
503+
parser.add_argument(
504+
"--ioeventfd",
505+
dest="ioeventfds",
506+
action="store_true",
507+
help="show all ioeventfds info",
508+
)
509+
parser.add_argument(
510+
"--iobus",
511+
dest="iobus",
512+
action="store_true",
513+
help="show all iobus info",
514+
)
515+
parser.add_argument(
516+
"--kvmstat",
517+
dest="kvmstat",
518+
action="store_true",
519+
help="show all iobus info",
520+
)
521+
parser.add_argument(
522+
"--all",
523+
action="store_true",
524+
help="show all of the above info",
525+
)
305526

306527
def run(self, prog: Program, args: argparse.Namespace) -> None:
307-
if args.list_vm:
528+
if args.list_vm or args.all:
308529
print_vm_list(prog)
309-
if args.vcpu_list:
530+
if args.vcpu_list or args.all:
310531
print_vcpu_list(prog)
311-
if args.memslot:
532+
if args.memslot or args.all:
312533
print_memslot_info(prog)
534+
if args.ioeventfds or args.all:
535+
print_ioeventfd_info(prog)
536+
if args.iobus or args.all:
537+
print_iobus_info(prog)
538+
if args.kvmstat or args.all:
539+
print_kvmstat_info(prog)
313540
return

tests/test_kvm.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ def test_kvmutil(prog):
77
kvm.print_vm_list(prog)
88
kvm.print_vcpu_list(prog)
99
kvm.print_memslot_info(prog)
10+
kvm.print_ioeventfd_info(prog)
11+
kvm.print_iobus_info(prog)
12+
kvm.print_kvmstat_info(prog)

0 commit comments

Comments
 (0)