All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 1/3] perf parse-regs: Split parse_regs
@ 2019-05-14 20:19 kan.liang
  2019-05-14 20:19 ` [PATCH V2 2/3] perf parse-regs: Add generic support for arch__intr/user_reg_mask() kan.liang
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: kan.liang @ 2019-05-14 20:19 UTC (permalink / raw)
  To: acme, jolsa, mingo, linux-kernel; +Cc: ak, Kan Liang

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

The available registers for --int-regs and --user-regs may be different,
e.g. XMM registers.

Split parse_regs into two dedicated functions for --int-regs and
--user-regs respectively.

Modify the warning message. "--user-regs=?" should be applied to show
the available registers for --user-regs.

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
---

No changes since V1

 tools/perf/builtin-record.c          |  4 ++--
 tools/perf/util/parse-regs-options.c | 19 ++++++++++++++++---
 tools/perf/util/parse-regs-options.h |  3 ++-
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 386e665..45172bb 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -2029,10 +2029,10 @@ static struct option __record_options[] = {
 		    "use per-thread mmaps"),
 	OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
 		    "sample selected machine registers on interrupt,"
-		    " use '-I?' to list register names", parse_regs),
+		    " use '-I?' to list register names", parse_intr_regs),
 	OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
 		    "sample selected machine registers on interrupt,"
-		    " use '-I?' to list register names", parse_regs),
+		    " use '--user-regs=?' to list register names", parse_user_regs),
 	OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
 		    "Record running/enabled time of read (:S) events"),
 	OPT_CALLBACK('k', "clockid", &record.opts,
diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
index 9cb187a..b21617f 100644
--- a/tools/perf/util/parse-regs-options.c
+++ b/tools/perf/util/parse-regs-options.c
@@ -5,8 +5,8 @@
 #include <subcmd/parse-options.h>
 #include "util/parse-regs-options.h"
 
-int
-parse_regs(const struct option *opt, const char *str, int unset)
+static int
+__parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 {
 	uint64_t *mode = (uint64_t *)opt->value;
 	const struct sample_reg *r;
@@ -48,7 +48,8 @@ parse_regs(const struct option *opt, const char *str, int unset)
 					break;
 			}
 			if (!r->name) {
-				ui__warning("Unknown register \"%s\", check man page or run \"perf record -I?\"\n", s);
+				ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n",
+					    s, intr ? "-I" : "--user-regs=");
 				goto error;
 			}
 
@@ -69,3 +70,15 @@ parse_regs(const struct option *opt, const char *str, int unset)
 	free(os);
 	return ret;
 }
+
+int
+parse_user_regs(const struct option *opt, const char *str, int unset)
+{
+	return __parse_regs(opt, str, unset, false);
+}
+
+int
+parse_intr_regs(const struct option *opt, const char *str, int unset)
+{
+	return __parse_regs(opt, str, unset, true);
+}
diff --git a/tools/perf/util/parse-regs-options.h b/tools/perf/util/parse-regs-options.h
index cdefb1a..2b23d25 100644
--- a/tools/perf/util/parse-regs-options.h
+++ b/tools/perf/util/parse-regs-options.h
@@ -2,5 +2,6 @@
 #ifndef _PERF_PARSE_REGS_OPTIONS_H
 #define _PERF_PARSE_REGS_OPTIONS_H 1
 struct option;
-int parse_regs(const struct option *opt, const char *str, int unset);
+int parse_user_regs(const struct option *opt, const char *str, int unset);
+int parse_intr_regs(const struct option *opt, const char *str, int unset);
 #endif /* _PERF_PARSE_REGS_OPTIONS_H */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH V2 2/3] perf parse-regs: Add generic support for arch__intr/user_reg_mask()
  2019-05-14 20:19 [PATCH V2 1/3] perf parse-regs: Split parse_regs kan.liang
@ 2019-05-14 20:19 ` kan.liang
  2019-05-18  9:31   ` [tip:perf/core] " tip-bot for Kan Liang
  2019-05-14 20:19 ` [PATCH V2 3/3] perf regs x86: Add X86 specific arch__intr_reg_mask() kan.liang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: kan.liang @ 2019-05-14 20:19 UTC (permalink / raw)
  To: acme, jolsa, mingo, linux-kernel; +Cc: ak, Kan Liang

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

There may be different register mask for use with intr or user on some
platforms, e.g. Icelake.

Add weak functions arch__intr_reg_mask() and arch__user_reg_mask() to
return intr and user register mask respectively.

Check mask before printing or comparing the register name.

Generic code always return PERF_REGS_MASK. No functional change.

