@@ -2119,6 +2119,16 @@ static struct extra_reg intel_grt_extra_regs[] __read_mostly = {
2119
2119
EVENT_EXTRA_END
2120
2120
};
2121
2121
2122
+ static struct extra_reg intel_cmt_extra_regs [] __read_mostly = {
2123
+ /* must define OFFCORE_RSP_X first, see intel_fixup_er() */
2124
+ INTEL_UEVENT_EXTRA_REG (0x01b7 , MSR_OFFCORE_RSP_0 , 0x800ff3ffffffffffull , RSP_0 ),
2125
+ INTEL_UEVENT_EXTRA_REG (0x02b7 , MSR_OFFCORE_RSP_1 , 0xff3ffffffffffull , RSP_1 ),
2126
+ INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG (0x5d0 ),
2127
+ INTEL_UEVENT_EXTRA_REG (0x0127 , MSR_SNOOP_RSP_0 , 0xffffffffffffffffull , SNOOP_0 ),
2128
+ INTEL_UEVENT_EXTRA_REG (0x0227 , MSR_SNOOP_RSP_1 , 0xffffffffffffffffull , SNOOP_1 ),
2129
+ EVENT_EXTRA_END
2130
+ };
2131
+
2122
2132
#define KNL_OT_L2_HITE BIT_ULL(19) /* Other Tile L2 Hit */
2123
2133
#define KNL_OT_L2_HITF BIT_ULL(20) /* Other Tile L2 Hit */
2124
2134
#define KNL_MCDRAM_LOCAL BIT_ULL(21)
@@ -3026,10 +3036,8 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
3026
3036
3027
3037
perf_sample_data_init (& data , 0 , event -> hw .last_period );
3028
3038
3029
- if (has_branch_stack (event )) {
3030
- data .br_stack = & cpuc -> lbr_stack ;
3031
- data .sample_flags |= PERF_SAMPLE_BRANCH_STACK ;
3032
- }
3039
+ if (has_branch_stack (event ))
3040
+ perf_sample_save_brstack (& data , event , & cpuc -> lbr_stack );
3033
3041
3034
3042
if (perf_event_overflow (event , & data , regs ))
3035
3043
x86_pmu_stop (event , 0 );
@@ -4182,6 +4190,12 @@ static int hsw_hw_config(struct perf_event *event)
4182
4190
static struct event_constraint counter0_constraint =
4183
4191
INTEL_ALL_EVENT_CONSTRAINT (0 , 0x1 );
4184
4192
4193
+ static struct event_constraint counter1_constraint =
4194
+ INTEL_ALL_EVENT_CONSTRAINT (0 , 0x2 );
4195
+
4196
+ static struct event_constraint counter0_1_constraint =
4197
+ INTEL_ALL_EVENT_CONSTRAINT (0 , 0x3 );
4198
+
4185
4199
static struct event_constraint counter2_constraint =
4186
4200
EVENT_CONSTRAINT (0 , 0x4 , 0 );
4187
4201
@@ -4191,6 +4205,12 @@ static struct event_constraint fixed0_constraint =
4191
4205
static struct event_constraint fixed0_counter0_constraint =
4192
4206
INTEL_ALL_EVENT_CONSTRAINT (0 , 0x100000001ULL );
4193
4207
4208
+ static struct event_constraint fixed0_counter0_1_constraint =
4209
+ INTEL_ALL_EVENT_CONSTRAINT (0 , 0x100000003ULL );
4210
+
4211
+ static struct event_constraint counters_1_7_constraint =
4212
+ INTEL_ALL_EVENT_CONSTRAINT (0 , 0xfeULL );
4213
+
4194
4214
static struct event_constraint *
4195
4215
hsw_get_event_constraints (struct cpu_hw_events * cpuc , int idx ,
4196
4216
struct perf_event * event )
@@ -4322,6 +4342,78 @@ adl_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
4322
4342
return & emptyconstraint ;
4323
4343
}
4324
4344
4345
+ static struct event_constraint *
4346
+ cmt_get_event_constraints (struct cpu_hw_events * cpuc , int idx ,
4347
+ struct perf_event * event )
4348
+ {
4349
+ struct event_constraint * c ;
4350
+
4351
+ c = intel_get_event_constraints (cpuc , idx , event );
4352
+
4353
+ /*
4354
+ * The :ppp indicates the Precise Distribution (PDist) facility, which
4355
+ * is only supported on the GP counter 0 & 1 and Fixed counter 0.
4356
+ * If a :ppp event which is not available on the above eligible counters,
4357
+ * error out.
4358
+ */
4359
+ if (event -> attr .precise_ip == 3 ) {
4360
+ /* Force instruction:ppp on PMC0, 1 and Fixed counter 0 */
4361
+ if (constraint_match (& fixed0_constraint , event -> hw .config ))
4362
+ return & fixed0_counter0_1_constraint ;
4363
+
4364
+ switch (c -> idxmsk64 & 0x3ull ) {
4365
+ case 0x1 :
4366
+ return & counter0_constraint ;
4367
+ case 0x2 :
4368
+ return & counter1_constraint ;
4369
+ case 0x3 :
4370
+ return & counter0_1_constraint ;
4371
+ }
4372
+ return & emptyconstraint ;
4373
+ }
4374
+
4375
+ return c ;
4376
+ }
4377
+
4378
+ static struct event_constraint *
4379
+ rwc_get_event_constraints (struct cpu_hw_events * cpuc , int idx ,
4380
+ struct perf_event * event )
4381
+ {
4382
+ struct event_constraint * c ;
4383
+
4384
+ c = spr_get_event_constraints (cpuc , idx , event );
4385
+
4386
+ /* The Retire Latency is not supported by the fixed counter 0. */
4387
+ if (event -> attr .precise_ip &&
4388
+ (event -> attr .sample_type & PERF_SAMPLE_WEIGHT_TYPE ) &&
4389
+ constraint_match (& fixed0_constraint , event -> hw .config )) {
4390
+ /*
4391
+ * The Instruction PDIR is only available
4392
+ * on the fixed counter 0. Error out for this case.
4393
+ */
4394
+ if (event -> attr .precise_ip == 3 )
4395
+ return & emptyconstraint ;
4396
+ return & counters_1_7_constraint ;
4397
+ }
4398
+
4399
+ return c ;
4400
+ }
4401
+
4402
+ static struct event_constraint *
4403
+ mtl_get_event_constraints (struct cpu_hw_events * cpuc , int idx ,
4404
+ struct perf_event * event )
4405
+ {
4406
+ struct x86_hybrid_pmu * pmu = hybrid_pmu (event -> pmu );
4407
+
4408
+ if (pmu -> cpu_type == hybrid_big )
4409
+ return rwc_get_event_constraints (cpuc , idx , event );
4410
+ if (pmu -> cpu_type == hybrid_small )
4411
+ return cmt_get_event_constraints (cpuc , idx , event );
4412
+
4413
+ WARN_ON (1 );
4414
+ return & emptyconstraint ;
4415
+ }
4416
+
4325
4417
static int adl_hw_config (struct perf_event * event )
4326
4418
{
4327
4419
struct x86_hybrid_pmu * pmu = hybrid_pmu (event -> pmu );
@@ -4494,6 +4586,25 @@ static void flip_smm_bit(void *data)
4494
4586
}
4495
4587
}
4496
4588
4589
+ static void intel_pmu_check_num_counters (int * num_counters ,
4590
+ int * num_counters_fixed ,
4591
+ u64 * intel_ctrl , u64 fixed_mask );
4592
+
4593
+ static void update_pmu_cap (struct x86_hybrid_pmu * pmu )
4594
+ {
4595
+ unsigned int sub_bitmaps = cpuid_eax (ARCH_PERFMON_EXT_LEAF );
4596
+ unsigned int eax , ebx , ecx , edx ;
4597
+
4598
+ if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT ) {
4599
+ cpuid_count (ARCH_PERFMON_EXT_LEAF , ARCH_PERFMON_NUM_COUNTER_LEAF ,
4600
+ & eax , & ebx , & ecx , & edx );
4601
+ pmu -> num_counters = fls (eax );
4602
+ pmu -> num_counters_fixed = fls (ebx );
4603
+ intel_pmu_check_num_counters (& pmu -> num_counters , & pmu -> num_counters_fixed ,
4604
+ & pmu -> intel_ctrl , ebx );
4605
+ }
4606
+ }
4607
+
4497
4608
static bool init_hybrid_pmu (int cpu )
4498
4609
{
4499
4610
struct cpu_hw_events * cpuc = & per_cpu (cpu_hw_events , cpu );
@@ -4519,6 +4630,9 @@ static bool init_hybrid_pmu(int cpu)
4519
4630
if (!cpumask_empty (& pmu -> supported_cpus ))
4520
4631
goto end ;
4521
4632
4633
+ if (this_cpu_has (X86_FEATURE_ARCH_PERFMON_EXT ))
4634
+ update_pmu_cap (pmu );
4635
+
4522
4636
if (!check_hw_exists (& pmu -> pmu , pmu -> num_counters , pmu -> num_counters_fixed ))
4523
4637
return false;
4524
4638
@@ -5463,6 +5577,12 @@ static struct attribute *adl_hybrid_mem_attrs[] = {
5463
5577
NULL ,
5464
5578
};
5465
5579
5580
+ static struct attribute * mtl_hybrid_mem_attrs [] = {
5581
+ EVENT_PTR (mem_ld_adl ),
5582
+ EVENT_PTR (mem_st_adl ),
5583
+ NULL
5584
+ };
5585
+
5466
5586
EVENT_ATTR_STR_HYBRID (tx - start , tx_start_adl , "event=0xc9,umask=0x1" , hybrid_big );
5467
5587
EVENT_ATTR_STR_HYBRID (tx - commit , tx_commit_adl , "event=0xc9,umask=0x2" , hybrid_big );
5468
5588
EVENT_ATTR_STR_HYBRID (tx - abort , tx_abort_adl , "event=0xc9,umask=0x4" , hybrid_big );
@@ -5490,20 +5610,40 @@ FORMAT_ATTR_HYBRID(offcore_rsp, hybrid_big_small);
5490
5610
FORMAT_ATTR_HYBRID (ldlat , hybrid_big_small );
5491
5611
FORMAT_ATTR_HYBRID (frontend , hybrid_big );
5492
5612
5613
+ #define ADL_HYBRID_RTM_FORMAT_ATTR \
5614
+ FORMAT_HYBRID_PTR(in_tx), \
5615
+ FORMAT_HYBRID_PTR(in_tx_cp)
5616
+
5617
+ #define ADL_HYBRID_FORMAT_ATTR \
5618
+ FORMAT_HYBRID_PTR(offcore_rsp), \
5619
+ FORMAT_HYBRID_PTR(ldlat), \
5620
+ FORMAT_HYBRID_PTR(frontend)
5621
+
5493
5622
static struct attribute * adl_hybrid_extra_attr_rtm [] = {
5494
- FORMAT_HYBRID_PTR (in_tx ),
5495
- FORMAT_HYBRID_PTR (in_tx_cp ),
5496
- FORMAT_HYBRID_PTR (offcore_rsp ),
5497
- FORMAT_HYBRID_PTR (ldlat ),
5498
- FORMAT_HYBRID_PTR (frontend ),
5499
- NULL ,
5623
+ ADL_HYBRID_RTM_FORMAT_ATTR ,
5624
+ ADL_HYBRID_FORMAT_ATTR ,
5625
+ NULL
5500
5626
};
5501
5627
5502
5628
static struct attribute * adl_hybrid_extra_attr [] = {
5503
- FORMAT_HYBRID_PTR (offcore_rsp ),
5504
- FORMAT_HYBRID_PTR (ldlat ),
5505
- FORMAT_HYBRID_PTR (frontend ),
5506
- NULL ,
5629
+ ADL_HYBRID_FORMAT_ATTR ,
5630
+ NULL
5631
+ };
5632
+
5633
+ PMU_FORMAT_ATTR_SHOW (snoop_rsp , "config1:0-63" );
5634
+ FORMAT_ATTR_HYBRID (snoop_rsp , hybrid_small );
5635
+
5636
+ static struct attribute * mtl_hybrid_extra_attr_rtm [] = {
5637
+ ADL_HYBRID_RTM_FORMAT_ATTR ,
5638
+ ADL_HYBRID_FORMAT_ATTR ,
5639
+ FORMAT_HYBRID_PTR (snoop_rsp ),
5640
+ NULL
5641
+ };
5642
+
5643
+ static struct attribute * mtl_hybrid_extra_attr [] = {
5644
+ ADL_HYBRID_FORMAT_ATTR ,
5645
+ FORMAT_HYBRID_PTR (snoop_rsp ),
5646
+ NULL
5507
5647
};
5508
5648
5509
5649
static bool is_attr_for_this_pmu (struct kobject * kobj , struct attribute * attr )
@@ -5725,6 +5865,12 @@ static void intel_pmu_check_hybrid_pmus(u64 fixed_mask)
5725
5865
}
5726
5866
}
5727
5867
5868
+ static __always_inline bool is_mtl (u8 x86_model )
5869
+ {
5870
+ return (x86_model == INTEL_FAM6_METEORLAKE ) ||
5871
+ (x86_model == INTEL_FAM6_METEORLAKE_L );
5872
+ }
5873
+
5728
5874
__init int intel_pmu_init (void )
5729
5875
{
5730
5876
struct attribute * * extra_skl_attr = & empty_attrs ;
@@ -6382,6 +6528,8 @@ __init int intel_pmu_init(void)
6382
6528
case INTEL_FAM6_RAPTORLAKE :
6383
6529
case INTEL_FAM6_RAPTORLAKE_P :
6384
6530
case INTEL_FAM6_RAPTORLAKE_S :
6531
+ case INTEL_FAM6_METEORLAKE :
6532
+ case INTEL_FAM6_METEORLAKE_L :
6385
6533
/*
6386
6534
* Alder Lake has 2 types of CPU, core and atom.
6387
6535
*
@@ -6401,9 +6549,7 @@ __init int intel_pmu_init(void)
6401
6549
x86_pmu .flags |= PMU_FL_HAS_RSP_1 ;
6402
6550
x86_pmu .flags |= PMU_FL_NO_HT_SHARING ;
6403
6551
x86_pmu .flags |= PMU_FL_INSTR_LATENCY ;
6404
- x86_pmu .flags |= PMU_FL_MEM_LOADS_AUX ;
6405
6552
x86_pmu .lbr_pt_coexist = true;
6406
- intel_pmu_pebs_data_source_adl ();
6407
6553
x86_pmu .pebs_latency_data = adl_latency_data_small ;
6408
6554
x86_pmu .num_topdown_events = 8 ;
6409
6555
static_call_update (intel_pmu_update_topdown_event ,
@@ -6490,8 +6636,22 @@ __init int intel_pmu_init(void)
6490
6636
pmu -> event_constraints = intel_slm_event_constraints ;
6491
6637
pmu -> pebs_constraints = intel_grt_pebs_event_constraints ;
6492
6638
pmu -> extra_regs = intel_grt_extra_regs ;
6493
- pr_cont ("Alderlake Hybrid events, " );
6494
- name = "alderlake_hybrid" ;
6639
+ if (is_mtl (boot_cpu_data .x86_model )) {
6640
+ x86_pmu .pebs_latency_data = mtl_latency_data_small ;
6641
+ extra_attr = boot_cpu_has (X86_FEATURE_RTM ) ?
6642
+ mtl_hybrid_extra_attr_rtm : mtl_hybrid_extra_attr ;
6643
+ mem_attr = mtl_hybrid_mem_attrs ;
6644
+ intel_pmu_pebs_data_source_mtl ();
6645
+ x86_pmu .get_event_constraints = mtl_get_event_constraints ;
6646
+ pmu -> extra_regs = intel_cmt_extra_regs ;
6647
+ pr_cont ("Meteorlake Hybrid events, " );
6648
+ name = "meteorlake_hybrid" ;
6649
+ } else {
6650
+ x86_pmu .flags |= PMU_FL_MEM_LOADS_AUX ;
6651
+ intel_pmu_pebs_data_source_adl ();
6652
+ pr_cont ("Alderlake Hybrid events, " );
6653
+ name = "alderlake_hybrid" ;
6654
+ }
6495
6655
break ;
6496
6656
6497
6657
default :
@@ -6606,6 +6766,9 @@ __init int intel_pmu_init(void)
6606
6766
if (is_hybrid ())
6607
6767
intel_pmu_check_hybrid_pmus ((u64 )fixed_mask );
6608
6768
6769
+ if (x86_pmu .intel_cap .pebs_timing_info )
6770
+ x86_pmu .flags |= PMU_FL_RETIRE_LATENCY ;
6771
+
6609
6772
intel_aux_output_init ();
6610
6773
6611
6774
return 0 ;
0 commit comments