@@ -97,6 +97,8 @@ void (*metadata_destroy)(Cache *cache);
97
97
98
98
static int cores ;
99
99
static Cache * * l1_dcaches , * * l1_icaches ;
100
+
101
+ static bool use_l2 ;
100
102
static Cache * * l2_ucaches ;
101
103
102
104
static GMutex * l1_dcache_locks ;
@@ -410,7 +412,7 @@ static void vcpu_mem_access(unsigned int vcpu_index, qemu_plugin_meminfo_t info,
410
412
l1_dcaches [cache_idx ]-> accesses ++ ;
411
413
g_mutex_unlock (& l1_dcache_locks [cache_idx ]);
412
414
413
- if (hit_in_l1 ) {
415
+ if (hit_in_l1 || ! use_l2 ) {
414
416
/* No need to access L2 */
415
417
return ;
416
418
}
@@ -445,7 +447,7 @@ static void vcpu_insn_exec(unsigned int vcpu_index, void *userdata)
445
447
l1_icaches [cache_idx ]-> accesses ++ ;
446
448
g_mutex_unlock (& l1_icache_locks [cache_idx ]);
447
449
448
- if (hit_in_l1 ) {
450
+ if (hit_in_l1 || ! use_l2 ) {
449
451
/* No need to access L2 */
450
452
return ;
451
453
}
@@ -542,19 +544,25 @@ static void append_stats_line(GString *line, uint64_t l1_daccess,
542
544
543
545
l1_dmiss_rate = ((double ) l1_dmisses ) / (l1_daccess ) * 100.0 ;
544
546
l1_imiss_rate = ((double ) l1_imisses ) / (l1_iaccess ) * 100.0 ;
545
- l2_miss_rate = ((double ) l2_misses ) / (l2_access ) * 100.0 ;
546
547
547
548
g_string_append_printf (line , "%-14lu %-12lu %9.4lf%% %-14lu %-12lu"
548
- " %9.4lf%% %-12lu %-11lu %10.4lf%%\n " ,
549
+ " %9.4lf%%" ,
549
550
l1_daccess ,
550
551
l1_dmisses ,
551
552
l1_daccess ? l1_dmiss_rate : 0.0 ,
552
553
l1_iaccess ,
553
554
l1_imisses ,
554
- l1_iaccess ? l1_imiss_rate : 0.0 ,
555
- l2_access ,
556
- l2_misses ,
557
- l2_access ? l2_miss_rate : 0.0 );
555
+ l1_iaccess ? l1_imiss_rate : 0.0 );
556
+
557
+ if (use_l2 ) {
558
+ l2_miss_rate = ((double ) l2_misses ) / (l2_access ) * 100.0 ;
559
+ g_string_append_printf (line , " %-12lu %-11lu %10.4lf%%" ,
560
+ l2_access ,
561
+ l2_misses ,
562
+ l2_access ? l2_miss_rate : 0.0 );
563
+ }
564
+
565
+ g_string_append (line , "\n" );
558
566
}
559
567
560
568
static void sum_stats (void )
@@ -568,8 +576,10 @@ static void sum_stats(void)
568
576
l1_imem_accesses += l1_icaches [i ]-> accesses ;
569
577
l1_dmem_accesses += l1_dcaches [i ]-> accesses ;
570
578
571
- l2_misses += l2_ucaches [i ]-> misses ;
572
- l2_mem_accesses += l2_ucaches [i ]-> accesses ;
579
+ if (use_l2 ) {
580
+ l2_misses += l2_ucaches [i ]-> misses ;
581
+ l2_mem_accesses += l2_ucaches [i ]-> accesses ;
582
+ }
573
583
}
574
584
}
575
585
@@ -604,25 +614,31 @@ static void log_stats(void)
604
614
605
615
g_autoptr (GString ) rep = g_string_new ("core #, data accesses, data misses,"
606
616
" dmiss rate, insn accesses,"
607
- " insn misses, imiss rate,"
608
- " l2 accesses, l2 misses,"
609
- " l2 miss rate\n" );
617
+ " insn misses, imiss rate" );
618
+
619
+ if (use_l2 ) {
620
+ g_string_append (rep , ", l2 accesses, l2 misses, l2 miss rate" );
621
+ }
622
+
623
+ g_string_append (rep , "\n" );
610
624
611
625
for (i = 0 ; i < cores ; i ++ ) {
612
626
g_string_append_printf (rep , "%-8d" , i );
613
627
dcache = l1_dcaches [i ];
614
628
icache = l1_icaches [i ];
615
- l2_cache = l2_ucaches [i ];
629
+ l2_cache = use_l2 ? l2_ucaches [i ] : NULL ;
616
630
append_stats_line (rep , dcache -> accesses , dcache -> misses ,
617
- icache -> accesses , icache -> misses , l2_cache -> accesses ,
618
- l2_cache -> misses );
631
+ icache -> accesses , icache -> misses ,
632
+ l2_cache ? l2_cache -> accesses : 0 ,
633
+ l2_cache ? l2_cache -> misses : 0 );
619
634
}
620
635
621
636
if (cores > 1 ) {
622
637
sum_stats ();
623
638
g_string_append_printf (rep , "%-8s" , "sum" );
624
639
append_stats_line (rep , l1_dmem_accesses , l1_dmisses ,
625
- l1_imem_accesses , l1_imisses , l2_mem_accesses , l2_misses );
640
+ l1_imem_accesses , l1_imisses ,
641
+ l2_cache ? l2_mem_accesses : 0 , l2_cache ? l2_misses : 0 );
626
642
}
627
643
628
644
g_string_append (rep , "\n" );
@@ -663,6 +679,10 @@ static void log_top_insns(void)
663
679
insn -> disas_str );
664
680
}
665
681
682
+ if (!use_l2 ) {
683
+ goto finish ;
684
+ }
685
+
666
686
miss_insns = g_list_sort (miss_insns , l2_cmp );
667
687
g_string_append_printf (rep , "%s" , "\naddress, L2 misses, instruction\n" );
668
688
@@ -676,6 +696,7 @@ static void log_top_insns(void)
676
696
insn -> disas_str );
677
697
}
678
698
699
+ finish :
679
700
qemu_plugin_outs (rep -> str );
680
701
g_list_free (miss_insns );
681
702
}
@@ -687,11 +708,14 @@ static void plugin_exit(qemu_plugin_id_t id, void *p)
687
708
688
709
caches_free (l1_dcaches );
689
710
caches_free (l1_icaches );
690
- caches_free (l2_ucaches );
691
711
692
712
g_free (l1_dcache_locks );
693
713
g_free (l1_icache_locks );
694
- g_free (l2_ucache_locks );
714
+
715
+ if (use_l2 ) {
716
+ caches_free (l2_ucaches );
717
+ g_free (l2_ucache_locks );
718
+ }
695
719
696
720
g_hash_table_destroy (miss_ht );
697
721
}
@@ -767,11 +791,19 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
767
791
} else if (g_strcmp0 (tokens [0 ], "cores" ) == 0 ) {
768
792
cores = STRTOLL (tokens [1 ]);
769
793
} else if (g_strcmp0 (tokens [0 ], "l2cachesize" ) == 0 ) {
794
+ use_l2 = true;
770
795
l2_cachesize = STRTOLL (tokens [1 ]);
771
796
} else if (g_strcmp0 (tokens [0 ], "l2blksize" ) == 0 ) {
797
+ use_l2 = true;
772
798
l2_blksize = STRTOLL (tokens [1 ]);
773
799
} else if (g_strcmp0 (tokens [0 ], "l2assoc" ) == 0 ) {
800
+ use_l2 = true;
774
801
l2_assoc = STRTOLL (tokens [1 ]);
802
+ } else if (g_strcmp0 (tokens [0 ], "l2" ) == 0 ) {
803
+ if (!qemu_plugin_bool_parse (tokens [0 ], tokens [1 ], & use_l2 )) {
804
+ fprintf (stderr , "boolean argument parsing failed: %s\n" , opt );
805
+ return -1 ;
806
+ }
775
807
} else if (g_strcmp0 (tokens [0 ], "evict" ) == 0 ) {
776
808
if (g_strcmp0 (tokens [1 ], "rand" ) == 0 ) {
777
809
policy = RAND ;
@@ -807,8 +839,8 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
807
839
return -1 ;
808
840
}
809
841
810
- l2_ucaches = caches_init (l2_blksize , l2_assoc , l2_cachesize );
811
- if (!l2_ucaches ) {
842
+ l2_ucaches = use_l2 ? caches_init (l2_blksize , l2_assoc , l2_cachesize ) : NULL ;
843
+ if (!l2_ucaches && use_l2 ) {
812
844
const char * err = cache_config_error (l2_blksize , l2_assoc , l2_cachesize );
813
845
fprintf (stderr , "L2 cache cannot be constructed from given parameters\n" );
814
846
fprintf (stderr , "%s\n" , err );
@@ -817,7 +849,7 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
817
849
818
850
l1_dcache_locks = g_new0 (GMutex , cores );
819
851
l1_icache_locks = g_new0 (GMutex , cores );
820
- l2_ucache_locks = g_new0 (GMutex , cores );
852
+ l2_ucache_locks = use_l2 ? g_new0 (GMutex , cores ) : NULL ;
821
853
822
854
qemu_plugin_register_vcpu_tb_trans_cb (id , vcpu_tb_trans );
823
855
qemu_plugin_register_atexit_cb (id , plugin_exit , NULL );
0 commit comments