Suggested-by: Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
---

Changes since V1:
- Drop has_non_gprs_support() and non_gprs_mask()
  Use arch__intr/user_reg_mask()

 tools/perf/util/parse-regs-options.c | 13 ++++++++++---
 tools/perf/util/perf_regs.c          | 10 ++++++++++
 tools/perf/util/perf_regs.h          |  2 ++
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
index b21617f..08581e2 100644
--- a/tools/perf/util/parse-regs-options.c
+++ b/tools/perf/util/parse-regs-options.c
@@ -12,6 +12,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 	const struct sample_reg *r;
 	char *s, *os = NULL, *p;
 	int ret = -1;
+	uint64_t mask;
 
 	if (unset)
 		return 0;
@@ -22,6 +23,11 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 	if (*mode)
 		return -1;
 
+	if (intr)
+		mask = arch__intr_reg_mask();
+	else
+		mask = arch__user_reg_mask();
+
 	/* str may be NULL in case no arg is passed to -I */
 	if (str) {
 		/* because str is read-only */
@@ -37,14 +43,15 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 			if (!strcmp(s, "?")) {
 				fprintf(stderr, "available registers: ");
 				for (r = sample_reg_masks; r->name; r++) {
-					fprintf(stderr, "%s ", r->name);
+					if (r->mask & mask)
+						fprintf(stderr, "%s ", r->name);
 				}
 				fputc('\n', stderr);
 				/* just printing available regs */
 				return -1;
 			}
 			for (r = sample_reg_masks; r->name; r++) {
-				if (!strcasecmp(s, r->name))
+				if ((r->mask & mask) && !strcasecmp(s, r->name))
 					break;
 			}
 			if (!r->name) {
@@ -65,7 +72,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 
 	/* default to all possible regs */
 	if (*mode == 0)
-		*mode = PERF_REGS_MASK;
+		*mode = mask;
 error:
 	free(os);
 	return ret;
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
index 2acfcc5..2774cec 100644
--- a/tools/perf/util/perf_regs.c
+++ b/tools/perf/util/perf_regs.c
@@ -13,6 +13,16 @@ int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused,
 	return SDT_ARG_SKIP;
 }
 
+uint64_t __weak arch__intr_reg_mask(void)
+{
+	return PERF_REGS_MASK;
+}
+
+uint64_t __weak arch__user_reg_mask(void)
+{
+	return PERF_REGS_MASK;
+}
+
 #ifdef HAVE_PERF_REGS_SUPPORT
 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
 {
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index 1a15a4b..cb9c246 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -23,6 +23,8 @@ enum {
 };
 
 int arch_sdt_arg_parse_op(char *old_op, char **new_op);
+uint64_t arch__intr_reg_mask(void);
+uint64_t arch__user_reg_mask(void);
 
 #ifdef HAVE_PERF_REGS_SUPPORT
 #include <perf_regs.h>
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH V2 3/3] perf regs x86: Add X86 specific arch__intr_reg_mask()
  2019-05-14 20:19 [PATCH V2 1/3] perf parse-regs: Split parse_regs kan.liang
  2019-05-14 20:19 ` [PATCH V2 2/3] perf parse-regs: Add generic support for arch__intr/user_reg_mask() kan.liang
@ 2019-05-14 20:19 ` kan.liang
  2019-05-15 19:28   ` Arnaldo Carvalho de Melo
  2019-05-18  9:31   ` [tip:perf/core] " tip-bot for Kan Liang
  2019-05-15  6:49 ` [PATCH V2 1/3] perf parse-regs: Split parse_regs Ravi Bangoria
  2019-05-18  9:30 ` [tip:perf/core] " tip-bot for Kan Liang
  3 siblings, 2 replies; 9+ messages in thread
From: kan.liang @ 2019-05-14 20:19 UTC (permalink / raw)
  To: acme, jolsa, mingo, linux-kernel; +Cc: ak, Kan Liang

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

XMM registers can be collected on Icelake and later platforms.

Add specific arch__intr_reg_mask(), which creating an event to check if
the kernel and hardware can collect XMM registers.

Test on Skylake which doesn't support XMM registers collection. There is
nothing changed.

   #perf record -I?
   available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9
   R10 R11 R12 R13 R14 R15

   Usage: perf record [<options>] [<command>]
    or: perf record [<options>] -- <command> [<options>]

    -I, --intr-regs[=<any register>]
                          sample selected machine registers on
   interrupt, use '-I?' to list register names

   #perf record -I
   [ perf record: Woken up 1 times to write data ]
   [ perf record: Captured and wrote 0.905 MB perf.data (2520 samples) ]

   #perf evlist -v
   cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type:
   IP|TID|TIME|CPU|PERIOD|REGS_INTR, read_format: ID, disabled: 1,
   inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, precise_ip: 3,
   sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol:
   1, bpf_event: 1, sample_regs_intr: 0xff0fff

Test on Icelake which support XMM registers collection.

   #perf record -I?
   available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10
   R11 R12 R13 R14 R15 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 XMM9
   XMM10 XMM11 XMM12 XMM13 XMM14 XMM15

   Usage: perf record [<options>] [<command>]
    or: perf record [<options>] -- <command> [<options>]

    -I, --intr-regs[=<any register>]
                          sample selected machine registers on
   interrupt, use '-I?' to list register names

   #perf record -I
   [ perf record: Woken up 1 times to write data ]
   [ perf record: Captured and wrote 0.800 MB perf.data (318 samples) ]

   #perf evlist -v
   cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type:
   IP|TID|TIME|CPU|PERIOD|REGS_INTR, read_format: ID, disabled: 1,
   inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, precise_ip: 3,
   sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol:
   1, bpf_event: 1, sample_regs_intr: 0xffffffff00ff0fff

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
---

Changes since V1:
- Add specific arch__intr_reg_mask() support
  Drop specific has_non_gprs_support() and non_gprs_mask()

 tools/perf/arch/x86/include/perf_regs.h |  1 +
 tools/perf/arch/x86/util/perf_regs.c    | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h
index b732133..b7cd91a 100644
--- a/tools/perf/arch/x86/include/perf_regs.h
+++ b/tools/perf/arch/x86/include/perf_regs.h
@@ -9,6 +9,7 @@
 void perf_regs_load(u64 *regs);
 
 #define PERF_REGS_MAX PERF_REG_X86_XMM_MAX
+#define PERF_XMM_REGS_MASK	(~((1ULL << PERF_REG_X86_XMM0) - 1))
 #ifndef HAVE_ARCH_X86_64_SUPPORT
 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
 #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c
index 71d7604..c3d7479 100644
--- a/tools/perf/arch/x86/util/perf_regs.c
+++ b/tools/perf/arch/x86/util/perf_regs.c
@@ -270,3 +270,28 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
 
 	return SDT_ARG_VALID;
 }
