[SRU][D/OEM-OSP1-B][PATCH v2 00/20] Add perf support for Comet Lake/Ice Lake CPU

classic Classic list List threaded Threaded
24 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 00/20] Add perf support for Comet Lake/Ice Lake CPU

You-Sheng Yang
BugLink: https://bugs.launchpad.net/bugs/1848978

[Impact]
There is no complete perf support for Comet Lake CPU. For Ice Lake, some
changes has been included in v5.3, but still misses CPU IDs.

[Fix]
perf support for Comet Lake is based on previous works for Ice Lake, so
changes for both have to be backported.

[Test Case]
On platforms with Comet Lake/Ice Lake CPUs, one should find new
cstate_pkg events c{8,9,10}-residency appear in output of `perf list`
for use.

[Regression Potential]
Low. This backports perf support for previously incompletedly supported
cpu models.

V2:
- add one more patch from commit 6b89d4c1ae85 ("perf/x86/intel: Fix
  INTEL_FLAGS_EVENT_CONSTRAINT* masking").

Andi Kleen (3):
  perf/x86/kvm: Avoid unnecessary work in guest filtering
  perf/x86/intel: Extract memory code PEBS parser for reuse
  perf/x86/lbr: Avoid reading the LBRs when adaptive PEBS handles them

Kan Liang (14):
  x86/cpufeature: Add facility to check for min microcode revisions
  perf/x86: Support outputting XMM registers
  perf/x86/intel/ds: Extract code of event update in short period
  perf/x86/intel: Support adaptive PEBS v4
  perf/x86/intel: Add Icelake support
  perf/x86/intel/uncore: Add Intel Icelake uncore support
  perf/x86/intel: Add Icelake desktop CPUID
  perf/x86/intel: Add more Icelake CPUIDs
  x86/cpu: Add Comet Lake to the Intel CPU models header
  perf/x86/intel: Add Comet Lake CPU support
  perf/x86/msr: Add Comet Lake CPU support
  perf/x86/cstate: Add Comet Lake CPU support
  perf/x86/msr: Add new CPU model numbers for Ice Lake
  perf/x86/cstate: Update C-state counters for Ice Lake

Peter Zijlstra (1):
  perf/x86: Support constraint ranges

Rajneesh Bhardwaj (1):
  perf/x86: Add Intel Ice Lake NNPI uncore support

Stephane Eranian (1):
  perf/x86/intel: Fix INTEL_FLAGS_EVENT_CONSTRAINT* masking

 arch/x86/events/core.c                |  15 +
 arch/x86/events/intel/core.c          | 207 ++++++++++-
 arch/x86/events/intel/cstate.c        |  41 ++-
 arch/x86/events/intel/ds.c            | 505 ++++++++++++++++++++++----
 arch/x86/events/intel/lbr.c           |  35 +-
 arch/x86/events/intel/rapl.c          |   1 +
 arch/x86/events/intel/uncore.c        |   8 +
 arch/x86/events/intel/uncore.h        |   1 +
 arch/x86/events/intel/uncore_snb.c    |  91 +++++
 arch/x86/events/msr.c                 |   5 +
 arch/x86/events/perf_event.h          |  94 ++++-
 arch/x86/include/asm/cpu_device_id.h  |  28 ++
 arch/x86/include/asm/intel-family.h   |   3 +
 arch/x86/include/asm/intel_ds.h       |   2 +-
 arch/x86/include/asm/msr-index.h      |   1 +
 arch/x86/include/asm/perf_event.h     |  50 ++-
 arch/x86/include/uapi/asm/perf_regs.h |  23 +-
 arch/x86/kernel/cpu/match.c           |  31 ++
 arch/x86/kernel/perf_regs.c           |  27 +-
 19 files changed, 1049 insertions(+), 119 deletions(-)

--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 01/20] x86/cpufeature: Add facility to check for min microcode revisions

You-Sheng Yang
From: Kan Liang <[hidden email]>

For bug workarounds or checks, it is useful to check for specific
microcode revisions.

Add a new generic function to match the CPU with stepping.
Add the other function to check the min microcode revisions for
the matched CPU.

A new table format is introduced to facilitate the quirk to
fill the related information.

This does not change the existing x86_cpu_id because it's an ABI
shared with modules, and also has quite different requirements,
as in no wildcards, but everything has to be matched exactly.

Originally-by: Andi Kleen <[hidden email]>
Suggested-by: Thomas Gleixner <[hidden email]>
Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Acked-by: Borislav Petkov <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: [hidden email]
Link: https://lkml.kernel.org/r/1549319013-4522-1-git-send-email-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 0f42b790c9ba5ec2f25b7da8b0b6d361082d67b0)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/include/asm/cpu_device_id.h | 28 +++++++++++++++++++++++++
 arch/x86/kernel/cpu/match.c          | 31 ++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h
index baeba0567126..3417110574c1 100644
--- a/arch/x86/include/asm/cpu_device_id.h
+++ b/arch/x86/include/asm/cpu_device_id.h
@@ -11,4 +11,32 @@
 
 extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match);
 
+/*
+ * Match specific microcode revisions.
+ *
+ * vendor/family/model/stepping must be all set.
+ *
+ * Only checks against the boot CPU.  When mixed-stepping configs are
+ * valid for a CPU model, add a quirk for every valid stepping and
+ * do the fine-tuning in the quirk handler.
+ */
+
+struct x86_cpu_desc {
+ __u8 x86_family;
+ __u8 x86_vendor;
+ __u8 x86_model;
+ __u8 x86_stepping;
+ __u32 x86_microcode_rev;
+};
+
+#define INTEL_CPU_DESC(mod, step, rev) { \
+ .x86_family = 6, \
+ .x86_vendor = X86_VENDOR_INTEL, \
+ .x86_model = mod, \
+ .x86_stepping = step, \
+ .x86_microcode_rev = rev, \
+}
+
+extern bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table);
+
 #endif
diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
index 3fed38812eea..6dd78d8235e4 100644
--- a/arch/x86/kernel/cpu/match.c
+++ b/arch/x86/kernel/cpu/match.c
@@ -48,3 +48,34 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
  return NULL;
 }
 EXPORT_SYMBOL(x86_match_cpu);
+
+static const struct x86_cpu_desc *
+x86_match_cpu_with_stepping(const struct x86_cpu_desc *match)
+{
+ struct cpuinfo_x86 *c = &boot_cpu_data;
+ const struct x86_cpu_desc *m;
+
+ for (m = match; m->x86_family | m->x86_model; m++) {
+ if (c->x86_vendor != m->x86_vendor)
+ continue;
+ if (c->x86 != m->x86_family)
+ continue;
+ if (c->x86_model != m->x86_model)
+ continue;
+ if (c->x86_stepping != m->x86_stepping)
+ continue;
+ return m;
+ }
+ return NULL;
+}
+
+bool x86_cpu_has_min_microcode_rev(const struct x86_cpu_desc *table)
+{
+ const struct x86_cpu_desc *res = x86_match_cpu_with_stepping(table);
+
+ if (!res || res->x86_microcode_rev > boot_cpu_data.microcode)
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(x86_cpu_has_min_microcode_rev);
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 02/20] perf/x86/kvm: Avoid unnecessary work in guest filtering

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Andi Kleen <[hidden email]>

KVM added a workaround for PEBS events leaking into guests with
commit:

  26a4f3c08de4 ("perf/x86: disable PEBS on a guest entry.")

This uses the VT entry/exit list to add an extra disable of the
PEBS_ENABLE MSR.

Intel also added a fix for this issue to microcode updates on
Haswell/Broadwell/Skylake.

It turns out using the MSR entry/exit list makes VM exits
significantly slower. The list is only needed for disabling
PEBS, because the GLOBAL_CTRL change gets optimized by
KVM into changing the VMCS.

Check for the microcode updates that have the microcode
fix for leaking PEBS, and disable the extra entry/exit list
entry for PEBS_ENABLE. In addition we always clear the
GLOBAL_CTRL for the PEBS counter while running in the guest,
which is enough to make them never fire at the wrong
side of the host/guest transition.

The overhead for VM exits with the filtering active with the patch is
reduced from 8% to 4%.

The microcode patch has already been merged into future platforms.
This patch is one-off thing. The quirks is used here.

For other old platforms which doesn't have microcode patch and quirks,
extra disable of the PEBS_ENABLE MSR is still required.

Signed-off-by: Andi Kleen <[hidden email]>
Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: David Ahern <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Namhyung Kim <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Link: https://lkml.kernel.org/r/1549319013-4522-2-git-send-email-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 9b545c04abd4f7246a3bde040efde587abebb23c)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/core.c | 74 +++++++++++++++++++++++++++++++-----
 arch/x86/events/intel/ds.c   |  2 +
 arch/x86/events/perf_event.h | 15 ++++----
 3 files changed, 75 insertions(+), 16 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 4978f1d1bc60..4c64fba70832 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -18,6 +18,7 @@
 #include <asm/hardirq.h>
 #include <asm/intel-family.h>
 #include <asm/apic.h>
+#include <asm/cpu_device_id.h>
 
 #include "../perf_event.h"
 
@@ -3250,16 +3251,27 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr)
  arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL;
  arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask;
  arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask;
- /*
- * If PMU counter has PEBS enabled it is not enough to disable counter
- * on a guest entry since PEBS memory write can overshoot guest entry
- * and corrupt guest memory. Disabling PEBS solves the problem.
- */
- arr[1].msr = MSR_IA32_PEBS_ENABLE;
- arr[1].host = cpuc->pebs_enabled;
- arr[1].guest = 0;
+ if (x86_pmu.flags & PMU_FL_PEBS_ALL)
+ arr[0].guest &= ~cpuc->pebs_enabled;
+ else
+ arr[0].guest &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK);
+ *nr = 1;
+
+ if (x86_pmu.pebs && x86_pmu.pebs_no_isolation) {
+ /*
+ * If PMU counter has PEBS enabled it is not enough to
+ * disable counter on a guest entry since PEBS memory
+ * write can overshoot guest entry and corrupt guest
+ * memory. Disabling PEBS solves the problem.
+ *
+ * Don't do this if the CPU already enforces it.
+ */
+ arr[1].msr = MSR_IA32_PEBS_ENABLE;
+ arr[1].host = cpuc->pebs_enabled;
+ arr[1].guest = 0;
+ *nr = 2;
+ }
 
- *nr = 2;
  return arr;
 }
 
@@ -3833,6 +3845,47 @@ static __init void intel_clovertown_quirk(void)
  x86_pmu.pebs_constraints = NULL;
 }
 
