Skip to content

Commit f3e884b

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

File tree

2 files changed

+235
-6
lines changed

2 files changed

+235
-6
lines changed

drgn_tools/kvm.py

Lines changed: 232 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,203 @@ 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+
307+
vm_list = for_each_vm(prog)
308+
kvm_bus_type = enum_type_to_class(
309+
prog.type("enum kvm_bus"), "kvm_bus_type"
310+
)
311+
312+
for vm in vm_list:
313+
iobus_iterator = iter(vm.buses)
314+
for i, bus in enumerate(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+
str(bus_name),
329+
dev_count,
330+
eventfd_count,
331+
range,
332+
]
333+
)
334+
print("=============<< IOBUS >>=============")
335+
print_table(rows)
336+
337+
338+
def print_kvmstat_info(prog: Program) -> None:
339+
"""
340+
print vmstat and vcpustat information of a VM
341+
"""
342+
vm_list = for_each_vm(prog)
343+
344+
for vm in vm_list:
345+
stat = vm.stat
346+
if has_member(stat, "generic"):
347+
rtlab_flush = stat.generic.remote_tlb_flush.value_()
348+
else:
349+
rtlab_flush = stat.remote_tlb_flush.value_()
350+
if has_member(stat, "lpages"):
351+
lpages = stat.lpages.value_()
352+
else:
353+
lpages = "NA"
354+
if has_member(stat, "pages_1g"):
355+
pages_1g = stat.pages_1g.counter.value_()
356+
else:
357+
pages_1g = "NA"
358+
if has_member(stat, "pages_2m"):
359+
pages_2m = stat.pages_2m.counter.value_()
360+
else:
361+
pages_2m = "NA"
362+
if has_member(stat, "pages_4k"):
363+
pages_4k = stat.pages_4k.counter.value_()
364+
else:
365+
pages_4k = "NA"
366+
367+
print("=============<< VMSTAT >>============= \n")
368+
rows_mm = [
369+
["KVM", hex(vm.value_())],
370+
["KVM_STAT", hex(vm.stat.address_of_())],
371+
["Remote TLB Flush", rtlab_flush],
372+
["MMU Shadow Zapped", stat.mmu_shadow_zapped.value_()],
373+
["MMU PTE Write", stat.mmu_pte_write.value_()],
374+
["MMU PDE Zapped", stat.mmu_pde_zapped.value_()],
375+
["MMU Floaded", stat.mmu_flooded.value_()],
376+
["MMU Recycled", stat.mmu_recycled.value_()],
377+
["MMU Cache Miss", stat.mmu_cache_miss.value_()],
378+
["MMU Unsync", stat.mmu_unsync.value_()],
379+
["Lpages", lpages],
380+
["NX Lpage Splits", stat.nx_lpage_splits.value_()],
381+
[
382+
"Max MMU Page Hash Collisions",
383+
stat.max_mmu_page_hash_collisions.value_(),
384+
],
385+
["Pages_1G", pages_1g],
386+
["Pgaes_2M", pages_2m],
387+
["Pages_4k", pages_4k],
388+
]
389+
print_table(rows_mm)
390+
391+
print("\n=============<< VCPU STAT >>============ \n")
392+
for vcpu in for_each_vcpu(vm):
393+
vcpu_stat = vcpu.stat
394+
rows_vcpu = [
395+
[
396+
"\nVCPU:",
397+
vcpu.vcpu_id.value_(),
398+
"HALT_SUC:",
399+
vcpu_stat.generic.halt_successful_poll.value_(),
400+
"HALT_ATTMPT:",
401+
vcpu_stat.generic.halt_attempted_poll.value_(),
402+
"HALT_INV:",
403+
vcpu_stat.generic.halt_poll_invalid.value_(),
404+
],
405+
[
406+
"PF_FIXED:",
407+
vcpu_stat.pf_fixed.value_(),
408+
"PF_GUEST:",
409+
vcpu_stat.pf_guest.value_(),
410+
"TLB_FLUSH:",
411+
vcpu_stat.tlb_flush.value_(),
412+
"INVLPG:",
413+
vcpu_stat.invlpg.value_(),
414+
],
415+
[
416+
"EXITS:",
417+
vcpu_stat.exits.value_(),
418+
"IO_EXIT:",
419+
vcpu_stat.io_exits.value_(),
420+
"MMIO_EXIT:",
421+
vcpu_stat.mmio_exits.value_(),
422+
"SIG_EXIT:",
423+
vcpu_stat.signal_exits.value_(),
424+
],
425+
[
426+
"IRQ_WIN_EXIT:",
427+
vcpu_stat.irq_window_exits.value_(),
428+
"NMI_WIN_EXIT:",
429+
vcpu_stat.nmi_window_exits.value_(),
430+
"L1D_FLUSH:",
431+
vcpu_stat.l1d_flush.value_(),
432+
"HALT_EXIT:",
433+
vcpu_stat.halt_exits.value_(),
434+
],
435+
[
436+
"REQ_IRQ_EXIT:",
437+
vcpu_stat.request_irq_exits.value_(),
438+
"IRQ_EXITS:",
439+
vcpu_stat.irq_exits.value_(),
440+
"HOST_STATE_RL:",
441+
vcpu_stat.host_state_reload.value_(),
442+
"FPU_RL:",
443+
vcpu_stat.fpu_reload.value_(),
444+
],
445+
[
446+
"INSN_EMUL:",
447+
vcpu_stat.insn_emulation.value_(),
448+
"INSN_EMUL_FAIL:",
449+
vcpu_stat.insn_emulation_fail.value_(),
450+
"HYPERCALLS:",
451+
vcpu_stat.hypercalls.value_(),
452+
"IRQ_INJ:",
453+
vcpu_stat.irq_injections.value_(),
454+
],
455+
[
456+
"NMI_INJ:",
457+
vcpu_stat.nmi_injections.value_(),
458+
"REQ_EVENT:",
459+
vcpu_stat.req_event.value_(),
460+
"PREEMPT_RPT:",
461+
vcpu_stat.preemption_reported.value_(),
462+
"PREEMT_OTH:",
463+
vcpu_stat.preemption_other.value_(),
464+
],
465+
]
466+
print()
467+
print_table(rows_vcpu)
468+
469+
271470
class KvmUtil(CorelensModule):
272471
"""
273472
Show all the VM related info from KVM host side
@@ -277,9 +476,7 @@ class KvmUtil(CorelensModule):
277476

278477
default_args = [
279478
[
280-
"--vms",
281-
"--vcpu",
282-
"--mmslot",
479+
"--all",
283480
]
284481
]
285482

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

306526
def run(self, prog: Program, args: argparse.Namespace) -> None:
307-
if args.list_vm:
527+
if args.list_vm or args.all:
308528
print_vm_list(prog)
309-
if args.vcpu_list:
529+
if args.vcpu_list or args.all:
310530
print_vcpu_list(prog)
311-
if args.memslot:
531+
if args.memslot or args.all:
312532
print_memslot_info(prog)
533+
if args.ioeventfds or args.all:
534+
print_ioeventfd_info(prog)
535+
if args.iobus or args.all:
536+
print_iobus_info(prog)
537+
if args.kvmstat or args.all:
538+
print_kvmstat_info(prog)
313539
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)