+
+uint64_t arch__intr_reg_mask(void)
+{
+	struct perf_event_attr attr = {
+		.type			= PERF_TYPE_HARDWARE,
+		.config			= PERF_COUNT_HW_CPU_CYCLES,
+		.sample_period		= 1,
+		.sample_type		= PERF_SAMPLE_REGS_INTR,
+		.sample_regs_intr	= PERF_XMM_REGS_MASK,
+		.precise_ip		= 1,
+		.disabled 		= 1,
+		.exclude_kernel		= 1,
+	};
+	int fd;
+
+	event_attr_init(&attr);
+
+	fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
+	if (fd != -1) {
+		close(fd);
+		return (PERF_XMM_REGS_MASK | PERF_REGS_MASK);
+	}
+
+	return PERF_REGS_MASK;
+}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH V2 1/3] perf parse-regs: Split parse_regs
  2019-05-14 20:19 [PATCH V2 1/3] perf parse-regs: Split parse_regs kan.liang
  2019-05-14 20:19 ` [PATCH V2 2/3] perf parse-regs: Add generic support for arch__intr/user_reg_mask() kan.liang
  2019-05-14 20:19 ` [PATCH V2 3/3] perf regs x86: Add X86 specific arch__intr_reg_mask() kan.liang
@ 2019-05-15  6:49 ` Ravi Bangoria
  2019-05-15 14:15   ` Liang, Kan
  2019-05-18  9:30 ` [tip:perf/core] " tip-bot for Kan Liang
  3 siblings, 1 reply; 9+ messages in thread
From: Ravi Bangoria @ 2019-05-15  6:49 UTC (permalink / raw)
  To: kan.liang, acme; +Cc: jolsa, mingo, linux-kernel, ak, Ravi Bangoria


On 5/15/19 1:49 AM, kan.liang@linux.intel.com wrote:
> From: Kan Liang <kan.liang@linux.intel.com>
> 
> The available registers for --int-regs and --user-regs may be different,
> e.g. XMM registers.
> 
> Split parse_regs into two dedicated functions for --int-regs and
> --user-regs respectively.
> 
> Modify the warning message. "--user-regs=?" should be applied to show
> the available registers for --user-regs.
> 
> Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
> ---

For patch 1 and 2,
Tested-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>

Minor neat. Should we update document as well? May be something like:

  tools/perf/Documentation/perf-record.txt

  --user-regs::
  Similar to -I, but capture user registers at sample time. To list the available
  user registers use --user-regs=\?.

Ravi


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V2 1/3] perf parse-regs: Split parse_regs
  2019-05-15  6:49 ` [PATCH V2 1/3] perf parse-regs: Split parse_regs Ravi Bangoria