+static const struct x86_cpu_desc isolation_ucodes[] = {
+ INTEL_CPU_DESC(INTEL_FAM6_HASWELL_CORE, 3, 0x0000001f),
+ INTEL_CPU_DESC(INTEL_FAM6_HASWELL_ULT, 1, 0x0000001e),
+ INTEL_CPU_DESC(INTEL_FAM6_HASWELL_GT3E, 1, 0x00000015),
+ INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 2, 0x00000037),
+ INTEL_CPU_DESC(INTEL_FAM6_HASWELL_X, 4, 0x0000000a),
+ INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_CORE, 4, 0x00000023),
+ INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_GT3E, 1, 0x00000014),
+ INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 2, 0x00000010),
+ INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 3, 0x07000009),
+ INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 4, 0x0f000009),
+ INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_XEON_D, 5, 0x0e000002),
+ INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 2, 0x0b000014),
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x00000021),
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x00000000),
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_MOBILE, 3, 0x0000007c),
+ INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_DESKTOP, 3, 0x0000007c),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 9, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 9, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 10, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 11, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_MOBILE, 12, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 10, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 11, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 12, 0x0000004e),
+ INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE_DESKTOP, 13, 0x0000004e),
+ {}
+};
+
+static void intel_check_pebs_isolation(void)
+{
+ x86_pmu.pebs_no_isolation = !x86_cpu_has_min_microcode_rev(isolation_ucodes);
+}
+
+static __init void intel_pebs_isolation_quirk(void)
+{
+ WARN_ON_ONCE(x86_pmu.check_microcode);
+ x86_pmu.check_microcode = intel_check_pebs_isolation;
+ intel_check_pebs_isolation();
+}
+
 static int intel_snb_pebs_broken(int cpu)
 {
  u32 rev = UINT_MAX; /* default to broken for unknown models */
@@ -4536,6 +4589,7 @@ __init int intel_pmu_init(void)
  case INTEL_FAM6_HASWELL_ULT:
  case INTEL_FAM6_HASWELL_GT3E:
  x86_add_quirk(intel_ht_bug);
+ x86_add_quirk(intel_pebs_isolation_quirk);
  x86_pmu.late_ack = true;
  memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
  memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
@@ -4567,6 +4621,7 @@ __init int intel_pmu_init(void)
  case INTEL_FAM6_BROADWELL_XEON_D:
  case INTEL_FAM6_BROADWELL_GT3E:
  case INTEL_FAM6_BROADWELL_X:
+ x86_add_quirk(intel_pebs_isolation_quirk);
  x86_pmu.late_ack = true;
  memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
  memcpy(hw_cache_extra_regs, hsw_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
@@ -4629,6 +4684,7 @@ __init int intel_pmu_init(void)
  case INTEL_FAM6_SKYLAKE_X:
  case INTEL_FAM6_KABYLAKE_MOBILE:
  case INTEL_FAM6_KABYLAKE_DESKTOP:
+ x86_add_quirk(intel_pebs_isolation_quirk);
  x86_pmu.late_ack = true;
  memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
  memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 18cb68d3e003..b71adf603b86 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1628,6 +1628,8 @@ void __init intel_ds_init(void)
  x86_pmu.bts  = boot_cpu_has(X86_FEATURE_BTS);
  x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
  x86_pmu.pebs_buffer_size = PEBS_BUFFER_SIZE;
+ if (x86_pmu.version <= 4)
+ x86_pmu.pebs_no_isolation = 1;
  if (x86_pmu.pebs) {
  char pebs_type = x86_pmu.intel_cap.pebs_trap ?  '+' : '-';
  int format = x86_pmu.intel_cap.pebs_format;
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index b68ab65454ff..1e98a42b560a 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -606,13 +606,14 @@ struct x86_pmu {
  /*
  * Intel DebugStore bits
  */
- unsigned int bts :1,
- bts_active :1,
- pebs :1,
- pebs_active :1,
- pebs_broken :1,
- pebs_prec_dist :1,
- pebs_no_tlb :1;
+ unsigned int bts :1,
+ bts_active :1,
+ pebs :1,
+ pebs_active :1,
+ pebs_broken :1,
+ pebs_prec_dist :1,
+ pebs_no_tlb :1,
+ pebs_no_isolation :1;
  int pebs_record_size;
  int pebs_buffer_size;
  void (*drain_pebs)(struct pt_regs *regs);
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 03/20] perf/x86: Support outputting XMM registers

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Starting from Icelake, XMM registers can be collected in PEBS record.
But current code only output the pt_regs.

Add a new struct x86_perf_regs for both pt_regs and xmm_regs. The
xmm_regs will be used later to keep a pointer to PEBS record which has
XMM information.

XMM registers are 128 bit. To simplify the code, they are handled like
two different registers, which means setting two bits in the register
bitmap. This also allows only sampling the lower 64bit bits in XMM.

The index of XMM registers starts from 32. There are 16 XMM registers.
So all reserved space for regs are used. Remove REG_RESERVED.

Add PERF_REG_X86_XMM_MAX, which stands for the max number of all x86
regs including both GPRs and XMM.

Add REG_NOSUPPORT for 32bit to exclude unsupported registers.

Previous platforms can not collect XMM information in PEBS record.
Adding pebs_no_xmm_regs to indicate the unsupported platforms.

The common code still validates the supported registers. However, it
cannot check model specific registers, e.g. XMM. Add extra check in
x86_pmu_hw_config() to reject invalid config of regs_user and regs_intr.
The regs_user never supports XMM collection.
The regs_intr only supports XMM collection when sampling PEBS event on
icelake and later platforms.

Originally-by: Andi Kleen <[hidden email]>
Suggested-by: Peter Zijlstra (Intel) <[hidden email]>
Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190402194509.2832-3-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 878068ea270ea82767ff1d26c91583263c81fba0)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/core.c                | 15 +++++++++++++++
 arch/x86/events/intel/ds.c            |  4 +++-
 arch/x86/events/perf_event.h          | 21 ++++++++++++++++++++-
 arch/x86/include/asm/perf_event.h     |  5 +++++
 arch/x86/include/uapi/asm/perf_regs.h | 23 ++++++++++++++++++++++-
 arch/x86/kernel/perf_regs.c           | 27 ++++++++++++++++++++-------
 6 files changed, 85 insertions(+), 10 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 81911e11a15d..e5de540c5c41 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -560,6 +560,21 @@ int x86_pmu_hw_config(struct perf_event *event)
  return -EINVAL;
  }
 
+ /* sample_regs_user never support XMM registers */
+ if (unlikely(event->attr.sample_regs_user & PEBS_XMM_REGS))
+ return -EINVAL;
+ /*
+ * Besides the general purpose registers, XMM registers may
+ * be collected in PEBS on some platforms, e.g. Icelake
+ */
+ if (unlikely(event->attr.sample_regs_intr & PEBS_XMM_REGS)) {
+ if (x86_pmu.pebs_no_xmm_regs)
+ return -EINVAL;
+
+ if (!event->attr.precise_ip)
+ return -EINVAL;
+ }
+
  return x86_setup_perfctr(event);
 }
 
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index b71adf603b86..054eb6c51ddf 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1628,8 +1628,10 @@ void __init intel_ds_init(void)
  x86_pmu.bts  = boot_cpu_has(X86_FEATURE_BTS);
  x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
  x86_pmu.pebs_buffer_size = PEBS_BUFFER_SIZE;
- if (x86_pmu.version <= 4)
+ if (x86_pmu.version <= 4) {
  x86_pmu.pebs_no_isolation = 1;
+ x86_pmu.pebs_no_xmm_regs = 1;
+ }
  if (x86_pmu.pebs) {
  char pebs_type = x86_pmu.intel_cap.pebs_trap ?  '+' : '-';
  int format = x86_pmu.intel_cap.pebs_format;
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 1e98a42b560a..305eeff8d9f3 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -116,6 +116,24 @@ struct amd_nb {
  (1ULL << PERF_REG_X86_R14)   | \
  (1ULL << PERF_REG_X86_R15))
 
+#define PEBS_XMM_REGS                   \
+ ((1ULL << PERF_REG_X86_XMM0)  | \
+ (1ULL << PERF_REG_X86_XMM1)  | \
+ (1ULL << PERF_REG_X86_XMM2)  | \
+ (1ULL << PERF_REG_X86_XMM3)  | \
+ (1ULL << PERF_REG_X86_XMM4)  | \
+ (1ULL << PERF_REG_X86_XMM5)  | \
+ (1ULL << PERF_REG_X86_XMM6)  | \
+ (1ULL << PERF_REG_X86_XMM7)  | \
+ (1ULL << PERF_REG_X86_XMM8)  | \
+ (1ULL << PERF_REG_X86_XMM9)  | \
+ (1ULL << PERF_REG_X86_XMM10) | \
+ (1ULL << PERF_REG_X86_XMM11) | \
+ (1ULL << PERF_REG_X86_XMM12) | \
+ (1ULL << PERF_REG_X86_XMM13) | \
+ (1ULL << PERF_REG_X86_XMM14) | \
+ (1ULL << PERF_REG_X86_XMM15))
+
 /*
  * Per register state.
  */
@@ -613,7 +631,8 @@ struct x86_pmu {
  pebs_broken :1,
  pebs_prec_dist :1,
  pebs_no_tlb :1,
- pebs_no_isolation :1;
+ pebs_no_isolation :1,
+ pebs_no_xmm_regs :1;
  int pebs_record_size;
  int pebs_buffer_size;
  void (*drain_pebs)(struct pt_regs *regs);
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index a81443bd290f..74566657ef0b 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -252,6 +252,11 @@ extern void perf_events_lapic_init(void);
 #define PERF_EFLAGS_VM (1UL << 5)
 
 struct pt_regs;
+struct x86_perf_regs {
+ struct pt_regs regs;
+ u64 *xmm_regs;
+};
+
 extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
 extern unsigned long perf_misc_flags(struct pt_regs *regs);
 #define perf_misc_flags(regs) perf_misc_flags(regs)
diff --git a/arch/x86/include/uapi/asm/perf_regs.h b/arch/x86/include/uapi/asm/perf_regs.h
index f3329cabce5c..ac67bbea10ca 100644
--- a/arch/x86/include/uapi/asm/perf_regs.h
+++ b/arch/x86/include/uapi/asm/perf_regs.h
@@ -27,8 +27,29 @@ enum perf_event_x86_regs {
  PERF_REG_X86_R13,
  PERF_REG_X86_R14,
  PERF_REG_X86_R15,
-
+ /* These are the limits for the GPRs. */
  PERF_REG_X86_32_MAX = PERF_REG_X86_GS + 1,
  PERF_REG_X86_64_MAX = PERF_REG_X86_R15 + 1,
+
+ /* These all need two bits set because they are 128bit */
+ PERF_REG_X86_XMM0  = 32,
+ PERF_REG_X86_XMM1  = 34,
+ PERF_REG_X86_XMM2  = 36,
+ PERF_REG_X86_XMM3  = 38,
+ PERF_REG_X86_XMM4  = 40,
+ PERF_REG_X86_XMM5  = 42,
+ PERF_REG_X86_XMM6  = 44,
+ PERF_REG_X86_XMM7  = 46,
+ PERF_REG_X86_XMM8  = 48,
+ PERF_REG_X86_XMM9  = 50,
+ PERF_REG_X86_XMM10 = 52,
+ PERF_REG_X86_XMM11 = 54,
+ PERF_REG_X86_XMM12 = 56,
+ PERF_REG_X86_XMM13 = 58,
+ PERF_REG_X86_XMM14 = 60,
+ PERF_REG_X86_XMM15 = 62,
+
+ /* These include both GPRs and XMMX registers */
+ PERF_REG_X86_XMM_MAX = PERF_REG_X86_XMM15 + 2,
 };
 #endif /* _ASM_X86_PERF_REGS_H */
diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c
index c06c4c16c6b6..07c30ee17425 100644
--- a/arch/x86/kernel/perf_regs.c
+++ b/arch/x86/kernel/perf_regs.c
@@ -59,18 +59,34 @@ static unsigned int pt_regs_offset[PERF_REG_X86_MAX] = {
 
 u64 perf_reg_value(struct pt_regs *regs, int idx)
 {
+ struct x86_perf_regs *perf_regs;
+
+ if (idx >= PERF_REG_X86_XMM0 && idx < PERF_REG_X86_XMM_MAX) {
+ perf_regs = container_of(regs, struct x86_perf_regs, regs);
+ if (!perf_regs->xmm_regs)
+ return 0;
+ return perf_regs->xmm_regs[idx - PERF_REG_X86_XMM0];
+ }
+
  if (WARN_ON_ONCE(idx >= ARRAY_SIZE(pt_regs_offset)))
  return 0;
 
  return regs_get_register(regs, pt_regs_offset[idx]);
 }
 
-#define REG_RESERVED (~((1ULL << PERF_REG_X86_MAX) - 1ULL))
-
 #ifdef CONFIG_X86_32
+#define REG_NOSUPPORT ((1ULL << PERF_REG_X86_R8) | \
+       (1ULL << PERF_REG_X86_R9) | \
+       (1ULL << PERF_REG_X86_R10) | \
+       (1ULL << PERF_REG_X86_R11) | \
+       (1ULL << PERF_REG_X86_R12) | \
+       (1ULL << PERF_REG_X86_R13) | \
+       (1ULL << PERF_REG_X86_R14) | \
+       (1ULL << PERF_REG_X86_R15))
+
 int perf_reg_validate(u64 mask)
 {
- if (!mask || mask & REG_RESERVED)
+ if (!mask || (mask & REG_NOSUPPORT))
  return -EINVAL;
 
  return 0;
@@ -96,10 +112,7 @@ void perf_get_regs_user(struct perf_regs *regs_user,
 
 int perf_reg_validate(u64 mask)
 {
- if (!mask || mask & REG_RESERVED)
- return -EINVAL;
-
- if (mask & REG_NOSUPPORT)
+ if (!mask || (mask & REG_NOSUPPORT))
  return -EINVAL;
 
  return 0;
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 04/20] perf/x86/intel: Extract memory code PEBS parser for reuse

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Andi Kleen <[hidden email]>

Extract some code related to memory profiling from the PEBS record
parser into separate functions. It can be reused by the upcoming
adaptive PEBS parser. No functional changes.
Rename intel_hsw_weight to intel_get_tsx_weight, and
intel_hsw_transaction to intel_get_tsx_transaction. Because the input is
not the hsw pebs format anymore.

Signed-off-by: Andi Kleen <[hidden email]>
Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190402194509.2832-4-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 48f38aa4cc5a48bc0fe85c5c4b1ab171fbb539b6)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/ds.c | 63 ++++++++++++++++++++------------------
 1 file changed, 34 insertions(+), 29 deletions(-)

diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 054eb6c51ddf..ae1d43ac3a5b 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1125,34 +1125,50 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
  return 0;
 }
 
-static inline u64 intel_hsw_weight(struct pebs_record_skl *pebs)
+static inline u64 intel_get_tsx_weight(u64 tsx_tuning)
 {
- if (pebs->tsx_tuning) {
- union hsw_tsx_tuning tsx = { .value = pebs->tsx_tuning };
+ if (tsx_tuning) {
+ union hsw_tsx_tuning tsx = { .value = tsx_tuning };
  return tsx.cycles_last_block;
  }
  return 0;
 }
 
-static inline u64 intel_hsw_transaction(struct pebs_record_skl *pebs)
+static inline u64 intel_get_tsx_transaction(u64 tsx_tuning, u64 ax)
 {
- u64 txn = (pebs->tsx_tuning & PEBS_HSW_TSX_FLAGS) >> 32;
+ u64 txn = (tsx_tuning & PEBS_HSW_TSX_FLAGS) >> 32;
 
  /* For RTM XABORTs also log the abort code from AX */
- if ((txn & PERF_TXN_TRANSACTION) && (pebs->ax & 1))
- txn |= ((pebs->ax >> 24) & 0xff) << PERF_TXN_ABORT_SHIFT;
+ if ((txn & PERF_TXN_TRANSACTION) && (ax & 1))
+ txn |= ((ax >> 24) & 0xff) << PERF_TXN_ABORT_SHIFT;
  return txn;
 }
 
+#define PERF_X86_EVENT_PEBS_HSW_PREC \
+ (PERF_X86_EVENT_PEBS_ST_HSW | \
+ PERF_X86_EVENT_PEBS_LD_HSW | \
+ PERF_X86_EVENT_PEBS_NA_HSW)
+
+static u64 get_data_src(struct perf_event *event, u64 aux)
+{
+ u64 val = PERF_MEM_NA;
+ int fl = event->hw.flags;
+ bool fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC);
+
+ if (fl & PERF_X86_EVENT_PEBS_LDLAT)
+ val = load_latency_data(aux);
+ else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC))
+ val = precise_datala_hsw(event, aux);
+ else if (fst)
+ val = precise_store_data(aux);
+ return val;
+}
+
 static void setup_pebs_sample_data(struct perf_event *event,
    struct pt_regs *iregs, void *__pebs,
    struct perf_sample_data *data,
    struct pt_regs *regs)
 {
-#define PERF_X86_EVENT_PEBS_HSW_PREC \
- (PERF_X86_EVENT_PEBS_ST_HSW | \
- PERF_X86_EVENT_PEBS_LD_HSW | \
- PERF_X86_EVENT_PEBS_NA_HSW)
  /*
  * We cast to the biggest pebs_record but are careful not to
  * unconditionally access the 'extra' entries.
@@ -1160,17 +1176,13 @@ static void setup_pebs_sample_data(struct perf_event *event,
  struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
  struct pebs_record_skl *pebs = __pebs;
  u64 sample_type;
- int fll, fst, dsrc;
- int fl = event->hw.flags;
+ int fll;
 
  if (pebs == NULL)
  return;
 
  sample_type = event->attr.sample_type;
- dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
-
- fll = fl & PERF_X86_EVENT_PEBS_LDLAT;
- fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC);
+ fll = event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT;
 
  perf_sample_data_init(data, 0, event->hw.last_period);
 
@@ -1185,16 +1197,8 @@ static void setup_pebs_sample_data(struct perf_event *event,
  /*
  * data.data_src encodes the data source
  */
- if (dsrc) {
- u64 val = PERF_MEM_NA;
- if (fll)
- val = load_latency_data(pebs->dse);
- else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC))
- val = precise_datala_hsw(event, pebs->dse);
- else if (fst)
- val = precise_store_data(pebs->dse);
- data->data_src.val = val;
- }
+ if (sample_type & PERF_SAMPLE_DATA_SRC)
+ data->data_src.val = get_data_src(event, pebs->dse);
 
  /*
  * We must however always use iregs for the unwinder to stay sane; the
@@ -1281,10 +1285,11 @@ static void setup_pebs_sample_data(struct perf_event *event,
  if (x86_pmu.intel_cap.pebs_format >= 2) {
  /* Only set the TSX weight when no memory weight. */
  if ((sample_type & PERF_SAMPLE_WEIGHT) && !fll)
