8
8
from drgn import cast
9
9
from drgn import Object
10
10
from drgn import Program
11
+ from drgn .helpers .common .type import enum_type_to_class
11
12
from drgn .helpers .linux .list import list_for_each_entry
12
13
from drgn .helpers .linux .pid import find_task
13
14
from drgn .helpers .linux .sched import task_state_to_char
14
15
from drgn .helpers .linux .xarray import xa_for_each
15
16
16
17
from drgn_tools .corelens import CorelensModule
17
18
from drgn_tools .table import print_table
19
+ from drgn_tools .util import enum_name_get
18
20
from drgn_tools .util import has_member
19
21
20
22
@@ -268,6 +270,204 @@ def print_memslot_info(prog: Program) -> None:
268
270
print ("\n ## Total Pages: %d ##" % (nr_pages ))
269
271
270
272
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
+ "\n VCPU:" ,
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
+
271
471
class KvmUtil (CorelensModule ):
272
472
"""
273
473
Show all the VM related info from KVM host side
@@ -277,9 +477,7 @@ class KvmUtil(CorelensModule):
277
477
278
478
default_args = [
279
479
[
280
- "--vms" ,
281
- "--vcpu" ,
282
- "--mmslot" ,
480
+ "--all" ,
283
481
]
284
482
]
285
483
@@ -302,12 +500,41 @@ def add_args(self, parser: argparse.ArgumentParser) -> None:
302
500
action = "store_true" ,
303
501
help = "show all memslot info" ,
304
502
)
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
+ )
305
526
306
527
def run (self , prog : Program , args : argparse .Namespace ) -> None :
307
- if args .list_vm :
528
+ if args .list_vm or args . all :
308
529
print_vm_list (prog )
309
- if args .vcpu_list :
530
+ if args .vcpu_list or args . all :
310
531
print_vcpu_list (prog )
311
- if args .memslot :
532
+ if args .memslot or args . all :
312
533
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 )
313
540
return
0 commit comments