@ 2019-05-15 14:15   ` Liang, Kan
  0 siblings, 0 replies; 9+ messages in thread
From: Liang, Kan @ 2019-05-15 14:15 UTC (permalink / raw)
  To: Ravi Bangoria, acme; +Cc: jolsa, mingo, linux-kernel, ak



On 5/15/2019 2:49 AM, Ravi Bangoria wrote:
> 
> On 5/15/19 1:49 AM, kan.liang@linux.intel.com wrote:
>> From: Kan Liang <kan.liang@linux.intel.com>
>>
>> The available registers for --int-regs and --user-regs may be different,
>> e.g. XMM registers.
>>
>> Split parse_regs into two dedicated functions for --int-regs and
>> --user-regs respectively.
>>
>> Modify the warning message. "--user-regs=?" should be applied to show
>> the available registers for --user-regs.
>>
>> Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
>> ---
> 
> For patch 1 and 2,
> Tested-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
> 
> Minor neat. Should we update document as well? May be something like:
> 
>    tools/perf/Documentation/perf-record.txt
> 
>    --user-regs::
>    Similar to -I, but capture user registers at sample time. To list the available
>    user registers use --user-regs=\?.
>
Hi Ravi,

Thanks for test.

The change of document looks good.

Thanks,
Kan


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH V2 3/3] perf regs x86: Add X86 specific arch__intr_reg_mask()
  2019-05-14 20:19 ` [PATCH V2 3/3] perf regs x86: Add X86 specific arch__intr_reg_mask() kan.liang
@ 2019-05-15 19:28   ` Arnaldo Carvalho de Melo
  2019-05-18  9:31   ` [tip:perf/core] " tip-bot for Kan Liang
  1 sibling, 0 replies; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-05-15 19:28 UTC (permalink / raw)
  To: kan.liang; +Cc: jolsa, mingo, linux-kernel, ak

Em Tue, May 14, 2019 at 01:19:34PM -0700, kan.liang@linux.intel.com escreveu:
> From: Kan Liang <kan.liang@linux.intel.com>
> 
> XMM registers can be collected on Icelake and later platforms.
> 
> Add specific arch__intr_reg_mask(), which creating an event to check if
> the kernel and hardware can collect XMM registers.
> 
> Test on Skylake which doesn't support XMM registers collection. There is
> nothing changed.

Thanks a lot for doing this and tested on both a machine without these
registers as well as on one with it.

Applied, together with Ravi's tested-by for the first two and the change
in the --user-regs doc,

Regards,

- Arnaldo
 
