@@ -237,7 +237,7 @@ void intel_pmu_lbr_reset_64(void)
237
237
wrmsrl (x86_pmu .lbr_from + i , 0 );
238
238
wrmsrl (x86_pmu .lbr_to + i , 0 );
239
239
if (x86_pmu .intel_cap .lbr_format == LBR_FORMAT_INFO )
240
- wrmsrl (MSR_LBR_INFO_0 + i , 0 );
240
+ wrmsrl (x86_pmu . lbr_info + i , 0 );
241
241
}
242
242
}
243
243
@@ -343,6 +343,11 @@ static __always_inline void wrlbr_to(unsigned int idx, u64 val)
343
343
wrmsrl (x86_pmu .lbr_to + idx , val );
344
344
}
345
345
346
+ static __always_inline void wrlbr_info (unsigned int idx , u64 val )
347
+ {
348
+ wrmsrl (x86_pmu .lbr_info + idx , val );
349
+ }
350
+
346
351
static __always_inline u64 rdlbr_from (unsigned int idx )
347
352
{
348
353
u64 val ;
@@ -361,8 +366,44 @@ static __always_inline u64 rdlbr_to(unsigned int idx)
361
366
return val ;
362
367
}
363
368
369
+ static __always_inline u64 rdlbr_info (unsigned int idx )
370
+ {
371
+ u64 val ;
372
+
373
+ rdmsrl (x86_pmu .lbr_info + idx , val );
374
+
375
+ return val ;
376
+ }
377
+
378
+ static inline void
379
+ wrlbr_all (struct lbr_entry * lbr , unsigned int idx , bool need_info )
380
+ {
381
+ wrlbr_from (idx , lbr -> from );
382
+ wrlbr_to (idx , lbr -> to );
383
+ if (need_info )
384
+ wrlbr_info (idx , lbr -> info );
385
+ }
386
+
387
+ static inline bool
388
+ rdlbr_all (struct lbr_entry * lbr , unsigned int idx , bool need_info )
389
+ {
390
+ u64 from = rdlbr_from (idx );
391
+
392
+ /* Don't read invalid entry */
393
+ if (!from )
394
+ return false;
395
+
396
+ lbr -> from = from ;
397
+ lbr -> to = rdlbr_to (idx );
398
+ if (need_info )
399
+ lbr -> info = rdlbr_info (idx );
400
+
401
+ return true;
402
+ }
403
+
364
404
void intel_pmu_lbr_restore (void * ctx )
365
405
{
406
+ bool need_info = x86_pmu .intel_cap .lbr_format == LBR_FORMAT_INFO ;
366
407
struct cpu_hw_events * cpuc = this_cpu_ptr (& cpu_hw_events );
367
408
struct x86_perf_task_context * task_ctx = ctx ;
368
409
int i ;
@@ -372,19 +413,15 @@ void intel_pmu_lbr_restore(void *ctx)
372
413
mask = x86_pmu .lbr_nr - 1 ;
373
414
for (i = 0 ; i < task_ctx -> valid_lbrs ; i ++ ) {
374
415
lbr_idx = (tos - i ) & mask ;
375
- wrlbr_from (lbr_idx , task_ctx -> lbr [i ].from );
376
- wrlbr_to (lbr_idx , task_ctx -> lbr [i ].to );
377
-
378
- if (x86_pmu .intel_cap .lbr_format == LBR_FORMAT_INFO )
379
- wrmsrl (MSR_LBR_INFO_0 + lbr_idx , task_ctx -> lbr [i ].info );
416
+ wrlbr_all (& task_ctx -> lbr [i ], lbr_idx , need_info );
380
417
}
381
418
382
419
for (; i < x86_pmu .lbr_nr ; i ++ ) {
383
420
lbr_idx = (tos - i ) & mask ;
384
421
wrlbr_from (lbr_idx , 0 );
385
422
wrlbr_to (lbr_idx , 0 );
386
423
if (x86_pmu .intel_cap .lbr_format == LBR_FORMAT_INFO )
387
- wrmsrl ( MSR_LBR_INFO_0 + lbr_idx , 0 );
424
+ wrlbr_info ( lbr_idx , 0 );
388
425
}
389
426
390
427
wrmsrl (x86_pmu .lbr_tos , tos );
@@ -427,23 +464,19 @@ static void __intel_pmu_lbr_restore(void *ctx)
427
464
428
465
void intel_pmu_lbr_save (void * ctx )
429
466
{
467
+ bool need_info = x86_pmu .intel_cap .lbr_format == LBR_FORMAT_INFO ;
430
468
struct cpu_hw_events * cpuc = this_cpu_ptr (& cpu_hw_events );
431
469
struct x86_perf_task_context * task_ctx = ctx ;
432
470
unsigned lbr_idx , mask ;
433
- u64 tos , from ;
471
+ u64 tos ;
434
472
int i ;
435
473
436
474
mask = x86_pmu .lbr_nr - 1 ;
437
475
tos = intel_pmu_lbr_tos ();
438
476
for (i = 0 ; i < x86_pmu .lbr_nr ; i ++ ) {
439
477
lbr_idx = (tos - i ) & mask ;
440
- from = rdlbr_from (lbr_idx );
441
- if (!from )
478
+ if (!rdlbr_all (& task_ctx -> lbr [i ], lbr_idx , need_info ))
442
479
break ;
443
- task_ctx -> lbr [i ].from = from ;
444
- task_ctx -> lbr [i ].to = rdlbr_to (lbr_idx );
445
- if (x86_pmu .intel_cap .lbr_format == LBR_FORMAT_INFO )
446
- rdmsrl (MSR_LBR_INFO_0 + lbr_idx , task_ctx -> lbr [i ].info );
447
480
}
448
481
task_ctx -> valid_lbrs = i ;
449
482
task_ctx -> tos = tos ;
@@ -689,7 +722,7 @@ void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
689
722
if (lbr_format == LBR_FORMAT_INFO && need_info ) {
690
723
u64 info ;
691
724
692
- rdmsrl ( MSR_LBR_INFO_0 + lbr_idx , info );
725
+ info = rdlbr_info ( lbr_idx );
693
726
mis = !!(info & LBR_INFO_MISPRED );
694
727
pred = !mis ;
695
728
in_tx = !!(info & LBR_INFO_IN_TX );
@@ -1336,6 +1369,7 @@ __init void intel_pmu_lbr_init_skl(void)
1336
1369
x86_pmu .lbr_tos = MSR_LBR_TOS ;
1337
1370
x86_pmu .lbr_from = MSR_LBR_NHM_FROM ;
1338
1371
x86_pmu .lbr_to = MSR_LBR_NHM_TO ;
1372
+ x86_pmu .lbr_info = MSR_LBR_INFO_0 ;
1339
1373
1340
1374
x86_pmu .lbr_sel_mask = LBR_SEL_MASK ;
1341
1375
x86_pmu .lbr_sel_map = hsw_lbr_sel_map ;
@@ -1421,7 +1455,7 @@ int x86_perf_get_lbr(struct x86_pmu_lbr *lbr)
1421
1455
lbr -> nr = x86_pmu .lbr_nr ;
1422
1456
lbr -> from = x86_pmu .lbr_from ;
1423
1457
lbr -> to = x86_pmu .lbr_to ;
1424
- lbr -> info = (lbr_fmt == LBR_FORMAT_INFO ) ? MSR_LBR_INFO_0 : 0 ;
1458
+ lbr -> info = (lbr_fmt == LBR_FORMAT_INFO ) ? x86_pmu . lbr_info : 0 ;
1425
1459
1426
1460
return 0 ;
1427
1461
}
0 commit comments