- data->weight = intel_hsw_weight(pebs);
+ data->weight = intel_get_tsx_weight(pebs->tsx_tuning);
 
  if (sample_type & PERF_SAMPLE_TRANSACTION)
- data->txn = intel_hsw_transaction(pebs);
+ data->txn = intel_get_tsx_transaction(pebs->tsx_tuning,
+      pebs->ax);
  }
 
  /*
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 05/20] perf/x86/intel/ds: Extract code of event update in short period

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

The drain_pebs() could be called twice in a short period for auto-reload
event in pmu::read(). The intel_pmu_save_and_restart_reload() should be
called to update the event->count.

This case should also be handled on Icelake. Extract the code for
later reuse.

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190402194509.2832-5-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 477f00f9617009a9a3a9271885231573b728ca4f)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/ds.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index ae1d43ac3a5b..334ee6242c8a 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1491,6 +1491,25 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
  __intel_pmu_pebs_event(event, iregs, at, top, 0, n);
 }
 
+static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, int size)
+{
+ struct perf_event *event;
+ int bit;
+
+ /*
+ * The drain_pebs() could be called twice in a short period
+ * for auto-reload event in pmu::read(). There are no
+ * overflows have happened in between.
+ * It needs to call intel_pmu_save_and_restart_reload() to
+ * update the event->count for this case.
+ */
+ for_each_set_bit(bit, (unsigned long *)&cpuc->pebs_enabled, size) {
+ event = cpuc->events[bit];
+ if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD)
+ intel_pmu_save_and_restart_reload(event, 0);
+ }
+}
+
 static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
 {
  struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
@@ -1518,19 +1537,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
  }
 
  if (unlikely(base >= top)) {
- /*
- * The drain_pebs() could be called twice in a short period
- * for auto-reload event in pmu::read(). There are no
- * overflows have happened in between.
- * It needs to call intel_pmu_save_and_restart_reload() to
- * update the event->count for this case.
- */
- for_each_set_bit(bit, (unsigned long *)&cpuc->pebs_enabled,
- size) {
- event = cpuc->events[bit];
- if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD)
- intel_pmu_save_and_restart_reload(event, 0);
- }
+ intel_pmu_pebs_event_update_no_drain(cpuc, size);
  return;
  }
 
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 06/20] perf/x86/intel: Support adaptive PEBS v4

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Adaptive PEBS is a new way to report PEBS sampling information. Instead
of a fixed size record for all PEBS events it allows to configure the
PEBS record to only include the information needed. Events can then opt
in to use such an extended record, or stay with a basic record which
only contains the IP.

The major new feature is to support LBRs in PEBS record.
Besides normal LBR, this allows (much faster) large PEBS, while still
supporting callstacks through callstack LBR. So essentially a lot of
profiling can now be done without frequent interrupts, dropping the
overhead significantly.

The main requirement still is to use a period, and not use frequency
mode, because frequency mode requires reevaluating the frequency on each
overflow.

The floating point state (XMM) is also supported, which allows efficient
profiling of FP function arguments.

Introduce specific drain function to handle variable length records.
Use a new callback to parse the new record format, and also handle the
STATUS field now being at a different offset.

Add code to set up the configuration register. Since there is only a
single register, all events either get the full super set of all events,
or only the basic record.

Originally-by: Andi Kleen <[hidden email]>
Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190402194509.2832-6-kan.liang@...
[ Renamed GPRS => GP. ]
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit c22497f5838c237e3094a4dfb99d1c5de6353239)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/core.c      |   7 +
 arch/x86/events/intel/ds.c        | 380 ++++++++++++++++++++++++++++--
 arch/x86/events/intel/lbr.c       |  22 ++
 arch/x86/events/perf_event.h      |  11 +-
 arch/x86/include/asm/msr-index.h  |   1 +
 arch/x86/include/asm/perf_event.h |  43 ++++
 6 files changed, 438 insertions(+), 26 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 4c64fba70832..5d7707a5a5d9 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2147,6 +2147,11 @@ static void intel_pmu_enable_fixed(struct perf_event *event)
  bits <<= (idx * 4);
  mask = 0xfULL << (idx * 4);
 
+ if (x86_pmu.intel_cap.pebs_baseline && event->attr.precise_ip) {
+ bits |= ICL_FIXED_0_ADAPTIVE << (idx * 4);
+ mask |= ICL_FIXED_0_ADAPTIVE << (idx * 4);
+ }
+
  rdmsrl(hwc->config_base, ctrl_val);
  ctrl_val &= ~mask;
  ctrl_val |= bits;
@@ -3514,6 +3519,8 @@ static struct intel_excl_cntrs *allocate_excl_cntrs(int cpu)
 
 int intel_cpuc_prepare(struct cpu_hw_events *cpuc, int cpu)
 {
+ cpuc->pebs_record_size = x86_pmu.pebs_record_size;
+
  if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) {
  cpuc->shared_regs = allocate_shared_regs(cpu);
  if (!cpuc->shared_regs)
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 334ee6242c8a..87dd3e7f084e 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -906,17 +906,87 @@ static inline void pebs_update_threshold(struct cpu_hw_events *cpuc)
 
  if (cpuc->n_pebs == cpuc->n_large_pebs) {
  threshold = ds->pebs_absolute_maximum -
- reserved * x86_pmu.pebs_record_size;
+ reserved * cpuc->pebs_record_size;
  } else {
- threshold = ds->pebs_buffer_base + x86_pmu.pebs_record_size;
+ threshold = ds->pebs_buffer_base + cpuc->pebs_record_size;
  }
 
  ds->pebs_interrupt_threshold = threshold;
 }
 
+static void adaptive_pebs_record_size_update(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ u64 pebs_data_cfg = cpuc->pebs_data_cfg;
+ int sz = sizeof(struct pebs_basic);
+
+ if (pebs_data_cfg & PEBS_DATACFG_MEMINFO)
+ sz += sizeof(struct pebs_meminfo);
+ if (pebs_data_cfg & PEBS_DATACFG_GP)
+ sz += sizeof(struct pebs_gprs);
+ if (pebs_data_cfg & PEBS_DATACFG_XMMS)
+ sz += sizeof(struct pebs_xmm);
+ if (pebs_data_cfg & PEBS_DATACFG_LBRS)
+ sz += x86_pmu.lbr_nr * sizeof(struct pebs_lbr_entry);
+
+ cpuc->pebs_record_size = sz;
+}
+
+#define PERF_PEBS_MEMINFO_TYPE (PERF_SAMPLE_ADDR | PERF_SAMPLE_DATA_SRC |   \
+ PERF_SAMPLE_PHYS_ADDR | PERF_SAMPLE_WEIGHT | \
+ PERF_SAMPLE_TRANSACTION)
+
+static u64 pebs_update_adaptive_cfg(struct perf_event *event)
+{
+ struct perf_event_attr *attr = &event->attr;
+ u64 sample_type = attr->sample_type;
+ u64 pebs_data_cfg = 0;
+ bool gprs, tsx_weight;
+
+ if (!(sample_type & ~(PERF_SAMPLE_IP|PERF_SAMPLE_TIME)) &&
+    attr->precise_ip > 1)
+ return pebs_data_cfg;
+
+ if (sample_type & PERF_PEBS_MEMINFO_TYPE)
+ pebs_data_cfg |= PEBS_DATACFG_MEMINFO;
+
+ /*
+ * We need GPRs when:
+ * + user requested them
+ * + precise_ip < 2 for the non event IP
+ * + For RTM TSX weight we need GPRs for the abort code.
+ */
+ gprs = (sample_type & PERF_SAMPLE_REGS_INTR) &&
+       (attr->sample_regs_intr & PEBS_GP_REGS);
+
+ tsx_weight = (sample_type & PERF_SAMPLE_WEIGHT) &&
+     ((attr->config & INTEL_ARCH_EVENT_MASK) ==
+      x86_pmu.rtm_abort_event);
+
+ if (gprs || (attr->precise_ip < 2) || tsx_weight)
+ pebs_data_cfg |= PEBS_DATACFG_GP;
+
+ if ((sample_type & PERF_SAMPLE_REGS_INTR) &&
+    (attr->sample_regs_intr & PEBS_XMM_REGS))
+ pebs_data_cfg |= PEBS_DATACFG_XMMS;
+
+ if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
+ /*
+ * For now always log all LBRs. Could configure this
+ * later.
+ */
+ pebs_data_cfg |= PEBS_DATACFG_LBRS |
+ ((x86_pmu.lbr_nr-1) << PEBS_DATACFG_LBR_SHIFT);
+ }
+
+ return pebs_data_cfg;
+}
+
 static void
-pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc, struct pmu *pmu)
+pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
+  struct perf_event *event, bool add)
 {
+ struct pmu *pmu = event->ctx->pmu;
  /*
  * Make sure we get updated with the first PEBS
  * event. It will trigger also during removal, but
@@ -933,6 +1003,29 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc, struct pmu *pmu)
  update = true;
  }
 
+ /*
+ * The PEBS record doesn't shrink on pmu::del(). Doing so would require
+ * iterating all remaining PEBS events to reconstruct the config.
+ */
+ if (x86_pmu.intel_cap.pebs_baseline && add) {
+ u64 pebs_data_cfg;
+
+ /* Clear pebs_data_cfg and pebs_record_size for first PEBS. */
+ if (cpuc->n_pebs == 1) {
+ cpuc->pebs_data_cfg = 0;
+ cpuc->pebs_record_size = sizeof(struct pebs_basic);
+ }
+
+ pebs_data_cfg = pebs_update_adaptive_cfg(event);
+
+ /* Update pebs_record_size if new event requires more data. */
+ if (pebs_data_cfg & ~cpuc->pebs_data_cfg) {
+ cpuc->pebs_data_cfg |= pebs_data_cfg;
+ adaptive_pebs_record_size_update();
+ update = true;
+ }
+ }
+
  if (update)
  pebs_update_threshold(cpuc);
 }
@@ -947,7 +1040,7 @@ void intel_pmu_pebs_add(struct perf_event *event)
  if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
  cpuc->n_large_pebs++;
 
- pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
+ pebs_update_state(needed_cb, cpuc, event, true);
 }
 
 void intel_pmu_pebs_enable(struct perf_event *event)
@@ -965,6 +1058,14 @@ void intel_pmu_pebs_enable(struct perf_event *event)
  else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
  cpuc->pebs_enabled |= 1ULL << 63;
 
+ if (x86_pmu.intel_cap.pebs_baseline) {
+ hwc->config |= ICL_EVENTSEL_ADAPTIVE;
+ if (cpuc->pebs_data_cfg != cpuc->active_pebs_data_cfg) {
+ wrmsrl(MSR_PEBS_DATA_CFG, cpuc->pebs_data_cfg);
+ cpuc->active_pebs_data_cfg = cpuc->pebs_data_cfg;
+ }
+ }
+
  /*
  * Use auto-reload if possible to save a MSR write in the PMI.
  * This must be done in pmu::start(), because PERF_EVENT_IOC_PERIOD.
@@ -991,7 +1092,7 @@ void intel_pmu_pebs_del(struct perf_event *event)
  if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
  cpuc->n_large_pebs--;
 
- pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
+ pebs_update_state(needed_cb, cpuc, event, false);
 }
 
 void intel_pmu_pebs_disable(struct perf_event *event)
@@ -1144,6 +1245,13 @@ static inline u64 intel_get_tsx_transaction(u64 tsx_tuning, u64 ax)
  return txn;
 }
 
+static inline u64 get_pebs_status(void *n)
+{
+ if (x86_pmu.intel_cap.pebs_format < 4)
+ return ((struct pebs_record_nhm *)n)->status;
+ return ((struct pebs_basic *)n)->applicable_counters;
+}
+
 #define PERF_X86_EVENT_PEBS_HSW_PREC \
  (PERF_X86_EVENT_PEBS_ST_HSW | \
  PERF_X86_EVENT_PEBS_LD_HSW | \
@@ -1164,7 +1272,7 @@ static u64 get_data_src(struct perf_event *event, u64 aux)
  return val;
 }
 
-static void setup_pebs_sample_data(struct perf_event *event,
+static void setup_pebs_fixed_sample_data(struct perf_event *event,
    struct pt_regs *iregs, void *__pebs,
    struct perf_sample_data *data,
    struct pt_regs *regs)
@@ -1306,6 +1414,140 @@ static void setup_pebs_sample_data(struct perf_event *event,
  data->br_stack = &cpuc->lbr_stack;
 }
 
+static void adaptive_pebs_save_regs(struct pt_regs *regs,
+    struct pebs_gprs *gprs)
+{
+ regs->ax = gprs->ax;
+ regs->bx = gprs->bx;
+ regs->cx = gprs->cx;
+ regs->dx = gprs->dx;
+ regs->si = gprs->si;
+ regs->di = gprs->di;
+ regs->bp = gprs->bp;
+ regs->sp = gprs->sp;
+#ifndef CONFIG_X86_32
+ regs->r8 = gprs->r8;
+ regs->r9 = gprs->r9;
+ regs->r10 = gprs->r10;
+ regs->r11 = gprs->r11;
+ regs->r12 = gprs->r12;
+ regs->r13 = gprs->r13;
+ regs->r14 = gprs->r14;
+ regs->r15 = gprs->r15;
+#endif
+}
+
+/*
+ * With adaptive PEBS the layout depends on what fields are configured.
+ */
+
+static void setup_pebs_adaptive_sample_data(struct perf_event *event,
+    struct pt_regs *iregs, void *__pebs,
+    struct perf_sample_data *data,
+    struct pt_regs *regs)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct pebs_basic *basic = __pebs;
+ void *next_record = basic + 1;
+ u64 sample_type;
+ u64 format_size;
+ struct pebs_meminfo *meminfo = NULL;
+ struct pebs_gprs *gprs = NULL;
+ struct x86_perf_regs *perf_regs;
+
+ if (basic == NULL)
+ return;
+
+ perf_regs = container_of(regs, struct x86_perf_regs, regs);
+ perf_regs->xmm_regs = NULL;
+
+ sample_type = event->attr.sample_type;
+ format_size = basic->format_size;
+ perf_sample_data_init(data, 0, event->hw.last_period);
+ data->period = event->hw.last_period;
+
+ if (event->attr.use_clockid == 0)
+ data->time = native_sched_clock_from_tsc(basic->tsc);
+
+ /*
+ * We must however always use iregs for the unwinder to stay sane; the
+ * record BP,SP,IP can point into thin air when the record is from a
+ * previous PMI context or an (I)RET happened between the record and
+ * PMI.
+ */
+ if (sample_type & PERF_SAMPLE_CALLCHAIN)
+ data->callchain = perf_callchain(event, iregs);
+
+ *regs = *iregs;
+ /* The ip in basic is EventingIP */
+ set_linear_ip(regs, basic->ip);
+ regs->flags = PERF_EFLAGS_EXACT;
+
+ /*
+ * The record for MEMINFO is in front of GP
+ * But PERF_SAMPLE_TRANSACTION needs gprs->ax.
+ * Save the pointer here but process later.
+ */
+ if (format_size & PEBS_DATACFG_MEMINFO) {
+ meminfo = next_record;
+ next_record = meminfo + 1;
+ }
+
+ if (format_size & PEBS_DATACFG_GP) {
+ gprs = next_record;
+ next_record = gprs + 1;
+
+ if (event->attr.precise_ip < 2) {
+ set_linear_ip(regs, gprs->ip);
+ regs->flags &= ~PERF_EFLAGS_EXACT;
+ }
+
+ if (sample_type & PERF_SAMPLE_REGS_INTR)
+ adaptive_pebs_save_regs(regs, gprs);
+ }
+
+ if (format_size & PEBS_DATACFG_MEMINFO) {
+ if (sample_type & PERF_SAMPLE_WEIGHT)
+ data->weight = meminfo->latency ?:
+ intel_get_tsx_weight(meminfo->tsx_tuning);
+
+ if (sample_type & PERF_SAMPLE_DATA_SRC)
+ data->data_src.val = get_data_src(event, meminfo->aux);
+
+ if (sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR))
+ data->addr = meminfo->address;
+
+ if (sample_type & PERF_SAMPLE_TRANSACTION)
+ data->txn = intel_get_tsx_transaction(meminfo->tsx_tuning,
+  gprs ? gprs->ax : 0);
+ }
+
+ if (format_size & PEBS_DATACFG_XMMS) {
+ struct pebs_xmm *xmm = next_record;
+
+ next_record = xmm + 1;
+ perf_regs->xmm_regs = xmm->xmm;
+ }
+
+ if (format_size & PEBS_DATACFG_LBRS) {
+ struct pebs_lbr *lbr = next_record;
+ int num_lbr = ((format_size >> PEBS_DATACFG_LBR_SHIFT)
+ & 0xff) + 1;
+ next_record = next_record + num_lbr*sizeof(struct pebs_lbr_entry);
+
+ if (has_branch_stack(event)) {
+ intel_pmu_store_pebs_lbrs(lbr);
+ data->br_stack = &cpuc->lbr_stack;
+ }
+ }
+
+ WARN_ONCE(next_record != __pebs + (format_size >> 48),
+ "PEBS record size %llu, expected %llu, config %llx\n",
+ format_size >> 48,
+ (u64)(next_record - __pebs),
+ basic->format_size);
+}
+
 static inline void *
 get_next_pebs_record_by_bit(void *base, void *top, int bit)
 {
@@ -1323,19 +1565,19 @@ get_next_pebs_record_by_bit(void *base, void *top, int bit)
  if (base == NULL)
  return NULL;
 
- for (at = base; at < top; at += x86_pmu.pebs_record_size) {
- struct pebs_record_nhm *p = at;
+ for (at = base; at < top; at += cpuc->pebs_record_size) {
+ unsigned long status = get_pebs_status(at);
 
- if (test_bit(bit, (unsigned long *)&p->status)) {
+ if (test_bit(bit, (unsigned long *)&status)) {
  /* PEBS v3 has accurate status bits */
  if (x86_pmu.intel_cap.pebs_format >= 3)
  return at;
 
- if (p->status == (1 << bit))
+ if (status == (1 << bit))
  return at;
 
  /* clear non-PEBS bit and re-check */
- pebs_status = p->status & cpuc->pebs_enabled;
+ pebs_status = status & cpuc->pebs_enabled;
  pebs_status &= PEBS_COUNTER_MASK;
  if (pebs_status == (1 << bit))
  return at;
@@ -1415,11 +1657,18 @@ intel_pmu_save_and_restart_reload(struct perf_event *event, int count)
 static void __intel_pmu_pebs_event(struct perf_event *event,
    struct pt_regs *iregs,
    void *base, void *top,
-   int bit, int count)
+   int bit, int count,
+   void (*setup_sample)(struct perf_event *,
+ struct pt_regs *,
+ void *,
+ struct perf_sample_data *,
+ struct pt_regs *))
 {
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
  struct hw_perf_event *hwc = &event->hw;
  struct perf_sample_data data;
- struct pt_regs regs;
+ struct x86_perf_regs perf_regs;
+ struct pt_regs *regs = &perf_regs.regs;
  void *at = get_next_pebs_record_by_bit(base, top, bit);
 
  if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
@@ -1434,20 +1683,20 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
  return;
 
  while (count > 1) {
- setup_pebs_sample_data(event, iregs, at, &data, &regs);
- perf_event_output(event, &data, &regs);
- at += x86_pmu.pebs_record_size;
+ setup_sample(event, iregs, at, &data, regs);
+ perf_event_output(event, &data, regs);
+ at += cpuc->pebs_record_size;
  at = get_next_pebs_record_by_bit(at, top, bit);
  count--;
  }
 
- setup_pebs_sample_data(event, iregs, at, &data, &regs);
+ setup_sample(event, iregs, at, &data, regs);
 
  /*
  * All but the last records are processed.
  * The last one is left to be able to call the overflow handler.
  */
- if (perf_event_overflow(event, &data, &regs)) {
+ if (perf_event_overflow(event, &data, regs)) {
  x86_pmu_stop(event, 0);
  return;
  }
@@ -1488,7 +1737,8 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
  return;
  }
 
- __intel_pmu_pebs_event(event, iregs, at, top, 0, n);
+ __intel_pmu_pebs_event(event, iregs, at, top, 0, n,
+       setup_pebs_fixed_sample_data);
 }
 
 static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, int size)
@@ -1550,8 +1800,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
 
  /* PEBS v3 has more accurate status bits */
  if (x86_pmu.intel_cap.pebs_format >= 3) {
- for_each_set_bit(bit, (unsigned long *)&pebs_status,
- size)
+ for_each_set_bit(bit, (unsigned long *)&pebs_status, size)
  counts[bit]++;
 
  continue;
@@ -1590,8 +1839,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
  * If collision happened, the record will be dropped.
  */
  if (p->status != (1ULL << bit)) {
- for_each_set_bit(i, (unsigned long *)&pebs_status,
- x86_pmu.max_pebs_events)
+ for_each_set_bit(i, (unsigned long *)&pebs_status, size)
  error[i]++;
  continue;
  }
@@ -1599,7 +1847,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
  counts[bit]++;
  }
 
- for (bit = 0; bit < size; bit++) {
+ for_each_set_bit(bit, (unsigned long *)&mask, size) {
  if ((counts[bit] == 0) && (error[bit] == 0))
  continue;
 
@@ -1620,11 +1868,66 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
 
  if (counts[bit]) {
  __intel_pmu_pebs_event(event, iregs, base,
-       top, bit, counts[bit]);
+       top, bit, counts[bit],
+       setup_pebs_fixed_sample_data);
  }
  }
 }
 
+static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs)
+{
+ short counts[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ struct debug_store *ds = cpuc->ds;
+ struct perf_event *event;
+ void *base, *at, *top;
+ int bit, size;
+ u64 mask;
+
+ if (!x86_pmu.pebs_active)
+ return;
+
+ base = (struct pebs_basic *)(unsigned long)ds->pebs_buffer_base;
+ top = (struct pebs_basic *)(unsigned long)ds->pebs_index;
+
+ ds->pebs_index = ds->pebs_buffer_base;
+
+ mask = ((1ULL << x86_pmu.max_pebs_events) - 1) |
+       (((1ULL << x86_pmu.num_counters_fixed) - 1) << INTEL_PMC_IDX_FIXED);
+ size = INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed;
+
+ if (unlikely(base >= top)) {
+ intel_pmu_pebs_event_update_no_drain(cpuc, size);
+ return;
+ }
+
+ for (at = base; at < top; at += cpuc->pebs_record_size) {
+ u64 pebs_status;
+
+ pebs_status = get_pebs_status(at) & cpuc->pebs_enabled;
+ pebs_status &= mask;
+
+ for_each_set_bit(bit, (unsigned long *)&pebs_status, size)
+ counts[bit]++;
+ }
+
+ for_each_set_bit(bit, (unsigned long *)&mask, size) {
+ if (counts[bit] == 0)
+ continue;
+
+ event = cpuc->events[bit];
+ if (WARN_ON_ONCE(!event))
+ continue;
+
+ if (WARN_ON_ONCE(!event->attr.precise_ip))
+ continue;
+
+ __intel_pmu_pebs_event(event, iregs, base,
+       top, bit, counts[bit],
+       setup_pebs_adaptive_sample_data);
+ }
+}
+
 /*
  * BTS, PEBS probe and setup
  */
@@ -1646,8 +1949,12 @@ void __init intel_ds_init(void)
  }
  if (x86_pmu.pebs) {
  char pebs_type = x86_pmu.intel_cap.pebs_trap ?  '+' : '-';
+ char *pebs_qual = "";
  int format = x86_pmu.intel_cap.pebs_format;
 
+ if (format < 4)
+ x86_pmu.intel_cap.pebs_baseline = 0;
+
  switch (format) {
  case 0:
  pr_cont("PEBS fmt0%c, ", pebs_type);
@@ -1683,6 +1990,29 @@ void __init intel_ds_init(void)
  x86_pmu.large_pebs_flags |= PERF_SAMPLE_TIME;
  break;
 
+ case 4:
+ x86_pmu.drain_pebs = intel_pmu_drain_pebs_icl;
+ x86_pmu.pebs_record_size = sizeof(struct pebs_basic);
+ if (x86_pmu.intel_cap.pebs_baseline) {
+ x86_pmu.large_pebs_flags |=
+ PERF_SAMPLE_BRANCH_STACK |
+ PERF_SAMPLE_TIME;
+ x86_pmu.flags |= PMU_FL_PEBS_ALL;
+ pebs_qual = "-baseline";
+ } else {
+ /* Only basic record supported */
+ x86_pmu.pebs_no_xmm_regs = 1;
+ x86_pmu.large_pebs_flags &=
+ ~(PERF_SAMPLE_ADDR |
+  PERF_SAMPLE_TIME |
+  PERF_SAMPLE_DATA_SRC |
+  PERF_SAMPLE_TRANSACTION |
+  PERF_SAMPLE_REGS_USER |
+  PERF_SAMPLE_REGS_INTR);
+ }
+ pr_cont("PEBS fmt4%c%s, ", pebs_type, pebs_qual);
+ break;
+
  default:
  pr_cont("no PEBS fmt%d%c, ", format, pebs_type);
  x86_pmu.pebs = 0;
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index c88ed39582a1..58889f952959 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1079,6 +1079,28 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
  }
 }
 
+void intel_pmu_store_pebs_lbrs(struct pebs_lbr *lbr)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int i;
+
+ cpuc->lbr_stack.nr = x86_pmu.lbr_nr;
+ for (i = 0; i < x86_pmu.lbr_nr; i++) {
+ u64 info = lbr->lbr[i].info;
+ struct perf_branch_entry *e = &cpuc->lbr_entries[i];
+
+ e->from = lbr->lbr[i].from;
+ e->to = lbr->lbr[i].to;
+ e->mispred = !!(info & LBR_INFO_MISPRED);
+ e->predicted = !(info & LBR_INFO_MISPRED);
+ e->in_tx = !!(info & LBR_INFO_IN_TX);
+ e->abort = !!(info & LBR_INFO_ABORT);
+ e->cycles = info & LBR_INFO_CYCLES;
+ e->reserved = 0;
+ }
+ intel_pmu_lbr_filter(cpuc);
+}
+
 /*
  * Map interface branch filters onto LBR filters
  */
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 305eeff8d9f3..84d225cfaacc 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -225,6 +225,11 @@ struct cpu_hw_events {
  int n_pebs;
  int n_large_pebs;
 
+ /* Current super set of events hardware configuration */
+ u64 pebs_data_cfg;
+ u64 active_pebs_data_cfg;
+ int pebs_record_size;
+
  /*
  * Intel LBR bits
  */
@@ -491,6 +496,7 @@ union perf_capabilities {
  * values > 32bit.
  */
  u64 full_width_write:1;
+ u64     pebs_baseline:1;
  };
  u64 capabilities;
 };