>    #perf record -I?
>    available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9
>    R10 R11 R12 R13 R14 R15
> 
>    Usage: perf record [<options>] [<command>]
>     or: perf record [<options>] -- <command> [<options>]
> 
>     -I, --intr-regs[=<any register>]
>                           sample selected machine registers on
>    interrupt, use '-I?' to list register names
> 
>    #perf record -I
>    [ perf record: Woken up 1 times to write data ]
>    [ perf record: Captured and wrote 0.905 MB perf.data (2520 samples) ]
> 
>    #perf evlist -v
>    cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type:
>    IP|TID|TIME|CPU|PERIOD|REGS_INTR, read_format: ID, disabled: 1,
>    inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, precise_ip: 3,
>    sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol:
>    1, bpf_event: 1, sample_regs_intr: 0xff0fff
> 
> Test on Icelake which support XMM registers collection.
> 
>    #perf record -I?
>    available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10
>    R11 R12 R13 R14 R15 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 XMM9
>    XMM10 XMM11 XMM12 XMM13 XMM14 XMM15
> 
>    Usage: perf record [<options>] [<command>]
>     or: perf record [<options>] -- <command> [<options>]
> 
>     -I, --intr-regs[=<any register>]
>                           sample selected machine registers on
>    interrupt, use '-I?' to list register names
> 
>    #perf record -I
>    [ perf record: Woken up 1 times to write data ]
>    [ perf record: Captured and wrote 0.800 MB perf.data (318 samples) ]
> 
>    #perf evlist -v
>    cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type:
>    IP|TID|TIME|CPU|PERIOD|REGS_INTR, read_format: ID, disabled: 1,
>    inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, precise_ip: 3,
>    sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol:
>    1, bpf_event: 1, sample_regs_intr: 0xffffffff00ff0fff
> 
> Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
> ---
> 
> Changes since V1:
> - Add specific arch__intr_reg_mask() support
>   Drop specific has_non_gprs_support() and non_gprs_mask()
> 
>  tools/perf/arch/x86/include/perf_regs.h |  1 +
>  tools/perf/arch/x86/util/perf_regs.c    | 25 +++++++++++++++++++++++++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h
> index b732133..b7cd91a 100644
> --- a/tools/perf/arch/x86/include/perf_regs.h
> +++ b/tools/perf/arch/x86/include/perf_regs.h
> @@ -9,6 +9,7 @@
>  void perf_regs_load(u64 *regs);
>  
>  #define PERF_REGS_MAX PERF_REG_X86_XMM_MAX
> +#define PERF_XMM_REGS_MASK	(~((1ULL << PERF_REG_X86_XMM0) - 1))
>  #ifndef HAVE_ARCH_X86_64_SUPPORT
>  #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
>  #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
> diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c
> index 71d7604..c3d7479 100644
> --- a/tools/perf/arch/x86/util/perf_regs.c
> +++ b/tools/perf/arch/x86/util/perf_regs.c
> @@ -270,3 +270,28 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
>  
>  	return SDT_ARG_VALID;
>  }
> +
> +uint64_t arch__intr_reg_mask(void)
> +{
> +	struct perf_event_attr attr = {
> +		.type			= PERF_TYPE_HARDWARE,
> +		.config			= PERF_COUNT_HW_CPU_CYCLES,
> +		.sample_period		= 1,
> +		.sample_type		= PERF_SAMPLE_REGS_INTR,
> +		.sample_regs_intr	= PERF_XMM_REGS_MASK,
> +		.precise_ip		= 1,
> +		.disabled 		= 1,
> +		.exclude_kernel		= 1,
> +	};
> +	int fd;
> +
> +	event_attr_init(&attr);
> +
> +	fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
> +	if (fd != -1) {
> +		close(fd);
> +		return (PERF_XMM_REGS_MASK | PERF_REGS_MASK);
> +	}
> +
> +	return PERF_REGS_MASK;
> +}
> -- 
> 2.7.4

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [tip:perf/core] perf parse-regs: Split parse_regs
  2019-05-14 20:19 [PATCH V2 1/3] perf parse-regs: Split parse_regs kan.liang
                   ` (2 preceding siblings ...)
  2019-05-15  6:49 ` [PATCH V2 1/3] perf parse-regs: Split parse_regs Ravi Bangoria
