41
41
* MSR_CORE_C1_RES: CORE C1 Residency Counter
42
42
* perf code: 0x00
43
43
* Available model: SLM,AMT,GLM,CNL,ICX,TNT,ADL,RPL
44
- * MTL
44
+ * MTL,SRF
45
45
* Scope: Core (each processor core has a MSR)
46
46
* MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
47
47
* perf code: 0x01
52
52
* perf code: 0x02
53
53
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
54
54
* SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
55
- * TGL,TNT,RKL,ADL,RPL,SPR,MTL
55
+ * TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF
56
56
* Scope: Core
57
57
* MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
58
58
* perf code: 0x03
75
75
* perf code: 0x02
76
76
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
77
77
* SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
78
- * TGL,TNT,RKL,ADL,RPL,SPR,MTL
78
+ * TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF
79
79
* Scope: Package (physical package)
80
80
* MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter.
81
81
* perf code: 0x03
97
97
* Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL,
98
98
* TNT,RKL,ADL,RPL,MTL
99
99
* Scope: Package (physical package)
100
+ * MSR_MODULE_C6_RES_MS: Module C6 Residency Counter.
101
+ * perf code: 0x00
102
+ * Available model: SRF
103
+ * Scope: A cluster of cores shared L2 cache
100
104
*
101
105
*/
102
106
@@ -130,6 +134,7 @@ static ssize_t cstate_get_attr_cpumask(struct device *dev,
130
134
struct cstate_model {
131
135
unsigned long core_events ;
132
136
unsigned long pkg_events ;
137
+ unsigned long module_events ;
133
138
unsigned long quirks ;
134
139
};
135
140
@@ -270,6 +275,28 @@ static struct perf_msr pkg_msr[] = {
270
275
271
276
static cpumask_t cstate_pkg_cpu_mask ;
272
277
278
+ /* cstate_module PMU */
279
+ static struct pmu cstate_module_pmu ;
280
+ static bool has_cstate_module ;
281
+
282
+ enum perf_cstate_module_events {
283
+ PERF_CSTATE_MODULE_C6_RES = 0 ,
284
+
285
+ PERF_CSTATE_MODULE_EVENT_MAX ,
286
+ };
287
+
288
+ PMU_EVENT_ATTR_STRING (c6 - residency , attr_cstate_module_c6 , "event=0x00" );
289
+
290
+ static unsigned long module_msr_mask ;
291
+
292
+ PMU_EVENT_GROUP (events , cstate_module_c6 );
293
+
294
+ static struct perf_msr module_msr [] = {
295
+ [PERF_CSTATE_MODULE_C6_RES ] = { MSR_MODULE_C6_RES_MS , & group_cstate_module_c6 , test_msr },
296
+ };
297
+
298
+ static cpumask_t cstate_module_cpu_mask ;
299
+
273
300
static ssize_t cstate_get_attr_cpumask (struct device * dev ,
274
301
struct device_attribute * attr ,
275
302
char * buf )
@@ -280,6 +307,8 @@ static ssize_t cstate_get_attr_cpumask(struct device *dev,
280
307
return cpumap_print_to_pagebuf (true, buf , & cstate_core_cpu_mask );
281
308
else if (pmu == & cstate_pkg_pmu )
282
309
return cpumap_print_to_pagebuf (true, buf , & cstate_pkg_cpu_mask );
310
+ else if (pmu == & cstate_module_pmu )
311
+ return cpumap_print_to_pagebuf (true, buf , & cstate_module_cpu_mask );
283
312
else
284
313
return 0 ;
285
314
}
@@ -320,6 +349,15 @@ static int cstate_pmu_event_init(struct perf_event *event)
320
349
event -> hw .event_base = pkg_msr [cfg ].msr ;
321
350
cpu = cpumask_any_and (& cstate_pkg_cpu_mask ,
322
351
topology_die_cpumask (event -> cpu ));
352
+ } else if (event -> pmu == & cstate_module_pmu ) {
353
+ if (cfg >= PERF_CSTATE_MODULE_EVENT_MAX )
354
+ return - EINVAL ;
355
+ cfg = array_index_nospec ((unsigned long )cfg , PERF_CSTATE_MODULE_EVENT_MAX );
356
+ if (!(module_msr_mask & (1 << cfg )))
357
+ return - EINVAL ;
358
+ event -> hw .event_base = module_msr [cfg ].msr ;
359
+ cpu = cpumask_any_and (& cstate_module_cpu_mask ,
360
+ topology_cluster_cpumask (event -> cpu ));
323
361
} else {
324
362
return - ENOENT ;
325
363
}
@@ -407,6 +445,17 @@ static int cstate_cpu_exit(unsigned int cpu)
407
445
perf_pmu_migrate_context (& cstate_pkg_pmu , cpu , target );
408
446
}
409
447
}
448
+
449
+ if (has_cstate_module &&
450
+ cpumask_test_and_clear_cpu (cpu , & cstate_module_cpu_mask )) {
451
+
452
+ target = cpumask_any_but (topology_cluster_cpumask (cpu ), cpu );
453
+ /* Migrate events if there is a valid target */
454
+ if (target < nr_cpu_ids ) {
455
+ cpumask_set_cpu (target , & cstate_module_cpu_mask );
456
+ perf_pmu_migrate_context (& cstate_module_pmu , cpu , target );
457
+ }
458
+ }
410
459
return 0 ;
411
460
}
412
461
@@ -433,6 +482,15 @@ static int cstate_cpu_init(unsigned int cpu)
433
482
if (has_cstate_pkg && target >= nr_cpu_ids )
434
483
cpumask_set_cpu (cpu , & cstate_pkg_cpu_mask );
435
484
485
+ /*
486
+ * If this is the first online thread of that cluster, set it
487
+ * in the cluster cpu mask as the designated reader.
488
+ */
489
+ target = cpumask_any_and (& cstate_module_cpu_mask ,
490
+ topology_cluster_cpumask (cpu ));
491
+ if (has_cstate_module && target >= nr_cpu_ids )
492
+ cpumask_set_cpu (cpu , & cstate_module_cpu_mask );
493
+
436
494
return 0 ;
437
495
}
438
496
@@ -455,6 +513,11 @@ static const struct attribute_group *pkg_attr_update[] = {
455
513
NULL ,
456
514
};
457
515
516
+ static const struct attribute_group * module_attr_update [] = {
517
+ & group_cstate_module_c6 ,
518
+ NULL
519
+ };
520
+
458
521
static struct pmu cstate_core_pmu = {
459
522
.attr_groups = cstate_attr_groups ,
460
523
.attr_update = core_attr_update ,
@@ -485,6 +548,21 @@ static struct pmu cstate_pkg_pmu = {
485
548
.module = THIS_MODULE ,
486
549
};
487
550
551
+ static struct pmu cstate_module_pmu = {
552
+ .attr_groups = cstate_attr_groups ,
553
+ .attr_update = module_attr_update ,
554
+ .name = "cstate_module" ,
555
+ .task_ctx_nr = perf_invalid_context ,
556
+ .event_init = cstate_pmu_event_init ,
557
+ .add = cstate_pmu_event_add ,
558
+ .del = cstate_pmu_event_del ,
559
+ .start = cstate_pmu_event_start ,
560
+ .stop = cstate_pmu_event_stop ,
561
+ .read = cstate_pmu_event_update ,
562
+ .capabilities = PERF_PMU_CAP_NO_INTERRUPT | PERF_PMU_CAP_NO_EXCLUDE ,
563
+ .module = THIS_MODULE ,
564
+ };
565
+
488
566
static const struct cstate_model nhm_cstates __initconst = {
489
567
.core_events = BIT (PERF_CSTATE_CORE_C3_RES ) |
490
568
BIT (PERF_CSTATE_CORE_C6_RES ),
@@ -599,6 +677,15 @@ static const struct cstate_model glm_cstates __initconst = {
599
677
BIT (PERF_CSTATE_PKG_C10_RES ),
600
678
};
601
679
680
+ static const struct cstate_model srf_cstates __initconst = {
681
+ .core_events = BIT (PERF_CSTATE_CORE_C1_RES ) |
682
+ BIT (PERF_CSTATE_CORE_C6_RES ),
683
+
684
+ .pkg_events = BIT (PERF_CSTATE_PKG_C6_RES ),
685
+
686
+ .module_events = BIT (PERF_CSTATE_MODULE_C6_RES ),
687
+ };
688
+
602
689
603
690
static const struct x86_cpu_id intel_cstates_match [] __initconst = {
604
691
X86_MATCH_INTEL_FAM6_MODEL (NEHALEM , & nhm_cstates ),
@@ -651,6 +738,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
651
738
X86_MATCH_INTEL_FAM6_MODEL (ATOM_TREMONT , & glm_cstates ),
652
739
X86_MATCH_INTEL_FAM6_MODEL (ATOM_TREMONT_L , & glm_cstates ),
653
740
X86_MATCH_INTEL_FAM6_MODEL (ATOM_GRACEMONT , & adl_cstates ),
741
+ X86_MATCH_INTEL_FAM6_MODEL (ATOM_CRESTMONT_X , & srf_cstates ),
654
742
655
743
X86_MATCH_INTEL_FAM6_MODEL (ICELAKE_L , & icl_cstates ),
656
744
X86_MATCH_INTEL_FAM6_MODEL (ICELAKE , & icl_cstates ),
@@ -692,10 +780,14 @@ static int __init cstate_probe(const struct cstate_model *cm)
692
780
pkg_msr_mask = perf_msr_probe (pkg_msr , PERF_CSTATE_PKG_EVENT_MAX ,
693
781
true, (void * ) & cm -> pkg_events );
694
782
783
+ module_msr_mask = perf_msr_probe (module_msr , PERF_CSTATE_MODULE_EVENT_MAX ,
784
+ true, (void * ) & cm -> module_events );
785
+
695
786
has_cstate_core = !!core_msr_mask ;
696
787
has_cstate_pkg = !!pkg_msr_mask ;
788
+ has_cstate_module = !!module_msr_mask ;
697
789
698
- return (has_cstate_core || has_cstate_pkg ) ? 0 : - ENODEV ;
790
+ return (has_cstate_core || has_cstate_pkg || has_cstate_module ) ? 0 : - ENODEV ;
699
791
}
700
792
701
793
static inline void cstate_cleanup (void )
@@ -708,6 +800,9 @@ static inline void cstate_cleanup(void)
708
800
709
801
if (has_cstate_pkg )
710
802
perf_pmu_unregister (& cstate_pkg_pmu );
803
+
804
+ if (has_cstate_module )
805
+ perf_pmu_unregister (& cstate_module_pmu );
711
806
}
712
807
713
808
static int __init cstate_init (void )
@@ -744,6 +839,16 @@ static int __init cstate_init(void)
744
839
return err ;
745
840
}
746
841
}
842
+
843
+ if (has_cstate_module ) {
844
+ err = perf_pmu_register (& cstate_module_pmu , cstate_module_pmu .name , -1 );
845
+ if (err ) {
846
+ has_cstate_module = false;
847
+ pr_info ("Failed to register cstate cluster pmu\n" );
848
+ cstate_cleanup ();
849
+ return err ;
850
+ }
851
+ }
747
852
return 0 ;
748
853
}
749
854
0 commit comments