@@ -635,11 +641,12 @@ struct x86_pmu {
  pebs_no_xmm_regs :1;
  int pebs_record_size;
  int pebs_buffer_size;
+ int max_pebs_events;
  void (*drain_pebs)(struct pt_regs *regs);
  struct event_constraint *pebs_constraints;
  void (*pebs_aliases)(struct perf_event *event);
- int max_pebs_events;
  unsigned long large_pebs_flags;
+ u64 rtm_abort_event;
 
  /*
  * Intel LBR
@@ -978,6 +985,8 @@ void intel_pmu_pebs_sched_task(struct perf_event_context *ctx, bool sched_in);
 
 void intel_pmu_auto_reload_read(struct perf_event *event);
 
+void intel_pmu_store_pebs_lbrs(struct pebs_lbr *lbr);
+
 void intel_ds_init(void);
 
 void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in);
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 2b28538bf8f7..1637288d6c54 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -139,6 +139,7 @@
 #define LBR_INFO_CYCLES 0xffff
 
 #define MSR_IA32_PEBS_ENABLE 0x000003f1
+#define MSR_PEBS_DATA_CFG 0x000003f2
 #define MSR_IA32_DS_AREA 0x00000600
 #define MSR_IA32_PERF_CAPABILITIES 0x00000345
 #define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 74566657ef0b..fbdc2e8fc5aa 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -32,6 +32,8 @@
 
 #define HSW_IN_TX (1ULL << 32)
 #define HSW_IN_TX_CHECKPOINTED (1ULL << 33)
+#define ICL_EVENTSEL_ADAPTIVE (1ULL << 34)
+#define ICL_FIXED_0_ADAPTIVE (1ULL << 32)
 
 #define AMD64_EVENTSEL_INT_CORE_ENABLE (1ULL << 36)
 #define AMD64_EVENTSEL_GUESTONLY (1ULL << 40)
@@ -87,6 +89,12 @@
 #define ARCH_PERFMON_BRANCH_MISSES_RETIRED 6
 #define ARCH_PERFMON_EVENTS_COUNT 7
 
+#define PEBS_DATACFG_MEMINFO BIT_ULL(0)
+#define PEBS_DATACFG_GP BIT_ULL(1)
+#define PEBS_DATACFG_XMMS BIT_ULL(2)
+#define PEBS_DATACFG_LBRS BIT_ULL(3)
+#define PEBS_DATACFG_LBR_SHIFT 24
+
 /*
  * Intel "Architectural Performance Monitoring" CPUID
  * detection/enumeration details:
@@ -176,6 +184,41 @@ struct x86_pmu_capability {
 #define GLOBAL_STATUS_LBRS_FROZEN BIT_ULL(58)
 #define GLOBAL_STATUS_TRACE_TOPAPMI BIT_ULL(55)
 
+/*
+ * Adaptive PEBS v4
+ */
+
+struct pebs_basic {
+ u64 format_size;
+ u64 ip;
+ u64 applicable_counters;
+ u64 tsc;
+};
+
+struct pebs_meminfo {
+ u64 address;
+ u64 aux;
+ u64 latency;
+ u64 tsx_tuning;
+};
+
+struct pebs_gprs {
+ u64 flags, ip, ax, cx, dx, bx, sp, bp, si, di;
+ u64 r8, r9, r10, r11, r12, r13, r14, r15;
+};
+
+struct pebs_xmm {
+ u64 xmm[16*2]; /* two entries for each register */
+};
+
+struct pebs_lbr_entry {
+ u64 from, to, info;
+};
+
+struct pebs_lbr {
+ struct pebs_lbr_entry lbr[0]; /* Variable length */
+};
+
 /*
  * IBS cpuid feature detection
  */
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 07/20] perf/x86/lbr: Avoid reading the LBRs when adaptive PEBS handles them

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Andi Kleen <[hidden email]>

With adaptive PEBS the CPU can directly supply the LBR information,
so we don't need to read it again. But the LBRs still need to be
enabled. Add a special count to the cpuc that distinguishes these
two cases, and avoid reading the LBRs unnecessarily when PEBS is
active.

Signed-off-by: Andi Kleen <[hidden email]>
Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190402194509.2832-7-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit d3617b98b04583df222f34992e65712862a77bf1)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/lbr.c  | 13 ++++++++++++-
 arch/x86/events/perf_event.h |  1 +
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 58889f952959..b8cac31f089c 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -488,6 +488,8 @@ void intel_pmu_lbr_add(struct perf_event *event)
  * be 'new'. Conversely, a new event can get installed through the
  * context switch path for the first time.
  */
+ if (x86_pmu.intel_cap.pebs_baseline && event->attr.precise_ip > 0)
+ cpuc->lbr_pebs_users++;
  perf_sched_cb_inc(event->ctx->pmu);
  if (!cpuc->lbr_users++ && !event->total_time_running)
  intel_pmu_lbr_reset();
@@ -507,8 +509,11 @@ void intel_pmu_lbr_del(struct perf_event *event)
  task_ctx->lbr_callstack_users--;
  }
 
+ if (x86_pmu.intel_cap.pebs_baseline && event->attr.precise_ip > 0)
+ cpuc->lbr_pebs_users--;
  cpuc->lbr_users--;
  WARN_ON_ONCE(cpuc->lbr_users < 0);
+ WARN_ON_ONCE(cpuc->lbr_pebs_users < 0);
  perf_sched_cb_dec(event->ctx->pmu);
 }
 
