Perf tools: perf-regs bug fix and optimization
Subsystems (4)
v3 cover Perf tools: perf-regs bug fix and optimization
Changes:
v2 -> v3:
* Fix the abort issue for "-I" or "--user-regs" options. (Patch 1/4)
* Address Ian's comments.
v1 -> v2:
* Fixing "PERF_REG_EXTENDED_MASK" redefinition building error by changing the "asm/perf_regs.h" header path to relative UAPI path. (Patch 1/3)
* Spliting xxx_reg_mask() and xxx_sdt_arg_parse_op() conversion into 2 patches.
This patch-set remove the below three architecture specific __weak functions and converted them into the general architecture specific functions which are dispatched base on "em_machine".
uint64_t arch__intr_reg_mask(void);uint64_t arch__user_reg_mask(void);
int arch_sdt_arg_parse_op(char *old_op, char **new_op);
The advantage of this conversion is that these architectural functions can be called even for a different architecture with host instead of only called on the host architecture.
Although the converted functions shown below can be called on any architecture, currently they are still only called for the host architecture (EM_HOST).
int perf_sdt_arg_parse_op(uint16_t e_machine, char *old_op, char **new_op); uint64_t perf_intr_reg_mask(uint16_t e_machine);uint64_t perf_user_reg_mask(uint16_t e_machine);
Tests:
* This patch-set is only tested on x86 platforms. No issues are found for both intr-regs and user-regs options.
* Tests on other architectures are welcomed and appreciated.
History:
v1: https://lore.kernel.org/all/[email protected]/
v2: https://lore.kernel.org/all/[email protected]/
Dapeng Mi (4):
perf regs: Fix abort for "-I" or "--user-regs" options perf arch: Update arch headers to use relative UAPI paths perf regs: Remove __weak attributive arch__xxx_reg_mask() functions perf regs: Remove __weak attributive arch_sdt_arg_parse_op() function
tools/perf/arch/arm/include/perf_regs.h | 2 +- tools/perf/arch/arm/util/Build | 2 - tools/perf/arch/arm/util/perf_regs.c | 13 - tools/perf/arch/arm64/include/perf_regs.h | 2 +- tools/perf/arch/arm64/util/Build | 1 - tools/perf/arch/arm64/util/perf_regs.c | 141 --------- tools/perf/arch/csky/Build | 1 - tools/perf/arch/csky/include/perf_regs.h | 2 +- tools/perf/arch/csky/util/Build | 1 - tools/perf/arch/csky/util/perf_regs.c | 13 - tools/perf/arch/loongarch/include/perf_regs.h | 2 +- tools/perf/arch/loongarch/util/Build | 1 - tools/perf/arch/loongarch/util/perf_regs.c | 13 - tools/perf/arch/mips/include/perf_regs.h | 2 +- tools/perf/arch/mips/util/Build | 1 - tools/perf/arch/mips/util/perf_regs.c | 13 - tools/perf/arch/powerpc/include/perf_regs.h | 2 +- tools/perf/arch/powerpc/util/Build | 1 - tools/perf/arch/powerpc/util/perf_regs.c | 172 ----------- tools/perf/arch/riscv/include/perf_regs.h | 9 +- tools/perf/arch/riscv/util/Build | 1 - tools/perf/arch/riscv/util/perf_regs.c | 13 - tools/perf/arch/s390/include/perf_regs.h | 2 +- tools/perf/arch/s390/util/Build | 1 - tools/perf/arch/s390/util/perf_regs.c | 13 - tools/perf/arch/x86/include/perf_regs.h | 2 +- tools/perf/arch/x86/util/Build | 1 - tools/perf/arch/x86/util/perf_regs.c | 283 ------------------ tools/perf/util/evsel.c | 4 +- tools/perf/util/parse-regs-options.c | 13 +- .../util/perf-regs-arch/perf_regs_aarch64.c | 139 ++++++++- .../perf/util/perf-regs-arch/perf_regs_arm.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_csky.c | 7 +- .../util/perf-regs-arch/perf_regs_loongarch.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_mips.c | 7 +- .../util/perf-regs-arch/perf_regs_powerpc.c | 183 ++++++++++- .../util/perf-regs-arch/perf_regs_riscv.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_s390.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_x86.c | 281 ++++++++++++++++- tools/perf/util/perf_regs.c | 109 ++++++- tools/perf/util/perf_regs.h | 27 +- tools/perf/util/probe-file.c | 3 +- 42 files changed, 787 insertions(+), 724 deletions(-) delete mode 100644 tools/perf/arch/arm/util/perf_regs.c delete mode 100644 tools/perf/arch/arm64/util/perf_regs.c delete mode 100644 tools/perf/arch/csky/Build delete mode 100644 tools/perf/arch/csky/util/Build delete mode 100644 tools/perf/arch/csky/util/perf_regs.c delete mode 100644 tools/perf/arch/loongarch/util/perf_regs.c delete mode 100644 tools/perf/arch/mips/util/perf_regs.c delete mode 100644 tools/perf/arch/powerpc/util/perf_regs.c delete mode 100644 tools/perf/arch/riscv/util/perf_regs.c delete mode 100644 tools/perf/arch/s390/util/perf_regs.c delete mode 100644 tools/perf/arch/x86/util/perf_regs.c
Signature · 1 line
2.34.1
PATCH v3 1/4 perf regs: Fix abort for "-I" or "--user-regs" options
Fix an issue where the perf tool aborts unexpectedly when running the following command:
```
perf record -e cycles -I -- true
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
```The usage of the -I or --user-regs options without specifying any registers should default to sampling all general-purpose registers. However, this currently causes an abnormal termination.
The issue was introduced by commit 3d06db9bad1a ("perf regs: Refactor
use of arch__sample_reg_masks() to perf_reg_name()"). This patch
resolves the problem, ensuring that the -I or --user-regs options work as intended without causing an abort.
--- tools/perf/util/parse-regs-options.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
tools/perf/util/parse-regs-options.c +6 -7
@@ -66,12 +66,14 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)if (*mode)return -1 ; -/* str may be NULL in case no arg is passed to -I */ -if (!str) -return -1 ; - mask = intr ?arch__intr_reg_mask () :arch__user_reg_mask (); +/* str may be NULL in case no arg is passed to -I */ +if (!str) { + *mode = mask; +return 0 ; + } +/* because str is read-only */ s = os =strdup (str);if (!s)
@@ -104,9 +106,6 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr) } ret =0 ; -/* default to all possible regs */ -if (*mode ==0 ) - *mode = mask; error:free (os);return ret;
Signature · 1 line
2.34.1
Re: [Patch v3 1/4] perf regs: Fix abort for "-I" or "--user-regs" options
Quoted 18 lines · Dapeng Mi
Fix an issue where the
perftool aborts unexpectedly when running the following command:``` perf record -e cycles -I -- true 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 ```The usage of the
-Ior--user-regsoptions without specifying any registers should default to sampling all general-purpose registers. However, this currently causes an abnormal termination.
Quoted 7 lines
The issue was introduced by commit
3d06db9bad1a("perf regs: Refactor
use ofarch__sample_reg_masks()toperf_reg_name()"). This patch
resolves the problem, ensuring that the-Ior--user-regsoptions work as intended without causing an abort.Fixes 3d06db9bad1a ("perf regs: Refactor use of arch__sample_reg_masks() to perf_reg_name()")Signed-off-by Dapeng Mi <[email protected]>
Thanks,
Ian
Quoted 40 lines
--- tools/perf/util/parse-regs-options.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)tools/perf/util/parse-regs-options.c +6
-8@@ -66,12 +66,14 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)if (*mode)return -1 ; -/* str may be NULL in case no arg is passed to -I */ -if (!str) -return -1 ; - mask = intr ?arch__intr_reg_mask () :arch__user_reg_mask (); +/* str may be NULL in case no arg is passed to -I */ +if (!str) { + *mode = mask; +return 0 ; + } +/* because str is read-only */ s = os =strdup (str);if (!s)@@ -104,9 +106,6 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr) } ret =0 ; -/* default to all possible regs */ -if (*mode ==0 ) - *mode = mask; error:free (os);return ret; --2.34.1
PATCH v3 2/4 perf arch: Update arch headers to use relative UAPI paths
In reply to Dapeng MiThe architectural specific headers perf_regs.h currently rely on the host architecture's 'asm/perf_regs.h'. This can lead to compilation inconsistencies or failures when including and building perf for a target architecture that differs from the host's architecture.
Explicitly point to the UAPI headers within the tools source tree using relative paths. This ensures that perf is always built against the intended architecture.
No functional changes are intended.
--- tools/perf/arch/arm/include/perf_regs.h | 2 +- tools/perf/arch/arm64/include/perf_regs.h | 2 +- tools/perf/arch/csky/include/perf_regs.h | 2 +- tools/perf/arch/loongarch/include/perf_regs.h | 2 +- tools/perf/arch/mips/include/perf_regs.h | 2 +- tools/perf/arch/powerpc/include/perf_regs.h | 2 +- tools/perf/arch/riscv/include/perf_regs.h | 2 +- tools/perf/arch/s390/include/perf_regs.h | 2 +- tools/perf/arch/x86/include/perf_regs.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-)
tools/perf/arch/arm/include/perf_regs.h +1 -1
@@ -4,7 +4,7 @@#include <stdlib.h> #include <linux/types.h> -#include <asm/perf_regs.h> +#include "../../../../arch/arm/include/uapi/asm/perf_regs.h" void perf_regs_load (u64 *regs);
tools/perf/arch/arm64/include/perf_regs.h +1 -1
@@ -5,7 +5,7 @@#include <stdlib.h> #include <linux/types.h> #define perf_event_arm_regs perf_event_arm64_regs -#include <asm/perf_regs.h> +#include "../../../../arch/arm64/include/uapi/asm/perf_regs.h" #undef perf_event_arm_regsvoid perf_regs_load (u64 *regs);
tools/perf/arch/csky/include/perf_regs.h +1 -1
@@ -6,7 +6,7 @@#include <stdlib.h> #include <linux/types.h> -#include <asm/perf_regs.h> +#include "../../../../arch/csky/include/uapi/asm/perf_regs.h" #define PERF_REGS_MASK ((1ULL << PERF_REG_CSKY_MAX) - 1)#define PERF_REGS_MAX PERF_REG_CSKY_MAX
tools/perf/arch/loongarch/include/perf_regs.h +1 -1
@@ -4,7 +4,7 @@#include <stdlib.h> #include <linux/types.h> -#include <asm/perf_regs.h> +#include "../../../../arch/loongarch/include/uapi/asm/perf_regs.h" #define PERF_REGS_MAX PERF_REG_LOONGARCH_MAX
tools/perf/arch/mips/include/perf_regs.h +1 -1
@@ -4,7 +4,7 @@#include <stdlib.h> #include <linux/types.h> -#include <asm/perf_regs.h> +#include "../../../../arch/mips/include/uapi/asm/perf_regs.h" #define PERF_REGS_MAX PERF_REG_MIPS_MAX
tools/perf/arch/powerpc/include/perf_regs.h +1 -1
@@ -4,7 +4,7 @@#include <stdlib.h> #include <linux/types.h> -#include <asm/perf_regs.h> +#include "../../../../arch/powerpc/include/uapi/asm/perf_regs.h" void perf_regs_load (u64 *regs);
tools/perf/arch/riscv/include/perf_regs.h +1 -1
@@ -6,7 +6,7 @@#include <stdlib.h> #include <linux/types.h> -#include <asm/perf_regs.h> +#include "../../../../arch/riscv/include/uapi/asm/perf_regs.h" #define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1)#define PERF_REGS_MAX PERF_REG_RISCV_MAX
tools/perf/arch/s390/include/perf_regs.h +1 -1
@@ -3,7 +3,7 @@#include <stdlib.h> #include <linux/types.h> -#include <asm/perf_regs.h> +#include "../../../../arch/s390/include/uapi/asm/perf_regs.h" void perf_regs_load (u64 *regs);
tools/perf/arch/x86/include/perf_regs.h +1 -1
@@ -4,7 +4,7 @@#include <stdlib.h> #include <linux/types.h> -#include <asm/perf_regs.h> +#include "../../../../arch/x86/include/uapi/asm/perf_regs.h" void perf_regs_load (u64 *regs);
Signature · 1 line
2.34.1
PATCH v3 3/4 perf regs: Remove __weak attributive arch__xxx_reg_mask() functions
In reply to Dapeng MiCurrently, some architecture-specific perf-regs functions, such as arch__intr_reg_mask() and arch__user_reg_mask(), are defined with the __weak attribute. This approach ensures that only functions matching the architecture of the build/run host are compiled and executed, reducing build time and binary size.
However, this __weak attribute restricts these functions to be called only on the same architecture, preventing cross-architecture functionality. For example, a perf.data file captured on x86 cannot be parsed on an ARM platform.
To address this limitation, this patch removes the __weak attribute from these perf-regs functions. The architecture-specific code is moved from the arch/ directory to the util/perf-regs-arch/ directory. The appropriate architectural functions are then called based on the EM_HOST.
No functional changes are intended.
--- tools/perf/arch/arm/util/Build | 2 - tools/perf/arch/arm/util/perf_regs.c | 13 --- tools/perf/arch/arm64/util/perf_regs.c | 36 -------- tools/perf/arch/csky/Build | 1 - tools/perf/arch/csky/util/Build | 1 - tools/perf/arch/csky/util/perf_regs.c | 13 --- tools/perf/arch/loongarch/util/Build | 1 - tools/perf/arch/loongarch/util/perf_regs.c | 13 --- tools/perf/arch/mips/util/Build | 1 - tools/perf/arch/mips/util/perf_regs.c | 13 --- tools/perf/arch/powerpc/util/perf_regs.c | 47 ----------- tools/perf/arch/riscv/include/perf_regs.h | 7 +- tools/perf/arch/riscv/util/Build | 1 - tools/perf/arch/riscv/util/perf_regs.c | 13 --- tools/perf/arch/s390/util/Build | 1 - tools/perf/arch/s390/util/perf_regs.c | 13 --- tools/perf/arch/x86/util/perf_regs.c | 48 ----------- tools/perf/util/evsel.c | 4 +- tools/perf/util/parse-regs-options.c | 2 +- .../util/perf-regs-arch/perf_regs_aarch64.c | 53 +++++++++++- .../perf/util/perf-regs-arch/perf_regs_arm.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_csky.c | 7 +- .../util/perf-regs-arch/perf_regs_loongarch.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_mips.c | 7 +- .../util/perf-regs-arch/perf_regs_powerpc.c | 77 ++++++++++++++++- .../util/perf-regs-arch/perf_regs_riscv.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_s390.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_x86.c | 60 ++++++++++++- tools/perf/util/perf_regs.c | 84 ++++++++++++++++++- tools/perf/util/perf_regs.h | 22 ++++- 30 files changed, 332 insertions(+), 236 deletions(-) delete mode 100644 tools/perf/arch/arm/util/perf_regs.c delete mode 100644 tools/perf/arch/csky/Build delete mode 100644 tools/perf/arch/csky/util/Build delete mode 100644 tools/perf/arch/csky/util/perf_regs.c delete mode 100644 tools/perf/arch/loongarch/util/perf_regs.c delete mode 100644 tools/perf/arch/mips/util/perf_regs.c delete mode 100644 tools/perf/arch/riscv/util/perf_regs.c delete mode 100644 tools/perf/arch/s390/util/perf_regs.c
tools/perf/arch/arm/util/Build +0 -2
@@ -1,5 +1,3 @@ -perf-util-y += perf_regs.o - perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-util-y += pmu.o auxtrace.o cs-etm.o
tools/perf/arch/arm/util/perf_regs.c deleted +0 -13
@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}
tools/perf/arch/arm64/util/perf_regs.c +0 -36
@@ -103,39 +103,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)return SDT_ARG_VALID ; } - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -struct perf_event_attr attr = { - .type =PERF_TYPE_HARDWARE , - .config =PERF_COUNT_HW_CPU_CYCLES , - .sample_type =PERF_SAMPLE_REGS_USER , - .disabled =1 , - .exclude_kernel =1 , - .sample_period =1 , - .sample_regs_user =PERF_REGS_MASK - }; -int fd; - -if (getauxval (AT_HWCAP ) &HWCAP_SVE ) - attr.sample_regs_user |=SMPL_REG_MASK (PERF_REG_ARM64_VG ); - -/* -* Check if the pmu supports perf extended regs, before -* returning the register mask to sample. -*/ -if (attr.sample_regs_user !=PERF_REGS_MASK ) { -event_attr_init (&attr); - fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,0 ); -if (fd !=-1 ) { -close (fd); -return attr.sample_regs_user; - } - } -return PERF_REGS_MASK ; -}
tools/perf/arch/csky/Build deleted +0 -1
@@ -1 +0,0 @@ -perf-util-y += util/
tools/perf/arch/csky/util/Build deleted +0 -1
@@ -1 +0,0 @@ -perf-util-y += perf_regs.o
tools/perf/arch/csky/util/perf_regs.c deleted +0 -13
@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}
tools/perf/arch/loongarch/util/Build +0 -1
@@ -1,5 +1,4 @@ perf-util-y += header.o -perf-util-y += perf_regs.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
tools/perf/arch/loongarch/util/perf_regs.c deleted +0 -13
@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}
tools/perf/arch/mips/util/Build +0 -1
@@ -1,2 +1 @@ -perf-util-y += perf_regs.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
tools/perf/arch/mips/util/perf_regs.c deleted +0 -13
@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}
tools/perf/arch/powerpc/util/perf_regs.c +0 -47
50 lines not on this page · raw message
tools/perf/arch/riscv/include/perf_regs.h +6 -1
@@ -10,10 +10,15 @@#define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1)#define PERF_REGS_MAX PERF_REG_RISCV_MAX + +#if defined(__riscv_xlen)#if __riscv_xlen ==64 -#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64#else #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32#endif +#else +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_NONE +#endif #endif /* ARCH_PERF_REGS_H */
tools/perf/arch/riscv/util/Build +0 -1
@@ -1,4 +1,3 @@ -perf-util-y += perf_regs.o perf-util-y += header.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
tools/perf/arch/riscv/util/perf_regs.c deleted +0 -13
@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}
tools/perf/arch/s390/util/Build +0 -1
@@ -1,6 +1,5 @@ perf-util-y += header.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o perf-util-y += machine.o perf-util-y += pmu.o
tools/perf/arch/s390/util/perf_regs.c deleted +0 -13
@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}
tools/perf/arch/x86/util/perf_regs.c +0 -48
51 lines not on this page · raw message
tools/perf/util/evsel.c +2 -2
@@ -1055,13 +1055,13 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *oevsel__set_sample_bit (evsel,REGS_USER );evsel__set_sample_bit (evsel,STACK_USER );if (opts->sample_user_regs && -DWARF_MINIMAL_REGS (e_machine) !=arch__user_reg_mask ()) { +DWARF_MINIMAL_REGS (e_machine) !=perf_user_reg_mask (EM_HOST )) { attr->sample_regs_user |=DWARF_MINIMAL_REGS (e_machine);pr_warning ("WARNING: The use of --call-graph=dwarf may require all the user registers, " "specifying a subset with --user-regs may render DWARF unwinding unreliable, " "so the minimal registers set (IP, SP) is explicitly forced.\n" ); }else { - attr->sample_regs_user |=arch__user_reg_mask (); + attr->sample_regs_user |=perf_user_reg_mask (EM_HOST ); } attr->sample_stack_user = param->dump_size; attr->exclude_callchain_user =1 ;
tools/perf/util/parse-regs-options.c +1 -1
@@ -66,7 +66,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)if (*mode)return -1 ; - mask = intr ?arch__intr_reg_mask () :arch__user_reg_mask (); + mask = intr ?perf_intr_reg_mask (EM_HOST ) :perf_user_reg_mask (EM_HOST );/* str may be NULL in case no arg is passed to -I */ if (!str) {
tools/perf/util/perf-regs-arch/perf_regs_aarch64.c +52 -1
59 lines not on this page · raw message
tools/perf/util/perf-regs-arch/perf_regs_arm.c +6 -1
@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/arm/include/uapi/asm/perf_regs.h" +#include "../../arch/arm/include/perf_regs.h" + +uint64_t __perf_reg_mask_arm (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_arm (int id) {
tools/perf/util/perf-regs-arch/perf_regs_csky.c +6 -1
@@ -9,7 +9,12 @@#include "../perf_regs.h" #undef __CSKYABIV2__#define __CSKYABIV2__ 1 // Always want the V2 register definitions. -#include "../../arch/csky/include/uapi/asm/perf_regs.h" +#include "../../arch/csky/include/perf_regs.h" + +uint64_t __perf_reg_mask_csky (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_csky (int id,uint32_t e_flags) {
tools/perf/util/perf-regs-arch/perf_regs_loongarch.c +6 -1
@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/loongarch/include/uapi/asm/perf_regs.h" +#include "../../arch/loongarch/include/perf_regs.h" + +uint64_t __perf_reg_mask_loongarch (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_loongarch (int id) {
tools/perf/util/perf-regs-arch/perf_regs_mips.c +6 -1
@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/mips/include/uapi/asm/perf_regs.h" +#include "../../arch/mips/include/perf_regs.h" + +uint64_t __perf_reg_mask_mips (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_mips (int id) {
tools/perf/util/perf-regs-arch/perf_regs_powerpc.c +76 -1
83 lines not on this page · raw message
tools/perf/util/perf-regs-arch/perf_regs_riscv.c +6 -1
@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/riscv/include/uapi/asm/perf_regs.h" +#include "../../arch/riscv/include/perf_regs.h" + +uint64_t __perf_reg_mask_riscv (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_riscv (int id) {
tools/perf/util/perf-regs-arch/perf_regs_s390.c +6 -1
@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/s390/include/uapi/asm/perf_regs.h" +#include "../../arch/s390/include/perf_regs.h" + +uint64_t __perf_reg_mask_s390 (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_s390 (int id) {
tools/perf/util/perf-regs-arch/perf_regs_x86.c +59 -1
66 lines not on this page · raw message
tools/perf/util/perf_regs.c +80 -4
94 lines not on this page · raw message
tools/perf/util/perf_regs.h +20 -2
@@ -13,37 +13,55 @@ 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 ); +uint64_t perf_intr_reg_mask (uint16_t e_machine); +uint64_t perf_user_reg_mask (uint16_t e_machine);const char *perf_reg_name (int id,uint16_t e_machine,uint32_t e_flags);int perf_reg_value (u64 *valp,struct regs_dump *regs,int id);uint64_t perf_arch_reg_ip (uint16_t e_machine);uint64_t perf_arch_reg_sp (uint16_t e_machine); + +uint64_t __perf_reg_mask_arm64 (bool intr);const char *__perf_reg_name_arm64 (int id);uint64_t __perf_reg_ip_arm64 (void );uint64_t __perf_reg_sp_arm64 (void ); + +uint64_t __perf_reg_mask_arm (bool intr);const char *__perf_reg_name_arm (int id);uint64_t __perf_reg_ip_arm (void );uint64_t __perf_reg_sp_arm (void ); + +uint64_t __perf_reg_mask_csky (bool intr);const char *__perf_reg_name_csky (int id,uint32_t e_flags);uint64_t __perf_reg_ip_csky (void );uint64_t __perf_reg_sp_csky (void ); + +uint64_t __perf_reg_mask_loongarch (bool intr);const char *__perf_reg_name_loongarch (int id);uint64_t __perf_reg_ip_loongarch (void );uint64_t __perf_reg_sp_loongarch (void ); + +uint64_t __perf_reg_mask_mips (bool intr);const char *__perf_reg_name_mips (int id);uint64_t __perf_reg_ip_mips (void );uint64_t __perf_reg_sp_mips (void ); + +uint64_t __perf_reg_mask_powerpc (bool intr);const char *__perf_reg_name_powerpc (int id);uint64_t __perf_reg_ip_powerpc (void );uint64_t __perf_reg_sp_powerpc (void ); + +uint64_t __perf_reg_mask_riscv (bool intr);const char *__perf_reg_name_riscv (int id);uint64_t __perf_reg_ip_riscv (void );uint64_t __perf_reg_sp_riscv (void ); + +uint64_t __perf_reg_mask_s390 (bool intr);const char *__perf_reg_name_s390 (int id);uint64_t __perf_reg_ip_s390 (void );uint64_t __perf_reg_sp_s390 (void ); + +uint64_t __perf_reg_mask_x86 (bool intr);const char *__perf_reg_name_x86 (int id);uint64_t __perf_reg_ip_x86 (void );uint64_t __perf_reg_sp_x86 (void );
Signature · 1 line
2.34.1
Re: [Patch v3 3/4] perf regs: Remove __weak attributive arch__xxx_reg_mask() functions
Quoted 17 lines · Dapeng Mi
Currently, some architecture-specific perf-regs functions, such as
arch__intr_reg_mask()andarch__user_reg_mask(), are defined with the__weakattribute. This approach ensures that only functions matching the architecture of the build/run host are compiled and executed, reducing build time and binary size.However, this
__weakattribute restricts these functions to be called only on the same architecture, preventing cross-architecture functionality. For example, a perf.data file captured on x86 cannot be parsed on an ARM platform.To address this limitation, this patch removes the
__weakattribute from these perf-regs functions. The architecture-specific code is moved from thearch/directory to the util/perf-regs-arch/ directory. The appropriate architectural functions are then called based on theEM_HOST.
Quoted 4 lines
No functional changes are intended.
Suggested-by Ian Rogers <[email protected]>Signed-off-by Dapeng Mi <[email protected]>
Thanks,
Ian
Quoted 920 lines
--- tools/perf/arch/arm/util/Build | 2 - tools/perf/arch/arm/util/perf_regs.c | 13 --- tools/perf/arch/arm64/util/perf_regs.c | 36 -------- tools/perf/arch/csky/Build | 1 - tools/perf/arch/csky/util/Build | 1 - tools/perf/arch/csky/util/perf_regs.c | 13 --- tools/perf/arch/loongarch/util/Build | 1 - tools/perf/arch/loongarch/util/perf_regs.c | 13 --- tools/perf/arch/mips/util/Build | 1 - tools/perf/arch/mips/util/perf_regs.c | 13 --- tools/perf/arch/powerpc/util/perf_regs.c | 47 ----------- tools/perf/arch/riscv/include/perf_regs.h | 7 +- tools/perf/arch/riscv/util/Build | 1 - tools/perf/arch/riscv/util/perf_regs.c | 13 --- tools/perf/arch/s390/util/Build | 1 - tools/perf/arch/s390/util/perf_regs.c | 13 --- tools/perf/arch/x86/util/perf_regs.c | 48 ----------- tools/perf/util/evsel.c | 4 +- tools/perf/util/parse-regs-options.c | 2 +- .../util/perf-regs-arch/perf_regs_aarch64.c | 53 +++++++++++- .../perf/util/perf-regs-arch/perf_regs_arm.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_csky.c | 7 +- .../util/perf-regs-arch/perf_regs_loongarch.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_mips.c | 7 +- .../util/perf-regs-arch/perf_regs_powerpc.c | 77 ++++++++++++++++- .../util/perf-regs-arch/perf_regs_riscv.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_s390.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_x86.c | 60 ++++++++++++- tools/perf/util/perf_regs.c | 84 ++++++++++++++++++- tools/perf/util/perf_regs.h | 22 ++++- 30 files changed, 332 insertions(+), 236 deletions(-) delete mode 100644 tools/perf/arch/arm/util/perf_regs.c delete mode 100644 tools/perf/arch/csky/Build delete mode 100644 tools/perf/arch/csky/util/Build delete mode 100644 tools/perf/arch/csky/util/perf_regs.c delete mode 100644 tools/perf/arch/loongarch/util/perf_regs.c delete mode 100644 tools/perf/arch/mips/util/perf_regs.c delete mode 100644 tools/perf/arch/riscv/util/perf_regs.c delete mode 100644 tools/perf/arch/s390/util/perf_regs.ctools/perf/arch/arm/util/Build +0
-2@@ -1,5 +1,3 @@ -perf-util-y += perf_regs.o - perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-util-y += pmu.o auxtrace.o cs-etm.otools/perf/arch/arm/util/perf_regs.c deleted +0
-13@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}tools/perf/arch/arm64/util/perf_regs.c +0
-36@@ -103,39 +103,3 @@ int arch_sdt_arg_parse_op(char *old_op, char **new_op)return SDT_ARG_VALID ; } - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -struct perf_event_attr attr = { - .type =PERF_TYPE_HARDWARE , - .config =PERF_COUNT_HW_CPU_CYCLES , - .sample_type =PERF_SAMPLE_REGS_USER , - .disabled =1 , - .exclude_kernel =1 , - .sample_period =1 , - .sample_regs_user =PERF_REGS_MASK - }; -int fd; - -if (getauxval (AT_HWCAP ) &HWCAP_SVE ) - attr.sample_regs_user |=SMPL_REG_MASK (PERF_REG_ARM64_VG ); - -/* -* Check if the pmu supports perf extended regs, before -* returning the register mask to sample. -*/ -if (attr.sample_regs_user !=PERF_REGS_MASK ) { -event_attr_init (&attr); - fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,0 ); -if (fd !=-1 ) { -close (fd); -return attr.sample_regs_user; - } - } -return PERF_REGS_MASK ; -}tools/perf/arch/csky/Build deleted +0
-1@@ -1 +0,0 @@ -perf-util-y += util/tools/perf/arch/csky/util/Build deleted +0
-1@@ -1 +0,0 @@ -perf-util-y += perf_regs.otools/perf/arch/csky/util/perf_regs.c deleted +0
-13@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}tools/perf/arch/loongarch/util/Build +0
-1@@ -1,5 +1,4 @@ perf-util-y += header.o -perf-util-y += perf_regs.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.otools/perf/arch/loongarch/util/perf_regs.c deleted +0
-13@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}tools/perf/arch/mips/util/Build +0
-1@@ -1,2 +1 @@ -perf-util-y += perf_regs.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.otools/perf/arch/mips/util/perf_regs.c deleted +0
-13@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}tools/perf/arch/powerpc/util/perf_regs.c +0
-47@@ -123,50 +123,3 @@ 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 if ((version ==PVR_POWER10 ) || (version ==PVR_POWER11 )) - extended_mask =PERF_REG_PMU_MASK_31 ; -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; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}tools/perf/arch/riscv/include/perf_regs.h +6
-1@@ -10,10 +10,15 @@#define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1)#define PERF_REGS_MAX PERF_REG_RISCV_MAX + +#if defined(__riscv_xlen)#if __riscv_xlen ==64 -#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64#else #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32#endif +#else +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_NONE +#endif #endif /* ARCH_PERF_REGS_H */ tools/perf/arch/riscv/util/Build +0
-1@@ -1,4 +1,3 @@ -perf-util-y += perf_regs.o perf-util-y += header.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.otools/perf/arch/riscv/util/perf_regs.c deleted +0
-13@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}tools/perf/arch/s390/util/Build +0
-1@@ -1,6 +1,5 @@ perf-util-y += header.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o perf-util-y += machine.o perf-util-y += pmu.otools/perf/arch/s390/util/perf_regs.c deleted +0
-13@@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -uint64_t arch__intr_reg_mask (void ) -{ -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}tools/perf/arch/x86/util/perf_regs.c +0
-48@@ -233,51 +233,3 @@ 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_REG_EXTENDED_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 ; - -if (perf_pmus__num_core_pmus () >1 ) { -struct perf_pmu *pmu =NULL ; -__u64 type =PERF_TYPE_RAW ; - -/* -* The same register set is supported among different hybrid PMUs. -* Only check the first available one. -*/ -while ((pmu =perf_pmus__scan_core (pmu)) !=NULL ) { - type = pmu->type; -break ; - } - attr.config |= type <<PERF_PMU_TYPE_SHIFT ; - } - -event_attr_init (&attr); - - fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,0 ); -if (fd !=-1 ) { -close (fd); -return (PERF_REG_EXTENDED_MASK |PERF_REGS_MASK ); - } - -return PERF_REGS_MASK ; -} - -uint64_t arch__user_reg_mask (void ) -{ -return PERF_REGS_MASK ; -}tools/perf/util/evsel.c +2
-2@@ -1055,13 +1055,13 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *oevsel__set_sample_bit (evsel,REGS_USER );evsel__set_sample_bit (evsel,STACK_USER );if (opts->sample_user_regs && -DWARF_MINIMAL_REGS (e_machine) !=arch__user_reg_mask ()) { +DWARF_MINIMAL_REGS (e_machine) !=perf_user_reg_mask (EM_HOST )) { attr->sample_regs_user |=DWARF_MINIMAL_REGS (e_machine);pr_warning ("WARNING: The use of --call-graph=dwarf may require all the user registers, " "specifying a subset with --user-regs may render DWARF unwinding unreliable, " "so the minimal registers set (IP, SP) is explicitly forced.\n" ); }else { - attr->sample_regs_user |=arch__user_reg_mask (); + attr->sample_regs_user |=perf_user_reg_mask (EM_HOST ); } attr->sample_stack_user = param->dump_size; attr->exclude_callchain_user =1 ;tools/perf/util/parse-regs-options.c +1
-1@@ -66,7 +66,7 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr)if (*mode)return -1 ; - mask = intr ?arch__intr_reg_mask () :arch__user_reg_mask (); + mask = intr ?perf_intr_reg_mask (EM_HOST ) :perf_user_reg_mask (EM_HOST );/* str may be NULL in case no arg is passed to -I */ if (!str) {tools/perf/util/perf-regs-arch/perf_regs_aarch64.c +52
-1@@ -1,7 +1,58 @@// SPDX-License-Identifier: GPL-2.0 +#include <errno.h> +#include <regex.h> +#include <string.h> +#include <sys/auxv.h> +#include <linux/kernel.h> +#include <linux/zalloc.h> +#include "../debug.h" +#include "../event.h" #include "../perf_regs.h" -#include "../../../arch/arm64/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/arm64/include/perf_regs.h" + +#define SMPL_REG_MASK (b) (1ULL << (b)) + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +uint64_t __perf_reg_mask_arm64 (bool intr) +{ +struct perf_event_attr attr = { + .type =PERF_TYPE_HARDWARE , + .config =PERF_COUNT_HW_CPU_CYCLES , + .sample_type =PERF_SAMPLE_REGS_USER , + .disabled =1 , + .exclude_kernel =1 , + .sample_period =1 , + .sample_regs_user =PERF_REGS_MASK + }; +int fd; + +if (intr) +return PERF_REGS_MASK ; + +if (getauxval (AT_HWCAP ) &HWCAP_SVE ) + attr.sample_regs_user |=SMPL_REG_MASK (PERF_REG_ARM64_VG ); + +/* +* Check if the pmu supports perf extended regs, before +* returning the register mask to sample. Open the event +* on the perf process to check this. +*/ +if (attr.sample_regs_user !=PERF_REGS_MASK ) { +event_attr_init (&attr); + fd =sys_perf_event_open (&attr,/*pid=*/ 0 ,/*cpu=*/ -1 , +/*group_fd=*/ -1 ,/*flags=*/ 0 ); +if (fd !=-1 ) { +close (fd); +return attr.sample_regs_user; + } + } +return PERF_REGS_MASK ; +}const char *__perf_reg_name_arm64 (int id) {tools/perf/util/perf-regs-arch/perf_regs_arm.c +6
-1@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/arm/include/uapi/asm/perf_regs.h" +#include "../../arch/arm/include/perf_regs.h" + +uint64_t __perf_reg_mask_arm (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_arm (int id) {tools/perf/util/perf-regs-arch/perf_regs_csky.c +6
-1@@ -9,7 +9,12 @@#include "../perf_regs.h" #undef __CSKYABIV2__#define __CSKYABIV2__ 1 // Always want the V2 register definitions. -#include "../../arch/csky/include/uapi/asm/perf_regs.h" +#include "../../arch/csky/include/perf_regs.h" + +uint64_t __perf_reg_mask_csky (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_csky (int id,uint32_t e_flags) {tools/perf/util/perf-regs-arch/perf_regs_loongarch.c +6
-1@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/loongarch/include/uapi/asm/perf_regs.h" +#include "../../arch/loongarch/include/perf_regs.h" + +uint64_t __perf_reg_mask_loongarch (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_loongarch (int id) {tools/perf/util/perf-regs-arch/perf_regs_mips.c +6
-1@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/mips/include/uapi/asm/perf_regs.h" +#include "../../arch/mips/include/perf_regs.h" + +uint64_t __perf_reg_mask_mips (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_mips (int id) {tools/perf/util/perf-regs-arch/perf_regs_powerpc.c +76
-1@@ -1,7 +1,82 @@// SPDX-License-Identifier: GPL-2.0 +#include <errno.h> +#include <string.h> +#include <regex.h> +#include <linux/zalloc.h> + +#include "../debug.h" +#include "../event.h" +#include "../header.h" #include "../perf_regs.h" -#include "../../../arch/powerpc/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/powerpc/util/utils_header.h" +#include "../../arch/powerpc/include/perf_regs.h" + +#include <linux/kernel.h> + +#define PVR_POWER9 0x004E +#define PVR_POWER10 0x0080 +#define PVR_POWER11 0x0082 + +/* +* mfspr is a POWERPC specific instruction, ensure it's only +* built and called on POWERPC by guarding with __powerpc64__ +* or __powerpc__. +*/ +#if defined(__powerpc64__) && defined(__powerpc__) +uint64_t __perf_reg_mask_powerpc (bool intr) +{ +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 ; + +if (!intr) +return 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 if ((version ==PVR_POWER10 ) || (version ==PVR_POWER11 )) + extended_mask =PERF_REG_PMU_MASK_31 ; +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. Open the event +* on the perf process to check this. +*/ + fd =sys_perf_event_open (&attr,/*pid=*/ 0 ,/*cpu=*/ -1 , +/*group_fd=*/ -1 ,/*flags=*/ 0 ); +if (fd !=-1 ) { +close (fd); + mask |= extended_mask; + } +return mask; +} +#else +uint64_t __perf_reg_mask_powerpc (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +} +#endif const char *__perf_reg_name_powerpc (int id) {tools/perf/util/perf-regs-arch/perf_regs_riscv.c +6
-1@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/riscv/include/uapi/asm/perf_regs.h" +#include "../../arch/riscv/include/perf_regs.h" + +uint64_t __perf_reg_mask_riscv (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_riscv (int id) {tools/perf/util/perf-regs-arch/perf_regs_s390.c +6
-1@@ -1,7 +1,12 @@// SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/s390/include/uapi/asm/perf_regs.h" +#include "../../arch/s390/include/perf_regs.h" + +uint64_t __perf_reg_mask_s390 (bool intr__maybe_unused ) +{ +return PERF_REGS_MASK ; +}const char *__perf_reg_name_s390 (int id) {tools/perf/util/perf-regs-arch/perf_regs_x86.c +59
-1@@ -1,7 +1,65 @@// SPDX-License-Identifier: GPL-2.0 +#include <errno.h> +#include <string.h> +#include <regex.h> +#include <linux/kernel.h> +#include <linux/zalloc.h> + +#include "../debug.h" +#include "../event.h" +#include "../pmu.h" +#include "../pmus.h" #include "../perf_regs.h" -#include "../../../arch/x86/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/x86/include/perf_regs.h" + +uint64_t __perf_reg_mask_x86 (bool intr) +{ +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_REG_EXTENDED_MASK , + .precise_ip =1 , + .disabled =1 , + .exclude_kernel =1 , + }; +int fd; + +if (!intr) +return PERF_REGS_MASK ; + +/* +* In an unnamed union, init it here to build on older gcc versions +*/ + attr.sample_period =1 ; + +if (perf_pmus__num_core_pmus () >1 ) { +struct perf_pmu *pmu =NULL ; +__u64 type =PERF_TYPE_RAW ; + +/* +* The same register set is supported among different hybrid PMUs. +* Only check the first available one. +*/ +while ((pmu =perf_pmus__scan_core (pmu)) !=NULL ) { + type = pmu->type; +break ; + } + attr.config |= type <<PERF_PMU_TYPE_SHIFT ; + } + +event_attr_init (&attr); + fd =sys_perf_event_open (&attr,/*pid=*/ 0 ,/*cpu=*/ -1 , +/*group_fd=*/ -1 ,/*flags=*/ 0 ); +if (fd !=-1 ) { +close (fd); +return (PERF_REG_EXTENDED_MASK |PERF_REGS_MASK ); + } + +return PERF_REGS_MASK ; +}const char *__perf_reg_name_x86 (int id) {tools/perf/util/perf_regs.c +80
-4@@ -13,14 +13,90 @@ int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused,return SDT_ARG_SKIP ; } -uint64_t __weak arch__intr_reg_mask (void ) +uint64_t perf_intr_reg_mask (uint16_t e_machine) { -return 0 ; +uint64_t mask =0 ; + +switch (e_machine) { +case EM_ARM : + mask =__perf_reg_mask_arm (/*intr=*/ true); +break ; +case EM_AARCH64 : + mask =__perf_reg_mask_arm64 (/*intr=*/ true); +break ; +case EM_CSKY : + mask =__perf_reg_mask_csky (/*intr=*/ true); +break ; +case EM_LOONGARCH : + mask =__perf_reg_mask_loongarch (/*intr=*/ true); +break ; +case EM_MIPS : + mask =__perf_reg_mask_mips (/*intr=*/ true); +break ; +case EM_PPC : +case EM_PPC64 : + mask =__perf_reg_mask_powerpc (/*intr=*/ true); +break ; +case EM_RISCV : + mask =__perf_reg_mask_riscv (/*intr=*/ true); +break ; +case EM_S390 : + mask =__perf_reg_mask_s390 (/*intr=*/ true); +break ; +case EM_386 : +case EM_X86_64 : + mask =__perf_reg_mask_x86 (/*intr=*/ true); +break ; +default : +pr_debug ("Unknown ELF machine %d, interrupt sampling register mask will be empty.\n" , + e_machine); +break ; + } + +return mask; } -uint64_t __weak arch__user_reg_mask (void ) +uint64_t perf_user_reg_mask (uint16_t e_machine) { -return 0 ; +uint64_t mask =0 ; + +switch (e_machine) { +case EM_ARM : + mask =__perf_reg_mask_arm (/*intr=*/ false); +break ; +case EM_AARCH64 : + mask =__perf_reg_mask_arm64 (/*intr=*/ false); +break ; +case EM_CSKY : + mask =__perf_reg_mask_csky (/*intr=*/ false); +break ; +case EM_LOONGARCH : + mask =__perf_reg_mask_loongarch (/*intr=*/ false); +break ; +case EM_MIPS : + mask =__perf_reg_mask_mips (/*intr=*/ false); +break ; +case EM_PPC : +case EM_PPC64 : + mask =__perf_reg_mask_powerpc (/*intr=*/ false); +break ; +case EM_RISCV : + mask =__perf_reg_mask_riscv (/*intr=*/ false); +break ; +case EM_S390 : + mask =__perf_reg_mask_s390 (/*intr=*/ false); +break ; +case EM_386 : +case EM_X86_64 : + mask =__perf_reg_mask_x86 (/*intr=*/ false); +break ; +default : +pr_debug ("Unknown ELF machine %d, user sampling register mask will be empty.\n" , + e_machine); +break ; + } + +return mask; }const char *perf_reg_name (int id,uint16_t e_machine,uint32_t e_flags)tools/perf/util/perf_regs.h +20
-3@@ -13,37 +13,55 @@ 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 ); +uint64_t perf_intr_reg_mask (uint16_t e_machine); +uint64_t perf_user_reg_mask (uint16_t e_machine);const char *perf_reg_name (int id,uint16_t e_machine,uint32_t e_flags);int perf_reg_value (u64 *valp,struct regs_dump *regs,int id);uint64_t perf_arch_reg_ip (uint16_t e_machine);uint64_t perf_arch_reg_sp (uint16_t e_machine); + +uint64_t __perf_reg_mask_arm64 (bool intr);const char *__perf_reg_name_arm64 (int id);uint64_t __perf_reg_ip_arm64 (void );uint64_t __perf_reg_sp_arm64 (void ); + +uint64_t __perf_reg_mask_arm (bool intr);const char *__perf_reg_name_arm (int id);uint64_t __perf_reg_ip_arm (void );uint64_t __perf_reg_sp_arm (void ); + +uint64_t __perf_reg_mask_csky (bool intr);const char *__perf_reg_name_csky (int id,uint32_t e_flags);uint64_t __perf_reg_ip_csky (void );uint64_t __perf_reg_sp_csky (void ); + +uint64_t __perf_reg_mask_loongarch (bool intr);const char *__perf_reg_name_loongarch (int id);uint64_t __perf_reg_ip_loongarch (void );uint64_t __perf_reg_sp_loongarch (void ); + +uint64_t __perf_reg_mask_mips (bool intr);const char *__perf_reg_name_mips (int id);uint64_t __perf_reg_ip_mips (void );uint64_t __perf_reg_sp_mips (void ); + +uint64_t __perf_reg_mask_powerpc (bool intr);const char *__perf_reg_name_powerpc (int id);uint64_t __perf_reg_ip_powerpc (void );uint64_t __perf_reg_sp_powerpc (void ); + +uint64_t __perf_reg_mask_riscv (bool intr);const char *__perf_reg_name_riscv (int id);uint64_t __perf_reg_ip_riscv (void );uint64_t __perf_reg_sp_riscv (void ); + +uint64_t __perf_reg_mask_s390 (bool intr);const char *__perf_reg_name_s390 (int id);uint64_t __perf_reg_ip_s390 (void );uint64_t __perf_reg_sp_s390 (void ); + +uint64_t __perf_reg_mask_x86 (bool intr);const char *__perf_reg_name_x86 (int id);uint64_t __perf_reg_ip_x86 (void );uint64_t __perf_reg_sp_x86 (void ); --2.34.1
PATCH v3 4/4 perf regs: Remove __weak attributive arch_sdt_arg_parse_op() function
In reply to Dapeng MiIn line with the previous patch, the __weak arch_sdt_arg_parse_op() function is removed. Architectural-specific implementations in the arch/ directory are now converted into sub-functions within the util/perf-regs-arch/ directory. The perf_sdt_arg_parse_op() function will call these sub-functions based on the EM_HOST.
This change enables cross-architecture calls to arch_sdt_arg_parse_op().
No functional changes are intended.
--- tools/perf/arch/arm64/util/Build | 1 - tools/perf/arch/arm64/util/perf_regs.c | 105 -------- tools/perf/arch/powerpc/util/Build | 1 - tools/perf/arch/powerpc/util/perf_regs.c | 125 ---------- tools/perf/arch/x86/util/Build | 1 - tools/perf/arch/x86/util/perf_regs.c | 235 ------------------ .../util/perf-regs-arch/perf_regs_aarch64.c | 86 +++++++ .../util/perf-regs-arch/perf_regs_powerpc.c | 106 ++++++++ .../perf/util/perf-regs-arch/perf_regs_x86.c | 221 ++++++++++++++++ tools/perf/util/perf_regs.c | 25 +- tools/perf/util/perf_regs.h | 5 +- tools/perf/util/probe-file.c | 3 +- 12 files changed, 441 insertions(+), 473 deletions(-) delete mode 100644 tools/perf/arch/arm64/util/perf_regs.c delete mode 100644 tools/perf/arch/powerpc/util/perf_regs.c delete mode 100644 tools/perf/arch/x86/util/perf_regs.c
tools/perf/arch/arm64/util/Build +0 -1
@@ -8,6 +8,5 @@ perf-util-y += header.o perf-util-y += hisi-ptt.o perf-util-y += machine.o perf-util-y += mem-events.o -perf-util-y += perf_regs.o perf-util-y += pmu.o perf-util-y += tsc.o
tools/perf/arch/arm64/util/perf_regs.c deleted +0 -105
105 lines not on this page · raw message
tools/perf/arch/powerpc/util/Build +0 -1
@@ -1,6 +1,5 @@ perf-util-y += header.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o perf-util-y += mem-events.o perf-util-y += pmu.o perf-util-y += sym-handling.o
tools/perf/arch/powerpc/util/perf_regs.c deleted +0 -125
125 lines not on this page · raw message
tools/perf/arch/x86/util/Build +0 -1
@@ -2,7 +2,6 @@ perf-util-y += header.o perf-util-y += tsc.o perf-util-y += pmu.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o perf-util-y += topdown.o perf-util-y += machine.o perf-util-y += event.o
tools/perf/arch/x86/util/perf_regs.c deleted +0 -235
235 lines not on this page · raw message
tools/perf/util/perf-regs-arch/perf_regs_aarch64.c +86 -0
92 lines not on this page · raw message
tools/perf/util/perf-regs-arch/perf_regs_powerpc.c +106 -0
112 lines not on this page · raw message
tools/perf/util/perf-regs-arch/perf_regs_x86.c +221 -0
227 lines not on this page · raw message
tools/perf/util/perf_regs.c +22 -3
@@ -7,10 +7,29 @@#include "util/sample.h" #include "debug.h" -int __weak arch_sdt_arg_parse_op (char *old_op__maybe_unused , -char **new_op__maybe_unused ) +int perf_sdt_arg_parse_op (uint16_t e_machine,char *old_op,char **new_op) { -return SDT_ARG_SKIP ; +int ret =SDT_ARG_SKIP ; + +switch (e_machine) { +case EM_AARCH64 : + ret =__perf_sdt_arg_parse_op_arm64 (old_op, new_op); +break ; +case EM_PPC : +case EM_PPC64 : + ret =__perf_sdt_arg_parse_op_powerpc (old_op, new_op); +break ; +case EM_386 : +case EM_X86_64 : + ret =__perf_sdt_arg_parse_op_x86 (old_op, new_op); +break ; +default : +pr_debug ("Unknown ELF machine %d, standard arguments parse will be skipped.\n" , + e_machine); +break ; + } + +return ret; }uint64_t perf_intr_reg_mask (uint16_t e_machine)
tools/perf/util/perf_regs.h +4 -1
@@ -12,7 +12,7 @@ enum { SDT_ARG_SKIP, }; -int arch_sdt_arg_parse_op (char *old_op,char **new_op); +int perf_sdt_arg_parse_op (uint16_t e_machine,char *old_op,char **new_op);uint64_t perf_intr_reg_mask (uint16_t e_machine);uint64_t perf_user_reg_mask (uint16_t e_machine);
@@ -21,6 +21,7 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id);uint64_t perf_arch_reg_ip (uint16_t e_machine);uint64_t perf_arch_reg_sp (uint16_t e_machine); +int __perf_sdt_arg_parse_op_arm64 (char *old_op,char **new_op);uint64_t __perf_reg_mask_arm64 (bool intr);const char *__perf_reg_name_arm64 (int id);uint64_t __perf_reg_ip_arm64 (void );
@@ -46,6 +47,7 @@ const char *__perf_reg_name_mips(int id);uint64_t __perf_reg_ip_mips (void );uint64_t __perf_reg_sp_mips (void ); +int __perf_sdt_arg_parse_op_powerpc (char *old_op,char **new_op);uint64_t __perf_reg_mask_powerpc (bool intr);const char *__perf_reg_name_powerpc (int id);uint64_t __perf_reg_ip_powerpc (void );
@@ -61,6 +63,7 @@ const char *__perf_reg_name_s390(int id);uint64_t __perf_reg_ip_s390 (void );uint64_t __perf_reg_sp_s390 (void ); +int __perf_sdt_arg_parse_op_x86 (char *old_op,char **new_op);uint64_t __perf_reg_mask_x86 (bool intr);const char *__perf_reg_name_x86 (int id);uint64_t __perf_reg_ip_x86 (void );
tools/perf/util/probe-file.c +2 -1
@@ -28,6 +28,7 @@#include "session.h" #include "perf_regs.h" #include "string2.h" +#include "dwarf-regs.h" /* 4096 - 2 ('\n' + '\0') */ #define MAX_CMDLEN 4094
@@ -784,7 +785,7 @@ static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) op = desc; } - ret =arch_sdt_arg_parse_op (op, &new_op); + ret =perf_sdt_arg_parse_op (EM_HOST , op, &new_op);if (ret <0 ) goto error;
Signature · 1 line
2.34.1
Re: [Patch v3 4/4] perf regs: Remove __weak attributive arch_sdt_arg_parse_op() function
Quoted 7 lines · Dapeng Mi
In line with the previous patch, the
__weakarch_sdt_arg_parse_op()function is removed. Architectural-specific implementations in thearch/directory are now converted into sub-functions within the util/perf-regs-arch/ directory. Theperf_sdt_arg_parse_op()function will call these sub-functions based on theEM_HOST.
Quoted 6 lines
This change enables cross-architecture calls to
arch_sdt_arg_parse_op().No functional changes are intended.
Suggested-by Ian Rogers <[email protected]>Signed-off-by Dapeng Mi <[email protected]>
Thanks,
Ian
Quoted 1,079 lines
--- tools/perf/arch/arm64/util/Build | 1 - tools/perf/arch/arm64/util/perf_regs.c | 105 -------- tools/perf/arch/powerpc/util/Build | 1 - tools/perf/arch/powerpc/util/perf_regs.c | 125 ---------- tools/perf/arch/x86/util/Build | 1 - tools/perf/arch/x86/util/perf_regs.c | 235 ------------------ .../util/perf-regs-arch/perf_regs_aarch64.c | 86 +++++++ .../util/perf-regs-arch/perf_regs_powerpc.c | 106 ++++++++ .../perf/util/perf-regs-arch/perf_regs_x86.c | 221 ++++++++++++++++ tools/perf/util/perf_regs.c | 25 +- tools/perf/util/perf_regs.h | 5 +- tools/perf/util/probe-file.c | 3 +- 12 files changed, 441 insertions(+), 473 deletions(-) delete mode 100644 tools/perf/arch/arm64/util/perf_regs.c delete mode 100644 tools/perf/arch/powerpc/util/perf_regs.c delete mode 100644 tools/perf/arch/x86/util/perf_regs.ctools/perf/arch/arm64/util/Build +0
-1@@ -8,6 +8,5 @@ perf-util-y += header.o perf-util-y += hisi-ptt.o perf-util-y += machine.o perf-util-y += mem-events.o -perf-util-y += perf_regs.o perf-util-y += pmu.o perf-util-y += tsc.otools/perf/arch/arm64/util/perf_regs.c deleted +0
-105@@ -1,105 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <errno.h> -#include <regex.h> -#include <string.h> -#include <sys/auxv.h> -#include <linux/kernel.h> -#include <linux/zalloc.h> - -#include "perf_regs.h" -#include "../../../perf-sys.h" -#include "../../../util/debug.h" -#include "../../../util/event.h" -#include "../../../util/perf_regs.h" - -#define SMPL_REG_MASK (b) (1ULL << (b)) - -#ifndef HWCAP_SVE -#define HWCAP_SVE (1 << 22) -#endif - -/* %xNUM */ -#define SDT_OP_REGEX1 "^(x[1-2]?[0-9]|3[0-1])$" - -/* [sp], [sp, NUM] */ -#define SDT_OP_REGEX2 "^\\[sp(, )?([0-9]+)?\\]$" - -static regex_t sdt_op_regex1, sdt_op_regex2; - -static int sdt_init_op_regex (void ) -{ -static int initialized; -int ret =0 ; - -if (initialized) -return 0 ; - - ret =regcomp (&sdt_op_regex1,SDT_OP_REGEX1 ,REG_EXTENDED ); -if (ret) - goto error; - - ret =regcomp (&sdt_op_regex2,SDT_OP_REGEX2 ,REG_EXTENDED ); -if (ret) - goto free_regex1; - - initialized =1 ; -return 0 ; - -free_regex1: -regfree (&sdt_op_regex1); -error: -pr_debug4 ("Regex compilation error.\n" ); -return ret; -} - -/* -* SDT marker arguments on Arm64 uses %xREG or [sp, NUM], currently -* support these two formats. -*/ -int arch_sdt_arg_parse_op (char *old_op,char **new_op) -{ -int ret, new_len; -regmatch_t rm[5 ]; - - ret =sdt_init_op_regex (); -if (ret <0 ) -return ret; - -if (!regexec (&sdt_op_regex1, old_op,3 , rm,0 )) { -/* Extract xNUM */ - new_len =2 ;/* % NULL */ - new_len += (int )(rm[1 ].rm_eo - rm[1 ].rm_so); - - *new_op =zalloc (new_len); -if (!*new_op) -return -ENOMEM ; - -scnprintf (*new_op, new_len,"%%%.*s" , - (int )(rm[1 ].rm_eo - rm[1 ].rm_so), old_op + rm[1 ].rm_so); - }else if (!regexec (&sdt_op_regex2, old_op,5 , rm,0 )) { -/* [sp], [sp, NUM] or [sp,NUM] */ - new_len =7 ;/* + ( % s p ) NULL */ - -/* If the argument is [sp], need to fill offset '0' */ -if (rm[2 ].rm_so ==-1 ) - new_len +=1 ; -else - new_len += (int )(rm[2 ].rm_eo - rm[2 ].rm_so); - - *new_op =zalloc (new_len); -if (!*new_op) -return -ENOMEM ; - -if (rm[2 ].rm_so ==-1 ) -scnprintf (*new_op, new_len,"+0(%%sp)" ); -else -scnprintf (*new_op, new_len,"+%.*s(%%sp)" , - (int )(rm[2 ].rm_eo - rm[2 ].rm_so), - old_op + rm[2 ].rm_so); - }else { -pr_debug4 ("Skipping unsupported SDT argument: %s\n" , old_op); -return SDT_ARG_SKIP ; - } - -return SDT_ARG_VALID ; -}tools/perf/arch/powerpc/util/Build +0
-1@@ -1,6 +1,5 @@ perf-util-y += header.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o perf-util-y += mem-events.o perf-util-y += pmu.o perf-util-y += sym-handling.otools/perf/arch/powerpc/util/perf_regs.c deleted +0
-125@@ -1,125 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <errno.h> -#include <string.h> -#include <regex.h> -#include <linux/zalloc.h> - -#include "perf_regs.h" -#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 -#define PVR_POWER10 0x0080 -#define PVR_POWER11 0x0082 - -/* REG or %rREG */ -#define SDT_OP_REGEX1 "^(%r)?([1-2]?[0-9]|3[0-1])$" - -/* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) */ -#define SDT_OP_REGEX2 "^(\\-)?([0-9]+)\\((%r)?([1-2]?[0-9]|3[0-1])\\)$" - -static regex_t sdt_op_regex1, sdt_op_regex2; - -static int sdt_init_op_regex (void ) -{ -static int initialized; -int ret =0 ; - -if (initialized) -return 0 ; - - ret =regcomp (&sdt_op_regex1,SDT_OP_REGEX1 ,REG_EXTENDED ); -if (ret) - goto error; - - ret =regcomp (&sdt_op_regex2,SDT_OP_REGEX2 ,REG_EXTENDED ); -if (ret) - goto free_regex1; - - initialized =1 ; -return 0 ; - -free_regex1: -regfree (&sdt_op_regex1); -error: -pr_debug4 ("Regex compilation error.\n" ); -return ret; -} - -/* -* Parse OP and convert it into uprobe format, which is, +/-NUM(%gprREG). -* Possible variants of OP are: -* Format Example -* ------------------------- -* NUM(REG) 48(18) -* -NUM(REG) -48(18) -* NUM(%rREG) 48(%r18) -* -NUM(%rREG) -48(%r18) -* REG 18 -* %rREG %r18 -* iNUM i0 -* i-NUM i-1 -* -* SDT marker arguments on Powerpc uses %rREG form with -mregnames flag -* and REG form with -mno-regnames. Here REG is general purpose register, -* which is in 0 to 31 range. -*/ -int arch_sdt_arg_parse_op (char *old_op,char **new_op) -{ -int ret, new_len; -regmatch_t rm[5 ]; -char prefix; - -/* Constant argument. Uprobe does not support it */ -if (old_op[0 ] =='i' ) { -pr_debug4 ("Skipping unsupported SDT argument: %s\n" , old_op); -return SDT_ARG_SKIP ; - } - - ret =sdt_init_op_regex (); -if (ret <0 ) -return ret; - -if (!regexec (&sdt_op_regex1, old_op,3 , rm,0 )) { -/* REG or %rREG --> %gprREG */ - - new_len =5 ;/* % g p r NULL */ - new_len += (int )(rm[2 ].rm_eo - rm[2 ].rm_so); - - *new_op =zalloc (new_len); -if (!*new_op) -return -ENOMEM ; - -scnprintf (*new_op, new_len,"%%gpr%.*s" , - (int )(rm[2 ].rm_eo - rm[2 ].rm_so), old_op + rm[2 ].rm_so); - }else if (!regexec (&sdt_op_regex2, old_op,5 , rm,0 )) { -/* -* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) --> -* +/-NUM(%gprREG) -*/ - prefix = (rm[1 ].rm_so ==-1 ) ?'+' :'-' ; - - new_len =8 ;/* +/- ( % g p r ) NULL */ - new_len += (int )(rm[2 ].rm_eo - rm[2 ].rm_so); - new_len += (int )(rm[4 ].rm_eo - rm[4 ].rm_so); - - *new_op =zalloc (new_len); -if (!*new_op) -return -ENOMEM ; - -scnprintf (*new_op, new_len,"%c%.*s(%%gpr%.*s)" , prefix, - (int )(rm[2 ].rm_eo - rm[2 ].rm_so), old_op + rm[2 ].rm_so, - (int )(rm[4 ].rm_eo - rm[4 ].rm_so), old_op + rm[4 ].rm_so); - }else { -pr_debug4 ("Skipping unsupported SDT argument: %s\n" , old_op); -return SDT_ARG_SKIP ; - } - -return SDT_ARG_VALID ; -}tools/perf/arch/x86/util/Build +0
-1@@ -2,7 +2,6 @@ perf-util-y += header.o perf-util-y += tsc.o perf-util-y += pmu.o perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o perf-util-y += topdown.o perf-util-y += machine.o perf-util-y += event.otools/perf/arch/x86/util/perf_regs.c deleted +0
-235@@ -1,235 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <errno.h> -#include <string.h> -#include <regex.h> -#include <linux/kernel.h> -#include <linux/zalloc.h> - -#include "perf_regs.h" -#include "../../../perf-sys.h" -#include "../../../util/perf_regs.h" -#include "../../../util/debug.h" -#include "../../../util/event.h" -#include "../../../util/pmu.h" -#include "../../../util/pmus.h" - -struct sdt_name_reg { -const char *sdt_name; -const char *uprobe_name; -}; -#define SDT_NAME_REG (n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} -#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} - -static const struct sdt_name_reg sdt_reg_tbl[] = { -SDT_NAME_REG (eax, ax), -SDT_NAME_REG (rax, ax), -SDT_NAME_REG (al, ax), -SDT_NAME_REG (ah, ax), -SDT_NAME_REG (ebx, bx), -SDT_NAME_REG (rbx, bx), -SDT_NAME_REG (bl, bx), -SDT_NAME_REG (bh, bx), -SDT_NAME_REG (ecx, cx), -SDT_NAME_REG (rcx, cx), -SDT_NAME_REG (cl, cx), -SDT_NAME_REG (ch, cx), -SDT_NAME_REG (edx, dx), -SDT_NAME_REG (rdx, dx), -SDT_NAME_REG (dl, dx), -SDT_NAME_REG (dh, dx), -SDT_NAME_REG (esi, si), -SDT_NAME_REG (rsi, si), -SDT_NAME_REG (sil, si), -SDT_NAME_REG (edi, di), -SDT_NAME_REG (rdi, di), -SDT_NAME_REG (dil, di), -SDT_NAME_REG (ebp, bp), -SDT_NAME_REG (rbp, bp), -SDT_NAME_REG (bpl, bp), -SDT_NAME_REG (rsp, sp), -SDT_NAME_REG (esp, sp), -SDT_NAME_REG (spl, sp), - -/* rNN registers */ -SDT_NAME_REG (r8b, r8), -SDT_NAME_REG (r8w, r8), -SDT_NAME_REG (r8d, r8), -SDT_NAME_REG (r9b, r9), -SDT_NAME_REG (r9w, r9), -SDT_NAME_REG (r9d, r9), -SDT_NAME_REG (r10b, r10), -SDT_NAME_REG (r10w, r10), -SDT_NAME_REG (r10d, r10), -SDT_NAME_REG (r11b, r11), -SDT_NAME_REG (r11w, r11), -SDT_NAME_REG (r11d, r11), -SDT_NAME_REG (r12b, r12), -SDT_NAME_REG (r12w, r12), -SDT_NAME_REG (r12d, r12), -SDT_NAME_REG (r13b, r13), -SDT_NAME_REG (r13w, r13), -SDT_NAME_REG (r13d, r13), -SDT_NAME_REG (r14b, r14), -SDT_NAME_REG (r14w, r14), -SDT_NAME_REG (r14d, r14), -SDT_NAME_REG (r15b, r15), -SDT_NAME_REG (r15w, r15), -SDT_NAME_REG (r15d, r15), -SDT_NAME_REG_END , -}; - -/* -* Perf only supports OP which is in +/-NUM(REG) form. -* Here plus-minus sign, NUM and parenthesis are optional, -* only REG is mandatory. -* -* SDT events also supports indirect addressing mode with a -* symbol as offset, scaled mode and constants in OP. But -* perf does not support them yet. Below are few examples. -* -* OP with scaled mode: -* (%rax,%rsi,8) -* 10(%ras,%rsi,8) -* -* OP with indirect addressing mode: -* check_action(%rip) -* mp_+52(%rip) -* 44+mp_(%rip) -* -* OP with constant values: -* $0 -* $123 -* $-1 -*/ -#define SDT_OP_REGEX "^([+\\-]?)([0-9]*)(\\(?)(%[a-z][a-z0-9]+)(\\)?)$" - -static regex_t sdt_op_regex; - -static int sdt_init_op_regex (void ) -{ -static int initialized; -int ret =0 ; - -if (initialized) -return 0 ; - - ret =regcomp (&sdt_op_regex,SDT_OP_REGEX ,REG_EXTENDED ); -if (ret <0 ) { -pr_debug4 ("Regex compilation error.\n" ); -return ret; - } - - initialized =1 ; -return 0 ; -} - -/* -* Max x86 register name length is 5(ex: %r15d). So, 6th char -* should always contain NULL. This helps to find register name -* length using strlen, instead of maintaining one more variable. -*/ -#define SDT_REG_NAME_SIZE 6 - -/* -* The uprobe parser does not support all gas register names; -* so, we have to replace them (ex. for x86_64: %rax -> %ax). -* Note: If register does not require renaming, just copy -* paste as it is, but don't leave it empty. -*/ -static void sdt_rename_register (char *sdt_reg,int sdt_len,char *uprobe_reg) -{ -int i =0 ; - -for (i =0 ; sdt_reg_tbl[i].sdt_name !=NULL ; i++) { -if (!strncmp (sdt_reg_tbl[i].sdt_name, sdt_reg, sdt_len)) { -strcpy (uprobe_reg, sdt_reg_tbl[i].uprobe_name); -return ; - } - } - -strncpy (uprobe_reg, sdt_reg, sdt_len); -} - -int arch_sdt_arg_parse_op (char *old_op,char **new_op) -{ -char new_reg[SDT_REG_NAME_SIZE ] = {0 }; -int new_len =0 , ret; -/* -* rm[0]: +/-NUM(REG) -* rm[1]: +/- -* rm[2]: NUM -* rm[3]: ( -* rm[4]: REG -* rm[5]: ) -*/ -regmatch_t rm[6 ]; -/* -* Max prefix length is 2 as it may contains sign(+/-) -* and displacement 0 (Both sign and displacement 0 are -* optional so it may be empty). Use one more character -* to hold last NULL so that strlen can be used to find -* prefix length, instead of maintaining one more variable. -*/ -char prefix[3 ] = {0 }; - - ret =sdt_init_op_regex (); -if (ret <0 ) -return ret; - -/* -* If unsupported OR does not match with regex OR -* register name too long, skip it. -*/ -if (strchr (old_op,',' ) ||strchr (old_op,'$' ) || -regexec (&sdt_op_regex, old_op,6 , rm,0 ) || - rm[4 ].rm_eo - rm[4 ].rm_so >SDT_REG_NAME_SIZE ) { -pr_debug4 ("Skipping unsupported SDT argument: %s\n" , old_op); -return SDT_ARG_SKIP ; - } - -/* -* Prepare prefix. -* If SDT OP has parenthesis but does not provide -* displacement, add 0 for displacement. -* SDT Uprobe Prefix -* ----------------------------- -* +24(%rdi) +24(%di) + -* 24(%rdi) +24(%di) + -* %rdi %di -* (%rdi) +0(%di) +0 -* -80(%rbx) -80(%bx) - -*/ -if (rm[3 ].rm_so != rm[3 ].rm_eo) { -if (rm[1 ].rm_so != rm[1 ].rm_eo) - prefix[0 ] = *(old_op + rm[1 ].rm_so); -else if (rm[2 ].rm_so != rm[2 ].rm_eo) - prefix[0 ] ='+' ; -else -scnprintf (prefix,sizeof (prefix),"+0" ); - } - -/* Rename register */ -sdt_rename_register (old_op + rm[4 ].rm_so, rm[4 ].rm_eo - rm[4 ].rm_so, - new_reg); - -/* Prepare final OP which should be valid for uprobe_events */ - new_len =strlen (prefix) + - (rm[2 ].rm_eo - rm[2 ].rm_so) + - (rm[3 ].rm_eo - rm[3 ].rm_so) + -strlen (new_reg) + - (rm[5 ].rm_eo - rm[5 ].rm_so) + -1 ;/* NULL */ - - *new_op =zalloc (new_len); -if (!*new_op) -return -ENOMEM ; - -scnprintf (*new_op, new_len,"%.*s%.*s%.*s%.*s%.*s" , -strlen (prefix), prefix, - (int )(rm[2 ].rm_eo - rm[2 ].rm_so), old_op + rm[2 ].rm_so, - (int )(rm[3 ].rm_eo - rm[3 ].rm_so), old_op + rm[3 ].rm_so, -strlen (new_reg), new_reg, - (int )(rm[5 ].rm_eo - rm[5 ].rm_so), old_op + rm[5 ].rm_so); - -return SDT_ARG_VALID ; -}tools/perf/util/perf-regs-arch/perf_regs_aarch64.c +86
-0@@ -18,6 +18,92 @@#define HWCAP_SVE (1 << 22)#endif +/* %xNUM */ +#define SDT_OP_REGEX1 "^(x[1-2]?[0-9]|3[0-1])$" + +/* [sp], [sp, NUM] */ +#define SDT_OP_REGEX2 "^\\[sp(, )?([0-9]+)?\\]$" + +static regex_t sdt_op_regex1, sdt_op_regex2; + +static int sdt_init_op_regex (void ) +{ +static int initialized; +int ret =0 ; + +if (initialized) +return 0 ; + + ret =regcomp (&sdt_op_regex1,SDT_OP_REGEX1 ,REG_EXTENDED ); +if (ret) + goto error; + + ret =regcomp (&sdt_op_regex2,SDT_OP_REGEX2 ,REG_EXTENDED ); +if (ret) + goto free_regex1; + + initialized =1 ; +return 0 ; + +free_regex1: +regfree (&sdt_op_regex1); +error: +pr_debug4 ("Regex compilation error.\n" ); +return ret; +} + +/* +* SDT marker arguments on Arm64 uses %xREG or [sp, NUM], currently +* support these two formats. +*/ +int __perf_sdt_arg_parse_op_arm64 (char *old_op,char **new_op) +{ +int ret, new_len; +regmatch_t rm[5 ]; + + ret =sdt_init_op_regex (); +if (ret <0 ) +return ret; + +if (!regexec (&sdt_op_regex1, old_op,3 , rm,0 )) { +/* Extract xNUM */ + new_len =2 ;/* % NULL */ + new_len += (int )(rm[1 ].rm_eo - rm[1 ].rm_so); + + *new_op =zalloc (new_len); +if (!*new_op) +return -ENOMEM ; + +scnprintf (*new_op, new_len,"%%%.*s" , + (int )(rm[1 ].rm_eo - rm[1 ].rm_so), old_op + rm[1 ].rm_so); + }else if (!regexec (&sdt_op_regex2, old_op,5 , rm,0 )) { +/* [sp], [sp, NUM] or [sp,NUM] */ + new_len =7 ;/* + ( % s p ) NULL */ + +/* If the argument is [sp], need to fill offset '0' */ +if (rm[2 ].rm_so ==-1 ) + new_len +=1 ; +else + new_len += (int )(rm[2 ].rm_eo - rm[2 ].rm_so); + + *new_op =zalloc (new_len); +if (!*new_op) +return -ENOMEM ; + +if (rm[2 ].rm_so ==-1 ) +scnprintf (*new_op, new_len,"+0(%%sp)" ); +else +scnprintf (*new_op, new_len,"+%.*s(%%sp)" , + (int )(rm[2 ].rm_eo - rm[2 ].rm_so), + old_op + rm[2 ].rm_so); + }else { +pr_debug4 ("Skipping unsupported SDT argument: %s\n" , old_op); +return SDT_ARG_SKIP ; + } + +return SDT_ARG_VALID ; +} +uint64_t __perf_reg_mask_arm64 (bool intr) {struct perf_event_attr attr = {tools/perf/util/perf-regs-arch/perf_regs_powerpc.c +106
-0@@ -19,6 +19,112 @@#define PVR_POWER10 0x0080#define PVR_POWER11 0x0082 +/* REG or %rREG */ +#define SDT_OP_REGEX1 "^(%r)?([1-2]?[0-9]|3[0-1])$" + +/* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) */ +#define SDT_OP_REGEX2 "^(\\-)?([0-9]+)\\((%r)?([1-2]?[0-9]|3[0-1])\\)$" + +static regex_t sdt_op_regex1, sdt_op_regex2; + +static int sdt_init_op_regex (void ) +{ +static int initialized; +int ret =0 ; + +if (initialized) +return 0 ; + + ret =regcomp (&sdt_op_regex1,SDT_OP_REGEX1 ,REG_EXTENDED ); +if (ret) + goto error; + + ret =regcomp (&sdt_op_regex2,SDT_OP_REGEX2 ,REG_EXTENDED ); +if (ret) + goto free_regex1; + + initialized =1 ; +return 0 ; + +free_regex1: +regfree (&sdt_op_regex1); +error: +pr_debug4 ("Regex compilation error.\n" ); +return ret; +} + +/* +* Parse OP and convert it into uprobe format, which is, +/-NUM(%gprREG). +* Possible variants of OP are: +* Format Example +* ------------------------- +* NUM(REG) 48(18) +* -NUM(REG) -48(18) +* NUM(%rREG) 48(%r18) +* -NUM(%rREG) -48(%r18) +* REG 18 +* %rREG %r18 +* iNUM i0 +* i-NUM i-1 +* +* SDT marker arguments on Powerpc uses %rREG form with -mregnames flag +* and REG form with -mno-regnames. Here REG is general purpose register, +* which is in 0 to 31 range. +*/ +int __perf_sdt_arg_parse_op_powerpc (char *old_op,char **new_op) +{ +int ret, new_len; +regmatch_t rm[5 ]; +char prefix; + +/* Constant argument. Uprobe does not support it */ +if (old_op[0 ] =='i' ) { +pr_debug4 ("Skipping unsupported SDT argument: %s\n" , old_op); +return SDT_ARG_SKIP ; + } + + ret =sdt_init_op_regex (); +if (ret <0 ) +return ret; + +if (!regexec (&sdt_op_regex1, old_op,3 , rm,0 )) { +/* REG or %rREG --> %gprREG */ + + new_len =5 ;/* % g p r NULL */ + new_len += (int )(rm[2 ].rm_eo - rm[2 ].rm_so); + + *new_op =zalloc (new_len); +if (!*new_op) +return -ENOMEM ; + +scnprintf (*new_op, new_len,"%%gpr%.*s" , + (int )(rm[2 ].rm_eo - rm[2 ].rm_so), old_op + rm[2 ].rm_so); + }else if (!regexec (&sdt_op_regex2, old_op,5 , rm,0 )) { +/* +* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) --> +* +/-NUM(%gprREG) +*/ + prefix = (rm[1 ].rm_so ==-1 ) ?'+' :'-' ; + + new_len =8 ;/* +/- ( % g p r ) NULL */ + new_len += (int )(rm[2 ].rm_eo - rm[2 ].rm_so); + new_len += (int )(rm[4 ].rm_eo - rm[4 ].rm_so); + + *new_op =zalloc (new_len); +if (!*new_op) +return -ENOMEM ; + +scnprintf (*new_op, new_len,"%c%.*s(%%gpr%.*s)" , prefix, + (int )(rm[2 ].rm_eo - rm[2 ].rm_so), old_op + rm[2 ].rm_so, + (int )(rm[4 ].rm_eo - rm[4 ].rm_so), old_op + rm[4 ].rm_so); + }else { +pr_debug4 ("Skipping unsupported SDT argument: %s\n" , old_op); +return SDT_ARG_SKIP ; + } + +return SDT_ARG_VALID ; +} +/* * mfspr is a POWERPC specific instruction, ensure it's only * built and called on POWERPC by guarding with __powerpc64__ tools/perf/util/perf-regs-arch/perf_regs_x86.c +221
-0@@ -14,6 +14,227 @@#include "../../perf-sys.h" #include "../../arch/x86/include/perf_regs.h" +struct sdt_name_reg { +const char *sdt_name; +const char *uprobe_name; +}; +#define SDT_NAME_REG (n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} + +static const struct sdt_name_reg sdt_reg_tbl[] = { +SDT_NAME_REG (eax, ax), +SDT_NAME_REG (rax, ax), +SDT_NAME_REG (al, ax), +SDT_NAME_REG (ah, ax), +SDT_NAME_REG (ebx, bx), +SDT_NAME_REG (rbx, bx), +SDT_NAME_REG (bl, bx), +SDT_NAME_REG (bh, bx), +SDT_NAME_REG (ecx, cx), +SDT_NAME_REG (rcx, cx), +SDT_NAME_REG (cl, cx), +SDT_NAME_REG (ch, cx), +SDT_NAME_REG (edx, dx), +SDT_NAME_REG (rdx, dx), +SDT_NAME_REG (dl, dx), +SDT_NAME_REG (dh, dx), +SDT_NAME_REG (esi, si), +SDT_NAME_REG (rsi, si), +SDT_NAME_REG (sil, si), +SDT_NAME_REG (edi, di), +SDT_NAME_REG (rdi, di), +SDT_NAME_REG (dil, di), +SDT_NAME_REG (ebp, bp), +SDT_NAME_REG (rbp, bp), +SDT_NAME_REG (bpl, bp), +SDT_NAME_REG (rsp, sp), +SDT_NAME_REG (esp, sp), +SDT_NAME_REG (spl, sp), + +/* rNN registers */ +SDT_NAME_REG (r8b, r8), +SDT_NAME_REG (r8w, r8), +SDT_NAME_REG (r8d, r8), +SDT_NAME_REG (r9b, r9), +SDT_NAME_REG (r9w, r9), +SDT_NAME_REG (r9d, r9), +SDT_NAME_REG (r10b, r10), +SDT_NAME_REG (r10w, r10), +SDT_NAME_REG (r10d, r10), +SDT_NAME_REG (r11b, r11), +SDT_NAME_REG (r11w, r11), +SDT_NAME_REG (r11d, r11), +SDT_NAME_REG (r12b, r12), +SDT_NAME_REG (r12w, r12), +SDT_NAME_REG (r12d, r12), +SDT_NAME_REG (r13b, r13), +SDT_NAME_REG (r13w, r13), +SDT_NAME_REG (r13d, r13), +SDT_NAME_REG (r14b, r14), +SDT_NAME_REG (r14w, r14), +SDT_NAME_REG (r14d, r14), +SDT_NAME_REG (r15b, r15), +SDT_NAME_REG (r15w, r15), +SDT_NAME_REG (r15d, r15), +SDT_NAME_REG_END , +}; + +/* +* Perf only supports OP which is in +/-NUM(REG) form. +* Here plus-minus sign, NUM and parenthesis are optional, +* only REG is mandatory. +* +* SDT events also supports indirect addressing mode with a +* symbol as offset, scaled mode and constants in OP. But +* perf does not support them yet. Below are few examples. +* +* OP with scaled mode: +* (%rax,%rsi,8) +* 10(%ras,%rsi,8) +* +* OP with indirect addressing mode: +* check_action(%rip) +* mp_+52(%rip) +* 44+mp_(%rip) +* +* OP with constant values: +* $0 +* $123 +* $-1 +*/ +#define SDT_OP_REGEX "^([+\\-]?)([0-9]*)(\\(?)(%[a-z][a-z0-9]+)(\\)?)$" + +static regex_t sdt_op_regex; + +static int sdt_init_op_regex (void ) +{ +static int initialized; +int ret =0 ; + +if (initialized) +return 0 ; + + ret =regcomp (&sdt_op_regex,SDT_OP_REGEX ,REG_EXTENDED ); +if (ret <0 ) { +pr_debug4 ("Regex compilation error.\n" ); +return ret; + } + + initialized =1 ; +return 0 ; +} + +/* +* Max x86 register name length is 5(ex: %r15d). So, 6th char +* should always contain NULL. This helps to find register name +* length using strlen, instead of maintaining one more variable. +*/ +#define SDT_REG_NAME_SIZE 6 + +/* +* The uprobe parser does not support all gas register names; +* so, we have to replace them (ex. for x86_64: %rax -> %ax). +* Note: If register does not require renaming, just copy +* paste as it is, but don't leave it empty. +*/ +static void sdt_rename_register (char *sdt_reg,int sdt_len,char *uprobe_reg) +{ +int i =0 ; + +for (i =0 ; sdt_reg_tbl[i].sdt_name !=NULL ; i++) { +if (!strncmp (sdt_reg_tbl[i].sdt_name, sdt_reg, sdt_len)) { +strcpy (uprobe_reg, sdt_reg_tbl[i].uprobe_name); +return ; + } + } + +strncpy (uprobe_reg, sdt_reg, sdt_len); +} + +int __perf_sdt_arg_parse_op_x86 (char *old_op,char **new_op) +{ +char new_reg[SDT_REG_NAME_SIZE ] = {0 }; +int new_len =0 , ret; +/* +* rm[0]: +/-NUM(REG) +* rm[1]: +/- +* rm[2]: NUM +* rm[3]: ( +* rm[4]: REG +* rm[5]: ) +*/ +regmatch_t rm[6 ]; +/* +* Max prefix length is 2 as it may contains sign(+/-) +* and displacement 0 (Both sign and displacement 0 are +* optional so it may be empty). Use one more character +* to hold last NULL so that strlen can be used to find +* prefix length, instead of maintaining one more variable. +*/ +char prefix[3 ] = {0 }; + + ret =sdt_init_op_regex (); +if (ret <0 ) +return ret; + +/* +* If unsupported OR does not match with regex OR +* register name too long, skip it. +*/ +if (strchr (old_op,',' ) ||strchr (old_op,'$' ) || +regexec (&sdt_op_regex, old_op,6 , rm,0 ) || + rm[4 ].rm_eo - rm[4 ].rm_so >SDT_REG_NAME_SIZE ) { +pr_debug4 ("Skipping unsupported SDT argument: %s\n" , old_op); +return SDT_ARG_SKIP ; + } + +/* +* Prepare prefix. +* If SDT OP has parenthesis but does not provide +* displacement, add 0 for displacement. +* SDT Uprobe Prefix +* ----------------------------- +* +24(%rdi) +24(%di) + +* 24(%rdi) +24(%di) + +* %rdi %di +* (%rdi) +0(%di) +0 +* -80(%rbx) -80(%bx) - +*/ +if (rm[3 ].rm_so != rm[3 ].rm_eo) { +if (rm[1 ].rm_so != rm[1 ].rm_eo) + prefix[0 ] = *(old_op + rm[1 ].rm_so); +else if (rm[2 ].rm_so != rm[2 ].rm_eo) + prefix[0 ] ='+' ; +else +scnprintf (prefix,sizeof (prefix),"+0" ); + } + +/* Rename register */ +sdt_rename_register (old_op + rm[4 ].rm_so, rm[4 ].rm_eo - rm[4 ].rm_so, + new_reg); + +/* Prepare final OP which should be valid for uprobe_events */ + new_len =strlen (prefix) + + (rm[2 ].rm_eo - rm[2 ].rm_so) + + (rm[3 ].rm_eo - rm[3 ].rm_so) + +strlen (new_reg) + + (rm[5 ].rm_eo - rm[5 ].rm_so) + +1 ;/* NULL */ + + *new_op =zalloc (new_len); +if (!*new_op) +return -ENOMEM ; + +scnprintf (*new_op, new_len,"%.*s%.*s%.*s%.*s%.*s" , +strlen (prefix), prefix, + (int )(rm[2 ].rm_eo - rm[2 ].rm_so), old_op + rm[2 ].rm_so, + (int )(rm[3 ].rm_eo - rm[3 ].rm_so), old_op + rm[3 ].rm_so, +strlen (new_reg), new_reg, + (int )(rm[5 ].rm_eo - rm[5 ].rm_so), old_op + rm[5 ].rm_so); + +return SDT_ARG_VALID ; +} +uint64_t __perf_reg_mask_x86 (bool intr) {struct perf_event_attr attr = {tools/perf/util/perf_regs.c +22
-3@@ -7,10 +7,29 @@#include "util/sample.h" #include "debug.h" -int __weak arch_sdt_arg_parse_op (char *old_op__maybe_unused , -char **new_op__maybe_unused ) +int perf_sdt_arg_parse_op (uint16_t e_machine,char *old_op,char **new_op) { -return SDT_ARG_SKIP ; +int ret =SDT_ARG_SKIP ; + +switch (e_machine) { +case EM_AARCH64 : + ret =__perf_sdt_arg_parse_op_arm64 (old_op, new_op); +break ; +case EM_PPC : +case EM_PPC64 : + ret =__perf_sdt_arg_parse_op_powerpc (old_op, new_op); +break ; +case EM_386 : +case EM_X86_64 : + ret =__perf_sdt_arg_parse_op_x86 (old_op, new_op); +break ; +default : +pr_debug ("Unknown ELF machine %d, standard arguments parse will be skipped.\n" , + e_machine); +break ; + } + +return ret; }uint64_t perf_intr_reg_mask (uint16_t e_machine)tools/perf/util/perf_regs.h +4
-1@@ -12,7 +12,7 @@ enum { SDT_ARG_SKIP, }; -int arch_sdt_arg_parse_op (char *old_op,char **new_op); +int perf_sdt_arg_parse_op (uint16_t e_machine,char *old_op,char **new_op);uint64_t perf_intr_reg_mask (uint16_t e_machine);uint64_t perf_user_reg_mask (uint16_t e_machine);@@ -21,6 +21,7 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id);uint64_t perf_arch_reg_ip (uint16_t e_machine);uint64_t perf_arch_reg_sp (uint16_t e_machine); +int __perf_sdt_arg_parse_op_arm64 (char *old_op,char **new_op);uint64_t __perf_reg_mask_arm64 (bool intr);const char *__perf_reg_name_arm64 (int id);uint64_t __perf_reg_ip_arm64 (void );@@ -46,6 +47,7 @@ const char *__perf_reg_name_mips(int id);uint64_t __perf_reg_ip_mips (void );uint64_t __perf_reg_sp_mips (void ); +int __perf_sdt_arg_parse_op_powerpc (char *old_op,char **new_op);uint64_t __perf_reg_mask_powerpc (bool intr);const char *__perf_reg_name_powerpc (int id);uint64_t __perf_reg_ip_powerpc (void );@@ -61,6 +63,7 @@ const char *__perf_reg_name_s390(int id);uint64_t __perf_reg_ip_s390 (void );uint64_t __perf_reg_sp_s390 (void ); +int __perf_sdt_arg_parse_op_x86 (char *old_op,char **new_op);uint64_t __perf_reg_mask_x86 (bool intr);const char *__perf_reg_name_x86 (int id);uint64_t __perf_reg_ip_x86 (void );tools/perf/util/probe-file.c +2
-2@@ -28,6 +28,7 @@#include "session.h" #include "perf_regs.h" #include "string2.h" +#include "dwarf-regs.h" /* 4096 - 2 ('\n' + '\0') */ #define MAX_CMDLEN 4094@@ -784,7 +785,7 @@ static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) op = desc; } - ret =arch_sdt_arg_parse_op (op, &new_op); + ret =perf_sdt_arg_parse_op (EM_HOST , op, &new_op);if (ret <0 ) goto error; --2.34.1
Quoted 4 lines · Dapeng Mi
Changes:
v2 -> v3:
* Fix the abort issue for "-I" or "--user-regs" options. (Patch 1/4)
* Address Ian's comments.
Fixed up somme fuzz with powerpc, x86, riscv and s390 Build files wrt removing perf_regs.o
Thanks, applied to perf-tools-next,
- Arnaldo
Quoted 100 lines
v1 -> v2:
* Fixing "PERF_REG_EXTENDED_MASK" redefinition building error by changing the "asm/perf_regs.h" header path to relative UAPI path. (Patch 1/3)
* Splitingxxx_reg_mask()andxxx_sdt_arg_parse_op()conversion into 2 patches.This patch-set remove the below three architecture specific
__weakfunctions and converted them into the general architecture specific functions which are dispatched base on "em_machine".
uint64_tarch__intr_reg_mask(void);uint64_tarch__user_reg_mask(void);
intarch_sdt_arg_parse_op(char *old_op, char **new_op);The advantage of this conversion is that these architectural functions can be called even for a different architecture with host instead of only called on the host architecture.
Although the converted functions shown below can be called on any architecture, currently they are still only called for the host architecture (
EM_HOST).int
perf_sdt_arg_parse_op(uint16_t e_machine, char *old_op, char **new_op);uint64_tperf_intr_reg_mask(uint16_t e_machine);uint64_tperf_user_reg_mask(uint16_t e_machine);Tests:
* This patch-set is only tested on x86 platforms. No issues are found for both intr-regs and user-regs options.
* Tests on other architectures are welcomed and appreciated.History:
v1: https://lore.kernel.org/all/[email protected]/
v2: https://lore.kernel.org/all/[email protected]/Dapeng Mi (4):
perf regs: Fix abort for "-I" or "--user-regs" options perf arch: Update arch headers to use relative UAPI paths perf regs: Remove__weakattributivearch__xxx_reg_mask()functions perf regs: Remove__weakattributivearch_sdt_arg_parse_op()functiontools/perf/arch/arm/include/perf_regs.h | 2 +- tools/perf/arch/arm/util/Build | 2 - tools/perf/arch/arm/util/perf_regs.c | 13 - tools/perf/arch/arm64/include/perf_regs.h | 2 +- tools/perf/arch/arm64/util/Build | 1 - tools/perf/arch/arm64/util/perf_regs.c | 141 --------- tools/perf/arch/csky/Build | 1 - tools/perf/arch/csky/include/perf_regs.h | 2 +- tools/perf/arch/csky/util/Build | 1 - tools/perf/arch/csky/util/perf_regs.c | 13 - tools/perf/arch/loongarch/include/perf_regs.h | 2 +- tools/perf/arch/loongarch/util/Build | 1 - tools/perf/arch/loongarch/util/perf_regs.c | 13 - tools/perf/arch/mips/include/perf_regs.h | 2 +- tools/perf/arch/mips/util/Build | 1 - tools/perf/arch/mips/util/perf_regs.c | 13 - tools/perf/arch/powerpc/include/perf_regs.h | 2 +- tools/perf/arch/powerpc/util/Build | 1 - tools/perf/arch/powerpc/util/perf_regs.c | 172 ----------- tools/perf/arch/riscv/include/perf_regs.h | 9 +- tools/perf/arch/riscv/util/Build | 1 - tools/perf/arch/riscv/util/perf_regs.c | 13 - tools/perf/arch/s390/include/perf_regs.h | 2 +- tools/perf/arch/s390/util/Build | 1 - tools/perf/arch/s390/util/perf_regs.c | 13 - tools/perf/arch/x86/include/perf_regs.h | 2 +- tools/perf/arch/x86/util/Build | 1 - tools/perf/arch/x86/util/perf_regs.c | 283 ------------------ tools/perf/util/evsel.c | 4 +- tools/perf/util/parse-regs-options.c | 13 +- .../util/perf-regs-arch/perf_regs_aarch64.c | 139 ++++++++- .../perf/util/perf-regs-arch/perf_regs_arm.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_csky.c | 7 +- .../util/perf-regs-arch/perf_regs_loongarch.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_mips.c | 7 +- .../util/perf-regs-arch/perf_regs_powerpc.c | 183 ++++++++++- .../util/perf-regs-arch/perf_regs_riscv.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_s390.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_x86.c | 281 ++++++++++++++++- tools/perf/util/perf_regs.c | 109 ++++++- tools/perf/util/perf_regs.h | 27 +- tools/perf/util/probe-file.c | 3 +- 42 files changed, 787 insertions(+), 724 deletions(-) delete mode 100644 tools/perf/arch/arm/util/perf_regs.c delete mode 100644 tools/perf/arch/arm64/util/perf_regs.c delete mode 100644 tools/perf/arch/csky/Build delete mode 100644 tools/perf/arch/csky/util/Build delete mode 100644 tools/perf/arch/csky/util/perf_regs.c delete mode 100644 tools/perf/arch/loongarch/util/perf_regs.c delete mode 100644 tools/perf/arch/mips/util/perf_regs.c delete mode 100644 tools/perf/arch/powerpc/util/perf_regs.c delete mode 100644 tools/perf/arch/riscv/util/perf_regs.c delete mode 100644 tools/perf/arch/s390/util/perf_regs.c delete mode 100644 tools/perf/arch/x86/util/perf_regs.cSignature · 1 line
2.34.1
Quoted 7 lines · Arnaldo Carvalho de Melo
Quoted 4 lines · Dapeng Mi
Changes:
v2 -> v3:
* Fix the abort issue for "-I" or "--user-regs" options. (Patch 1/4)
* Address Ian's comments.Fixed up somme fuzz with powerpc, x86, riscv and s390 Build files wrt removing perf_regs.o
Thanks.
Quoted 105 lines
Thanks, applied to perf-tools-next,
- Arnaldo
Quoted 100 lines
v1 -> v2:
* Fixing "PERF_REG_EXTENDED_MASK" redefinition building error by changing the "asm/perf_regs.h" header path to relative UAPI path. (Patch 1/3)
* Splitingxxx_reg_mask()andxxx_sdt_arg_parse_op()conversion into 2 patches.This patch-set remove the below three architecture specific
__weakfunctions and converted them into the general architecture specific functions which are dispatched base on "em_machine".
uint64_tarch__intr_reg_mask(void);uint64_tarch__user_reg_mask(void);
intarch_sdt_arg_parse_op(char *old_op, char **new_op);The advantage of this conversion is that these architectural functions can be called even for a different architecture with host instead of only called on the host architecture.
Although the converted functions shown below can be called on any architecture, currently they are still only called for the host architecture (
EM_HOST).int
perf_sdt_arg_parse_op(uint16_t e_machine, char *old_op, char **new_op);uint64_tperf_intr_reg_mask(uint16_t e_machine);uint64_tperf_user_reg_mask(uint16_t e_machine);Tests:
* This patch-set is only tested on x86 platforms. No issues are found for both intr-regs and user-regs options.
* Tests on other architectures are welcomed and appreciated.History:
v1: https://lore.kernel.org/all/[email protected]/
v2: https://lore.kernel.org/all/[email protected]/Dapeng Mi (4):
perf regs: Fix abort for "-I" or "--user-regs" options perf arch: Update arch headers to use relative UAPI paths perf regs: Remove__weakattributivearch__xxx_reg_mask()functions perf regs: Remove__weakattributivearch_sdt_arg_parse_op()functiontools/perf/arch/arm/include/perf_regs.h | 2 +- tools/perf/arch/arm/util/Build | 2 - tools/perf/arch/arm/util/perf_regs.c | 13 - tools/perf/arch/arm64/include/perf_regs.h | 2 +- tools/perf/arch/arm64/util/Build | 1 - tools/perf/arch/arm64/util/perf_regs.c | 141 --------- tools/perf/arch/csky/Build | 1 - tools/perf/arch/csky/include/perf_regs.h | 2 +- tools/perf/arch/csky/util/Build | 1 - tools/perf/arch/csky/util/perf_regs.c | 13 - tools/perf/arch/loongarch/include/perf_regs.h | 2 +- tools/perf/arch/loongarch/util/Build | 1 - tools/perf/arch/loongarch/util/perf_regs.c | 13 - tools/perf/arch/mips/include/perf_regs.h | 2 +- tools/perf/arch/mips/util/Build | 1 - tools/perf/arch/mips/util/perf_regs.c | 13 - tools/perf/arch/powerpc/include/perf_regs.h | 2 +- tools/perf/arch/powerpc/util/Build | 1 - tools/perf/arch/powerpc/util/perf_regs.c | 172 ----------- tools/perf/arch/riscv/include/perf_regs.h | 9 +- tools/perf/arch/riscv/util/Build | 1 - tools/perf/arch/riscv/util/perf_regs.c | 13 - tools/perf/arch/s390/include/perf_regs.h | 2 +- tools/perf/arch/s390/util/Build | 1 - tools/perf/arch/s390/util/perf_regs.c | 13 - tools/perf/arch/x86/include/perf_regs.h | 2 +- tools/perf/arch/x86/util/Build | 1 - tools/perf/arch/x86/util/perf_regs.c | 283 ------------------ tools/perf/util/evsel.c | 4 +- tools/perf/util/parse-regs-options.c | 13 +- .../util/perf-regs-arch/perf_regs_aarch64.c | 139 ++++++++- .../perf/util/perf-regs-arch/perf_regs_arm.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_csky.c | 7 +- .../util/perf-regs-arch/perf_regs_loongarch.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_mips.c | 7 +- .../util/perf-regs-arch/perf_regs_powerpc.c | 183 ++++++++++- .../util/perf-regs-arch/perf_regs_riscv.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_s390.c | 7 +- .../perf/util/perf-regs-arch/perf_regs_x86.c | 281 ++++++++++++++++- tools/perf/util/perf_regs.c | 109 ++++++- tools/perf/util/perf_regs.h | 27 +- tools/perf/util/probe-file.c | 3 +- 42 files changed, 787 insertions(+), 724 deletions(-) delete mode 100644 tools/perf/arch/arm/util/perf_regs.c delete mode 100644 tools/perf/arch/arm64/util/perf_regs.c delete mode 100644 tools/perf/arch/csky/Build delete mode 100644 tools/perf/arch/csky/util/Build delete mode 100644 tools/perf/arch/csky/util/perf_regs.c delete mode 100644 tools/perf/arch/loongarch/util/perf_regs.c delete mode 100644 tools/perf/arch/mips/util/perf_regs.c delete mode 100644 tools/perf/arch/powerpc/util/perf_regs.c delete mode 100644 tools/perf/arch/riscv/util/perf_regs.c delete mode 100644 tools/perf/arch/s390/util/perf_regs.c delete mode 100644 tools/perf/arch/x86/util/perf_regs.cSignature · 1 line
2.34.1
This series was applied to riscv/linux.git (for-next) by Arnaldo Carvalho de Melo <[email protected]>:
Hello:
This series was applied to riscv/linux.git (for-next) by Arnaldo Carvalho de Melo <[email protected]>:
Quoted 5 lines · On Tue, 3 Feb 2026 10:43:52 +0800 you wrote:
Changes:
v2 -> v3:
* Fix the abort issue for "-I" or "--user-regs" options. (Patch 1/4)
* Address Ian's comments.
Quoted 8 lines
v1 -> v2:
* Fixing "PERF_REG_EXTENDED_MASK" redefinition building error by changing the "asm/perf_regs.h" header path to relative UAPI path. (Patch 1/3)
* Splitingxxx_reg_mask()andxxx_sdt_arg_parse_op()conversion into 2 patches.[...]
Here is the summary with links:
- [v3,1/4] perf regs: Fix abort for "-I" or "--user-regs" options
https://git.kernel.org/riscv/c/c2e28ae2946f - [v3,2/4] perf arch: Update arch headers to use relative UAPI paths https://git.kernel.org/riscv/c/e716e69cf67b
- [v3,3/4] perf regs: Remove __weak attributive arch__xxx_reg_mask() functions (no matching commit)
- [v3,4/4] perf regs: Remove __weak attributive arch_sdt_arg_parse_op() function (no matching commit)
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html