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,203 @@ 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
+
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
+ "\n VCPU:" ,
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
+
271
470
class KvmUtil (CorelensModule ):
272
471
"""
273
472
Show all the VM related info from KVM host side
@@ -277,9 +476,7 @@ class KvmUtil(CorelensModule):
277
476
278
477
default_args = [
279
478
[
280
- "--vms" ,
281
- "--vcpu" ,
282
- "--mmslot" ,
479
+ "--all" ,
283
480
]
284
481
]
285
482
@@ -302,12 +499,41 @@ def add_args(self, parser: argparse.ArgumentParser) -> None:
302
499
action = "store_true" ,
303
500
help = "show all memslot info" ,
304
501
)
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
+ )
305
525
306
526
def run (self , prog : Program , args : argparse .Namespace ) -> None :
307
- if args .list_vm :
527
+ if args .list_vm or args . all :
308
528
print_vm_list (prog )
309
- if args .vcpu_list :
529
+ if args .vcpu_list or args . all :
310
530
print_vcpu_list (prog )
311
- if args .memslot :
531
+ if args .memslot or args . all :
312
532
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 )
313
539
return
0 commit comments