@@ -658,7 +663,13 @@ void intel_pmu_lbr_read(void)
 {
  struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 
- if (!cpuc->lbr_users)
+ /*
+ * Don't read when all LBRs users are using adaptive PEBS.
+ *
+ * This could be smarter and actually check the event,
+ * but this simple approach seems to work for now.
+ */
+ if (!cpuc->lbr_users || cpuc->lbr_users == cpuc->lbr_pebs_users)
  return;
 
  if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 84d225cfaacc..cd6984ba50a6 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -234,6 +234,7 @@ struct cpu_hw_events {
  * Intel LBR bits
  */
  int lbr_users;
+ int lbr_pebs_users;
  struct perf_branch_stack lbr_stack;
  struct perf_branch_entry lbr_entries[MAX_LBR_ENTRIES];
  struct er_account *lbr_sel;
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 08/20] perf/x86: Support constraint ranges

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Peter Zijlstra <[hidden email]>

Icelake extended the general counters to 8, even when SMT is enabled.
However only a (large) subset of the events can be used on all 8
counters.

The events that can or cannot be used on all counters are organized
in ranges.

A lot of scheduler constraints are required to handle all this.

To avoid blowing up the tables add event code ranges to the constraint
tables, and a new inline function to match them.

Originally-by: Andi Kleen <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]> # developer hat on
Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]> # maintainer hat on
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190402194509.2832-8-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(backported from commit 63b79f6ebc464afb730bc45762c820795e276da1)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/core.c |  2 +-
 arch/x86/events/intel/ds.c   |  2 +-
 arch/x86/events/perf_event.h | 44 +++++++++++++++++++++++++++++++-----
 3 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 5d7707a5a5d9..360d530df9b3 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2695,7 +2695,7 @@ x86_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
 
  if (x86_pmu.event_constraints) {
  for_each_event_constraint(c, x86_pmu.event_constraints) {
- if ((event->hw.config & c->cmask) == c->code) {
+ if (constraint_match(c, event->hw.config)) {
  event->hw.flags |= c->flags;
  return c;
  }
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 87dd3e7f084e..b80cdec68d21 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -858,7 +858,7 @@ struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 
  if (x86_pmu.pebs_constraints) {
  for_each_event_constraint(c, x86_pmu.pebs_constraints) {
- if ((event->hw.config & c->cmask) == c->code) {
+ if (constraint_match(c, event->hw.config)) {
  event->hw.flags |= c->flags;
  return c;
  }
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index cd6984ba50a6..f3b8743d3372 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -49,12 +49,19 @@ struct event_constraint {
  unsigned long idxmsk[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
  u64 idxmsk64;
  };
- u64 code;
- u64 cmask;
- int weight;
- int overlap;
- int flags;
+ u64 code;
+ u64 cmask;
+ int weight;
+ int overlap;
+ int flags;
+ unsigned int size;
 };
+
+static inline bool constraint_match(struct event_constraint *c, u64 ecode)
+{
+ return ((ecode & c->cmask) - c->code) <= (u64)c->size;
+}
+
 /*
  * struct hw_perf_event.flags flags
  */
@@ -281,18 +288,29 @@ struct cpu_hw_events {
  void *kfree_on_online[X86_PERF_KFREE_MAX];
 };
 
-#define __EVENT_CONSTRAINT(c, n, m, w, o, f) {\
+#define __EVENT_CONSTRAINT_RANGE(c, e, n, m, w, o, f) { \
  { .idxmsk64 = (n) }, \
  .code = (c), \
+ .size = (e) - (c), \
  .cmask = (m), \
  .weight = (w), \
  .overlap = (o), \
  .flags = f, \
 }
 
+#define __EVENT_CONSTRAINT(c, n, m, w, o, f) \
+ __EVENT_CONSTRAINT_RANGE(c, c, n, m, w, o, f)
+
 #define EVENT_CONSTRAINT(c, n, m) \
  __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0, 0)
 
+/*
+ * The constraint_match() function only works for 'simple' event codes
+ * and not for extended (AMD64_EVENTSEL_EVENT) events codes.
+ */
+#define EVENT_CONSTRAINT_RANGE(c, e, n, m) \
+ __EVENT_CONSTRAINT_RANGE(c, e, n, m, HWEIGHT(n), 0, 0)
+
 #define INTEL_EXCLEVT_CONSTRAINT(c, n) \
  __EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT, HWEIGHT(n),\
    0, PERF_X86_EVENT_EXCL)
@@ -327,6 +345,12 @@ struct cpu_hw_events {
 #define INTEL_EVENT_CONSTRAINT(c, n) \
  EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
 
+/*
+ * Constraint on a range of Event codes
+ */
+#define INTEL_EVENT_CONSTRAINT_RANGE(c, e, n) \
+ EVENT_CONSTRAINT_RANGE(c, e, n, ARCH_PERFMON_EVENTSEL_EVENT)
+
 /*
  * Constraint on the Event code + UMask + fixed-mask
  *
@@ -374,6 +398,9 @@ struct cpu_hw_events {
 #define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \
  EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
 
+#define INTEL_FLAGS_EVENT_CONSTRAINT_RANGE(c, e, n) \
+ EVENT_CONSTRAINT_RANGE(c, e, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
+
 /* Check only flags, but allow all event/umask */
 #define INTEL_ALL_EVENT_CONSTRAINT(code, n) \
  EVENT_CONSTRAINT(code, n, X86_ALL_EVENT_FLAGS)
@@ -390,6 +417,11 @@ struct cpu_hw_events {
   ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
   HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
 
+#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(code, end, n) \
+ __EVENT_CONSTRAINT_RANGE(code, end, n, \
+  ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
+  HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW)
+
 #define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_XLD(code, n) \
  __EVENT_CONSTRAINT(code, n, \
   ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 09/20] perf/x86/intel: Fix INTEL_FLAGS_EVENT_CONSTRAINT* masking

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Stephane Eranian <[hidden email]>

On Intel Westmere, a cmdline as follows:

  $ perf record -e cpu/event=0xc4,umask=0x2,name=br_inst_retired.near_call/p ....

was failing. Yet the event+ umask support PEBS.

It turns out this is due to a bug in the the PEBS event constraint table for
westmere. All forms of BR_INST_RETIRED.* support PEBS. Therefore the constraint
mask should ignore the umask. The name of the macro INTEL_FLAGS_EVENT_CONSTRAINT()
hint that this is the case but it was not. That macros was checking both the
event code and event umask. Therefore, it was only matching on 0x00c4.
There are code+umask macros, they all have *UEVENT*.

This bug fixes the issue by checking only the event code in the mask.
Both single and range version are modified.

Signed-off-by: Stephane Eranian <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Link: http://lkml.kernel.org/r/20190509214556.123493-1-eranian@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 6b89d4c1ae8596a8c9240f169ef108704de373f2)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/perf_event.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index f3b8743d3372..11ffb822b9bf 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -396,10 +396,10 @@ struct cpu_hw_events {
 
 /* Event constraint, but match on all event flags too. */
 #define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \
- EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
+ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS)
 
 #define INTEL_FLAGS_EVENT_CONSTRAINT_RANGE(c, e, n) \
- EVENT_CONSTRAINT_RANGE(c, e, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS)
+ EVENT_CONSTRAINT_RANGE(c, e, n, ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS)
 
 /* Check only flags, but allow all event/umask */
 #define INTEL_ALL_EVENT_CONSTRAINT(code, n) \
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 10/20] perf/x86/intel: Add Icelake support

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Add Icelake core PMU perf code, including constraint tables and the main
enable code.

Icelake expanded the generic counters to always 8 even with HT on, but a
range of events cannot be scheduled on the extra 4 counters.
Add new constraint ranges to describe this to the scheduler.
The number of constraints that need to be checked is larger now than
with earlier CPUs.
At some point we may need a new data structure to look them up more
efficiently than with linear search. So far it still seems to be
acceptable however.

Icelake added a new fixed counter SLOTS. Full support for it is added
later in the patch series.

The cache events table is identical to Skylake.

Compare to PEBS instruction event on generic counter, fixed counter 0
has less skid. Force instruction:ppp always in fixed counter 0.

Originally-by: Andi Kleen <[hidden email]>
Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190402194509.2832-9-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 6017608936c1825ff5d7325270484042f597edff)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/core.c      | 111 ++++++++++++++++++++++++++++++
 arch/x86/events/intel/ds.c        |  25 ++++++-
 arch/x86/events/perf_event.h      |   2 +
 arch/x86/include/asm/intel_ds.h   |   2 +-
 arch/x86/include/asm/perf_event.h |   2 +-
 5 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 360d530df9b3..2429bae6f795 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -239,6 +239,35 @@ static struct extra_reg intel_skl_extra_regs[] __read_mostly = {
  EVENT_EXTRA_END
 };
 
+static struct event_constraint intel_icl_event_constraints[] = {
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
+ INTEL_UEVENT_CONSTRAINT(0x1c0, 0), /* INST_RETIRED.PREC_DIST */
+ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
+ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
+ FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */
+ INTEL_EVENT_CONSTRAINT_RANGE(0x03, 0x0a, 0xf),
+ INTEL_EVENT_CONSTRAINT_RANGE(0x1f, 0x28, 0xf),
+ INTEL_EVENT_CONSTRAINT(0x32, 0xf), /* SW_PREFETCH_ACCESS.* */
+ INTEL_EVENT_CONSTRAINT_RANGE(0x48, 0x54, 0xf),
+ INTEL_EVENT_CONSTRAINT_RANGE(0x60, 0x8b, 0xf),
+ INTEL_UEVENT_CONSTRAINT(0x04a3, 0xff),  /* CYCLE_ACTIVITY.STALLS_TOTAL */
+ INTEL_UEVENT_CONSTRAINT(0x10a3, 0xff),  /* CYCLE_ACTIVITY.STALLS_MEM_ANY */
+ INTEL_EVENT_CONSTRAINT(0xa3, 0xf),      /* CYCLE_ACTIVITY.* */
+ INTEL_EVENT_CONSTRAINT_RANGE(0xa8, 0xb0, 0xf),
+ INTEL_EVENT_CONSTRAINT_RANGE(0xb7, 0xbd, 0xf),
+ INTEL_EVENT_CONSTRAINT_RANGE(0xd0, 0xe6, 0xf),
+ INTEL_EVENT_CONSTRAINT_RANGE(0xf0, 0xf4, 0xf),
+ EVENT_CONSTRAINT_END
+};
+
+static struct extra_reg intel_icl_extra_regs[] __read_mostly = {
+ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x3fffff9fffull, RSP_0),
+ INTEL_UEVENT_EXTRA_REG(0x01bb, MSR_OFFCORE_RSP_1, 0x3fffff9fffull, RSP_1),
+ INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd),
+ INTEL_UEVENT_EXTRA_REG(0x01c6, MSR_PEBS_FRONTEND, 0x7fff17, FE),
+ EVENT_EXTRA_END
+};
+
 EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3");
 EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3");
 EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2");
@@ -3373,6 +3402,9 @@ static struct event_constraint counter0_constraint =
 static struct event_constraint counter2_constraint =
  EVENT_CONSTRAINT(0, 0x4, 0);
 
+static struct event_constraint fixed0_constraint =
+ FIXED_EVENT_CONSTRAINT(0x00c0, 0);
+
 static struct event_constraint *
 hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
   struct perf_event *event)
@@ -3391,6 +3423,21 @@ hsw_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
  return c;
 }
 
+static struct event_constraint *
+icl_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+  struct perf_event *event)
+{
+ /*
+ * Fixed counter 0 has less skid.
+ * Force instruction:ppp in Fixed counter 0
+ */
+ if ((event->attr.precise_ip == 3) &&
+    constraint_match(&fixed0_constraint, event->hw.config))
+ return &fixed0_constraint;
+
+ return hsw_get_event_constraints(cpuc, idx, event);
+}
+
 static struct event_constraint *
 glp_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
   struct perf_event *event)
@@ -4151,6 +4198,42 @@ static struct attribute *hsw_tsx_events_attrs[] = {
  NULL
 };
 
+EVENT_ATTR_STR(tx-capacity-read,  tx_capacity_read,  "event=0x54,umask=0x80");
+EVENT_ATTR_STR(tx-capacity-write, tx_capacity_write, "event=0x54,umask=0x2");
+EVENT_ATTR_STR(el-capacity-read,  el_capacity_read,  "event=0x54,umask=0x80");
+EVENT_ATTR_STR(el-capacity-write, el_capacity_write, "event=0x54,umask=0x2");
+
+static struct attribute *icl_events_attrs[] = {
+ EVENT_PTR(mem_ld_hsw),
+ EVENT_PTR(mem_st_hsw),
+ NULL,
+};
+
+static struct attribute *icl_tsx_events_attrs[] = {
+ EVENT_PTR(tx_start),
+ EVENT_PTR(tx_abort),
+ EVENT_PTR(tx_commit),
+ EVENT_PTR(tx_capacity_read),
+ EVENT_PTR(tx_capacity_write),
+ EVENT_PTR(tx_conflict),
+ EVENT_PTR(el_start),
+ EVENT_PTR(el_abort),
+ EVENT_PTR(el_commit),
+ EVENT_PTR(el_capacity_read),
+ EVENT_PTR(el_capacity_write),
+ EVENT_PTR(el_conflict),
+ EVENT_PTR(cycles_t),
+ EVENT_PTR(cycles_ct),
+ NULL,
+};
+
+static __init struct attribute **get_icl_events_attrs(void)
+{
+ return boot_cpu_has(X86_FEATURE_RTM) ?
+ merge_attr(icl_events_attrs, icl_tsx_events_attrs) :
+ icl_events_attrs;
+}
+
 static ssize_t freeze_on_smi_show(struct device *cdev,
   struct device_attribute *attr,
   char *buf)
@@ -4736,6 +4819,34 @@ __init int intel_pmu_init(void)
  name = "skylake";
  break;
 
