linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: kan.liang@linux.intel.com
To: peterz@infradead.org, acme@kernel.org, mingo@redhat.com,
	linux-kernel@vger.kernel.org
Cc: tglx@linutronix.de, jolsa@kernel.org, eranian@google.com,
	alexander.shishkin@linux.intel.com, ak@linux.intel.com,
	Kan Liang <kan.liang@linux.intel.com>
Subject: [PATCH V2 01/23] perf/x86: Support outputting XMM registers
Date: Thu, 21 Mar 2019 13:56:41 -0700	[thread overview]
Message-ID: <20190321205703.4256-2-kan.liang@linux.intel.com> (raw)
In-Reply-To: <20190321205703.4256-1-kan.liang@linux.intel.com>

From: Kan Liang <kan.liang@linux.intel.com>

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.
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.
PERF_REG_X86_MAX stands for the max number of all x86 regs include XMM.
PERF_REG_GPR_X86_MAX stands for the max number of all x86 general
purpose registers, which not include XMM.
PERF_REG_GPR_X86_32_MAX and PERF_REG_GPR_X86_64_MAX are introduced to
replace PERF_REG_X86_32_MAX and PERF_REG_X86_64_MAX for x86 general
purpose registers.

The REG_RESERVED is also updated to allow the XMM registers.
XMM is not supported on all platforms. Adding has_xmm_regs to indicate
the specific platform. Also add checks in x86_pmu_hw_config() to reject
invalid config of regs_user and regs_intr.

Originally-by: Andi Kleen <ak@linux.intel.com>
Suggested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
---

Changes since V1:
- Avoid the interface changes for perf_reg_value() and
  perf_output_sample_regs().
- Remove the extra_regs in struct perf_sample_data.
- Add struct x86_perf_regs
- Add has_xmm_regs to indicate the specific platform which support XMM
  registers collection.
- Add check in x86_pmu_hw_config() to reject invalid config of regs_user
  and regs_intr.

 arch/x86/events/core.c                | 10 ++++++++++
 arch/x86/events/perf_event.h          |  2 ++
 arch/x86/include/asm/perf_event.h     |  5 +++++
 arch/x86/include/uapi/asm/perf_regs.h | 26 ++++++++++++++++++++++++--
 arch/x86/kernel/perf_regs.c           | 18 ++++++++++++++----
 5 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index e2b1447192a8..9378c6b2128f 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -560,6 +560,16 @@ int x86_pmu_hw_config(struct perf_event *event)
 			return -EINVAL;
 	}
 
