Skip to content

Commit 33583e6

Browse files
anjutsudhakaracmel
authored andcommitted
perf tools powerpc: Add support for extended register capability
Add extended regs to sample_reg_mask in the tool side to use with `-I?` option. Perf tools side uses extended mask to display the platform supported register names (with -I? option) to the user and also send this mask to the kernel to capture the extended registers in each sample. Hence decide the mask value based on the processor version. Currently definitions for `mfspr`, `SPRN_PVR` are part of `arch/powerpc/util/header.c`. Move this to a header file so that these definitions can be re-used in other source files as well. Signed-off-by: Anju T Sudhakar <[email protected]> Reviewed-by: Kajol Jain <[email protected]> Reviewed-by: Madhavan Srinivasan <[email protected]> Reviewed--by: Ravi Bangoria <[email protected]> Tested-by: Ravi Bangoria <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Michael Neuling <[email protected]> <[email protected]> Cc: Ravi Bangoria <[email protected]> Cc: [email protected] [Decide extended mask at run time based on platform] Signed-off-by: Athira Jajeev <[email protected]> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent d01541d commit 33583e6

File tree

5 files changed

+82
-10
lines changed

5 files changed

+82
-10
lines changed

tools/arch/powerpc/include/uapi/asm/perf_regs.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ enum perf_event_powerpc_regs {
4848
PERF_REG_POWERPC_DSISR,
4949
PERF_REG_POWERPC_SIER,
5050
PERF_REG_POWERPC_MMCRA,
51-
PERF_REG_POWERPC_MAX,
51+
/* Extended registers */
52+
PERF_REG_POWERPC_MMCR0,
53+
PERF_REG_POWERPC_MMCR1,
54+
PERF_REG_POWERPC_MMCR2,
55+
/* Max regs without the extended regs */
56+
PERF_REG_POWERPC_MAX = PERF_REG_POWERPC_MMCRA + 1,
5257
};
58+
59+
#define PERF_REG_PMU_MASK ((1ULL << PERF_REG_POWERPC_MAX) - 1)
60+
61+
/* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300 */
62+
#define PERF_REG_PMU_MASK_300 (((1ULL << (PERF_REG_POWERPC_MMCR2 + 1)) - 1) - PERF_REG_PMU_MASK)
63+
64+
#define PERF_REG_MAX_ISA_300 (PERF_REG_POWERPC_MMCR2 + 1)
5365
#endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */

tools/perf/arch/powerpc/include/perf_regs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ static const char *reg_names[] = {
6464
[PERF_REG_POWERPC_DAR] = "dar",
6565
[PERF_REG_POWERPC_DSISR] = "dsisr",
6666
[PERF_REG_POWERPC_SIER] = "sier",
67-
[PERF_REG_POWERPC_MMCRA] = "mmcra"
67+
[PERF_REG_POWERPC_MMCRA] = "mmcra",
68+
[PERF_REG_POWERPC_MMCR0] = "mmcr0",
69+
[PERF_REG_POWERPC_MMCR1] = "mmcr1",
70+
[PERF_REG_POWERPC_MMCR2] = "mmcr2",
6871
};
6972

7073
static inline const char *perf_reg_name(int id)

tools/perf/arch/powerpc/util/header.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,10 @@
77
#include <string.h>
88
#include <linux/stringify.h>
99
#include "header.h"
10+
#include "utils_header.h"
1011
#include "metricgroup.h"
1112
#include <api/fs/fs.h>
1213

13-
#define mfspr(rn) ({unsigned long rval; \
14-
asm volatile("mfspr %0," __stringify(rn) \
15-
: "=r" (rval)); rval; })
16-
17-
#define SPRN_PVR 0x11F /* Processor Version Register */
18-
#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
19-
#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
20-
2114
int
2215
get_cpuid(char *buffer, size_t sz)
2316
{

tools/perf/arch/powerpc/util/perf_regs.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66

77
#include "../../../util/perf_regs.h"
88
#include "../../../util/debug.h"
9+
#include "../../../util/event.h"
10+
#include "../../../util/header.h"
11+
#include "../../../perf-sys.h"
12+
#include "utils_header.h"
913

1014
#include <linux/kernel.h>
1115

16+
#define PVR_POWER9 0x004E
17+
1218
const struct sample_reg sample_reg_masks[] = {
1319
SMPL_REG(r0, PERF_REG_POWERPC_R0),
1420
SMPL_REG(r1, PERF_REG_POWERPC_R1),
@@ -55,6 +61,9 @@ const struct sample_reg sample_reg_masks[] = {
5561
SMPL_REG(dsisr, PERF_REG_POWERPC_DSISR),
5662
SMPL_REG(sier, PERF_REG_POWERPC_SIER),
5763
SMPL_REG(mmcra, PERF_REG_POWERPC_MMCRA),
64+
SMPL_REG(mmcr0, PERF_REG_POWERPC_MMCR0),
65+
SMPL_REG(mmcr1, PERF_REG_POWERPC_MMCR1),
66+
SMPL_REG(mmcr2, PERF_REG_POWERPC_MMCR2),
5867
SMPL_REG_END
5968
};
6069

@@ -163,3 +172,43 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)
163172

164173
return SDT_ARG_VALID;
165174
}
175+
176+
uint64_t arch__intr_reg_mask(void)
177+
{
178+
struct perf_event_attr attr = {
179+
.type = PERF_TYPE_HARDWARE,
180+
.config = PERF_COUNT_HW_CPU_CYCLES,
181+
.sample_type = PERF_SAMPLE_REGS_INTR,
182+
.precise_ip = 1,
183+
.disabled = 1,
184+
.exclude_kernel = 1,
185+
};
186+
int fd;
187+
u32 version;
188+
u64 extended_mask = 0, mask = PERF_REGS_MASK;
189+
190+
/*
191+
* Get the PVR value to set the extended
192+
* mask specific to platform.
193+
*/
194+
version = (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF);
195+
if (version == PVR_POWER9)
196+
extended_mask = PERF_REG_PMU_MASK_300;
197+
else
198+
return mask;
199+
200+
attr.sample_regs_intr = extended_mask;
201+
attr.sample_period = 1;
202+
event_attr_init(&attr);
203+
204+
/*
205+
* check if the pmu supports perf extended regs, before
206+
* returning the register mask to sample.
207+
*/
208+
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
209+
if (fd != -1) {
210+
close(fd);
211+
mask |= extended_mask;
212+
}
213+
return mask;
214+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __PERF_UTIL_HEADER_H
3+
#define __PERF_UTIL_HEADER_H
4+
5+
#include <linux/stringify.h>
6+
7+
#define mfspr(rn) ({unsigned long rval; \
8+
asm volatile("mfspr %0," __stringify(rn) \
9+
: "=r" (rval)); rval; })
10+
11+
#define SPRN_PVR 0x11F /* Processor Version Register */
12+
#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
13+
#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */
14+
15+
#endif /* __PERF_UTIL_HEADER_H */

0 commit comments

Comments
 (0)