+ case INTEL_FAM6_ICELAKE_MOBILE:
+ x86_pmu.late_ack = true;
+ memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
+ hw_cache_event_ids[C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = -1;
+ intel_pmu_lbr_init_skl();
+
+ x86_pmu.event_constraints = intel_icl_event_constraints;
+ x86_pmu.pebs_constraints = intel_icl_pebs_event_constraints;
+ x86_pmu.extra_regs = intel_icl_extra_regs;
+ x86_pmu.pebs_aliases = NULL;
+ x86_pmu.pebs_prec_dist = true;
+ x86_pmu.flags |= PMU_FL_HAS_RSP_1;
+ x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
+
+ x86_pmu.hw_config = hsw_hw_config;
+ x86_pmu.get_event_constraints = icl_get_event_constraints;
+ extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
+ hsw_format_attr : nhm_format_attr;
+ extra_attr = merge_attr(extra_attr, skl_format_attr);
+ x86_pmu.cpu_events = get_icl_events_attrs();
+ x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xca, .umask=0x02);
+ x86_pmu.lbr_pt_coexist = true;
+ intel_pmu_pebs_data_source_skl(false);
+ pr_cont("Icelake events, ");
+ name = "icelake";
+ break;
+
  default:
  switch (x86_pmu.version) {
  case 1:
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index b80cdec68d21..7acc526b4ad2 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -849,6 +849,26 @@ struct event_constraint intel_skl_pebs_event_constraints[] = {
  EVENT_CONSTRAINT_END
 };
 
+struct event_constraint intel_icl_pebs_event_constraints[] = {
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x100000000ULL), /* INST_RETIRED.PREC_DIST */
+ INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x400000000ULL), /* SLOTS */
+
+ INTEL_PLD_CONSTRAINT(0x1cd, 0xff), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf), /* MEM_INST_RETIRED.LOAD */
+ INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf), /* MEM_INST_RETIRED.STORE */
+
+ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), /* MEM_LOAD_*_RETIRED.* */
+
+ INTEL_FLAGS_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_INST_RETIRED.* */
+
+ /*
+ * Everything else is handled by PMU_FL_PEBS_ALL, because we
+ * need the full constraints from the main table.
+ */
+
+ EVENT_CONSTRAINT_END
+};
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 {
  struct event_constraint *c;
@@ -1053,7 +1073,7 @@ void intel_pmu_pebs_enable(struct perf_event *event)
 
  cpuc->pebs_enabled |= 1ULL << hwc->idx;
 
- if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
+ if ((event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) && (x86_pmu.version < 5))
  cpuc->pebs_enabled |= 1ULL << (hwc->idx + 32);
  else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
  cpuc->pebs_enabled |= 1ULL << 63;
@@ -1105,7 +1125,8 @@ void intel_pmu_pebs_disable(struct perf_event *event)
 
  cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
 
- if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT)
+ if ((event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) &&
+    (x86_pmu.version < 5))
  cpuc->pebs_enabled &= ~(1ULL << (hwc->idx + 32));
  else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
  cpuc->pebs_enabled &= ~(1ULL << 63);
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 11ffb822b9bf..0cad3342d289 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -1000,6 +1000,8 @@ extern struct event_constraint intel_bdw_pebs_event_constraints[];
 
 extern struct event_constraint intel_skl_pebs_event_constraints[];
 
+extern struct event_constraint intel_icl_pebs_event_constraints[];
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
 
 void intel_pmu_pebs_add(struct perf_event *event);
diff --git a/arch/x86/include/asm/intel_ds.h b/arch/x86/include/asm/intel_ds.h
index ae26df1c2789..8380c3ddd4b2 100644
--- a/arch/x86/include/asm/intel_ds.h
+++ b/arch/x86/include/asm/intel_ds.h
@@ -8,7 +8,7 @@
 
 /* The maximal number of PEBS events: */
 #define MAX_PEBS_EVENTS 8
-#define MAX_FIXED_PEBS_EVENTS 3
+#define MAX_FIXED_PEBS_EVENTS 4
 
 /*
  * A debug store configuration.
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index fbdc2e8fc5aa..e4ee68d6cf1e 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -7,7 +7,7 @@
  */
 
 #define INTEL_PMC_MAX_GENERIC       32
-#define INTEL_PMC_MAX_FIXED 3
+#define INTEL_PMC_MAX_FIXED 4
 #define INTEL_PMC_IDX_FIXED       32
 
 #define X86_PMC_IDX_MAX       64
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 11/20] perf/x86/intel/uncore: Add Intel Icelake uncore support

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Add Intel Icelake uncore support:

 - The init code is based on Skylake
 - Add new PCI id for IMC
 - New MSR address for CBOX
 - Get CBOX# from CNL_UNC_CBO_CONFIG MSR directly
 - Create a new PMU for fixed clocktick counter

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Alexander Shishkin <[hidden email]>
Cc: Arnaldo Carvalho de Melo <[hidden email]>
Cc: Jiri Olsa <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Stephane Eranian <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: Vince Weaver <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190402194509.2832-13-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 6e394376ee89233508fa21d006546357f8efee31)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/uncore.c     |  6 ++
 arch/x86/events/intel/uncore.h     |  1 +
 arch/x86/events/intel/uncore_snb.c | 91 ++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+)

diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 2690135bf83f..31abdd6a3832 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1374,6 +1374,11 @@ static const struct intel_uncore_init_fun skx_uncore_init __initconst = {
  .pci_init = skx_uncore_pci_init,
 };
 
+static const struct intel_uncore_init_fun icl_uncore_init __initconst = {
+ .cpu_init = icl_uncore_cpu_init,
+ .pci_init = skl_uncore_pci_init,
+};
+
 static const struct x86_cpu_id intel_uncore_match[] __initconst = {
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_NEHALEM_EP,  nhm_uncore_init),
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_NEHALEM,  nhm_uncore_init),
@@ -1400,6 +1405,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X,      skx_uncore_init),
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE, skl_uncore_init),
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_uncore_init),
+ X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, icl_uncore_init),
  {},
 };
 
diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
index b24da63459c4..28499e39679f 100644
--- a/arch/x86/events/intel/uncore.h
+++ b/arch/x86/events/intel/uncore.h
@@ -522,6 +522,7 @@ int skl_uncore_pci_init(void);
 void snb_uncore_cpu_init(void);
 void nhm_uncore_cpu_init(void);
 void skl_uncore_cpu_init(void);
+void icl_uncore_cpu_init(void);
 int snb_pci2phy_map_init(int devid);
 
 /* uncore_snbep.c */
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index ef7faf486a1a..32bac590242c 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -34,6 +34,8 @@
 #define PCI_DEVICE_ID_INTEL_CFL_4S_S_IMC 0x3e33
 #define PCI_DEVICE_ID_INTEL_CFL_6S_S_IMC 0x3eca
 #define PCI_DEVICE_ID_INTEL_CFL_8S_S_IMC 0x3e32
+#define PCI_DEVICE_ID_INTEL_ICL_U_IMC 0x8a02
+#define PCI_DEVICE_ID_INTEL_ICL_U2_IMC 0x8a12
 
 /* SNB event control */
 #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff
@@ -93,6 +95,12 @@
 #define SKL_UNC_PERF_GLOBAL_CTL 0xe01
 #define SKL_UNC_GLOBAL_CTL_CORE_ALL ((1 << 5) - 1)
 
+/* ICL Cbo register */
+#define ICL_UNC_CBO_CONFIG 0x396
+#define ICL_UNC_NUM_CBO_MASK 0xf
+#define ICL_UNC_CBO_0_PER_CTR0 0x702
+#define ICL_UNC_CBO_MSR_OFFSET 0x8
+
 DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
 DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
 DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
@@ -280,6 +288,70 @@ void skl_uncore_cpu_init(void)
  snb_uncore_arb.ops = &skl_uncore_msr_ops;
 }
 
+static struct intel_uncore_type icl_uncore_cbox = {
+ .name = "cbox",
+ .num_counters   = 4,
+ .perf_ctr_bits = 44,
+ .perf_ctr = ICL_UNC_CBO_0_PER_CTR0,
+ .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0,
+ .event_mask = SNB_UNC_RAW_EVENT_MASK,
+ .msr_offset = ICL_UNC_CBO_MSR_OFFSET,
+ .ops = &skl_uncore_msr_ops,
+ .format_group = &snb_uncore_format_group,
+};
+
+static struct uncore_event_desc icl_uncore_events[] = {
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff"),
+ { /* end: all zeroes */ },
+};
+
+static struct attribute *icl_uncore_clock_formats_attr[] = {
+ &format_attr_event.attr,
+ NULL,
+};
+
+static struct attribute_group icl_uncore_clock_format_group = {
+ .name = "format",
+ .attrs = icl_uncore_clock_formats_attr,
+};
+
+static struct intel_uncore_type icl_uncore_clockbox = {
+ .name = "clock",
+ .num_counters = 1,
+ .num_boxes = 1,
+ .fixed_ctr_bits = 48,
+ .fixed_ctr = SNB_UNC_FIXED_CTR,
+ .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL,
+ .single_fixed = 1,
+ .event_mask = SNB_UNC_CTL_EV_SEL_MASK,
+ .format_group = &icl_uncore_clock_format_group,
+ .ops = &skl_uncore_msr_ops,
+ .event_descs = icl_uncore_events,
+};
+
+static struct intel_uncore_type *icl_msr_uncores[] = {
+ &icl_uncore_cbox,
+ &snb_uncore_arb,
+ &icl_uncore_clockbox,
+ NULL,
+};
+
+static int icl_get_cbox_num(void)
+{
+ u64 num_boxes;
+
+ rdmsrl(ICL_UNC_CBO_CONFIG, num_boxes);
+
+ return num_boxes & ICL_UNC_NUM_CBO_MASK;
+}
+
+void icl_uncore_cpu_init(void)
+{
+ uncore_msr_uncores = icl_msr_uncores;
+ icl_uncore_cbox.num_boxes = icl_get_cbox_num();
+ snb_uncore_arb.ops = &skl_uncore_msr_ops;
+}
+
 enum {
  SNB_PCI_UNCORE_IMC,
 };
@@ -673,6 +745,18 @@ static const struct pci_device_id skl_uncore_pci_ids[] = {
  { /* end: all zeroes */ },
 };
 
+static const struct pci_device_id icl_uncore_pci_ids[] = {
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICL_U_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* IMC */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICL_U2_IMC),
+ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+ },
+ { /* end: all zeroes */ },
+};
+
 static struct pci_driver snb_uncore_pci_driver = {
  .name = "snb_uncore",
  .id_table = snb_uncore_pci_ids,
@@ -698,6 +782,11 @@ static struct pci_driver skl_uncore_pci_driver = {
  .id_table = skl_uncore_pci_ids,
 };
 
+static struct pci_driver icl_uncore_pci_driver = {
+ .name = "icl_uncore",
+ .id_table = icl_uncore_pci_ids,
+};
+
 struct imc_uncore_pci_dev {
  __u32 pci_id;
  struct pci_driver *driver;
@@ -737,6 +826,8 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
  IMC_DEV(CFL_4S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 4 Cores Server */
  IMC_DEV(CFL_6S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 6 Cores Server */
  IMC_DEV(CFL_8S_S_IMC, &skl_uncore_pci_driver),  /* 8th Gen Core S 8 Cores Server */
+ IMC_DEV(ICL_U_IMC, &icl_uncore_pci_driver), /* 10th Gen Core Mobile */
+ IMC_DEV(ICL_U2_IMC, &icl_uncore_pci_driver), /* 10th Gen Core Mobile */
  {  /* end marker */ }
 };
 
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 12/20] perf/x86: Add Intel Ice Lake NNPI uncore support

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Rajneesh Bhardwaj <[hidden email]>

Intel Ice Lake uncore support already included IMC PCI ID but ICL-NNPI
CPUID is missing so add it to fix the probe function.

Fixes: e39875d15ad6 ("perf/x86: add Intel Icelake uncore support")
Signed-off-by: Rajneesh Bhardwaj <[hidden email]>
Signed-off-by: Thomas Gleixner <[hidden email]>
Acked-by: Peter Zijlstra <[hidden email]>
Cc: [hidden email]
Cc: Dave Hansen <[hidden email]>
Cc: Andy Shevchenko <[hidden email]>
Cc: "H. Peter Anvin" <[hidden email]>
Cc: Kan Liang <[hidden email]>
Cc: Qiuxu Zhuo <[hidden email]>
Cc: Srinivas Pandruvada <[hidden email]>
Cc: Len Brown <[hidden email]>
Cc: Linux PM <[hidden email]>
Link: https://lkml.kernel.org/r/20190614081701.13828-1-rajneesh.bhardwaj@...

(cherry picked from commit 5f4318c1b1d23a9290e4def78ee76017c288bf60)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/uncore.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 31abdd6a3832..39c9d35eddeb 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1406,6 +1406,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_MOBILE, skl_uncore_init),
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_uncore_init),
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, icl_uncore_init),
+ X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_NNPI, icl_uncore_init),
  {},
 };
 
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 13/20] perf/x86/intel: Add Icelake desktop CPUID

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Add new Icelake desktop CPUID for RAPL, CSTATE and UNCORE.

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190603134122.13853-3-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit 2a538fda82824a7722e296be656bb5d11d91a9cb)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/cstate.c | 1 +
 arch/x86/events/intel/rapl.c   | 1 +
 arch/x86/events/intel/uncore.c | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 4a650eb3d94a..6ced141d16b8 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -586,6 +586,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
  X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates),
 
  X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_MOBILE, snb_cstates),
