@@ -4598,6 +4598,28 @@ static inline bool erratum_hsw11(struct perf_event *event)
4598
4598
X86_CONFIG (.event = 0xc0 , .umask = 0x01 );
4599
4599
}
4600
4600
4601
+ static struct event_constraint *
4602
+ arl_h_get_event_constraints (struct cpu_hw_events * cpuc , int idx ,
4603
+ struct perf_event * event )
4604
+ {
4605
+ struct x86_hybrid_pmu * pmu = hybrid_pmu (event -> pmu );
4606
+
4607
+ if (pmu -> pmu_type == hybrid_tiny )
4608
+ return cmt_get_event_constraints (cpuc , idx , event );
4609
+
4610
+ return mtl_get_event_constraints (cpuc , idx , event );
4611
+ }
4612
+
4613
+ static int arl_h_hw_config (struct perf_event * event )
4614
+ {
4615
+ struct x86_hybrid_pmu * pmu = hybrid_pmu (event -> pmu );
4616
+
4617
+ if (pmu -> pmu_type == hybrid_tiny )
4618
+ return intel_pmu_hw_config (event );
4619
+
4620
+ return adl_hw_config (event );
4621
+ }
4622
+
4601
4623
/*
4602
4624
* The HSW11 requires a period larger than 100 which is the same as the BDM11.
4603
4625
* A minimum period of 128 is enforced as well for the INST_RETIRED.ALL.
@@ -4923,17 +4945,26 @@ static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void)
4923
4945
4924
4946
/*
4925
4947
* This essentially just maps between the 'hybrid_cpu_type'
4926
- * and 'hybrid_pmu_type' enums:
4948
+ * and 'hybrid_pmu_type' enums except for ARL-H processor
4949
+ * which needs to compare atom uarch native id since ARL-H
4950
+ * contains two different atom uarchs.
4927
4951
*/
4928
4952
for (i = 0 ; i < x86_pmu .num_hybrid_pmus ; i ++ ) {
4929
4953
enum hybrid_pmu_type pmu_type = x86_pmu .hybrid_pmu [i ].pmu_type ;
4954
+ u32 native_id ;
4930
4955
4931
- if (cpu_type == HYBRID_INTEL_CORE &&
4932
- pmu_type == hybrid_big )
4933
- return & x86_pmu .hybrid_pmu [i ];
4934
- if (cpu_type == HYBRID_INTEL_ATOM &&
4935
- pmu_type == hybrid_small )
4956
+ if (cpu_type == HYBRID_INTEL_CORE && pmu_type == hybrid_big )
4936
4957
return & x86_pmu .hybrid_pmu [i ];
4958
+ if (cpu_type == HYBRID_INTEL_ATOM ) {
4959
+ if (x86_pmu .num_hybrid_pmus == 2 && pmu_type == hybrid_small )
4960
+ return & x86_pmu .hybrid_pmu [i ];
4961
+
4962
+ native_id = get_this_hybrid_cpu_native_id ();
4963
+ if (native_id == skt_native_id && pmu_type == hybrid_small )
4964
+ return & x86_pmu .hybrid_pmu [i ];
4965
+ if (native_id == cmt_native_id && pmu_type == hybrid_tiny )
4966
+ return & x86_pmu .hybrid_pmu [i ];
4967
+ }
4937
4968
}
4938
4969
4939
4970
return NULL ;
@@ -5971,6 +6002,37 @@ static struct attribute *lnl_hybrid_events_attrs[] = {
5971
6002
NULL
5972
6003
};
5973
6004
6005
+ /* The event string must be in PMU IDX order. */
6006
+ EVENT_ATTR_STR_HYBRID (topdown - retiring ,
6007
+ td_retiring_arl_h ,
6008
+ "event=0xc2,umask=0x02;event=0x00,umask=0x80;event=0xc2,umask=0x0" ,
6009
+ hybrid_big_small_tiny );
6010
+ EVENT_ATTR_STR_HYBRID (topdown - bad - spec ,
6011
+ td_bad_spec_arl_h ,
6012
+ "event=0x73,umask=0x0;event=0x00,umask=0x81;event=0x73,umask=0x0" ,
6013
+ hybrid_big_small_tiny );
6014
+ EVENT_ATTR_STR_HYBRID (topdown - fe - bound ,
6015
+ td_fe_bound_arl_h ,
6016
+ "event=0x9c,umask=0x01;event=0x00,umask=0x82;event=0x71,umask=0x0" ,
6017
+ hybrid_big_small_tiny );
6018
+ EVENT_ATTR_STR_HYBRID (topdown - be - bound ,
6019
+ td_be_bound_arl_h ,
6020
+ "event=0xa4,umask=0x02;event=0x00,umask=0x83;event=0x74,umask=0x0" ,
6021
+ hybrid_big_small_tiny );
6022
+
6023
+ static struct attribute * arl_h_hybrid_events_attrs [] = {
6024
+ EVENT_PTR (slots_adl ),
6025
+ EVENT_PTR (td_retiring_arl_h ),
6026
+ EVENT_PTR (td_bad_spec_arl_h ),
6027
+ EVENT_PTR (td_fe_bound_arl_h ),
6028
+ EVENT_PTR (td_be_bound_arl_h ),
6029
+ EVENT_PTR (td_heavy_ops_adl ),
6030
+ EVENT_PTR (td_br_mis_adl ),
6031
+ EVENT_PTR (td_fetch_lat_adl ),
6032
+ EVENT_PTR (td_mem_bound_adl ),
6033
+ NULL ,
6034
+ };
6035
+
5974
6036
/* Must be in IDX order */
5975
6037
EVENT_ATTR_STR_HYBRID (mem - loads , mem_ld_adl , "event=0xd0,umask=0x5,ldlat=3;event=0xcd,umask=0x1,ldlat=3" , hybrid_big_small );
5976
6038
EVENT_ATTR_STR_HYBRID (mem - stores , mem_st_adl , "event=0xd0,umask=0x6;event=0xcd,umask=0x2" , hybrid_big_small );
@@ -5989,6 +6051,21 @@ static struct attribute *mtl_hybrid_mem_attrs[] = {
5989
6051
NULL
5990
6052
};
5991
6053
6054
+ EVENT_ATTR_STR_HYBRID (mem - loads ,
6055
+ mem_ld_arl_h ,
6056
+ "event=0xd0,umask=0x5,ldlat=3;event=0xcd,umask=0x1,ldlat=3;event=0xd0,umask=0x5,ldlat=3" ,
6057
+ hybrid_big_small_tiny );
6058
+ EVENT_ATTR_STR_HYBRID (mem - stores ,
6059
+ mem_st_arl_h ,
6060
+ "event=0xd0,umask=0x6;event=0xcd,umask=0x2;event=0xd0,umask=0x6" ,
6061
+ hybrid_big_small_tiny );
6062
+
6063
+ static struct attribute * arl_h_hybrid_mem_attrs [] = {
6064
+ EVENT_PTR (mem_ld_arl_h ),
6065
+ EVENT_PTR (mem_st_arl_h ),
6066
+ NULL ,
6067
+ };
6068
+
5992
6069
EVENT_ATTR_STR_HYBRID (tx - start , tx_start_adl , "event=0xc9,umask=0x1" , hybrid_big );
5993
6070
EVENT_ATTR_STR_HYBRID (tx - commit , tx_commit_adl , "event=0xc9,umask=0x2" , hybrid_big );
5994
6071
EVENT_ATTR_STR_HYBRID (tx - abort , tx_abort_adl , "event=0xc9,umask=0x4" , hybrid_big );
@@ -6012,8 +6089,8 @@ static struct attribute *adl_hybrid_tsx_attrs[] = {
6012
6089
6013
6090
FORMAT_ATTR_HYBRID (in_tx , hybrid_big );
6014
6091
FORMAT_ATTR_HYBRID (in_tx_cp , hybrid_big );
6015
- FORMAT_ATTR_HYBRID (offcore_rsp , hybrid_big_small );
6016
- FORMAT_ATTR_HYBRID (ldlat , hybrid_big_small );
6092
+ FORMAT_ATTR_HYBRID (offcore_rsp , hybrid_big_small_tiny );
6093
+ FORMAT_ATTR_HYBRID (ldlat , hybrid_big_small_tiny );
6017
6094
FORMAT_ATTR_HYBRID (frontend , hybrid_big );
6018
6095
6019
6096
#define ADL_HYBRID_RTM_FORMAT_ATTR \
@@ -6036,7 +6113,7 @@ static struct attribute *adl_hybrid_extra_attr[] = {
6036
6113
NULL
6037
6114
};
6038
6115
6039
- FORMAT_ATTR_HYBRID (snoop_rsp , hybrid_small );
6116
+ FORMAT_ATTR_HYBRID (snoop_rsp , hybrid_small_tiny );
6040
6117
6041
6118
static struct attribute * mtl_hybrid_extra_attr_rtm [] = {
6042
6119
ADL_HYBRID_RTM_FORMAT_ATTR ,
@@ -6244,8 +6321,9 @@ static inline int intel_pmu_v6_addr_offset(int index, bool eventsel)
6244
6321
}
6245
6322
6246
6323
static const struct { enum hybrid_pmu_type id ; char * name ; } intel_hybrid_pmu_type_map [] __initconst = {
6247
- { hybrid_small , "cpu_atom" },
6248
- { hybrid_big , "cpu_core" },
6324
+ { hybrid_small , "cpu_atom" },
6325
+ { hybrid_big , "cpu_core" },
6326
+ { hybrid_tiny , "cpu_lowpower" },
6249
6327
};
6250
6328
6251
6329
static __always_inline int intel_pmu_init_hybrid (enum hybrid_pmu_type pmus )
@@ -6278,7 +6356,7 @@ static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus)
6278
6356
0 , x86_pmu_num_counters (& pmu -> pmu ), 0 , 0 );
6279
6357
6280
6358
pmu -> intel_cap .capabilities = x86_pmu .intel_cap .capabilities ;
6281
- if (pmu -> pmu_type & hybrid_small ) {
6359
+ if (pmu -> pmu_type & hybrid_small_tiny ) {
6282
6360
pmu -> intel_cap .perf_metrics = 0 ;
6283
6361
pmu -> intel_cap .pebs_output_pt_available = 1 ;
6284
6362
pmu -> mid_ack = true;
@@ -7118,6 +7196,37 @@ __init int intel_pmu_init(void)
7118
7196
name = "lunarlake_hybrid" ;
7119
7197
break ;
7120
7198
7199
+ case INTEL_ARROWLAKE_H :
7200
+ intel_pmu_init_hybrid (hybrid_big_small_tiny );
7201
+
7202
+ x86_pmu .pebs_latency_data = arl_h_latency_data ;
7203
+ x86_pmu .get_event_constraints = arl_h_get_event_constraints ;
7204
+ x86_pmu .hw_config = arl_h_hw_config ;
7205
+
7206
+ td_attr = arl_h_hybrid_events_attrs ;
7207
+ mem_attr = arl_h_hybrid_mem_attrs ;
7208
+ tsx_attr = adl_hybrid_tsx_attrs ;
7209
+ extra_attr = boot_cpu_has (X86_FEATURE_RTM ) ?
7210
+ mtl_hybrid_extra_attr_rtm : mtl_hybrid_extra_attr ;
7211
+
7212
+ /* Initialize big core specific PerfMon capabilities. */
7213
+ pmu = & x86_pmu .hybrid_pmu [X86_HYBRID_PMU_CORE_IDX ];
7214
+ intel_pmu_init_lnc (& pmu -> pmu );
7215
+
7216
+ /* Initialize Atom core specific PerfMon capabilities. */
7217
+ pmu = & x86_pmu .hybrid_pmu [X86_HYBRID_PMU_ATOM_IDX ];
7218
+ intel_pmu_init_skt (& pmu -> pmu );
7219
+
7220
+ /* Initialize Lower Power Atom specific PerfMon capabilities. */
7221
+ pmu = & x86_pmu .hybrid_pmu [X86_HYBRID_PMU_TINY_IDX ];
7222
+ intel_pmu_init_grt (& pmu -> pmu );
7223
+ pmu -> extra_regs = intel_cmt_extra_regs ;
7224
+
7225
+ intel_pmu_pebs_data_source_arl_h ();
7226
+ pr_cont ("ArrowLake-H Hybrid events, " );
7227
+ name = "arrowlake_h_hybrid" ;
7228
+ break ;
7229
+
7121
7230
default :
7122
7231
switch (x86_pmu .version ) {
7123
7232
case 1 :
0 commit comments