@ 2019-05-18  9:30 ` tip-bot for Kan Liang
  3 siblings, 0 replies; 9+ messages in thread
From: tip-bot for Kan Liang @ 2019-05-18  9:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, tglx, linux-kernel, hpa, ak, kan.liang, ravi.bangoria,
	jolsa, acme

Commit-ID:  aeea9062d949584ac1f2f9a20f0e5ed306539a3e
Gitweb:     https://git.kernel.org/tip/aeea9062d949584ac1f2f9a20f0e5ed306539a3e
Author:     Kan Liang <kan.liang@linux.intel.com>
AuthorDate: Tue, 14 May 2019 13:19:32 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 15 May 2019 16:36:49 -0300

perf parse-regs: Split parse_regs

The available registers for --int-regs and --user-regs may be different,
e.g. XMM registers.

Split parse_regs into two dedicated functions for --int-regs and
--user-regs respectively.

Modify the warning message. "--user-regs=?" should be applied to show
the available registers for --user-regs.

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Tested-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/1557865174-56264-1-git-send-email-kan.liang@linux.intel.com
[ Changed docs as suggested by Ravi and agreed by Kan ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-record.txt |  3 ++-
 tools/perf/builtin-record.c              |  4 ++--
 tools/perf/util/parse-regs-options.c     | 19 ++++++++++++++++---
 tools/perf/util/parse-regs-options.h     |  3 ++-
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 27b37624c376..de269430720a 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -406,7 +406,8 @@ symbolic names, e.g. on x86, ax, si. To list the available registers use
 --intr-regs=ax,bx. The list of register is architecture dependent.
 
 --user-regs::
-Capture user registers at sample time. Same arguments as -I.
+Similar to -I, but capture user registers at sample time. To list the available
+user registers use --user-regs=\?.
 
 --running-time::
 Record running and enabled time for read events (:S)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 861395753c25..e2c3a585a61e 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -2168,10 +2168,10 @@ static struct option __record_options[] = {
 		    "use per-thread mmaps"),
 	OPT_CALLBACK_OPTARG('I', "intr-regs", &record.opts.sample_intr_regs, NULL, "any register",
 		    "sample selected machine registers on interrupt,"
-		    " use '-I?' to list register names", parse_regs),
+		    " use '-I?' to list register names", parse_intr_regs),
 	OPT_CALLBACK_OPTARG(0, "user-regs", &record.opts.sample_user_regs, NULL, "any register",
 		    "sample selected machine registers on interrupt,"
-		    " use '-I?' to list register names", parse_regs),
+		    " use '--user-regs=?' to list register names", parse_user_regs),
 	OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
 		    "Record running/enabled time of read (:S) events"),
 	OPT_CALLBACK('k', "clockid", &record.opts,
diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
index 9cb187a20fe2..b21617f2bec1 100644
--- a/tools/perf/util/parse-regs-options.c
+++ b/tools/perf/util/parse-regs-options.c
@@ -5,8 +5,8 @@
 #include <subcmd/parse-options.h>
 #include "util/parse-regs-options.h"
 
-int
-parse_regs(const struct option *opt, const char *str, int unset)
+static int
+__parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 {
 	uint64_t *mode = (uint64_t *)opt->value;
 	const struct sample_reg *r;
@@ -48,7 +48,8 @@ parse_regs(const struct option *opt, const char *str, int unset)
 					break;
 			}
 			if (!r->name) {
-				ui__warning("Unknown register \"%s\", check man page or run \"perf record -I?\"\n", s);
+				ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n",
+					    s, intr ? "-I" : "--user-regs=");
 				goto error;
 			}
 
@@ -69,3 +70,15 @@ error:
 	free(os);
 	return ret;
 }
+
+int
+parse_user_regs(const struct option *opt, const char *str, int unset)
+{
+	return __parse_regs(opt, str, unset, false);
+}
+
+int
+parse_intr_regs(const struct option *opt, const char *str, int unset)
+{
+	return __parse_regs(opt, str, unset, true);
+}
diff --git a/tools/perf/util/parse-regs-options.h b/tools/perf/util/parse-regs-options.h
index cdefb1acf6be..2b23d25c6394 100644
--- a/tools/perf/util/parse-regs-options.h
+++ b/tools/perf/util/parse-regs-options.h
@@ -2,5 +2,6 @@
 #ifndef _PERF_PARSE_REGS_OPTIONS_H
 #define _PERF_PARSE_REGS_OPTIONS_H 1
 struct option;
-int parse_regs(const struct option *opt, const char *str, int unset);
+int parse_user_regs(const struct option *opt, const char *str, int unset);
+int parse_intr_regs(const struct option *opt, const char *str, int unset);
 #endif /* _PERF_PARSE_REGS_OPTIONS_H */

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [tip:perf/core] perf parse-regs: Add generic support for arch__intr/user_reg_mask()
  2019-05-14 20:19 ` [PATCH V2 2/3] perf parse-regs: Add generic support for arch__intr/user_reg_mask() kan.liang
