Skip to content

Commit 8041ffd

Browse files
Kan LiangIngo Molnar
authored andcommitted
perf/x86/intel/uncore: Fix client IMC events return huge result
The client IMC bandwidth events currently return very large values: $ perf stat -e uncore_imc/data_reads/ -e uncore_imc/data_writes/ -I 10000 -a 10.000117222 34,788.76 MiB uncore_imc/data_reads/ 10.000117222 8.26 MiB uncore_imc/data_writes/ 20.000374584 34,842.89 MiB uncore_imc/data_reads/ 20.000374584 10.45 MiB uncore_imc/data_writes/ 30.000633299 37,965.29 MiB uncore_imc/data_reads/ 30.000633299 323.62 MiB uncore_imc/data_writes/ 40.000891548 41,012.88 MiB uncore_imc/data_reads/ 40.000891548 6.98 MiB uncore_imc/data_writes/ 50.001142480 1,125,899,906,621,494.75 MiB uncore_imc/data_reads/ 50.001142480 6.97 MiB uncore_imc/data_writes/ The client IMC events are freerunning counters. They still use the old event encoding format (0x1 for data_read and 0x2 for data write). The counter bit width is calculated by common code, which assume that the standard encoding format is used for the freerunning counters. Error bit width information is calculated. The patch intends to convert the old client IMC event encoding to the standard encoding format. Current common code uses event->attr.config which directly copy from user space. We should not implicitly modify it for a converted event. The event->hw.config is used to replace the event->attr.config in common code. For client IMC events, the event->attr.config is used to calculate a converted event with standard encoding format in the custom event_init(). The converted event is stored in event->hw.config. For other events of freerunning counters, they already use the standard encoding format. The same value as event->attr.config is assigned to event->hw.config in common event_init(). Reported-by: Jin Yao <[email protected]> Tested-by: Jin Yao <[email protected]> Signed-off-by: Kan Liang <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vince Weaver <[email protected]> Cc: [email protected] # v4.18+ Fixes: 9aae178 ("perf/x86/intel/uncore: Clean up client IMC uncore") Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 5768402 commit 8041ffd

File tree

3 files changed

+10
-7
lines changed

3 files changed

+10
-7
lines changed

arch/x86/events/intel/uncore.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@ static int uncore_pmu_event_init(struct perf_event *event)
732732
/* fixed counters have event field hardcoded to zero */
733733
hwc->config = 0ULL;
734734
} else if (is_freerunning_event(event)) {
735+
hwc->config = event->attr.config;
735736
if (!check_valid_freerunning_event(box, event))
736737
return -EINVAL;
737738
event->hw.idx = UNCORE_PMC_IDX_FREERUNNING;

arch/x86/events/intel/uncore.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ static inline
292292
unsigned int uncore_freerunning_counter(struct intel_uncore_box *box,
293293
struct perf_event *event)
294294
{
295-
unsigned int type = uncore_freerunning_type(event->attr.config);
296-
unsigned int idx = uncore_freerunning_idx(event->attr.config);
295+
unsigned int type = uncore_freerunning_type(event->hw.config);
296+
unsigned int idx = uncore_freerunning_idx(event->hw.config);
297297
struct intel_uncore_pmu *pmu = box->pmu;
298298

299299
return pmu->type->freerunning[type].counter_base +
@@ -377,15 +377,15 @@ static inline
377377
unsigned int uncore_freerunning_bits(struct intel_uncore_box *box,
378378
struct perf_event *event)
379379
{
380-
unsigned int type = uncore_freerunning_type(event->attr.config);
380+
unsigned int type = uncore_freerunning_type(event->hw.config);
381381

382382
return box->pmu->type->freerunning[type].bits;
383383
}
384384

385385
static inline int uncore_num_freerunning(struct intel_uncore_box *box,
386386
struct perf_event *event)
387387
{
388-
unsigned int type = uncore_freerunning_type(event->attr.config);
388+
unsigned int type = uncore_freerunning_type(event->hw.config);
389389

390390
return box->pmu->type->freerunning[type].num_counters;
391391
}
@@ -399,8 +399,8 @@ static inline int uncore_num_freerunning_types(struct intel_uncore_box *box,
399399
static inline bool check_valid_freerunning_event(struct intel_uncore_box *box,
400400
struct perf_event *event)
401401
{
402-
unsigned int type = uncore_freerunning_type(event->attr.config);
403-
unsigned int idx = uncore_freerunning_idx(event->attr.config);
402+
unsigned int type = uncore_freerunning_type(event->hw.config);
403+
unsigned int idx = uncore_freerunning_idx(event->hw.config);
404404

405405
return (type < uncore_num_freerunning_types(box, event)) &&
406406
(idx < uncore_num_freerunning(box, event));

arch/x86/events/intel/uncore_snb.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,11 @@ static int snb_uncore_imc_event_init(struct perf_event *event)
442442

443443
/* must be done before validate_group */
444444
event->hw.event_base = base;
445-
event->hw.config = cfg;
446445
event->hw.idx = idx;
447446

447+
/* Convert to standard encoding format for freerunning counters */
448+
event->hw.config = ((cfg - 1) << 8) | 0x10ff;
449+
448450
/* no group validation needed, we have free running counters */
449451

450452
return 0;

0 commit comments

Comments
 (0)