@@ -63,6 +63,15 @@ union intel_x86_pebs_dse {
63
63
unsigned int mtl_fwd_blk :1 ;
64
64
unsigned int ld_reserved4 :24 ;
65
65
};
66
+ struct {
67
+ unsigned int lnc_dse :8 ;
68
+ unsigned int ld_reserved5 :2 ;
69
+ unsigned int lnc_stlb_miss :1 ;
70
+ unsigned int lnc_locked :1 ;
71
+ unsigned int lnc_data_blk :1 ;
72
+ unsigned int lnc_addr_blk :1 ;
73
+ unsigned int ld_reserved6 :18 ;
74
+ };
66
75
};
67
76
68
77
@@ -77,7 +86,7 @@ union intel_x86_pebs_dse {
77
86
#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
78
87
79
88
/* Version for Sandy Bridge and later */
80
- static u64 pebs_data_source [] = {
89
+ static u64 pebs_data_source [PERF_PEBS_DATA_SOURCE_MAX ] = {
81
90
P (OP , LOAD ) | P (LVL , MISS ) | LEVEL (L3 ) | P (SNOOP , NA ),/* 0x00:ukn L3 */
82
91
OP_LH | P (LVL , L1 ) | LEVEL (L1 ) | P (SNOOP , NONE ), /* 0x01: L1 local */
83
92
OP_LH | P (LVL , LFB ) | LEVEL (LFB ) | P (SNOOP , NONE ), /* 0x02: LFB hit */
@@ -173,6 +182,40 @@ void __init intel_pmu_pebs_data_source_cmt(void)
173
182
__intel_pmu_pebs_data_source_cmt (pebs_data_source );
174
183
}
175
184
185
+ /* Version for Lion Cove and later */
186
+ static u64 lnc_pebs_data_source [PERF_PEBS_DATA_SOURCE_MAX ] = {
187
+ P (OP , LOAD ) | P (LVL , MISS ) | LEVEL (L3 ) | P (SNOOP , NA ), /* 0x00: ukn L3 */
188
+ OP_LH | P (LVL , L1 ) | LEVEL (L1 ) | P (SNOOP , NONE ), /* 0x01: L1 hit */
189
+ OP_LH | P (LVL , L1 ) | LEVEL (L1 ) | P (SNOOP , NONE ), /* 0x02: L1 hit */
190
+ OP_LH | P (LVL , LFB ) | LEVEL (LFB ) | P (SNOOP , NONE ), /* 0x03: LFB/L1 Miss Handling Buffer hit */
191
+ 0 , /* 0x04: Reserved */
192
+ OP_LH | P (LVL , L2 ) | LEVEL (L2 ) | P (SNOOP , NONE ), /* 0x05: L2 Hit */
193
+ OP_LH | LEVEL (L2_MHB ) | P (SNOOP , NONE ), /* 0x06: L2 Miss Handling Buffer Hit */
194
+ 0 , /* 0x07: Reserved */
195
+ OP_LH | P (LVL , L3 ) | LEVEL (L3 ) | P (SNOOP , NONE ), /* 0x08: L3 Hit */
196
+ 0 , /* 0x09: Reserved */
197
+ 0 , /* 0x0a: Reserved */
198
+ 0 , /* 0x0b: Reserved */
199
+ OP_LH | P (LVL , L3 ) | LEVEL (L3 ) | P (SNOOPX , FWD ), /* 0x0c: L3 Hit Snoop Fwd */
200
+ OP_LH | P (LVL , L3 ) | LEVEL (L3 ) | P (SNOOP , HITM ), /* 0x0d: L3 Hit Snoop HitM */
201
+ 0 , /* 0x0e: Reserved */
202
+ P (OP , LOAD ) | P (LVL , MISS ) | P (LVL , L3 ) | LEVEL (L3 ) | P (SNOOP , HITM ), /* 0x0f: L3 Miss Snoop HitM */
203
+ OP_LH | LEVEL (MSC ) | P (SNOOP , NONE ), /* 0x10: Memory-side Cache Hit */
204
+ OP_LH | P (LVL , LOC_RAM ) | LEVEL (RAM ) | P (SNOOP , NONE ), /* 0x11: Local Memory Hit */
205
+ };
206
+
207
+ void __init intel_pmu_pebs_data_source_lnl (void )
208
+ {
209
+ u64 * data_source ;
210
+
211
+ data_source = x86_pmu .hybrid_pmu [X86_HYBRID_PMU_CORE_IDX ].pebs_data_source ;
212
+ memcpy (data_source , lnc_pebs_data_source , sizeof (lnc_pebs_data_source ));
213
+
214
+ data_source = x86_pmu .hybrid_pmu [X86_HYBRID_PMU_ATOM_IDX ].pebs_data_source ;
215
+ memcpy (data_source , pebs_data_source , sizeof (pebs_data_source ));
216
+ __intel_pmu_pebs_data_source_cmt (data_source );
217
+ }
218
+
176
219
static u64 precise_store_data (u64 status )
177
220
{
178
221
union intel_x86_pebs_dse dse ;
@@ -264,7 +307,7 @@ static u64 __grt_latency_data(struct perf_event *event, u64 status,
264
307
265
308
WARN_ON_ONCE (hybrid_pmu (event -> pmu )-> pmu_type == hybrid_big );
266
309
267
- dse &= PERF_PEBS_DATA_SOURCE_MASK ;
310
+ dse &= PERF_PEBS_DATA_SOURCE_GRT_MASK ;
268
311
val = hybrid_var (event -> pmu , pebs_data_source )[dse ];
269
312
270
313
pebs_set_tlb_lock (& val , tlb , lock );
@@ -300,6 +343,51 @@ u64 cmt_latency_data(struct perf_event *event, u64 status)
300
343
dse .mtl_fwd_blk );
301
344
}
302
345
346
+ static u64 lnc_latency_data (struct perf_event * event , u64 status )
347
+ {
348
+ union intel_x86_pebs_dse dse ;
349
+ union perf_mem_data_src src ;
350
+ u64 val ;
351
+
352
+ dse .val = status ;
353
+
354
+ /* LNC core latency data */
355
+ val = hybrid_var (event -> pmu , pebs_data_source )[status & PERF_PEBS_DATA_SOURCE_MASK ];
356
+ if (!val )
357
+ val = P (OP , LOAD ) | LEVEL (NA ) | P (SNOOP , NA );
358
+
359
+ if (dse .lnc_stlb_miss )
360
+ val |= P (TLB , MISS ) | P (TLB , L2 );
361
+ else
362
+ val |= P (TLB , HIT ) | P (TLB , L1 ) | P (TLB , L2 );
363
+
364
+ if (dse .lnc_locked )
365
+ val |= P (LOCK , LOCKED );
366
+
367
+ if (dse .lnc_data_blk )
368
+ val |= P (BLK , DATA );
369
+ if (dse .lnc_addr_blk )
370
+ val |= P (BLK , ADDR );
371
+ if (!dse .lnc_data_blk && !dse .lnc_addr_blk )
372
+ val |= P (BLK , NA );
373
+
374
+ src .val = val ;
375
+ if (event -> hw .flags & PERF_X86_EVENT_PEBS_ST_HSW )
376
+ src .mem_op = P (OP , STORE );
377
+
378
+ return src .val ;
379
+ }
380
+
381
+ u64 lnl_latency_data (struct perf_event * event , u64 status )
382
+ {
383
+ struct x86_hybrid_pmu * pmu = hybrid_pmu (event -> pmu );
384
+
385
+ if (pmu -> pmu_type == hybrid_small )
386
+ return cmt_latency_data (event , status );
387
+
388
+ return lnc_latency_data (event , status );
389
+ }
390
+
303
391
static u64 load_latency_data (struct perf_event * event , u64 status )
304
392
{
305
393
union intel_x86_pebs_dse dse ;
@@ -1090,6 +1178,8 @@ struct event_constraint intel_lnc_pebs_event_constraints[] = {
1090
1178
INTEL_FLAGS_UEVENT_CONSTRAINT (0x100 , 0x100000000ULL ), /* INST_RETIRED.PREC_DIST */
1091
1179
INTEL_FLAGS_UEVENT_CONSTRAINT (0x0400 , 0x800000000ULL ),
1092
1180
1181
+ INTEL_HYBRID_LDLAT_CONSTRAINT (0x1cd , 0x3ff ),
1182
+ INTEL_HYBRID_STLAT_CONSTRAINT (0x2cd , 0x3 ),
1093
1183
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD (0x11d0 , 0xf ), /* MEM_INST_RETIRED.STLB_MISS_LOADS */
1094
1184
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST (0x12d0 , 0xf ), /* MEM_INST_RETIRED.STLB_MISS_STORES */
1095
1185
INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD (0x21d0 , 0xf ), /* MEM_INST_RETIRED.LOCK_LOADS */
0 commit comments