@ 2019-05-18  9:31   ` tip-bot for Kan Liang
  0 siblings, 0 replies; 9+ messages in thread
From: tip-bot for Kan Liang @ 2019-05-18  9:31 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ravi.bangoria, mingo, tglx, acme, linux-kernel, jolsa, ak,
	kan.liang, hpa

Commit-ID:  af785e75bf616704cab031e66403b6adcf5b700a
Gitweb:     https://git.kernel.org/tip/af785e75bf616704cab031e66403b6adcf5b700a
Author:     Kan Liang <kan.liang@linux.intel.com>
AuthorDate: Tue, 14 May 2019 13:19:33 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 16 May 2019 14:17:12 -0300

perf parse-regs: Add generic support for arch__intr/user_reg_mask()

There may be different register mask for use with intr or user on some
platforms, e.g. Icelake.

Add weak functions arch__intr_reg_mask() and arch__user_reg_mask() to
return intr and user register mask respectively.

Check mask before printing or comparing the register name.

Generic code always return PERF_REGS_MASK. No functional change.

Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Tested-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/1557865174-56264-2-git-send-email-kan.liang@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-regs-options.c | 13 ++++++++++---
 tools/perf/util/perf_regs.c          | 10 ++++++++++
 tools/perf/util/perf_regs.h          |  2 ++
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c
index b21617f2bec1..08581e276225 100644
--- a/tools/perf/util/parse-regs-options.c
+++ b/tools/perf/util/parse-regs-options.c
@@ -12,6 +12,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 	const struct sample_reg *r;
 	char *s, *os = NULL, *p;
 	int ret = -1;
+	uint64_t mask;
 
 	if (unset)
 		return 0;
@@ -22,6 +23,11 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 	if (*mode)
 		return -1;
 
+	if (intr)
+		mask = arch__intr_reg_mask();
+	else
+		mask = arch__user_reg_mask();
+
 	/* str may be NULL in case no arg is passed to -I */
 	if (str) {
 		/* because str is read-only */
@@ -37,14 +43,15 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 			if (!strcmp(s, "?")) {
 				fprintf(stderr, "available registers: ");
 				for (r = sample_reg_masks; r->name; r++) {
-					fprintf(stderr, "%s ", r->name);
+					if (r->mask & mask)
+						fprintf(stderr, "%s ", r->name);
 				}
 				fputc('\n', stderr);
 				/* just printing available regs */
 				return -1;
 			}
 			for (r = sample_reg_masks; r->name; r++) {
-				if (!strcasecmp(s, r->name))
+				if ((r->mask & mask) && !strcasecmp(s, r->name))
 					break;
 			}
 			if (!r->name) {
@@ -65,7 +72,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)
 
 	/* default to all possible regs */
 	if (*mode == 0)
-		*mode = PERF_REGS_MASK;
+		*mode = mask;
 error:
 	free(os);
 	return ret;
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
index 2acfcc527cac..2774cec1f15f 100644
--- a/tools/perf/util/perf_regs.c
+++ b/tools/perf/util/perf_regs.c
@@ -13,6 +13,16 @@ int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused,
 	return SDT_ARG_SKIP;
 }
 
+uint64_t __weak arch__intr_reg_mask(void)
+{
+	return PERF_REGS_MASK;
+}
+
+uint64_t __weak arch__user_reg_mask(void)
+{
+	return PERF_REGS_MASK;
+}
+
 #ifdef HAVE_PERF_REGS_SUPPORT
 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
 {
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index 1a15a4bfc28d..cb9c246c8962 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -23,6 +23,8 @@ enum {
 };
 
 int arch_sdt_arg_parse_op(char *old_op, char **new_op);
+uint64_t arch__intr_reg_mask(void);
+uint64_t arch__user_reg_mask(void);
 
 #ifdef HAVE_PERF_REGS_SUPPORT
 #include <perf_regs.h>

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [tip:perf/core] perf regs x86: Add X86 specific arch__intr_reg_mask()
  2019-05-14 20:19 ` [PATCH V2 3/3] perf regs x86: Add X86 specific arch__intr_reg_mask() kan.liang
  2019-05-15 19:28   ` Arnaldo Carvalho de Melo
@ 2019-05-18  9:31   ` tip-bot for Kan Liang
  1 sibling, 0 replies; 9+ messages in thread
From: tip-bot for Kan Liang @ 2019-05-18  9:31 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ak, jolsa, tglx, linux-kernel, hpa, kan.liang, acme, mingo

Commit-ID:  6466ec14aaf44ff14a05369dcf0929d0f01171c6
Gitweb:     https://git.kernel.org/tip/6466ec14aaf44ff14a05369dcf0929d0f01171c6
Author:     Kan Liang <kan.liang@linux.intel.com>
AuthorDate: Tue, 14 May 2019 13:19:34 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 16 May 2019 14:17:23 -0300

perf regs x86: Add X86 specific arch__intr_reg_mask()

XMM registers can be collected on Icelake and later platforms.

Add specific arch__intr_reg_mask(), which creating an event to check if
the kernel and hardware can collect XMM registers.

Test on Skylake which doesn't support XMM registers collection. There is
nothing changed.

   #perf record -I?
   available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9
   R10 R11 R12 R13 R14 R15

   Usage: perf record [<options>] [<command>]
    or: perf record [<options>] -- <command> [<options>]

    -I, --intr-regs[=<any register>]
                          sample selected machine registers on
   interrupt, use '-I?' to list register names

   #perf record -I
   [ perf record: Woken up 1 times to write data ]
   [ perf record: Captured and wrote 0.905 MB perf.data (2520 samples) ]

   #perf evlist -v
   cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type:
   IP|TID|TIME|CPU|PERIOD|REGS_INTR, read_format: ID, disabled: 1,
   inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, precise_ip: 3,
   sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol:
   1, bpf_event: 1, sample_regs_intr: 0xff0fff

