linux/arch/x86/events/intel
Stephane Eranian 11745ecfe8 perf/x86/intel/uncore: Fix broken read_counter() for SNB IMC PMU
Existing code was generating bogus counts for the SNB IMC bandwidth counters:

$ perf stat -a -I 1000 -e uncore_imc/data_reads/,uncore_imc/data_writes/
     1.000327813           1,024.03 MiB  uncore_imc/data_reads/
     1.000327813              20.73 MiB  uncore_imc/data_writes/
     2.000580153         261,120.00 MiB  uncore_imc/data_reads/
     2.000580153              23.28 MiB  uncore_imc/data_writes/

The problem was introduced by commit:
  07ce734dd8 ("perf/x86/intel/uncore: Clean up client IMC")

Where the read_counter callback was replace to point to the generic
uncore_mmio_read_counter() function.

The SNB IMC counters are freerunnig 32-bit counters laid out contiguously in
MMIO. But uncore_mmio_read_counter() is using a readq() call to read from
MMIO therefore reading 64-bit from MMIO. Although this is okay for the
uncore_perf_event_update() function because it is shifting the value based
on the actual counter width to compute a delta, it is not okay for the
uncore_pmu_event_start() which is simply reading the counter  and therefore
priming the event->prev_count with a bogus value which is responsible for
causing bogus deltas in the perf stat command above.

The fix is to reintroduce the custom callback for read_counter for the SNB
IMC PMU and use readl() instead of readq(). With the change the output of
perf stat is back to normal:
$ perf stat -a -I 1000 -e uncore_imc/data_reads/,uncore_imc/data_writes/
     1.000120987             296.94 MiB  uncore_imc/data_reads/
     1.000120987             138.42 MiB  uncore_imc/data_writes/
     2.000403144             175.91 MiB  uncore_imc/data_reads/
     2.000403144              68.50 MiB  uncore_imc/data_writes/

Fixes: 07ce734dd8 ("perf/x86/intel/uncore: Clean up client IMC")
Signed-off-by: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
Link: https://lore.kernel.org/r/20220803160031.1379788-1-eranian@google.com
2022-08-27 00:05:38 +02:00
..
bts.c perf/x86: Add compiler barrier after updating BTS 2021-09-17 15:08:38 +02:00
core.c perf/x86/core: Set pebs_capable and PMU_FL_PEBS_ALL for the Baseline 2022-08-19 19:47:31 +02:00
cstate.c perf/x86/cstate: Add new Alder Lake and Raptor Lake support 2022-05-11 16:27:08 +02:00
ds.c perf/x86/intel: Fix pebs event constraints for ADL 2022-08-19 19:47:31 +02:00
knc.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
lbr.c perf/x86/lbr: Enable the branch type for the Arch LBR by default 2022-08-19 19:47:30 +02:00
Makefile perf/x86/intel/uncore: Parse uncore discovery tables 2021-04-02 10:04:54 +02:00
p4.c Perf events changes in this cycle were: 2021-04-28 13:03:44 -07:00
p6.c x86/cpu: Rename cpu_data.x86_mask to cpu_data.x86_stepping 2018-02-15 01:15:52 +01:00
pt.c Changes for this cycle were: 2022-03-22 13:06:49 -07:00
pt.h perf/x86/intel/pt: Prevent redundant WRMSRs 2019-11-13 11:06:18 +01:00
uncore_discovery.c perf/x86/intel/uncore: Fix the build on !CONFIG_PHYS_ADDR_T_64BIT 2022-03-03 08:58:22 +01:00
uncore_discovery.h perf/x86/intel/uncore: Make uncore_discovery clean for 64 bit addresses 2022-03-01 16:19:01 +01:00
uncore_nhmex.c perf/x86/intel/uncore: Correct fixed counter index check for NHM 2018-05-31 12:36:28 +02:00
uncore_snb.c perf/x86/intel/uncore: Fix broken read_counter() for SNB IMC PMU 2022-08-27 00:05:38 +02:00
uncore_snbep.c perf/x86/intel/uncore: Fix CAS_COUNT_WRITE issue for ICX 2022-01-18 12:09:48 +01:00
uncore.c perf/x86/uncore: Add new Alder Lake and Raptor Lake support 2022-05-11 16:27:09 +02:00
uncore.h perf/x86/intel/uncore: Add IMC uncore support for ADL 2022-01-18 12:09:49 +01:00