]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
perf/x86/intel/uncore: Fix client IMC events return huge result
authorKan Liang <kan.liang@linux.intel.com>
Wed, 27 Feb 2019 16:57:29 +0000 (08:57 -0800)
committerIngo Molnar <mingo@kernel.org>
Sat, 9 Mar 2019 13:10:31 +0000 (14:10 +0100)
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 <yao.jin@linux.intel.com>
Tested-by: Jin Yao <yao.jin@linux.intel.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: stable@kernel.org # v4.18+
Fixes: 9aae1780e7e8 ("perf/x86/intel/uncore: Clean up client IMC uncore")
Link: https://lkml.kernel.org/r/20190227165729.1861-1-kan.liang@linux.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/events/intel/uncore.c
arch/x86/events/intel/uncore.h
arch/x86/events/intel/uncore_snb.c

index d516161c00c4710ed401ce3e148e7de73548824c..9fe64c01a2e5a9572386352669e0c03e833b1a61 100644 (file)
@@ -732,6 +732,7 @@ static int uncore_pmu_event_init(struct perf_event *event)
                /* fixed counters have event field hardcoded to zero */
                hwc->config = 0ULL;
        } else if (is_freerunning_event(event)) {
+               hwc->config = event->attr.config;
                if (!check_valid_freerunning_event(box, event))
                        return -EINVAL;
                event->hw.idx = UNCORE_PMC_IDX_FREERUNNING;
index cb46d602a6b8bd17eb458f84778019b56b15a93c..853a49a8ccf6748024e7da090c8e01c0c8edaeb1 100644 (file)
@@ -292,8 +292,8 @@ static inline
 unsigned int uncore_freerunning_counter(struct intel_uncore_box *box,
                                        struct perf_event *event)
 {
-       unsigned int type = uncore_freerunning_type(event->attr.config);
-       unsigned int idx = uncore_freerunning_idx(event->attr.config);
+       unsigned int type = uncore_freerunning_type(event->hw.config);
+       unsigned int idx = uncore_freerunning_idx(event->hw.config);
        struct intel_uncore_pmu *pmu = box->pmu;
 
        return pmu->type->freerunning[type].counter_base +
@@ -377,7 +377,7 @@ static inline
 unsigned int uncore_freerunning_bits(struct intel_uncore_box *box,
                                     struct perf_event *event)
 {
-       unsigned int type = uncore_freerunning_type(event->attr.config);
+       unsigned int type = uncore_freerunning_type(event->hw.config);
 
        return box->pmu->type->freerunning[type].bits;
 }
@@ -385,7 +385,7 @@ unsigned int uncore_freerunning_bits(struct intel_uncore_box *box,
 static inline int uncore_num_freerunning(struct intel_uncore_box *box,
                                         struct perf_event *event)
 {
-       unsigned int type = uncore_freerunning_type(event->attr.config);
+       unsigned int type = uncore_freerunning_type(event->hw.config);
 
        return box->pmu->type->freerunning[type].num_counters;
 }
@@ -399,8 +399,8 @@ static inline int uncore_num_freerunning_types(struct intel_uncore_box *box,
 static inline bool check_valid_freerunning_event(struct intel_uncore_box *box,
                                                 struct perf_event *event)
 {
-       unsigned int type = uncore_freerunning_type(event->attr.config);
-       unsigned int idx = uncore_freerunning_idx(event->attr.config);
+       unsigned int type = uncore_freerunning_type(event->hw.config);
+       unsigned int idx = uncore_freerunning_idx(event->hw.config);
 
        return (type < uncore_num_freerunning_types(box, event)) &&
               (idx < uncore_num_freerunning(box, event));
index b12517fae77a505b4c4beda2cacac9ea519fd83e..13493f43b24739928c006fb0dc1fe600f21ac9a9 100644 (file)
@@ -442,9 +442,11 @@ static int snb_uncore_imc_event_init(struct perf_event *event)
 
        /* must be done before validate_group */
        event->hw.event_base = base;
-       event->hw.config = cfg;
        event->hw.idx = idx;
 
+       /* Convert to standard encoding format for freerunning counters */
+       event->hw.config = ((cfg - 1) << 8) | 0x10ff;
+
        /* no group validation needed, we have free running counters */
 
        return 0;