+ X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_DESKTOP, snb_cstates),
  { },
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
index 2413169ce362..eb052addefce 100644
--- a/arch/x86/events/intel/rapl.c
+++ b/arch/x86/events/intel/rapl.c
@@ -782,6 +782,7 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
  X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_PLUS, hsw_rapl_init),
 
  X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE,  skl_rapl_init),
+ X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_DESKTOP, skl_rapl_init),
  {},
 };
 
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 39c9d35eddeb..a55383c6eb4c 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1407,6 +1407,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_uncore_init),
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_MOBILE, icl_uncore_init),
  X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_NNPI, icl_uncore_init),
+ X86_UNCORE_MODEL_MATCH(INTEL_FAM6_ICELAKE_DESKTOP, icl_uncore_init),
  {},
 };
 
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 14/20] perf/x86/intel: Add more Icelake CPUIDs

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Add new model number for Icelake desktop and server to perf.

The data source encoding for Icelake server is the same as Skylake
server.

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: [hidden email]
Cc: [hidden email]
Cc: [hidden email]
Cc: [hidden email]
Link: https://lkml.kernel.org/r/20190603134122.13853-2-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(cherry picked from commit faaeff98666c24376cebd0b106504d05a36881d1)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/core.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 2429bae6f795..1ab96f58987e 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4346,6 +4346,7 @@ __init int intel_pmu_init(void)
  struct event_constraint *c;
  unsigned int unused;
  struct extra_reg *er;
+ bool pmem = false;
  int version, i;
  char *name;
 
@@ -4769,9 +4770,10 @@ __init int intel_pmu_init(void)
  name = "knights-landing";
  break;
 
+ case INTEL_FAM6_SKYLAKE_X:
+ pmem = true;
  case INTEL_FAM6_SKYLAKE_MOBILE:
  case INTEL_FAM6_SKYLAKE_DESKTOP:
- case INTEL_FAM6_SKYLAKE_X:
  case INTEL_FAM6_KABYLAKE_MOBILE:
  case INTEL_FAM6_KABYLAKE_DESKTOP:
  x86_add_quirk(intel_pebs_isolation_quirk);
@@ -4804,8 +4806,7 @@ __init int intel_pmu_init(void)
  x86_pmu.cpu_events = hsw_events_attrs;
  mem_attr = hsw_mem_events_attrs;
  tsx_attr = hsw_tsx_events_attrs;
- intel_pmu_pebs_data_source_skl(
- boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X);
+ intel_pmu_pebs_data_source_skl(pmem);
 
  if (boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)) {
  x86_pmu.flags |= PMU_FL_TFA;
@@ -4819,7 +4820,11 @@ __init int intel_pmu_init(void)
  name = "skylake";
  break;
 
+ case INTEL_FAM6_ICELAKE_X:
+ case INTEL_FAM6_ICELAKE_XEON_D:
+ pmem = true;
  case INTEL_FAM6_ICELAKE_MOBILE:
+ case INTEL_FAM6_ICELAKE_DESKTOP:
  x86_pmu.late_ack = true;
  memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
  memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
@@ -4842,7 +4847,7 @@ __init int intel_pmu_init(void)
  x86_pmu.cpu_events = get_icl_events_attrs();
  x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xca, .umask=0x02);
  x86_pmu.lbr_pt_coexist = true;
- intel_pmu_pebs_data_source_skl(false);
+ intel_pmu_pebs_data_source_skl(pmem);
  pr_cont("Icelake events, ");
  name = "icelake";
  break;
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 15/20] x86/cpu: Add Comet Lake to the Intel CPU models header

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Comet Lake is the new 10th Gen Intel processor. Add two new CPU model
numbers to the Intel family list.

The CPU model numbers are not published in the SDM yet but they come
from an authoritative internal source.

 [ bp: Touch up commit message. ]

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Borislav Petkov <[hidden email]>
Reviewed-by: Tony Luck <[hidden email]>
Cc: [hidden email]
Cc: "H. Peter Anvin" <[hidden email]>
Cc: Ingo Molnar <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Cc: x86-ml <[hidden email]>
Link: https://lkml.kernel.org/r/1570549810-25049-2-git-send-email-kan.liang@...
(cherry picked from commit 8d7c6ac3b2371eb1cbc9925a88f4d10efff374de)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/include/asm/intel-family.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
index 7993a2b79a38..9782ed6f32af 100644
--- a/arch/x86/include/asm/intel-family.h
+++ b/arch/x86/include/asm/intel-family.h
@@ -64,6 +64,9 @@
 #define INTEL_FAM6_TIGERLAKE_L 0x8C
 #define INTEL_FAM6_TIGERLAKE 0x8D
 
+#define INTEL_FAM6_COMETLAKE 0xA5
+#define INTEL_FAM6_COMETLAKE_L 0xA6
+
 /* "Small Core" Processors (Atom) */
 
 #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 16/20] perf/x86/intel: Add Comet Lake CPU support

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Comet Lake is the new 10th Gen Intel processor. From the perspective
of Intel PMU, there is nothing changed compared with Sky Lake.
Share the perf code with Sky Lake.

The patch has been tested on real hardware.

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Link: https://lkml.kernel.org/r/1570549810-25049-3-git-send-email-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(backported from commit 9066288b2aab1804dc1eebec6ff88474363b89cb)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 1ab96f58987e..c7e8b41ba528 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4776,6 +4776,8 @@ __init int intel_pmu_init(void)
  case INTEL_FAM6_SKYLAKE_DESKTOP:
  case INTEL_FAM6_KABYLAKE_MOBILE:
  case INTEL_FAM6_KABYLAKE_DESKTOP:
+ case INTEL_FAM6_COMETLAKE_L:
+ case INTEL_FAM6_COMETLAKE:
  x86_add_quirk(intel_pebs_isolation_quirk);
  x86_pmu.late_ack = true;
  memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 17/20] perf/x86/msr: Add Comet Lake CPU support

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Comet Lake is the new 10th Gen Intel processor. PPERF and SMI_COUNT MSRs
are also supported.

The External Design Specification (EDS) is not published yet. It comes
from an authoritative internal source.

The patch has been tested on real hardware.

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Link: https://lkml.kernel.org/r/1570549810-25049-4-git-send-email-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(backported from commit 9674b1cc0f94c34f76e58c102623a866836f269e)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/msr.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
index ace6c1e752fb..6f327c612bcf 100644
--- a/arch/x86/events/msr.c
+++ b/arch/x86/events/msr.c
@@ -89,6 +89,8 @@ static bool test_intel(int idx)
  case INTEL_FAM6_SKYLAKE_X:
  case INTEL_FAM6_KABYLAKE_MOBILE:
  case INTEL_FAM6_KABYLAKE_DESKTOP:
+ case INTEL_FAM6_COMETLAKE_L:
+ case INTEL_FAM6_COMETLAKE:
  case INTEL_FAM6_ICELAKE_MOBILE:
  if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
  return true;
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 18/20] perf/x86/cstate: Add Comet Lake CPU support

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

Comet Lake is the new 10th Gen Intel processor. From the perspective of
Intel cstate residency counters, there is nothing changed compared with
Kaby Lake.

Share hswult_cstates with Kaby Lake.
Update the comments for Comet Lake.
Kaby Lake is missed in the comments for some Residency Counters. Update
the comments for Kaby Lake as well.

The External Design Specification (EDS) is not published yet. It comes
from an authoritative internal source.

The patch has been tested on real hardware.

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Link: https://lkml.kernel.org/r/1570549810-25049-5-git-send-email-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(backported from commit 1ffa6c04dae39776a3c222bdf88051e394386c01)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/intel/cstate.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 6ced141d16b8..09928a5bebef 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -45,46 +45,48 @@
  * MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
  *       perf code: 0x01
  *       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,GLM,
- CNL
+ * CNL,KBL,CML
  *       Scope: Core
  * MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter
  *       perf code: 0x02
  *       Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
- * SKL,KNL,GLM,CNL
+ * SKL,KNL,GLM,CNL,KBL,CML
  *       Scope: Core
  * MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
  *       perf code: 0x03
- *       Available model: SNB,IVB,HSW,BDW,SKL,CNL
+ *       Available model: SNB,IVB,HSW,BDW,SKL,CNL,KBL,CML
  *       Scope: Core
  * MSR_PKG_C2_RESIDENCY:  Package C2 Residency Counter.
  *       perf code: 0x00
- *       Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL
+ *       Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL,
+ * KBL,CML
  *       Scope: Package (physical package)
  * MSR_PKG_C3_RESIDENCY:  Package C3 Residency Counter.
  *       perf code: 0x01
  *       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL,
- * GLM,CNL
+ * GLM,CNL,KBL,CML
  *       Scope: Package (physical package)
  * MSR_PKG_C6_RESIDENCY:  Package C6 Residency Counter.
  *       perf code: 0x02
  *       Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW
- * SKL,KNL,GLM,CNL
+ * SKL,KNL,GLM,CNL,KBL,CML
  *       Scope: Package (physical package)
  * MSR_PKG_C7_RESIDENCY:  Package C7 Residency Counter.
  *       perf code: 0x03
- *       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL
+ *       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL,
+ * KBL,CML
  *       Scope: Package (physical package)
  * MSR_PKG_C8_RESIDENCY:  Package C8 Residency Counter.
  *       perf code: 0x04
- *       Available model: HSW ULT,KBL,CNL
+ *       Available model: HSW ULT,KBL,CNL,CML
  *       Scope: Package (physical package)
  * MSR_PKG_C9_RESIDENCY:  Package C9 Residency Counter.
  *       perf code: 0x05
- *       Available model: HSW ULT,KBL,CNL
+ *       Available model: HSW ULT,KBL,CNL,CML
  *       Scope: Package (physical package)
  * MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
  *       perf code: 0x06
- *       Available model: HSW ULT,KBL,GLM,CNL
+ *       Available model: HSW ULT,KBL,GLM,CNL,CML
  *       Scope: Package (physical package)
  *
  */
@@ -574,6 +576,8 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
 
  X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE,  hswult_cstates),
  X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_DESKTOP, hswult_cstates),
+ X86_CSTATES_MODEL(INTEL_FAM6_COMETLAKE_L, hswult_cstates),
+ X86_CSTATES_MODEL(INTEL_FAM6_COMETLAKE, hswult_cstates),
 
  X86_CSTATES_MODEL(INTEL_FAM6_CANNONLAKE_MOBILE, cnl_cstates),
 
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][D/OEM-OSP1-B][PATCH v2 19/20] perf/x86/msr: Add new CPU model numbers for Ice Lake

You-Sheng Yang
In reply to this post by You-Sheng Yang
From: Kan Liang <[hidden email]>

PPERF and SMI_COUNT MSRs are also supported by Ice Lake desktop and
server.

Signed-off-by: Kan Liang <[hidden email]>
Signed-off-by: Peter Zijlstra (Intel) <[hidden email]>
Cc: Linus Torvalds <[hidden email]>
Cc: Peter Zijlstra <[hidden email]>
Cc: Thomas Gleixner <[hidden email]>
Link: https://lkml.kernel.org/r/1570549810-25049-6-git-send-email-kan.liang@...
Signed-off-by: Ingo Molnar <[hidden email]>
(backported from commit 1a5da78d00ce0152994946debd1417513dc35eb3)
Signed-off-by: You-Sheng Yang <[hidden email]>
---
 arch/x86/events/msr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
index 6f327c612bcf..10604a5f1644 100644
--- a/arch/x86/events/msr.c
+++ b/arch/x86/events/msr.c
@@ -92,6 +92,9 @@ static bool test_intel(int idx)
  case INTEL_FAM6_COMETLAKE_L:
  case INTEL_FAM6_COMETLAKE:
  case INTEL_FAM6_ICELAKE_MOBILE:
+ case INTEL_FAM6_ICELAKE_DESKTOP:
+ case INTEL_FAM6_ICELAKE_X:
+ case INTEL_FAM6_ICELAKE_XEON_D:
  if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
  return true;
  break;
--
2.24.0


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
12