History

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.

Andi Kleen committed 7 years ago

Commit ca138a71 parent 4c1cf203 files · +40 −2Browse files

Unified · Split

3 files
  1. tools/perf/arch/x86/include/perf_regs.h +23 −2
  2. tools/perf/arch/x86/util/perf_regs.c +16 −0
  3. tools/perf/util/perf_regs.h +1 −0
tools/perf/arch/x86/include/perf_regs.h+23−2
@@ -8,9 +8,9 @@ · 7 unmodified lines
88
99 void perf_regs_load(u64 *regs);
1010
11+#define PERF_REGS_MAX PERF_REG_X86_XMM_MAX
1112 #ifndef HAVE_ARCH_X86_64_SUPPORT
1213 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
13−#define PERF_REGS_MAX PERF_REG_X86_32_MAX
1414 #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
1515 #else
1616 #define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
@@ -18,7 +18,6 @@ void perf_regs_load(u64 *regs); · 1 unmodified line
1818 (1ULL << PERF_REG_X86_FS) | \
1919 (1ULL << PERF_REG_X86_GS))
2020 #define PERF_REGS_MASK (((1ULL << PERF_REG_X86_64_MAX) - 1) & ~REG_NOSUPPORT)
21−#define PERF_REGS_MAX PERF_REG_X86_64_MAX
2221 #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
2322 #endif
2423 #define PERF_REG_IP PERF_REG_X86_IP
@@ -77,6 +76,28 @@ static inline const char *perf_reg_name(int id) · 52 unmodified lines
7776 case PERF_REG_X86_R15:
7877 return "R15";
7978 #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
80101 default:
81102 return NULL;
82103 }
tools/perf/arch/x86/util/perf_regs.c+16−0
@@ -31,6 +31,22 @@ const struct sample_reg sample_reg_masks[] = { · 30 unmodified lines
3131 SMPL_REG(R14, PERF_REG_X86_R14),
3232 SMPL_REG(R15, PERF_REG_X86_R15),
3333 #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),
3450 SMPL_REG_END
3551 };
3652
tools/perf/util/perf_regs.h+1−0
@@ -12,6 +12,7 @@ struct sample_reg { · 11 unmodified lines
1212 uint64_t mask;
1313 };
1414 #define SMPL_REG(n, b) { .name = #n, .mask = 1ULL << (b) }
15+#define SMPL_REG2(n, b) { .name = #n, .mask = 3ULL << (b) }
1516 #define SMPL_REG_END { .name = NULL }
1617
1718 extern const struct sample_reg sample_reg_masks[];