Test on Icelake which support XMM registers collection.

   #perf record -I?
   available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10
   R11 R12 R13 R14 R15 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 XMM9
   XMM10 XMM11 XMM12 XMM13 XMM14 XMM15

   Usage: perf record [<options>] [<command>]
    or: perf record [<options>] -- <command> [<options>]

    -I, --intr-regs[=<any register>]
                          sample selected machine registers on
   interrupt, use '-I?' to list register names

   #perf record -I
   [ perf record: Woken up 1 times to write data ]
   [ perf record: Captured and wrote 0.800 MB perf.data (318 samples) ]

   #perf evlist -v
   cycles: size: 112, { sample_period, sample_freq }: 4000, sample_type:
   IP|TID|TIME|CPU|PERIOD|REGS_INTR, read_format: ID, disabled: 1,
   inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, precise_ip: 3,
   sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol:
   1, bpf_event: 1, sample_regs_intr: 0xffffffff00ff0fff

Committer notes:

Don't set attr.sample_period as a named struct init, as it is part of an
unnamed union in 'struct perf_event_attr', and doing so breaks the build
on older gcc versions, such as:

  gcc version 4.1.2 20080704 (Red Hat 4.1.2-55)
  gcc version 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC)

  arch/x86/util/perf_regs.c: In function 'arch__intr_reg_mask':
  arch/x86/util/perf_regs.c:279: error: unknown field 'sample_period' specified in initializer
  cc1: warnings being treated as errors
  arch/x86/util/perf_regs.c:279: warning: missing braces around initializer
  arch/x86/util/perf_regs.c:279: warning: (near initialization for 'attr.<anonymous>')

Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
[ Only on a lenovo t480s, a skylake machine, where the XMM registers didn't show up in -I?/--user-regs=? as expected ]
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/1557865174-56264-3-git-send-email-kan.liang@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/x86/include/perf_regs.h |  1 +
 tools/perf/arch/x86/util/perf_regs.c    | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h
index b7321337d100..b7cd91a9014f 100644
--- a/tools/perf/arch/x86/include/perf_regs.h
+++ b/tools/perf/arch/x86/include/perf_regs.h
@@ -9,6 +9,7 @@
 void perf_regs_load(u64 *regs);
 
 #define PERF_REGS_MAX PERF_REG_X86_XMM_MAX
+#define PERF_XMM_REGS_MASK	(~((1ULL << PERF_REG_X86_XMM0) - 1))
 #ifndef HAVE_ARCH_X86_64_SUPPORT
 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
 #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c
index 71d7604dbf0b..7886ca5263e3 100644
--- a/tools/perf/arch/x86/util/perf_regs.c
+++ b/tools/perf/arch/x86/util/perf_regs.c
@@ -270,3 +270,31 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
 
 	return SDT_ARG_VALID;
 }
+
+uint64_t arch__intr_reg_mask(void)
+{
+	struct perf_event_attr attr = {
+		.type			= PERF_TYPE_HARDWARE,
+		.config			= PERF_COUNT_HW_CPU_CYCLES,
+		.sample_type		= PERF_SAMPLE_REGS_INTR,
+		.sample_regs_intr	= PERF_XMM_REGS_MASK,
+		.precise_ip		= 1,
+		.disabled 		= 1,
+		.exclude_kernel		= 1,
+	};
+	int fd;
+	/*
+	 * In an unnamed union, init it here to build on older gcc versions
+	 */
+	attr.sample_period = 1;
+
+	event_attr_init(&attr);
+
+	fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
+	if (fd != -1) {
+		close(fd);
+		return (PERF_XMM_REGS_MASK | PERF_REGS_MASK);
+	}
+
+	return PERF_REGS_MASK;
+}

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-05-18  9:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-14 20:19 [PATCH V2 1/3] perf parse-regs: Split parse_regs kan.liang
2019-05-14 20:19 ` [PATCH V2 2/3] perf parse-regs: Add generic support for arch__intr/user_reg_mask() kan.liang
2019-05-18  9:31   ` [tip:perf/core] " tip-bot for Kan Liang
2019-05-14 20:19 ` [PATCH V2 3/3] perf regs x86: Add X86 specific arch__intr_reg_mask() kan.liang
2019-05-15 19:28   ` Arnaldo Carvalho de Melo
2019-05-18  9:31   ` [tip:perf/core] " tip-bot for Kan Liang
2019-05-15  6:49 ` [PATCH V2 1/3] perf parse-regs: Split parse_regs Ravi Bangoria
2019-05-15 14:15   ` Liang, Kan
2019-05-18  9:30 ` [tip:perf/core] " tip-bot for Kan Liang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.