+	if (event->attr.sample_regs_user & ~PEBS_REGS)
+		return -EINVAL;
+	/*
+	 * Besides the general purpose registers, XMM registers may
+	 * be collected in PEBS on some platforms, e.g. Icelake
+	 */
+	if ((event->attr.sample_regs_intr & ~PEBS_REGS) &&
+	    (!x86_pmu.has_xmm_regs || !event->attr.precise_ip))
+		return -EINVAL;
+
 	return x86_setup_perfctr(event);
 }
 
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index a75955741c50..6428941a5073 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -657,6 +657,8 @@ struct x86_pmu {
 	 * Check period value for PERF_EVENT_IOC_PERIOD ioctl.
 	 */
 	int (*check_period) (struct perf_event *event, u64 period);
+
+	unsigned int	has_xmm_regs : 1; /* support XMM regs */
 };
 
 struct x86_perf_task_context {
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 8bdf74902293..d9f5bbe44b3c 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -248,6 +248,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..b33995313d17 100644
--- a/arch/x86/include/uapi/asm/perf_regs.h
+++ b/arch/x86/include/uapi/asm/perf_regs.h
@@ -28,7 +28,29 @@ enum perf_event_x86_regs {
 	PERF_REG_X86_R14,
 	PERF_REG_X86_R15,
 
-	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,
+
+	/* This does not include the XMMX registers */
+	PERF_REG_GPR_X86_32_MAX = PERF_REG_X86_GS + 1,
+	PERF_REG_GPR_X86_64_MAX = PERF_REG_X86_R15 + 1,
+
+	/* All registers include the XMMX registers */
+	PERF_REG_X86_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..421d76895565 100644
--- a/arch/x86/kernel/perf_regs.c
+++ b/arch/x86/kernel/perf_regs.c
@@ -10,14 +10,14 @@
 #include <asm/ptrace.h>
 
 #ifdef CONFIG_X86_32
-#define PERF_REG_X86_MAX PERF_REG_X86_32_MAX
+#define PERF_REG_GPR_X86_MAX PERF_REG_GPR_X86_32_MAX
 #else
-#define PERF_REG_X86_MAX PERF_REG_X86_64_MAX
+#define PERF_REG_GPR_X86_MAX PERF_REG_GPR_X86_64_MAX
 #endif
 
 #define PT_REGS_OFFSET(id, r) [id] = offsetof(struct pt_regs, r)
 
-static unsigned int pt_regs_offset[PERF_REG_X86_MAX] = {
+static unsigned int pt_regs_offset[PERF_REG_GPR_X86_MAX] = {
 	PT_REGS_OFFSET(PERF_REG_X86_AX, ax),
 	PT_REGS_OFFSET(PERF_REG_X86_BX, bx),
 	PT_REGS_OFFSET(PERF_REG_X86_CX, cx),
@@ -59,13 +59,23 @@ 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_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))
+#define REG_RESERVED \
+	(PERF_REG_X86_MAX == 64 ? 0 : ~((1ULL << PERF_REG_X86_MAX)) - 1ULL)
 
 #ifdef CONFIG_X86_32
 int perf_reg_validate(u64 mask)
-- 
2.17.1


  reply	other threads:[~2019-03-21 20:59 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-21 20:56 [PATCH V2 00/23] perf: Add Icelake support kan.liang
2019-03-21 20:56 ` kan.liang [this message]
2019-03-21 20:56 ` [PATCH V2 02/23] perf/x86/intel: Extract memory code PEBS parser for reuse kan.liang
2019-03-21 20:56 ` [PATCH V2 03/23] perf/x86/intel/ds: Extract code of event update in short period kan.liang
2019-03-21 20:56 ` [PATCH V2 04/23] perf/x86/intel: Support adaptive PEBSv4 kan.liang
2019-03-21 21:13   ` Peter Zijlstra
2019-03-21 21:17   ` Peter Zijlstra
2019-03-21 21:20   ` Peter Zijlstra
2019-03-22  0:40     ` Liang, Kan
2019-03-22 12:30       ` Peter Zijlstra
2019-03-21 20:56 ` [PATCH V2 05/23] perf/x86/lbr: Avoid reading the LBRs when adaptive PEBS handles them kan.liang
2019-03-21 20:56 ` [PATCH V2 06/23] perf/x86: Support constraint ranges kan.liang
2019-03-21 21:09   ` Peter Zijlstra
2019-03-21 20:56 ` [PATCH V2 07/23] perf/x86/intel: Add Icelake support kan.liang
2019-03-21 20:56 ` [PATCH V2 08/23] perf/x86/intel/cstate: " kan.liang
2019-03-21 20:56 ` [PATCH V2 09/23] perf/x86/intel/rapl: " kan.liang
2019-03-21 20:56 ` [PATCH V2 10/23] perf/x86/msr: " kan.liang
2019-03-21 20:56 ` [PATCH V2 11/23] perf/x86/intel/uncore: Add Intel Icelake uncore support kan.liang
2019-03-21 20:56 ` [PATCH V2 12/23] perf/core: Support a REMOVE transaction kan.liang
2019-03-21 20:56 ` [PATCH V2 13/23] perf/x86/intel: Basic support for metrics counters kan.liang
2019-03-21 20:56 ` [PATCH V2 14/23] perf/x86/intel: Support overflows on SLOTS kan.liang
2019-03-21 20:56 ` [PATCH V2 15/23] perf/x86/intel: Support hardware TopDown metrics kan.liang
2019-03-21 20:56 ` [PATCH V2 16/23] perf/x86/intel: Set correct weight for topdown subevent counters kan.liang
2019-03-21 20:56 ` [PATCH V2 17/23] perf/x86/intel: Export new top down events for Icelake kan.liang
2019-03-21 20:56 ` [PATCH V2 18/23] perf/x86/intel: Disable sampling read slots and topdown kan.liang
2019-03-21 20:56 ` [PATCH V2 19/23] perf/x86/intel: Support CPUID 10.ECX to disable fixed counters kan.liang
2019-03-21 20:57 ` [PATCH V2 20/23] perf, tools: Add support for recording and printing XMM registers kan.liang
2019-03-21 20:57 ` [PATCH V2 21/23] perf, tools, stat: Support new per thread TopDown metrics kan.liang
2019-03-21 20:57 ` [PATCH V2 22/23] perf, tools: Add documentation for topdown metrics kan.liang
2019-03-21 20:57 ` [PATCH V2 23/23] perf vendor events intel: Add JSON files for Icelake kan.liang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190321205703.4256-2-kan.liang@linux.intel.com \
    --to=kan.liang@linux.intel.com \
    --cc=acme@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=eranian@google.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).