Skip to content

Commit

Permalink
perf tools powerpc: Add support for extended register capability
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
anjutsudhakar authored and acmel committed Aug 7, 2020
1 parent d01541d commit 33583e6
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 10 deletions.
14 changes: 13 additions & 1 deletion tools/arch/powerpc/include/uapi/asm/perf_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ enum perf_event_powerpc_regs {
PERF_REG_POWERPC_DSISR,
PERF_REG_POWERPC_SIER,
PERF_REG_POWERPC_MMCRA,
PERF_REG_POWERPC_MAX,
/* Extended registers */
PERF_REG_POWERPC_MMCR0,
PERF_REG_POWERPC_MMCR1,
PERF_REG_POWERPC_MMCR2,
/* Max regs without the extended regs */
PERF_REG_POWERPC_MAX = PERF_REG_POWERPC_MMCRA + 1,
};

#define PERF_REG_PMU_MASK ((1ULL << PERF_REG_POWERPC_MAX) - 1)

/* PERF_REG_EXTENDED_MASK value for CPU_FTR_ARCH_300 */
#define PERF_REG_PMU_MASK_300 (((1ULL << (PERF_REG_POWERPC_MMCR2 + 1)) - 1) - PERF_REG_PMU_MASK)

#define PERF_REG_MAX_ISA_300 (PERF_REG_POWERPC_MMCR2 + 1)
#endif /* _UAPI_ASM_POWERPC_PERF_REGS_H */
5 changes: 4 additions & 1 deletion tools/perf/arch/powerpc/include/perf_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ static const char *reg_names[] = {
[PERF_REG_POWERPC_DAR] = "dar",
[PERF_REG_POWERPC_DSISR] = "dsisr",
[PERF_REG_POWERPC_SIER] = "sier",
[PERF_REG_POWERPC_MMCRA] = "mmcra"
[PERF_REG_POWERPC_MMCRA] = "mmcra",
[PERF_REG_POWERPC_MMCR0] = "mmcr0",
[PERF_REG_POWERPC_MMCR1] = "mmcr1",
[PERF_REG_POWERPC_MMCR2] = "mmcr2",
};

static inline const char *perf_reg_name(int id)
Expand Down
9 changes: 1 addition & 8 deletions tools/perf/arch/powerpc/util/header.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,10 @@
#include <string.h>
#include <linux/stringify.h>
#include "header.h"
#include "utils_header.h"
#include "metricgroup.h"
#include <api/fs/fs.h>

#define mfspr(rn) ({unsigned long rval; \
asm volatile("mfspr %0," __stringify(rn) \
: "=r" (rval)); rval; })

#define SPRN_PVR 0x11F /* Processor Version Register */
#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */

int
get_cpuid(char *buffer, size_t sz)
{
Expand Down
49 changes: 49 additions & 0 deletions tools/perf/arch/powerpc/util/perf_regs.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@

#include "../../../util/perf_regs.h"
#include "../../../util/debug.h"
#include "../../../util/event.h"
#include "../../../util/header.h"
#include "../../../perf-sys.h"
#include "utils_header.h"

#include <linux/kernel.h>

#define PVR_POWER9 0x004E

const struct sample_reg sample_reg_masks[] = {
SMPL_REG(r0, PERF_REG_POWERPC_R0),
SMPL_REG(r1, PERF_REG_POWERPC_R1),
Expand Down Expand Up @@ -55,6 +61,9 @@ const struct sample_reg sample_reg_masks[] = {
SMPL_REG(dsisr, PERF_REG_POWERPC_DSISR),
SMPL_REG(sier, PERF_REG_POWERPC_SIER),
SMPL_REG(mmcra, PERF_REG_POWERPC_MMCRA),
SMPL_REG(mmcr0, PERF_REG_POWERPC_MMCR0),
SMPL_REG(mmcr1, PERF_REG_POWERPC_MMCR1),
SMPL_REG(mmcr2, PERF_REG_POWERPC_MMCR2),
SMPL_REG_END
};

Expand Down Expand Up @@ -163,3 +172,43 @@ 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,
.precise_ip = 1,
.disabled = 1,
.exclude_kernel = 1,
};
int fd;
u32 version;
u64 extended_mask = 0, mask = PERF_REGS_MASK;

/*
* Get the PVR value to set the extended
* mask specific to platform.
*/
version = (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF);
if (version == PVR_POWER9)
extended_mask = PERF_REG_PMU_MASK_300;
else
return mask;

attr.sample_regs_intr = extended_mask;
attr.sample_period = 1;
event_attr_init(&attr);

/*
* check if the pmu supports perf extended regs, before
* returning the register mask to sample.
*/
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
if (fd != -1) {
close(fd);
mask |= extended_mask;
}
return mask;
}
15 changes: 15 additions & 0 deletions tools/perf/arch/powerpc/util/utils_header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PERF_UTIL_HEADER_H
#define __PERF_UTIL_HEADER_H

#include <linux/stringify.h>

#define mfspr(rn) ({unsigned long rval; \
asm volatile("mfspr %0," __stringify(rn) \
: "=r" (rval)); rval; })

#define SPRN_PVR 0x11F /* Processor Version Register */
#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */
#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */

#endif /* __PERF_UTIL_HEADER_H */

0 comments on commit 33583e6

Please sign in to comment.