aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2019-05-06 10:19:24 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-05-15 15:36:47 -0400
commitca138a7aabc68bf727918bb40ce08157cd5ec0a5 (patch)
tree670cd0eb2ba7e970961c5c939021437de109238f
parent4c1cf20334ae6e390e1ea787ef76c40a161370d1 (diff)
perf tools x86: Add support for recording and printing XMM registers
Icelake and later platforms support collecting XMM registers with PEBS event. Add support for 'perf script' to dump them, and support for the register parser in 'perf record -I=' ... to configure them. For now they are just printed in hex, we could potentially later add other formats too. Committer testing: Before: # perf record -IXMM0 Warning: unknown register XMM0, check man page or run 'perf record -I?' Usage: perf record [<options>] [<command>] or: perf record [<options>] -- <command> [<options>] # # 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>] # After: # perf record -IXMM0 Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (cycles). /bin/dmesg | grep -i perf may provide additional information. # # 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 # More work is needed to, when faced with such error, warn the user that that register is not available on the running platform. Signed-off-by: Andi Kleen <ak@linux.intel.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20190506141926.13659-1-kan.liang@linux.intel.com Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/arch/x86/include/perf_regs.h25
-rw-r--r--tools/perf/arch/x86/util/perf_regs.c16
-rw-r--r--tools/perf/util/perf_regs.h1
3 files changed, 40 insertions, 2 deletions
diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h
index 7f6d538f8a89..b7321337d100 100644
--- a/tools/perf/arch/x86/include/perf_regs.h
+++ b/tools/perf/arch/x86/include/perf_regs.h
@@ -8,9 +8,9 @@
8 8
9void perf_regs_load(u64 *regs); 9void perf_regs_load(u64 *regs);
10 10
11#define PERF_REGS_MAX PERF_REG_X86_XMM_MAX
11#ifndef HAVE_ARCH_X86_64_SUPPORT 12#ifndef HAVE_ARCH_X86_64_SUPPORT
12#define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1) 13#define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
13#define PERF_REGS_MAX PERF_REG_X86_32_MAX
14#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32 14#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
15#else 15#else
16#define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \ 16#define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
@@ -18,7 +18,6 @@ void perf_regs_load(u64 *regs);
18 (1ULL << PERF_REG_X86_FS) | \ 18 (1ULL << PERF_REG_X86_FS) | \
19 (1ULL << PERF_REG_X86_GS)) 19 (1ULL << PERF_REG_X86_GS))
20#define PERF_REGS_MASK (((1ULL << PERF_REG_X86_64_MAX) - 1) & ~REG_NOSUPPORT) 20#define PERF_REGS_MASK (((1ULL << PERF_REG_X86_64_MAX) - 1) & ~REG_NOSUPPORT)
21#define PERF_REGS_MAX PERF_REG_X86_64_MAX
22#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 21#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
23#endif 22#endif
24#define PERF_REG_IP PERF_REG_X86_IP 23#define PERF_REG_IP PERF_REG_X86_IP
@@ -77,6 +76,28 @@ static inline const char *perf_reg_name(int id)
77 case PERF_REG_X86_R15: 76 case PERF_REG_X86_R15:
78 return "R15"; 77 return "R15";
79#endif /* HAVE_ARCH_X86_64_SUPPORT */ 78#endif /* HAVE_ARCH_X86_64_SUPPORT */
79
80#define XMM(x) \
81 case PERF_REG_X86_XMM ## x: \
82 case PERF_REG_X86_XMM ## x + 1: \
83 return "XMM" #x;
84 XMM(0)
85 XMM(1)
86 XMM(2)
87 XMM(3)
88 XMM(4)
89 XMM(5)
90 XMM(6)
91 XMM(7)
92 XMM(8)
93 XMM(9)
94 XMM(10)
95 XMM(11)
96 XMM(12)
97 XMM(13)
98 XMM(14)
99 XMM(15)
100#undef XMM
80 default: 101 default:
81 return NULL; 102 return NULL;
82 } 103 }
diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c
index fead6b3b4206..71d7604dbf0b 100644
--- a/tools/perf/arch/x86/util/perf_regs.c
+++ b/tools/perf/arch/x86/util/perf_regs.c
@@ -31,6 +31,22 @@ const struct sample_reg sample_reg_masks[] = {
31 SMPL_REG(R14, PERF_REG_X86_R14), 31 SMPL_REG(R14, PERF_REG_X86_R14),
32 SMPL_REG(R15, PERF_REG_X86_R15), 32 SMPL_REG(R15, PERF_REG_X86_R15),
33#endif 33#endif
34 SMPL_REG2(XMM0, PERF_REG_X86_XMM0),
35 SMPL_REG2(XMM1, PERF_REG_X86_XMM1),
36 SMPL_REG2(XMM2, PERF_REG_X86_XMM2),
37 SMPL_REG2(XMM3, PERF_REG_X86_XMM3),
38 SMPL_REG2(XMM4, PERF_REG_X86_XMM4),
39 SMPL_REG2(XMM5, PERF_REG_X86_XMM5),
40 SMPL_REG2(XMM6, PERF_REG_X86_XMM6),
41 SMPL_REG2(XMM7, PERF_REG_X86_XMM7),
42 SMPL_REG2(XMM8, PERF_REG_X86_XMM8),
43 SMPL_REG2(XMM9, PERF_REG_X86_XMM9),
44 SMPL_REG2(XMM10, PERF_REG_X86_XMM10),
45 SMPL_REG2(XMM11, PERF_REG_X86_XMM11),
46 SMPL_REG2(XMM12, PERF_REG_X86_XMM12),
47 SMPL_REG2(XMM13, PERF_REG_X86_XMM13),
48 SMPL_REG2(XMM14, PERF_REG_X86_XMM14),
49 SMPL_REG2(XMM15, PERF_REG_X86_XMM15),
34 SMPL_REG_END 50 SMPL_REG_END
35}; 51};
36 52
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h
index c9319f8d17a6..1a15a4bfc28d 100644
--- a/tools/perf/util/perf_regs.h
+++ b/tools/perf/util/perf_regs.h
@@ -12,6 +12,7 @@ struct sample_reg {
12 uint64_t mask; 12 uint64_t mask;
13}; 13};
14#define SMPL_REG(n, b) { .name = #n, .mask = 1ULL << (b) } 14#define SMPL_REG(n, b) { .name = #n, .mask = 1ULL << (b) }
15#define SMPL_REG2(n, b) { .name = #n, .mask = 3ULL << (b) }
15#define SMPL_REG_END { .name = NULL } 16#define SMPL_REG_END { .name = NULL }
16 17
17extern const struct sample_reg sample_reg_masks[]; 18extern const struct sample_reg sample_reg_masks[];