From fa020dd78f9b6ec589c046c2b19a8a38127c3025 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 09:42:01 -0300 Subject: perf beauty: Make all sockaddr files use a common naming scheme The script that generates the tables was named 'socket.sh', which is confusing, rename it to sockaddr.sh and make sure the related Makefile.perf targets also use the 'sockaddr' namespace. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 12 ++++++------ tools/perf/trace/beauty/sockaddr.c | 2 +- tools/perf/trace/beauty/sockaddr.sh | 24 ++++++++++++++++++++++++ tools/perf/trace/beauty/socket.sh | 24 ------------------------ 4 files changed, 31 insertions(+), 31 deletions(-) create mode 100755 tools/perf/trace/beauty/sockaddr.sh delete mode 100755 tools/perf/trace/beauty/socket.sh (limited to 'tools/perf') diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 0777748b6da8..a1f22dd7b696 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -522,11 +522,11 @@ socket_ipproto_tbl := $(srctree)/tools/perf/trace/beauty/socket_ipproto.sh $(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl) $(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@ -socket_arrays := $(beauty_outdir)/socket_arrays.c -socket_tbl := $(srctree)/tools/perf/trace/beauty/socket.sh +sockaddr_arrays := $(beauty_outdir)/sockaddr.c +sockaddr_tbl := $(srctree)/tools/perf/trace/beauty/sockaddr.sh -$(socket_arrays): $(beauty_linux_dir)/socket.h $(socket_tbl) - $(Q)$(SHELL) '$(socket_tbl)' $(beauty_linux_dir) > $@ +$(sockaddr_arrays): $(beauty_linux_dir)/socket.h $(sockaddr_tbl) + $(Q)$(SHELL) '$(sockaddr_tbl)' $(beauty_linux_dir) > $@ vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux @@ -737,7 +737,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc $(kcmp_type_array) \ $(kvm_ioctl_array) \ $(socket_ipproto_array) \ - $(socket_arrays) \ + $(sockaddr_arrays) \ $(vhost_virtio_ioctl_array) \ $(madvise_behavior_array) \ $(mmap_flags_array) \ @@ -1114,7 +1114,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea $(OUTPUT)$(kvm_ioctl_array) \ $(OUTPUT)$(kcmp_type_array) \ $(OUTPUT)$(socket_ipproto_array) \ - $(OUTPUT)$(socket_arrays) \ + $(OUTPUT)$(sockaddr_arrays) \ $(OUTPUT)$(vhost_virtio_ioctl_array) \ $(OUTPUT)$(perf_ioctl_array) \ $(OUTPUT)$(prctl_option_array) \ diff --git a/tools/perf/trace/beauty/sockaddr.c b/tools/perf/trace/beauty/sockaddr.c index cd110634ab09..2e0e867c0c1b 100644 --- a/tools/perf/trace/beauty/sockaddr.c +++ b/tools/perf/trace/beauty/sockaddr.c @@ -7,7 +7,7 @@ #include #include -#include "trace/beauty/generated/socket_arrays.c" +#include "trace/beauty/generated/sockaddr.c" DEFINE_STRARRAY(socket_families, "PF_"); static size_t af_inet__scnprintf(struct sockaddr *sa, char *bf, size_t size) diff --git a/tools/perf/trace/beauty/sockaddr.sh b/tools/perf/trace/beauty/sockaddr.sh new file mode 100755 index 000000000000..3820e5c82293 --- /dev/null +++ b/tools/perf/trace/beauty/sockaddr.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# SPDX-License-Identifier: LGPL-2.1 + +# This one uses a copy from the kernel sources headers that is in a +# place used just for these tools/perf/beauty/ usage, we shouldn't not +# put it in tools/include/linux otherwise they would be used in the +# normal compiler building process and would drag needless stuff from the +# kernel. + +# When what these scripts need is already in tools/include/ then use it, +# otherwise grab and check the copy from the kernel sources just for these +# string table building scripts. + +[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/perf/trace/beauty/include/linux/ + +printf "static const char *socket_families[] = {\n" +# #define AF_LOCAL 1 /* POSIX name for AF_UNIX */ +regex='^#define[[:space:]]+AF_(\w+)[[:space:]]+([[:digit:]]+).*' + +egrep $regex ${header_dir}/socket.h | \ + sed -r "s/$regex/\2 \1/g" | \ + xargs printf "\t[%s] = \"%s\",\n" | \ + egrep -v "\"(UNIX|MAX)\"" +printf "};\n" diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh deleted file mode 100755 index 3820e5c82293..000000000000 --- a/tools/perf/trace/beauty/socket.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: LGPL-2.1 - -# This one uses a copy from the kernel sources headers that is in a -# place used just for these tools/perf/beauty/ usage, we shouldn't not -# put it in tools/include/linux otherwise they would be used in the -# normal compiler building process and would drag needless stuff from the -# kernel. - -# When what these scripts need is already in tools/include/ then use it, -# otherwise grab and check the copy from the kernel sources just for these -# string table building scripts. - -[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/perf/trace/beauty/include/linux/ - -printf "static const char *socket_families[] = {\n" -# #define AF_LOCAL 1 /* POSIX name for AF_UNIX */ -regex='^#define[[:space:]]+AF_(\w+)[[:space:]]+([[:digit:]]+).*' - -egrep $regex ${header_dir}/socket.h | \ - sed -r "s/$regex/\2 \1/g" | \ - xargs printf "\t[%s] = \"%s\",\n" | \ - egrep -v "\"(UNIX|MAX)\"" -printf "};\n" -- cgit v1.2.3 From 795f91db262ccc85dbc996ba27ce4ac6df529a85 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 10:05:53 -0300 Subject: perf beauty: Rename socket_ipproto.sh to socket.sh to hold more socket table generators To avoid having to add new entries to tools/perf/Makefile.perf prep socket.sh so that it can generate other socket table generators, such as the upcoming SOL_ socket level one. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 12 ++++++------ tools/perf/trace/beauty/socket.c | 3 ++- tools/perf/trace/beauty/socket.sh | 12 ++++++++++++ tools/perf/trace/beauty/socket_ipproto.sh | 12 ------------ 4 files changed, 20 insertions(+), 19 deletions(-) create mode 100755 tools/perf/trace/beauty/socket.sh delete mode 100755 tools/perf/trace/beauty/socket_ipproto.sh (limited to 'tools/perf') diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index a1f22dd7b696..50ac20798440 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -516,11 +516,11 @@ kvm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/kvm_ioctl.sh $(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl) $(Q)$(SHELL) '$(kvm_ioctl_tbl)' $(kvm_hdr_dir) > $@ -socket_ipproto_array := $(beauty_outdir)/socket_ipproto_array.c -socket_ipproto_tbl := $(srctree)/tools/perf/trace/beauty/socket_ipproto.sh +socket_arrays := $(beauty_outdir)/socket.c +socket_tbl := $(srctree)/tools/perf/trace/beauty/socket.sh -$(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl) - $(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@ +$(socket_arrays): $(linux_uapi_dir)/in.h $(socket_tbl) + $(Q)$(SHELL) '$(socket_tbl)' $(linux_uapi_dir) > $@ sockaddr_arrays := $(beauty_outdir)/sockaddr.c sockaddr_tbl := $(srctree)/tools/perf/trace/beauty/sockaddr.sh @@ -736,7 +736,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc $(sndrv_ctl_ioctl_array) \ $(kcmp_type_array) \ $(kvm_ioctl_array) \ - $(socket_ipproto_array) \ + $(socket_arrays) \ $(sockaddr_arrays) \ $(vhost_virtio_ioctl_array) \ $(madvise_behavior_array) \ @@ -1113,7 +1113,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea $(OUTPUT)$(sndrv_pcm_ioctl_array) \ $(OUTPUT)$(kvm_ioctl_array) \ $(OUTPUT)$(kcmp_type_array) \ - $(OUTPUT)$(socket_ipproto_array) \ + $(OUTPUT)$(socket_arrays) \ $(OUTPUT)$(sockaddr_arrays) \ $(OUTPUT)$(vhost_virtio_ioctl_array) \ $(OUTPUT)$(perf_ioctl_array) \ diff --git a/tools/perf/trace/beauty/socket.c b/tools/perf/trace/beauty/socket.c index f23a3dda2902..8aba260fcc33 100644 --- a/tools/perf/trace/beauty/socket.c +++ b/tools/perf/trace/beauty/socket.c @@ -9,9 +9,10 @@ #include #include +#include "trace/beauty/generated/socket.c" + static size_t socket__scnprintf_ipproto(int protocol, char *bf, size_t size, bool show_prefix) { -#include "trace/beauty/generated/socket_ipproto_array.c" static DEFINE_STRARRAY(socket_ipproto, "IPPROTO_"); return strarray__scnprintf(&strarray__socket_ipproto, bf, size, "%d", show_prefix, protocol); diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh new file mode 100755 index 000000000000..de0f2f29017f --- /dev/null +++ b/tools/perf/trace/beauty/socket.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# SPDX-License-Identifier: LGPL-2.1 + +[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ + +printf "static const char *socket_ipproto[] = {\n" +regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+),.*' + +egrep $regex ${header_dir}/in.h | \ + sed -r "s/$regex/\2 \1/g" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/trace/beauty/socket_ipproto.sh b/tools/perf/trace/beauty/socket_ipproto.sh deleted file mode 100755 index de0f2f29017f..000000000000 --- a/tools/perf/trace/beauty/socket_ipproto.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: LGPL-2.1 - -[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ - -printf "static const char *socket_ipproto[] = {\n" -regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+),.*' - -egrep $regex ${header_dir}/in.h | \ - sed -r "s/$regex/\2 \1/g" | \ - sort | xargs printf "\t[%s] = \"%s\",\n" -printf "};\n" -- cgit v1.2.3 From 012e5690360c542fa18694587c3f2e5392ddd475 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 10:31:33 -0300 Subject: perf beauty socket: Rename header_dir to uapi_header_dir Paving the way to pass more headers to be consumed, like tools/perf/trace/beauty/include/linux/socket.h in addition to the current tools/include/uapi/linux/in.h, to get the SOL_* defines. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/socket.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh index de0f2f29017f..e08a3fb880dd 100755 --- a/tools/perf/trace/beauty/socket.sh +++ b/tools/perf/trace/beauty/socket.sh @@ -1,12 +1,12 @@ #!/bin/sh # SPDX-License-Identifier: LGPL-2.1 -[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ +[ $# -eq 1 ] && uapi_header_dir=$1 || uapi_header_dir=tools/include/uapi/linux/ printf "static const char *socket_ipproto[] = {\n" regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+),.*' -egrep $regex ${header_dir}/in.h | \ +egrep $regex ${uapi_header_dir}/in.h | \ sed -r "s/$regex/\2 \1/g" | \ sort | xargs printf "\t[%s] = \"%s\",\n" printf "};\n" -- cgit v1.2.3 From 1a1edf33206c30b51638effa72a6940b7bc7618f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 10:34:06 -0300 Subject: perf beauty socket: Prep to receive more input header files Move from ternary like expression to an if block, this way we'll have just the extra lines for new files in the following patches. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/socket.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh index e08a3fb880dd..789b3d8c6bcc 100755 --- a/tools/perf/trace/beauty/socket.sh +++ b/tools/perf/trace/beauty/socket.sh @@ -1,7 +1,11 @@ #!/bin/sh # SPDX-License-Identifier: LGPL-2.1 -[ $# -eq 1 ] && uapi_header_dir=$1 || uapi_header_dir=tools/include/uapi/linux/ +if [ $# -gt 0 ] ; then + uapi_header_dir=$1 +else + uapi_header_dir=tools/include/uapi/linux/ +fi printf "static const char *socket_ipproto[] = {\n" regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+),.*' -- cgit v1.2.3 From 82e3664b0acce156bc8d366ec38374f314cd0111 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 10:38:27 -0300 Subject: perf beauty socket: Rename 'regex' to 'ipproto_regex' Paving the way for more regexps to be used here. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/socket.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh index 789b3d8c6bcc..6094e2411fa5 100755 --- a/tools/perf/trace/beauty/socket.sh +++ b/tools/perf/trace/beauty/socket.sh @@ -8,9 +8,9 @@ else fi printf "static const char *socket_ipproto[] = {\n" -regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+),.*' +ipproto_regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+),.*' -egrep $regex ${uapi_header_dir}/in.h | \ - sed -r "s/$regex/\2 \1/g" | \ +egrep $ipproto_regex ${uapi_header_dir}/in.h | \ + sed -r "s/$ipproto_regex/\2 \1/g" | \ sort | xargs printf "\t[%s] = \"%s\",\n" printf "};\n" -- cgit v1.2.3 From d3f82839f8d57e8679ef55773c432c89c7a7876a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 10:39:32 -0300 Subject: perf beauty socket: Sort the ipproto array entries Just tidying up the output for human consumption. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/socket.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh index 6094e2411fa5..7f1c9f0097c1 100755 --- a/tools/perf/trace/beauty/socket.sh +++ b/tools/perf/trace/beauty/socket.sh @@ -12,5 +12,5 @@ ipproto_regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+) egrep $ipproto_regex ${uapi_header_dir}/in.h | \ sed -r "s/$ipproto_regex/\2 \1/g" | \ - sort | xargs printf "\t[%s] = \"%s\",\n" + sort -n | xargs printf "\t[%s] = \"%s\",\n" printf "};\n" -- cgit v1.2.3 From ecf0a35ba22126160bd4bd2bf59d662e53d6e247 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 10:48:13 -0300 Subject: perf beauty socket: Add generator for socket level (SOL_*) string table $ tools/perf/trace/beauty/socket.sh static const char *socket_ipproto[] = { [0] = "IP", [1] = "ICMP", [255] = "RAW", [262] = "MPTCP", }; static const char *socket_level[] = { [0] = "IP", [6] = "TCP", [17] = "UDP", [41] = "IPV6", [58] = "ICMPV6", [132] = "SCTP", [136] = "UDPLITE", [255] = "RAW", [256] = "IPX", [257] = "AX25", [258] = "ATALK", [259] = "NETROM", [260] = "ROSE", [261] = "DECNET", [262] = "X25", [263] = "PACKET", [264] = "ATM", [265] = "AAL", [266] = "IRDA", [267] = "NETBEUI", [268] = "LLC", [269] = "DCCP", [270] = "NETLINK", [271] = "TIPC", [272] = "RXRPC", [273] = "PPPOL2TP", [274] = "BLUETOOTH", [275] = "PNPIPE", [276] = "RDS", [277] = "IUCV", [278] = "CAIF", [279] = "ALG", [280] = "NFC", [281] = "KCM", [282] = "TLS", [283] = "XDP", [284] = "MPTCP", [285] = "MCTP", }; $ Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 4 ++-- tools/perf/trace/beauty/beauty.h | 2 ++ tools/perf/trace/beauty/socket.sh | 14 +++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 50ac20798440..80522bcfafe0 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -519,8 +519,8 @@ $(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl) socket_arrays := $(beauty_outdir)/socket.c socket_tbl := $(srctree)/tools/perf/trace/beauty/socket.sh -$(socket_arrays): $(linux_uapi_dir)/in.h $(socket_tbl) - $(Q)$(SHELL) '$(socket_tbl)' $(linux_uapi_dir) > $@ +$(socket_arrays): $(linux_uapi_dir)/in.h $(beauty_linux_dir)/socket.h $(socket_tbl) + $(Q)$(SHELL) '$(socket_tbl)' $(linux_uapi_dir) $(beauty_linux_dir) > $@ sockaddr_arrays := $(beauty_outdir)/sockaddr.c sockaddr_tbl := $(srctree)/tools/perf/trace/beauty/sockaddr.sh diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index d6dfe68a7612..0501e8de0c59 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -62,6 +62,8 @@ size_t pid__scnprintf_fd(struct trace *trace, pid_t pid, int fd, char *bf, size_ extern struct strarray strarray__socket_families; +extern struct strarray strarray__socket_level; + /** * augmented_arg: extra payload for syscall pointer arguments diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh index 7f1c9f0097c1..76330acb27e5 100755 --- a/tools/perf/trace/beauty/socket.sh +++ b/tools/perf/trace/beauty/socket.sh @@ -3,8 +3,10 @@ if [ $# -gt 0 ] ; then uapi_header_dir=$1 + beauty_header_dir=$2 else uapi_header_dir=tools/include/uapi/linux/ + beauty_header_dir=tools/perf/trace/beauty/include/linux/ fi printf "static const char *socket_ipproto[] = {\n" @@ -13,4 +15,14 @@ ipproto_regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+) egrep $ipproto_regex ${uapi_header_dir}/in.h | \ sed -r "s/$ipproto_regex/\2 \1/g" | \ sort -n | xargs printf "\t[%s] = \"%s\",\n" -printf "};\n" +printf "};\n\n" + +printf "static const char *socket_level[] = {\n" +socket_level_regex='^#define[[:space:]]+SOL_(\w+)[[:space:]]+([[:digit:]]+)([[:space:]]+\/.*)?' + +egrep $socket_level_regex ${beauty_header_dir}/socket.h | \ + sed -r "s/$socket_level_regex/\2 \1/g" | \ + sort -n | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n\n" + +printf 'DEFINE_STRARRAY(socket_level, "SOL_");\n' -- cgit v1.2.3 From f1c1e45e9cca67b970a4941608767bced2e68695 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 15:29:10 -0300 Subject: perf trace: Beautify the 'level' argument of getsockopt # perf trace -e getsockopt 0.000 ( 0.006 ms): systemd-resolv/1121 getsockopt(fd: 21, level: 1, optname: 17, optval: 0x7ffee2c0c6cc, optlen: 0x7ffee2c0c6c8) = 0 0.301 ( 0.003 ms): systemd-resolv/1121 getsockopt(fd: 22, level: IP, optname: 14, optval: 0x7ffee2c0c1a0, optlen: 0x7ffee2c0c1a4) = -1 ENOTCONN (Transport endpoint is not connected) 2.215 ( 0.005 ms): systemd-resolv/1121 getsockopt(fd: 21, level: 1, optname: 17, optval: 0x7ffee2c0c6cc, optlen: 0x7ffee2c0c6c8) = 0 2.422 ( 0.005 ms): systemd-resolv/1121 getsockopt(fd: 22, level: IP, optname: 14, optval: 0x7ffee2c0c1a0, optlen: 0x7ffee2c0c1a4) = -1 ENOTCONN (Transport endpoint is not connected) 1001.308 ( 0.006 ms): systemd-resolv/1121 getsockopt(fd: 21, level: 1, optname: 17, optval: 0x7ffee2c0c6cc, optlen: 0x7ffee2c0c6c8) = 0 1001.586 ( 0.003 ms): systemd-resolv/1121 getsockopt(fd: 22, level: IP, optname: 14, optval: 0x7ffee2c0c1a0, optlen: 0x7ffee2c0c1a4) = -1 ENOTCONN (Transport endpoint is not connected) 1001.647 ( 0.002 ms): systemd-resolv/1121 getsockopt(fd: 23, level: IP, optname: 14, optval: 0x7ffee2c0c1a0, optlen: 0x7ffee2c0c1a4) = -1 ENOTCONN (Transport endpoint is not connected) 1003.868 ( 0.010 ms): systemd-resolv/1121 getsockopt(fd: 21, level: 1, optname: 17, optval: 0x7ffee2c0c6cc, optlen: 0x7ffee2c0c6c8) = 0 1004.036 ( 0.006 ms): systemd-resolv/1121 getsockopt(fd: 22, level: IP, optname: 14, optval: 0x7ffee2c0c1a0, optlen: 0x7ffee2c0c1a4) = -1 ENOTCONN (Transport endpoint is not connected) 1004.087 ( 0.002 ms): systemd-resolv/1121 getsockopt(fd: 23, level: IP, optname: 14, optval: 0x7ffee2c0c1a0, optlen: 0x7ffee2c0c1a4) = -1 ENOTCONN (Transport endpoint is not connected) ^C# So the simple straight STRARRAY method is not enough as SOL_SOCKET is '1' in most architectures but some use 0xffff (alpha, mips, parisc and sparc), so a followup patch will create a specialized scnprintf to cover that. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 624ea12ce5ca..aa5d22039511 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -979,6 +979,8 @@ static struct syscall_fmt syscall_fmts[] = { .arg = { [2] = { .scnprintf = SCA_GETRANDOM_FLAGS, /* flags */ }, }, }, { .name = "getrlimit", .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, + { .name = "getsockopt", + .arg = { [1] = STRARRAY(level, socket_level), }, }, { .name = "gettid", .errpid = true, }, { .name = "ioctl", .arg = { -- cgit v1.2.3 From 0826b7fd0a0188d9f8388ff031dd0b3e3beb77a6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Nov 2021 15:29:10 -0300 Subject: perf trace: Beautify the 'level' argument of setsockopt # perf trace -e setsockopt 0.000 ( 0.019 ms): systemd-resolv/1121 setsockopt(fd: 22, level: IP, optname: 50, optval: 0x7ffee2c0c134, optlen: 4) = 0 0.022 ( 0.003 ms): systemd-resolv/1121 setsockopt(fd: 22, level: IP, optname: 11, optval: 0x7ffee2c0c114, optlen: 4) = 0 0.027 ( 0.003 ms): systemd-resolv/1121 setsockopt(fd: 22, level: IP, optname: 8, optval: 0x7ffee2c0c134, optlen: 4) = 0 0.032 ( 0.002 ms): systemd-resolv/1121 setsockopt(fd: 22, level: IP, optname: 10, optval: 0x7ffee2c0c134, optlen: 4) = 0 0.036 ( 0.002 ms): systemd-resolv/1121 setsockopt(fd: 22, level: IP, optname: 25, optval: 0x7ffee2c0c114, optlen: 4) = 0 0.043 ( 0.003 ms): systemd-resolv/1121 setsockopt(fd: 22, level: 1, optname: 62, optval: 0x7ffee2c0c0fc, optlen: 4) = 0 0.055 ( 0.003 ms): systemd-resolv/1121 setsockopt(fd: 22, level: 1, optname: 25) ^C# So the simple straight STRARRAY method is not enough as SOL_SOCKET is '1' in most architectures but some use 0xffff (alpha, mips, parisc and sparc), so a followup patch will create a specialized scnprintf to cover that. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index aa5d22039511..0b52e08e558e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1123,6 +1123,8 @@ static struct syscall_fmt syscall_fmts[] = { .arg = { [0] = STRARRAY(which, itimers), }, }, { .name = "setrlimit", .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, + { .name = "setsockopt", + .arg = { [1] = STRARRAY(level, socket_level), }, }, { .name = "socket", .arg = { [0] = STRARRAY(family, socket_families), [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, -- cgit v1.2.3 From 66aee54ba42c72d594076f1de2d97fe0933836e8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 9 Nov 2021 09:23:07 -0300 Subject: perf beauty: Add socket level scnprintf that handles ARCH specific SOL_SOCKET SOL_SOCKET has a different value according to the architecture, some have it as 0xffff while all the others have it as 1, so a simple string array isn't usable, add a scnprintf routine that treats it as a special case, using the array for other values. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/beauty.h | 3 +++ tools/perf/trace/beauty/socket.c | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 0501e8de0c59..f527a46ab4e7 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -232,6 +232,9 @@ size_t syscall_arg__scnprintf_sockaddr(char *bf, size_t size, struct syscall_arg size_t syscall_arg__scnprintf_socket_protocol(char *bf, size_t size, struct syscall_arg *arg); #define SCA_SK_PROTO syscall_arg__scnprintf_socket_protocol +size_t syscall_arg__scnprintf_socket_level(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_SK_LEVEL syscall_arg__scnprintf_socket_level + size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags diff --git a/tools/perf/trace/beauty/socket.c b/tools/perf/trace/beauty/socket.c index 8aba260fcc33..b0870c7b48e5 100644 --- a/tools/perf/trace/beauty/socket.c +++ b/tools/perf/trace/beauty/socket.c @@ -27,3 +27,21 @@ size_t syscall_arg__scnprintf_socket_protocol(char *bf, size_t size, struct sysc return syscall_arg__scnprintf_int(bf, size, arg); } + +static size_t socket__scnprintf_level(int level, char *bf, size_t size, bool show_prefix) +{ +#if defined(__alpha__) || defined(__hppa__) || defined(__mips__) || defined(__sparc__) + const int sol_socket = 0xffff; +#else + const int sol_socket = 1; +#endif + if (level == sol_socket) + return scnprintf(bf, size, "%sSOCKET", show_prefix ? "SOL_" : ""); + + return strarray__scnprintf(&strarray__socket_level, bf, size, "%d", show_prefix, level); +} + +size_t syscall_arg__scnprintf_socket_level(char *bf, size_t size, struct syscall_arg *arg) +{ + return socket__scnprintf_level(arg->val, bf, size, arg->show_string_prefix); +} -- cgit v1.2.3 From fe90d378777a6f751f04ca85300f84d95952c159 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:47 -0700 Subject: perf test: Use macro for "suite" declarations Currently tests are setup in builtin-test with function pointers. Kunit exposes tests as a kunit_suite with a null terminated array of test cases. Use a macro to aid transition from one to the other in later changes. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/tests.h | 151 ++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 74 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index fe1306f58495..0846f66d67f9 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -40,94 +40,97 @@ struct test { void *priv; }; +#define DECLARE_SUITE(name) \ + int test__##name(struct test *test, int subtest) + /* Tests */ -int test__vmlinux_matches_kallsyms(struct test *test, int subtest); -int test__openat_syscall_event(struct test *test, int subtest); -int test__openat_syscall_event_on_all_cpus(struct test *test, int subtest); -int test__basic_mmap(struct test *test, int subtest); -int test__PERF_RECORD(struct test *test, int subtest); -int test__perf_evsel__roundtrip_name_test(struct test *test, int subtest); -int test__perf_evsel__tp_sched_test(struct test *test, int subtest); -int test__syscall_openat_tp_fields(struct test *test, int subtest); -int test__pmu(struct test *test, int subtest); -int test__pmu_events(struct test *test, int subtest); +DECLARE_SUITE(vmlinux_matches_kallsyms); +DECLARE_SUITE(openat_syscall_event); +DECLARE_SUITE(openat_syscall_event_on_all_cpus); +DECLARE_SUITE(basic_mmap); +DECLARE_SUITE(PERF_RECORD); +DECLARE_SUITE(perf_evsel__roundtrip_name_test); +DECLARE_SUITE(perf_evsel__tp_sched_test); +DECLARE_SUITE(syscall_openat_tp_fields); +DECLARE_SUITE(pmu); +DECLARE_SUITE(pmu_events); const char *test__pmu_events_subtest_get_desc(int subtest); const char *test__pmu_events_subtest_skip_reason(int subtest); int test__pmu_events_subtest_get_nr(void); -int test__attr(struct test *test, int subtest); -int test__dso_data(struct test *test, int subtest); -int test__dso_data_cache(struct test *test, int subtest); -int test__dso_data_reopen(struct test *test, int subtest); -int test__parse_events(struct test *test, int subtest); -int test__hists_link(struct test *test, int subtest); -int test__python_use(struct test *test, int subtest); -int test__bp_signal(struct test *test, int subtest); -int test__bp_signal_overflow(struct test *test, int subtest); -int test__bp_accounting(struct test *test, int subtest); -int test__wp(struct test *test, int subtest); +DECLARE_SUITE(attr); +DECLARE_SUITE(dso_data); +DECLARE_SUITE(dso_data_cache); +DECLARE_SUITE(dso_data_reopen); +DECLARE_SUITE(parse_events); +DECLARE_SUITE(hists_link); +DECLARE_SUITE(python_use); +DECLARE_SUITE(bp_signal); +DECLARE_SUITE(bp_signal_overflow); +DECLARE_SUITE(bp_accounting); +DECLARE_SUITE(wp); const char *test__wp_subtest_get_desc(int subtest); const char *test__wp_subtest_skip_reason(int subtest); int test__wp_subtest_get_nr(void); -int test__task_exit(struct test *test, int subtest); -int test__mem(struct test *test, int subtest); -int test__sw_clock_freq(struct test *test, int subtest); -int test__code_reading(struct test *test, int subtest); -int test__sample_parsing(struct test *test, int subtest); -int test__keep_tracking(struct test *test, int subtest); -int test__parse_no_sample_id_all(struct test *test, int subtest); -int test__dwarf_unwind(struct test *test, int subtest); -int test__expr(struct test *test, int subtest); -int test__hists_filter(struct test *test, int subtest); -int test__mmap_thread_lookup(struct test *test, int subtest); -int test__thread_maps_share(struct test *test, int subtest); -int test__hists_output(struct test *test, int subtest); -int test__hists_cumulate(struct test *test, int subtest); -int test__switch_tracking(struct test *test, int subtest); -int test__fdarray__filter(struct test *test, int subtest); -int test__fdarray__add(struct test *test, int subtest); -int test__kmod_path__parse(struct test *test, int subtest); -int test__thread_map(struct test *test, int subtest); -int test__llvm(struct test *test, int subtest); +DECLARE_SUITE(task_exit); +DECLARE_SUITE(mem); +DECLARE_SUITE(sw_clock_freq); +DECLARE_SUITE(code_reading); +DECLARE_SUITE(sample_parsing); +DECLARE_SUITE(keep_tracking); +DECLARE_SUITE(parse_no_sample_id_all); +DECLARE_SUITE(dwarf_unwind); +DECLARE_SUITE(expr); +DECLARE_SUITE(hists_filter); +DECLARE_SUITE(mmap_thread_lookup); +DECLARE_SUITE(thread_maps_share); +DECLARE_SUITE(hists_output); +DECLARE_SUITE(hists_cumulate); +DECLARE_SUITE(switch_tracking); +DECLARE_SUITE(fdarray__filter); +DECLARE_SUITE(fdarray__add); +DECLARE_SUITE(kmod_path__parse); +DECLARE_SUITE(thread_map); +DECLARE_SUITE(llvm); const char *test__llvm_subtest_get_desc(int subtest); int test__llvm_subtest_get_nr(void); -int test__bpf(struct test *test, int subtest); +DECLARE_SUITE(bpf); const char *test__bpf_subtest_get_desc(int subtest); int test__bpf_subtest_get_nr(void); -int test__session_topology(struct test *test, int subtest); -int test__thread_map_synthesize(struct test *test, int subtest); -int test__thread_map_remove(struct test *test, int subtest); -int test__cpu_map_synthesize(struct test *test, int subtest); -int test__synthesize_stat_config(struct test *test, int subtest); -int test__synthesize_stat(struct test *test, int subtest); -int test__synthesize_stat_round(struct test *test, int subtest); -int test__event_update(struct test *test, int subtest); -int test__event_times(struct test *test, int subtest); -int test__backward_ring_buffer(struct test *test, int subtest); -int test__cpu_map_print(struct test *test, int subtest); -int test__cpu_map_merge(struct test *test, int subtest); -int test__sdt_event(struct test *test, int subtest); -int test__is_printable_array(struct test *test, int subtest); -int test__bitmap_print(struct test *test, int subtest); -int test__perf_hooks(struct test *test, int subtest); -int test__clang(struct test *test, int subtest); +DECLARE_SUITE(session_topology); +DECLARE_SUITE(thread_map_synthesize); +DECLARE_SUITE(thread_map_remove); +DECLARE_SUITE(cpu_map_synthesize); +DECLARE_SUITE(synthesize_stat_config); +DECLARE_SUITE(synthesize_stat); +DECLARE_SUITE(synthesize_stat_round); +DECLARE_SUITE(event_update); +DECLARE_SUITE(event_times); +DECLARE_SUITE(backward_ring_buffer); +DECLARE_SUITE(cpu_map_print); +DECLARE_SUITE(cpu_map_merge); +DECLARE_SUITE(sdt_event); +DECLARE_SUITE(is_printable_array); +DECLARE_SUITE(bitmap_print); +DECLARE_SUITE(perf_hooks); +DECLARE_SUITE(clang); const char *test__clang_subtest_get_desc(int subtest); int test__clang_subtest_get_nr(void); -int test__unit_number__scnprint(struct test *test, int subtest); -int test__mem2node(struct test *t, int subtest); -int test__maps__merge_in(struct test *t, int subtest); -int test__time_utils(struct test *t, int subtest); -int test__jit_write_elf(struct test *test, int subtest); -int test__api_io(struct test *test, int subtest); -int test__demangle_java(struct test *test, int subtest); -int test__demangle_ocaml(struct test *test, int subtest); -int test__pfm(struct test *test, int subtest); +DECLARE_SUITE(unit_number__scnprint); +DECLARE_SUITE(mem2node); +DECLARE_SUITE(maps__merge_in); +DECLARE_SUITE(time_utils); +DECLARE_SUITE(jit_write_elf); +DECLARE_SUITE(api_io); +DECLARE_SUITE(demangle_java); +DECLARE_SUITE(demangle_ocaml); +DECLARE_SUITE(pfm); const char *test__pfm_subtest_get_desc(int subtest); int test__pfm_subtest_get_nr(void); -int test__parse_metric(struct test *test, int subtest); -int test__pe_file_parsing(struct test *test, int subtest); -int test__expand_cgroup_events(struct test *test, int subtest); -int test__perf_time_to_tsc(struct test *test, int subtest); -int test__dlfilter(struct test *test, int subtest); +DECLARE_SUITE(parse_metric); +DECLARE_SUITE(pe_file_parsing); +DECLARE_SUITE(expand_cgroup_events); +DECLARE_SUITE(perf_time_to_tsc); +DECLARE_SUITE(dlfilter); bool test__bp_signal_is_supported(void); bool test__bp_account_is_supported(void); @@ -142,7 +145,7 @@ int test__arch_unwind_sample(struct perf_sample *sample, #endif #if defined(__arm__) -int test__vectors_page(struct test *test, int subtest); +DECLARE_SUITE(vectors_page); #endif #endif /* TESTS_H */ -- cgit v1.2.3 From 54df5c8e014c52726a71a6c11534b9cd2df31039 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:48 -0700 Subject: perf test: Use macro for "suite" definitions Add a macro to simplify later refactoring. No functional change. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 479 +++++++++++++--------------------------- 1 file changed, 149 insertions(+), 330 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index da7dc5e45d0c..820fc1ae2210 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -36,337 +36,156 @@ struct test __weak arch_tests[] = { }, }; -static struct test generic_tests[] = { - { - .desc = "vmlinux symtab matches kallsyms", - .func = test__vmlinux_matches_kallsyms, - }, - { - .desc = "Detect openat syscall event", - .func = test__openat_syscall_event, - }, - { - .desc = "Detect openat syscall event on all cpus", - .func = test__openat_syscall_event_on_all_cpus, - }, - { - .desc = "Read samples using the mmap interface", - .func = test__basic_mmap, - }, - { - .desc = "Test data source output", - .func = test__mem, - }, - { - .desc = "Parse event definition strings", - .func = test__parse_events, - }, - { - .desc = "Simple expression parser", - .func = test__expr, - }, - { - .desc = "PERF_RECORD_* events & perf_sample fields", - .func = test__PERF_RECORD, - }, - { - .desc = "Parse perf pmu format", - .func = test__pmu, - }, - { - .desc = "PMU events", - .func = test__pmu_events, - .subtest = { - .skip_if_fail = false, - .get_nr = test__pmu_events_subtest_get_nr, - .get_desc = test__pmu_events_subtest_get_desc, - .skip_reason = test__pmu_events_subtest_skip_reason, - }, - - }, - { - .desc = "DSO data read", - .func = test__dso_data, - }, - { - .desc = "DSO data cache", - .func = test__dso_data_cache, - }, - { - .desc = "DSO data reopen", - .func = test__dso_data_reopen, - }, - { - .desc = "Roundtrip evsel->name", - .func = test__perf_evsel__roundtrip_name_test, - }, - { - .desc = "Parse sched tracepoints fields", - .func = test__perf_evsel__tp_sched_test, - }, - { - .desc = "syscalls:sys_enter_openat event fields", - .func = test__syscall_openat_tp_fields, - }, - { - .desc = "Setup struct perf_event_attr", - .func = test__attr, - }, - { - .desc = "Match and link multiple hists", - .func = test__hists_link, - }, - { - .desc = "'import perf' in python", - .func = test__python_use, - }, - { - .desc = "Breakpoint overflow signal handler", - .func = test__bp_signal, - .is_supported = test__bp_signal_is_supported, - }, - { - .desc = "Breakpoint overflow sampling", - .func = test__bp_signal_overflow, - .is_supported = test__bp_signal_is_supported, - }, - { - .desc = "Breakpoint accounting", - .func = test__bp_accounting, - .is_supported = test__bp_account_is_supported, - }, - { - .desc = "Watchpoint", - .func = test__wp, - .is_supported = test__wp_is_supported, - .subtest = { - .skip_if_fail = false, - .get_nr = test__wp_subtest_get_nr, - .get_desc = test__wp_subtest_get_desc, - .skip_reason = test__wp_subtest_skip_reason, - }, - }, - { - .desc = "Number of exit events of a simple workload", - .func = test__task_exit, - }, - { - .desc = "Software clock events period values", - .func = test__sw_clock_freq, - }, - { - .desc = "Object code reading", - .func = test__code_reading, - }, - { - .desc = "Sample parsing", - .func = test__sample_parsing, - }, - { - .desc = "Use a dummy software event to keep tracking", - .func = test__keep_tracking, - }, - { - .desc = "Parse with no sample_id_all bit set", - .func = test__parse_no_sample_id_all, - }, - { - .desc = "Filter hist entries", - .func = test__hists_filter, - }, - { - .desc = "Lookup mmap thread", - .func = test__mmap_thread_lookup, - }, - { - .desc = "Share thread maps", - .func = test__thread_maps_share, - }, - { - .desc = "Sort output of hist entries", - .func = test__hists_output, - }, - { - .desc = "Cumulate child hist entries", - .func = test__hists_cumulate, - }, - { - .desc = "Track with sched_switch", - .func = test__switch_tracking, - }, - { - .desc = "Filter fds with revents mask in a fdarray", - .func = test__fdarray__filter, - }, - { - .desc = "Add fd to a fdarray, making it autogrow", - .func = test__fdarray__add, - }, - { - .desc = "kmod_path__parse", - .func = test__kmod_path__parse, - }, - { - .desc = "Thread map", - .func = test__thread_map, - }, - { - .desc = "LLVM search and compile", - .func = test__llvm, - .subtest = { - .skip_if_fail = true, - .get_nr = test__llvm_subtest_get_nr, - .get_desc = test__llvm_subtest_get_desc, - }, - }, - { - .desc = "Session topology", - .func = test__session_topology, - }, - { - .desc = "BPF filter", - .func = test__bpf, - .subtest = { - .skip_if_fail = true, - .get_nr = test__bpf_subtest_get_nr, - .get_desc = test__bpf_subtest_get_desc, - }, - }, - { - .desc = "Synthesize thread map", - .func = test__thread_map_synthesize, - }, - { - .desc = "Remove thread map", - .func = test__thread_map_remove, - }, - { - .desc = "Synthesize cpu map", - .func = test__cpu_map_synthesize, - }, - { - .desc = "Synthesize stat config", - .func = test__synthesize_stat_config, - }, - { - .desc = "Synthesize stat", - .func = test__synthesize_stat, - }, - { - .desc = "Synthesize stat round", - .func = test__synthesize_stat_round, - }, - { - .desc = "Synthesize attr update", - .func = test__event_update, - }, - { - .desc = "Event times", - .func = test__event_times, - }, - { - .desc = "Read backward ring buffer", - .func = test__backward_ring_buffer, - }, - { - .desc = "Print cpu map", - .func = test__cpu_map_print, - }, - { - .desc = "Merge cpu map", - .func = test__cpu_map_merge, - }, +#define DEFINE_SUITE(description, name) \ + { \ + .desc = description, \ + .func = test__##name, \ + } - { - .desc = "Probe SDT events", - .func = test__sdt_event, - }, - { - .desc = "is_printable_array", - .func = test__is_printable_array, - }, - { - .desc = "Print bitmap", - .func = test__bitmap_print, - }, - { - .desc = "perf hooks", - .func = test__perf_hooks, - }, - { - .desc = "builtin clang support", - .func = test__clang, - .subtest = { - .skip_if_fail = true, - .get_nr = test__clang_subtest_get_nr, - .get_desc = test__clang_subtest_get_desc, - } - }, - { - .desc = "unit_number__scnprintf", - .func = test__unit_number__scnprint, - }, - { - .desc = "mem2node", - .func = test__mem2node, - }, - { - .desc = "time utils", - .func = test__time_utils, - }, - { - .desc = "Test jit_write_elf", - .func = test__jit_write_elf, - }, - { - .desc = "Test libpfm4 support", - .func = test__pfm, - .subtest = { - .skip_if_fail = true, - .get_nr = test__pfm_subtest_get_nr, - .get_desc = test__pfm_subtest_get_desc, - } - }, - { - .desc = "Test api io", - .func = test__api_io, - }, - { - .desc = "maps__merge_in", - .func = test__maps__merge_in, - }, - { - .desc = "Demangle Java", - .func = test__demangle_java, - }, - { - .desc = "Demangle OCaml", - .func = test__demangle_ocaml, - }, - { - .desc = "Parse and process metrics", - .func = test__parse_metric, - }, - { - .desc = "PE file support", - .func = test__pe_file_parsing, - }, - { - .desc = "Event expansion for cgroups", - .func = test__expand_cgroup_events, - }, - { - .desc = "Convert perf time to TSC", - .func = test__perf_time_to_tsc, - .is_supported = test__tsc_is_supported, - }, - { - .desc = "dlfilter C API", - .func = test__dlfilter, - }, - { - .func = NULL, - }, +static struct test generic_tests[] = { +DEFINE_SUITE("vmlinux symtab matches kallsyms", vmlinux_matches_kallsyms), +DEFINE_SUITE("Detect openat syscall event", openat_syscall_event), +DEFINE_SUITE("Detect openat syscall event on all cpus", openat_syscall_event_on_all_cpus), +DEFINE_SUITE("Read samples using the mmap interface", basic_mmap), +DEFINE_SUITE("Test data source output", mem), +DEFINE_SUITE("Parse event definition strings", parse_events), +DEFINE_SUITE("Simple expression parser", expr), +DEFINE_SUITE("PERF_RECORD_* events & perf_sample fields", PERF_RECORD), +DEFINE_SUITE("Parse perf pmu format", pmu), +{ + .desc = "PMU events", + .func = test__pmu_events, + .subtest = { + .skip_if_fail = false, + .get_nr = test__pmu_events_subtest_get_nr, + .get_desc = test__pmu_events_subtest_get_desc, + .skip_reason = test__pmu_events_subtest_skip_reason, + }, + +}, +DEFINE_SUITE("DSO data read", dso_data), +DEFINE_SUITE("DSO data cache", dso_data_cache), +DEFINE_SUITE("DSO data reopen", dso_data_reopen), +DEFINE_SUITE("Roundtrip evsel->name", perf_evsel__roundtrip_name_test), +DEFINE_SUITE("Parse sched tracepoints fields", perf_evsel__tp_sched_test), +DEFINE_SUITE("syscalls:sys_enter_openat event fields", syscall_openat_tp_fields), +DEFINE_SUITE("Setup struct perf_event_attr", attr), +DEFINE_SUITE("Match and link multiple hists", hists_link), +DEFINE_SUITE("'import perf' in python", python_use), +{ + .desc = "Breakpoint overflow signal handler", + .func = test__bp_signal, + .is_supported = test__bp_signal_is_supported, +}, +{ + .desc = "Breakpoint overflow sampling", + .func = test__bp_signal_overflow, + .is_supported = test__bp_signal_is_supported, +}, +{ + .desc = "Breakpoint accounting", + .func = test__bp_accounting, + .is_supported = test__bp_account_is_supported, +}, +{ + .desc = "Watchpoint", + .func = test__wp, + .is_supported = test__wp_is_supported, + .subtest = { + .skip_if_fail = false, + .get_nr = test__wp_subtest_get_nr, + .get_desc = test__wp_subtest_get_desc, + .skip_reason = test__wp_subtest_skip_reason, + }, +}, +DEFINE_SUITE("Number of exit events of a simple workload", task_exit), +DEFINE_SUITE("Software clock events period values", sw_clock_freq), +DEFINE_SUITE("Object code reading", code_reading), +DEFINE_SUITE("Sample parsing", sample_parsing), +DEFINE_SUITE("Use a dummy software event to keep tracking", keep_tracking), +DEFINE_SUITE("Parse with no sample_id_all bit set", parse_no_sample_id_all), +DEFINE_SUITE("Filter hist entries", hists_filter), +DEFINE_SUITE("Lookup mmap thread", mmap_thread_lookup), +DEFINE_SUITE("Share thread maps", thread_maps_share), +DEFINE_SUITE("Sort output of hist entries", hists_output), +DEFINE_SUITE("Cumulate child hist entries", hists_cumulate), +DEFINE_SUITE("Track with sched_switch", switch_tracking), +DEFINE_SUITE("Filter fds with revents mask in a fdarray", fdarray__filter), +DEFINE_SUITE("Add fd to a fdarray, making it autogrow", fdarray__add), +DEFINE_SUITE("kmod_path__parse", kmod_path__parse), +DEFINE_SUITE("Thread map", thread_map), +{ + .desc = "LLVM search and compile", + .func = test__llvm, + .subtest = { + .skip_if_fail = true, + .get_nr = test__llvm_subtest_get_nr, + .get_desc = test__llvm_subtest_get_desc, + }, +}, +DEFINE_SUITE("Session topology", session_topology), +{ + .desc = "BPF filter", + .func = test__bpf, + .subtest = { + .skip_if_fail = true, + .get_nr = test__bpf_subtest_get_nr, + .get_desc = test__bpf_subtest_get_desc, + }, +}, +DEFINE_SUITE("Synthesize thread map", thread_map_synthesize), +DEFINE_SUITE("Remove thread map", thread_map_remove), +DEFINE_SUITE("Synthesize cpu map", cpu_map_synthesize), +DEFINE_SUITE("Synthesize stat config", synthesize_stat_config), +DEFINE_SUITE("Synthesize stat", synthesize_stat), +DEFINE_SUITE("Synthesize stat round", synthesize_stat_round), +DEFINE_SUITE("Synthesize attr update", event_update), +DEFINE_SUITE("Event times", event_times), +DEFINE_SUITE("Read backward ring buffer", backward_ring_buffer), +DEFINE_SUITE("Print cpu map", cpu_map_print), +DEFINE_SUITE("Merge cpu map", cpu_map_merge), +DEFINE_SUITE("Probe SDT events", sdt_event), +DEFINE_SUITE("is_printable_array", is_printable_array), +DEFINE_SUITE("Print bitmap", bitmap_print), +DEFINE_SUITE("perf hooks", perf_hooks), +{ + .desc = "builtin clang support", + .func = test__clang, + .subtest = { + .skip_if_fail = true, + .get_nr = test__clang_subtest_get_nr, + .get_desc = test__clang_subtest_get_desc, + } +}, +DEFINE_SUITE("unit_number__scnprintf", unit_number__scnprint), +DEFINE_SUITE("mem2node", mem2node), +DEFINE_SUITE("time utils", time_utils), +DEFINE_SUITE("Test jit_write_elf", jit_write_elf), +{ + .desc = "Test libpfm4 support", + .func = test__pfm, + .subtest = { + .skip_if_fail = true, + .get_nr = test__pfm_subtest_get_nr, + .get_desc = test__pfm_subtest_get_desc, + } +}, +DEFINE_SUITE("Test api io", api_io), +DEFINE_SUITE("maps__merge_in", maps__merge_in), +DEFINE_SUITE("Demangle Java", demangle_java), +DEFINE_SUITE("Demangle OCaml", demangle_ocaml), +DEFINE_SUITE("Parse and process metrics", parse_metric), +DEFINE_SUITE("PE file support", pe_file_parsing), +DEFINE_SUITE("Event expansion for cgroups", expand_cgroup_events), +{ + .desc = "Convert perf time to TSC", + .func = test__perf_time_to_tsc, + .is_supported = test__tsc_is_supported, +}, +DEFINE_SUITE("dlfilter C API", dlfilter), +{ + .func = NULL, +}, }; static struct test *tests[] = { -- cgit v1.2.3 From df2252054eb0f9f65389f3911588256bcc4f973b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:49 -0700 Subject: perf test: Make each test/suite its own struct. By switching to an array of pointers to tests (later to be suites) the definition of the tests can be moved to the file containing the tests. Committer notes: It's "&vectors_page", not "&vectors_pages", noticed when cross building to 32-bit ARM. Also the DEFINE_SUITE(vectors_page) should be done where its function is implemented, in tools/perf/arch/arm/tests/vectors-page.c, so that we can make it static, as we don't have anymore its declaration in tests.h. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/include/arch-tests.h | 2 +- tools/perf/arch/arm/tests/arch-tests.c | 16 +- tools/perf/arch/arm/tests/vectors-page.c | 5 +- tools/perf/arch/arm64/include/arch-tests.h | 2 +- tools/perf/arch/arm64/tests/arch-tests.c | 11 +- tools/perf/arch/powerpc/include/arch-tests.h | 2 +- tools/perf/arch/powerpc/tests/arch-tests.c | 11 +- tools/perf/arch/x86/include/arch-tests.h | 2 +- tools/perf/arch/x86/tests/arch-tests.c | 47 ++--- tools/perf/tests/builtin-test.c | 273 ++++++++++++++++----------- tools/perf/tests/dwarf-unwind.c | 7 +- tools/perf/tests/tests.h | 8 +- 12 files changed, 216 insertions(+), 170 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/arch/arm/include/arch-tests.h b/tools/perf/arch/arm/include/arch-tests.h index c62538052404..37039e80f18b 100644 --- a/tools/perf/arch/arm/include/arch-tests.h +++ b/tools/perf/arch/arm/include/arch-tests.h @@ -2,6 +2,6 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H -extern struct test arch_tests[]; +extern struct test *arch_tests[]; #endif diff --git a/tools/perf/arch/arm/tests/arch-tests.c b/tools/perf/arch/arm/tests/arch-tests.c index 6848101a855f..8276740f7ff8 100644 --- a/tools/perf/arch/arm/tests/arch-tests.c +++ b/tools/perf/arch/arm/tests/arch-tests.c @@ -3,18 +3,10 @@ #include "tests/tests.h" #include "arch-tests.h" -struct test arch_tests[] = { +struct test *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT - { - .desc = "DWARF unwind", - .func = test__dwarf_unwind, - }, + &dwarf_unwind, #endif - { - .desc = "Vectors page", - .func = test__vectors_page, - }, - { - .func = NULL, - }, + &vectors_page, + NULL, }; diff --git a/tools/perf/arch/arm/tests/vectors-page.c b/tools/perf/arch/arm/tests/vectors-page.c index 7ffdd79971c8..dac7b32afb65 100644 --- a/tools/perf/arch/arm/tests/vectors-page.c +++ b/tools/perf/arch/arm/tests/vectors-page.c @@ -9,8 +9,7 @@ #define VECTORS__MAP_NAME "[vectors]" -int test__vectors_page(struct test *test __maybe_unused, - int subtest __maybe_unused) +static int test__vectors_page(struct test *test __maybe_unused, int subtest __maybe_unused) { void *start, *end; @@ -22,3 +21,5 @@ int test__vectors_page(struct test *test __maybe_unused, return TEST_OK; } + +DEFINE_SUITE("Vectors page", vectors_page); diff --git a/tools/perf/arch/arm64/include/arch-tests.h b/tools/perf/arch/arm64/include/arch-tests.h index c62538052404..37039e80f18b 100644 --- a/tools/perf/arch/arm64/include/arch-tests.h +++ b/tools/perf/arch/arm64/include/arch-tests.h @@ -2,6 +2,6 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H -extern struct test arch_tests[]; +extern struct test *arch_tests[]; #endif diff --git a/tools/perf/arch/arm64/tests/arch-tests.c b/tools/perf/arch/arm64/tests/arch-tests.c index 5b1543c98022..bc327048b807 100644 --- a/tools/perf/arch/arm64/tests/arch-tests.c +++ b/tools/perf/arch/arm64/tests/arch-tests.c @@ -3,14 +3,9 @@ #include "tests/tests.h" #include "arch-tests.h" -struct test arch_tests[] = { +struct test *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT - { - .desc = "DWARF unwind", - .func = test__dwarf_unwind, - }, + &dwarf_unwind, #endif - { - .func = NULL, - }, + NULL, }; diff --git a/tools/perf/arch/powerpc/include/arch-tests.h b/tools/perf/arch/powerpc/include/arch-tests.h index c62538052404..37039e80f18b 100644 --- a/tools/perf/arch/powerpc/include/arch-tests.h +++ b/tools/perf/arch/powerpc/include/arch-tests.h @@ -2,6 +2,6 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H -extern struct test arch_tests[]; +extern struct test *arch_tests[]; #endif diff --git a/tools/perf/arch/powerpc/tests/arch-tests.c b/tools/perf/arch/powerpc/tests/arch-tests.c index 8c3fbd4af817..bc327048b807 100644 --- a/tools/perf/arch/powerpc/tests/arch-tests.c +++ b/tools/perf/arch/powerpc/tests/arch-tests.c @@ -3,14 +3,9 @@ #include "tests/tests.h" #include "arch-tests.h" -struct test arch_tests[] = { +struct test *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT - { - .desc = "Test dwarf unwind", - .func = test__dwarf_unwind, - }, + &dwarf_unwind, #endif - { - .func = NULL, - }, + NULL, }; diff --git a/tools/perf/arch/x86/include/arch-tests.h b/tools/perf/arch/x86/include/arch-tests.h index 9599e7a3f1af..d6db9f72b6af 100644 --- a/tools/perf/arch/x86/include/arch-tests.h +++ b/tools/perf/arch/x86/include/arch-tests.h @@ -11,6 +11,6 @@ int test__intel_pt_pkt_decoder(struct test *test, int subtest); int test__bp_modify(struct test *test, int subtest); int test__x86_sample_parsing(struct test *test, int subtest); -extern struct test arch_tests[]; +extern struct test *arch_tests[]; #endif diff --git a/tools/perf/arch/x86/tests/arch-tests.c b/tools/perf/arch/x86/tests/arch-tests.c index 71aa67367ad6..f5e3195768a4 100644 --- a/tools/perf/arch/x86/tests/arch-tests.c +++ b/tools/perf/arch/x86/tests/arch-tests.c @@ -3,39 +3,28 @@ #include "tests/tests.h" #include "arch-tests.h" -struct test arch_tests[] = { - { - .desc = "x86 rdpmc", - .func = test__rdpmc, - }, +DEFINE_SUITE("x86 rdpmc", rdpmc); +#ifdef HAVE_AUXTRACE_SUPPORT +DEFINE_SUITE("x86 instruction decoder - new instructions", insn_x86); +DEFINE_SUITE("Intel PT packet decoder", intel_pt_pkt_decoder); +#endif +#if defined(__x86_64__) +DEFINE_SUITE("x86 bp modify", bp_modify); +#endif +DEFINE_SUITE("x86 Sample parsing", x86_sample_parsing); + +struct test *arch_tests[] = { + &rdpmc, #ifdef HAVE_DWARF_UNWIND_SUPPORT - { - .desc = "DWARF unwind", - .func = test__dwarf_unwind, - }, + &dwarf_unwind, #endif #ifdef HAVE_AUXTRACE_SUPPORT - { - .desc = "x86 instruction decoder - new instructions", - .func = test__insn_x86, - }, - { - .desc = "Intel PT packet decoder", - .func = test__intel_pt_pkt_decoder, - }, + &insn_x86, + &intel_pt_pkt_decoder, #endif #if defined(__x86_64__) - { - .desc = "x86 bp modify", - .func = test__bp_modify, - }, + &bp_modify, #endif - { - .desc = "x86 Sample parsing", - .func = test__x86_sample_parsing, - }, - { - .func = NULL, - }, - + &x86_sample_parsing, + NULL, }; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 820fc1ae2210..b2cbc12a70a2 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -30,29 +30,20 @@ static bool dont_fork; -struct test __weak arch_tests[] = { - { - .func = NULL, - }, +struct test *__weak arch_tests[] = { + NULL, }; -#define DEFINE_SUITE(description, name) \ - { \ - .desc = description, \ - .func = test__##name, \ - } - -static struct test generic_tests[] = { -DEFINE_SUITE("vmlinux symtab matches kallsyms", vmlinux_matches_kallsyms), -DEFINE_SUITE("Detect openat syscall event", openat_syscall_event), -DEFINE_SUITE("Detect openat syscall event on all cpus", openat_syscall_event_on_all_cpus), -DEFINE_SUITE("Read samples using the mmap interface", basic_mmap), -DEFINE_SUITE("Test data source output", mem), -DEFINE_SUITE("Parse event definition strings", parse_events), -DEFINE_SUITE("Simple expression parser", expr), -DEFINE_SUITE("PERF_RECORD_* events & perf_sample fields", PERF_RECORD), -DEFINE_SUITE("Parse perf pmu format", pmu), -{ +DEFINE_SUITE("vmlinux symtab matches kallsyms", vmlinux_matches_kallsyms); +DEFINE_SUITE("Detect openat syscall event", openat_syscall_event); +DEFINE_SUITE("Detect openat syscall event on all cpus", openat_syscall_event_on_all_cpus); +DEFINE_SUITE("Read samples using the mmap interface", basic_mmap); +DEFINE_SUITE("Test data source output", mem); +DEFINE_SUITE("Parse event definition strings", parse_events); +DEFINE_SUITE("Simple expression parser", expr); +DEFINE_SUITE("PERF_RECORD_* events & perf_sample fields", PERF_RECORD); +DEFINE_SUITE("Parse perf pmu format", pmu); +static struct test pmu_events = { .desc = "PMU events", .func = test__pmu_events, .subtest = { @@ -61,33 +52,32 @@ DEFINE_SUITE("Parse perf pmu format", pmu), .get_desc = test__pmu_events_subtest_get_desc, .skip_reason = test__pmu_events_subtest_skip_reason, }, - -}, -DEFINE_SUITE("DSO data read", dso_data), -DEFINE_SUITE("DSO data cache", dso_data_cache), -DEFINE_SUITE("DSO data reopen", dso_data_reopen), -DEFINE_SUITE("Roundtrip evsel->name", perf_evsel__roundtrip_name_test), -DEFINE_SUITE("Parse sched tracepoints fields", perf_evsel__tp_sched_test), -DEFINE_SUITE("syscalls:sys_enter_openat event fields", syscall_openat_tp_fields), -DEFINE_SUITE("Setup struct perf_event_attr", attr), -DEFINE_SUITE("Match and link multiple hists", hists_link), -DEFINE_SUITE("'import perf' in python", python_use), -{ +}; +DEFINE_SUITE("DSO data read", dso_data); +DEFINE_SUITE("DSO data cache", dso_data_cache); +DEFINE_SUITE("DSO data reopen", dso_data_reopen); +DEFINE_SUITE("Roundtrip evsel->name", perf_evsel__roundtrip_name_test); +DEFINE_SUITE("Parse sched tracepoints fields", perf_evsel__tp_sched_test); +DEFINE_SUITE("syscalls:sys_enter_openat event fields", syscall_openat_tp_fields); +DEFINE_SUITE("Setup struct perf_event_attr", attr); +DEFINE_SUITE("Match and link multiple hists", hists_link); +DEFINE_SUITE("'import perf' in python", python_use); +static struct test bp_signal = { .desc = "Breakpoint overflow signal handler", .func = test__bp_signal, .is_supported = test__bp_signal_is_supported, -}, -{ +}; +static struct test bp_signal_overflow = { .desc = "Breakpoint overflow sampling", .func = test__bp_signal_overflow, .is_supported = test__bp_signal_is_supported, -}, -{ +}; +static struct test bp_accounting = { .desc = "Breakpoint accounting", .func = test__bp_accounting, .is_supported = test__bp_account_is_supported, -}, -{ +}; +static struct test wp = { .desc = "Watchpoint", .func = test__wp, .is_supported = test__wp_is_supported, @@ -97,24 +87,24 @@ DEFINE_SUITE("'import perf' in python", python_use), .get_desc = test__wp_subtest_get_desc, .skip_reason = test__wp_subtest_skip_reason, }, -}, -DEFINE_SUITE("Number of exit events of a simple workload", task_exit), -DEFINE_SUITE("Software clock events period values", sw_clock_freq), -DEFINE_SUITE("Object code reading", code_reading), -DEFINE_SUITE("Sample parsing", sample_parsing), -DEFINE_SUITE("Use a dummy software event to keep tracking", keep_tracking), -DEFINE_SUITE("Parse with no sample_id_all bit set", parse_no_sample_id_all), -DEFINE_SUITE("Filter hist entries", hists_filter), -DEFINE_SUITE("Lookup mmap thread", mmap_thread_lookup), -DEFINE_SUITE("Share thread maps", thread_maps_share), -DEFINE_SUITE("Sort output of hist entries", hists_output), -DEFINE_SUITE("Cumulate child hist entries", hists_cumulate), -DEFINE_SUITE("Track with sched_switch", switch_tracking), -DEFINE_SUITE("Filter fds with revents mask in a fdarray", fdarray__filter), -DEFINE_SUITE("Add fd to a fdarray, making it autogrow", fdarray__add), -DEFINE_SUITE("kmod_path__parse", kmod_path__parse), -DEFINE_SUITE("Thread map", thread_map), -{ +}; +DEFINE_SUITE("Number of exit events of a simple workload", task_exit); +DEFINE_SUITE("Software clock events period values", sw_clock_freq); +DEFINE_SUITE("Object code reading", code_reading); +DEFINE_SUITE("Sample parsing", sample_parsing); +DEFINE_SUITE("Use a dummy software event to keep tracking", keep_tracking); +DEFINE_SUITE("Parse with no sample_id_all bit set", parse_no_sample_id_all); +DEFINE_SUITE("Filter hist entries", hists_filter); +DEFINE_SUITE("Lookup mmap thread", mmap_thread_lookup); +DEFINE_SUITE("Share thread maps", thread_maps_share); +DEFINE_SUITE("Sort output of hist entries", hists_output); +DEFINE_SUITE("Cumulate child hist entries", hists_cumulate); +DEFINE_SUITE("Track with sched_switch", switch_tracking); +DEFINE_SUITE("Filter fds with revents mask in a fdarray", fdarray__filter); +DEFINE_SUITE("Add fd to a fdarray, making it autogrow", fdarray__add); +DEFINE_SUITE("kmod_path__parse", kmod_path__parse); +DEFINE_SUITE("Thread map", thread_map); +static struct test llvm = { .desc = "LLVM search and compile", .func = test__llvm, .subtest = { @@ -122,9 +112,9 @@ DEFINE_SUITE("Thread map", thread_map), .get_nr = test__llvm_subtest_get_nr, .get_desc = test__llvm_subtest_get_desc, }, -}, -DEFINE_SUITE("Session topology", session_topology), -{ +}; +DEFINE_SUITE("Session topology", session_topology); +static struct test bpf = { .desc = "BPF filter", .func = test__bpf, .subtest = { @@ -132,23 +122,23 @@ DEFINE_SUITE("Session topology", session_topology), .get_nr = test__bpf_subtest_get_nr, .get_desc = test__bpf_subtest_get_desc, }, -}, -DEFINE_SUITE("Synthesize thread map", thread_map_synthesize), -DEFINE_SUITE("Remove thread map", thread_map_remove), -DEFINE_SUITE("Synthesize cpu map", cpu_map_synthesize), -DEFINE_SUITE("Synthesize stat config", synthesize_stat_config), -DEFINE_SUITE("Synthesize stat", synthesize_stat), -DEFINE_SUITE("Synthesize stat round", synthesize_stat_round), -DEFINE_SUITE("Synthesize attr update", event_update), -DEFINE_SUITE("Event times", event_times), -DEFINE_SUITE("Read backward ring buffer", backward_ring_buffer), -DEFINE_SUITE("Print cpu map", cpu_map_print), -DEFINE_SUITE("Merge cpu map", cpu_map_merge), -DEFINE_SUITE("Probe SDT events", sdt_event), -DEFINE_SUITE("is_printable_array", is_printable_array), -DEFINE_SUITE("Print bitmap", bitmap_print), -DEFINE_SUITE("perf hooks", perf_hooks), -{ +}; +DEFINE_SUITE("Synthesize thread map", thread_map_synthesize); +DEFINE_SUITE("Remove thread map", thread_map_remove); +DEFINE_SUITE("Synthesize cpu map", cpu_map_synthesize); +DEFINE_SUITE("Synthesize stat config", synthesize_stat_config); +DEFINE_SUITE("Synthesize stat", synthesize_stat); +DEFINE_SUITE("Synthesize stat round", synthesize_stat_round); +DEFINE_SUITE("Synthesize attr update", event_update); +DEFINE_SUITE("Event times", event_times); +DEFINE_SUITE("Read backward ring buffer", backward_ring_buffer); +DEFINE_SUITE("Print cpu map", cpu_map_print); +DEFINE_SUITE("Merge cpu map", cpu_map_merge); +DEFINE_SUITE("Probe SDT events", sdt_event); +DEFINE_SUITE("is_printable_array", is_printable_array); +DEFINE_SUITE("Print bitmap", bitmap_print); +DEFINE_SUITE("perf hooks", perf_hooks); +static struct test clang = { .desc = "builtin clang support", .func = test__clang, .subtest = { @@ -156,12 +146,12 @@ DEFINE_SUITE("perf hooks", perf_hooks), .get_nr = test__clang_subtest_get_nr, .get_desc = test__clang_subtest_get_desc, } -}, -DEFINE_SUITE("unit_number__scnprintf", unit_number__scnprint), -DEFINE_SUITE("mem2node", mem2node), -DEFINE_SUITE("time utils", time_utils), -DEFINE_SUITE("Test jit_write_elf", jit_write_elf), -{ +}; +DEFINE_SUITE("unit_number__scnprintf", unit_number__scnprint); +DEFINE_SUITE("mem2node", mem2node); +DEFINE_SUITE("time utils", time_utils); +DEFINE_SUITE("Test jit_write_elf", jit_write_elf); +static struct test pfm = { .desc = "Test libpfm4 support", .func = test__pfm, .subtest = { @@ -169,26 +159,99 @@ DEFINE_SUITE("Test jit_write_elf", jit_write_elf), .get_nr = test__pfm_subtest_get_nr, .get_desc = test__pfm_subtest_get_desc, } -}, -DEFINE_SUITE("Test api io", api_io), -DEFINE_SUITE("maps__merge_in", maps__merge_in), -DEFINE_SUITE("Demangle Java", demangle_java), -DEFINE_SUITE("Demangle OCaml", demangle_ocaml), -DEFINE_SUITE("Parse and process metrics", parse_metric), -DEFINE_SUITE("PE file support", pe_file_parsing), -DEFINE_SUITE("Event expansion for cgroups", expand_cgroup_events), -{ +}; +DEFINE_SUITE("Test api io", api_io); +DEFINE_SUITE("maps__merge_in", maps__merge_in); +DEFINE_SUITE("Demangle Java", demangle_java); +DEFINE_SUITE("Demangle OCaml", demangle_ocaml); +DEFINE_SUITE("Parse and process metrics", parse_metric); +DEFINE_SUITE("PE file support", pe_file_parsing); +DEFINE_SUITE("Event expansion for cgroups", expand_cgroup_events); +static struct test perf_time_to_tsc = { .desc = "Convert perf time to TSC", .func = test__perf_time_to_tsc, .is_supported = test__tsc_is_supported, -}, -DEFINE_SUITE("dlfilter C API", dlfilter), -{ - .func = NULL, -}, +}; +DEFINE_SUITE("dlfilter C API", dlfilter); + + +static struct test *generic_tests[] = { + &vmlinux_matches_kallsyms, + &openat_syscall_event, + &openat_syscall_event_on_all_cpus, + &basic_mmap, + &mem, + &parse_events, + &expr, + &PERF_RECORD, + &pmu, + &pmu_events, + &dso_data, + &dso_data_cache, + &dso_data_reopen, + &perf_evsel__roundtrip_name_test, + &perf_evsel__tp_sched_test, + &syscall_openat_tp_fields, + &attr, + &hists_link, + &python_use, + &bp_signal, + &bp_signal_overflow, + &bp_accounting, + &wp, + &task_exit, + &sw_clock_freq, + &code_reading, + &sample_parsing, + &keep_tracking, + &parse_no_sample_id_all, + &hists_filter, + &mmap_thread_lookup, + &thread_maps_share, + &hists_output, + &hists_cumulate, + &switch_tracking, + &fdarray__filter, + &fdarray__add, + &kmod_path__parse, + &thread_map, + &llvm, + &session_topology, + &bpf, + &thread_map_synthesize, + &thread_map_remove, + &cpu_map_synthesize, + &synthesize_stat_config, + &synthesize_stat, + &synthesize_stat_round, + &event_update, + &event_times, + &backward_ring_buffer, + &cpu_map_print, + &cpu_map_merge, + &sdt_event, + &is_printable_array, + &bitmap_print, + &perf_hooks, + &clang, + &unit_number__scnprint, + &mem2node, + &time_utils, + &jit_write_elf, + &pfm, + &api_io, + &maps__merge_in, + &demangle_java, + &demangle_ocaml, + &parse_metric, + &pe_file_parsing, + &expand_cgroup_events, + &perf_time_to_tsc, + &dlfilter, + NULL, }; -static struct test *tests[] = { +static struct test **tests[] = { generic_tests, arch_tests, }; @@ -269,9 +332,9 @@ static int run_test(struct test *test, int subtest) return err; } -#define for_each_test(j, t) \ +#define for_each_test(j, k, t) \ for (j = 0; j < ARRAY_SIZE(tests); j++) \ - for (t = &tests[j][0]; t->func; t++) + for (k = 0, t = tests[j][k]; tests[j][k]; k++, t = tests[j][k]) static int test_and_print(struct test *t, bool force_skip, int subtest) { @@ -470,18 +533,18 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width, static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) { struct test *t; - unsigned int j; + unsigned int j, k; int i = 0; int width = shell_tests__max_desc_width(); - for_each_test(j, t) { + for_each_test(j, k, t) { int len = strlen(t->desc); if (width < len) width = len; } - for_each_test(j, t) { + for_each_test(j, k, t) { int curr = i++, err; int subi; @@ -597,11 +660,11 @@ static int perf_test__list_shell(int argc, const char **argv, int i) static int perf_test__list(int argc, const char **argv) { - unsigned int j; + unsigned int j, k; struct test *t; int i = 0; - for_each_test(j, t) { + for_each_test(j, k, t) { int curr = i++; if (!perf_test__matches(t->desc, curr, argc, argv) || diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index c756284b3b13..38f16a53613f 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -195,7 +195,7 @@ NO_TAIL_CALL_ATTRIBUTE noinline int test_dwarf_unwind__krava_1(struct thread *th return ret; } -int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine *machine; struct thread *thread; @@ -237,3 +237,8 @@ int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __maybe_unu machine__delete(machine); return err; } + +struct test dwarf_unwind = { + .desc = "Test dwarf unwind", + .func = test__dwarf_unwind, +}; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 0846f66d67f9..8323a3c88284 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -43,6 +43,12 @@ struct test { #define DECLARE_SUITE(name) \ int test__##name(struct test *test, int subtest) +#define DEFINE_SUITE(description, name) \ + static struct test name = { \ + .desc = description, \ + .func = test__##name, \ + } + /* Tests */ DECLARE_SUITE(vmlinux_matches_kallsyms); DECLARE_SUITE(openat_syscall_event); @@ -78,7 +84,7 @@ DECLARE_SUITE(code_reading); DECLARE_SUITE(sample_parsing); DECLARE_SUITE(keep_tracking); DECLARE_SUITE(parse_no_sample_id_all); -DECLARE_SUITE(dwarf_unwind); +extern struct test dwarf_unwind; DECLARE_SUITE(expr); DECLARE_SUITE(hists_filter); DECLARE_SUITE(mmap_thread_lookup); -- cgit v1.2.3 From d68f0365087395fe232e39ac9c8ee53627522c3c Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:50 -0700 Subject: perf test: Move each test suite struct to its test Rather than export test functions, export the test struct. Rename with a suite__ prefix to avoid name collisions. Committer notes: Its '&suite__vectors_page', not '&suite__vectors_pages', noticed when cross building to arm (32-bit). Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/tests/arch-tests.c | 4 +- tools/perf/arch/arm64/tests/arch-tests.c | 2 +- tools/perf/arch/powerpc/tests/arch-tests.c | 2 +- tools/perf/arch/x86/tests/arch-tests.c | 12 +- tools/perf/tests/api-io.c | 6 +- tools/perf/tests/attr.c | 4 +- tools/perf/tests/backward-ring-buffer.c | 4 +- tools/perf/tests/bitmap.c | 4 +- tools/perf/tests/bp_account.c | 10 +- tools/perf/tests/bp_signal.c | 8 +- tools/perf/tests/bp_signal_overflow.c | 8 +- tools/perf/tests/bpf.c | 22 ++- tools/perf/tests/builtin-test.c | 285 +++++++--------------------- tools/perf/tests/clang.c | 18 +- tools/perf/tests/code-reading.c | 4 +- tools/perf/tests/cpumap.c | 10 +- tools/perf/tests/demangle-java-test.c | 4 +- tools/perf/tests/demangle-ocaml-test.c | 4 +- tools/perf/tests/dlfilter-test.c | 4 +- tools/perf/tests/dso-data.c | 10 +- tools/perf/tests/dwarf-unwind.c | 5 +- tools/perf/tests/event-times.c | 4 +- tools/perf/tests/event_update.c | 4 +- tools/perf/tests/evsel-roundtrip-name.c | 5 +- tools/perf/tests/evsel-tp-sched.c | 5 +- tools/perf/tests/expand-cgroup.c | 6 +- tools/perf/tests/expr.c | 4 +- tools/perf/tests/fdarray.c | 7 +- tools/perf/tests/genelf.c | 6 +- tools/perf/tests/hists_cumulate.c | 4 +- tools/perf/tests/hists_filter.c | 4 +- tools/perf/tests/hists_link.c | 4 +- tools/perf/tests/hists_output.c | 4 +- tools/perf/tests/is_printable_array.c | 4 +- tools/perf/tests/keep-tracking.c | 4 +- tools/perf/tests/kmod-path.c | 4 +- tools/perf/tests/llvm.c | 22 ++- tools/perf/tests/maps.c | 4 +- tools/perf/tests/mem.c | 4 +- tools/perf/tests/mem2node.c | 4 +- tools/perf/tests/mmap-basic.c | 4 +- tools/perf/tests/mmap-thread-lookup.c | 4 +- tools/perf/tests/openat-syscall-all-cpus.c | 5 +- tools/perf/tests/openat-syscall-tp-fields.c | 5 +- tools/perf/tests/openat-syscall.c | 5 +- tools/perf/tests/parse-events.c | 4 +- tools/perf/tests/parse-metric.c | 4 +- tools/perf/tests/parse-no-sample-id-all.c | 5 +- tools/perf/tests/pe-file-parsing.c | 6 +- tools/perf/tests/perf-hooks.c | 4 +- tools/perf/tests/perf-record.c | 4 +- tools/perf/tests/perf-time-to-tsc.c | 10 +- tools/perf/tests/pfm.c | 16 +- tools/perf/tests/pmu-events.c | 19 +- tools/perf/tests/pmu.c | 4 +- tools/perf/tests/python-use.c | 4 +- tools/perf/tests/sample-parsing.c | 4 +- tools/perf/tests/sdt.c | 6 +- tools/perf/tests/stat.c | 11 +- tools/perf/tests/sw-clock.c | 4 +- tools/perf/tests/switch-tracking.c | 4 +- tools/perf/tests/task-exit.c | 4 +- tools/perf/tests/tests.h | 23 +-- tools/perf/tests/thread-map.c | 10 +- tools/perf/tests/thread-maps-share.c | 4 +- tools/perf/tests/time-utils-test.c | 4 +- tools/perf/tests/topology.c | 4 +- tools/perf/tests/unit_number__scnprintf.c | 4 +- tools/perf/tests/vmlinux-kallsyms.c | 5 +- tools/perf/tests/wp.c | 22 ++- 70 files changed, 397 insertions(+), 348 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/arch/arm/tests/arch-tests.c b/tools/perf/arch/arm/tests/arch-tests.c index 8276740f7ff8..2495b5770637 100644 --- a/tools/perf/arch/arm/tests/arch-tests.c +++ b/tools/perf/arch/arm/tests/arch-tests.c @@ -5,8 +5,8 @@ struct test *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT - &dwarf_unwind, + &suite__dwarf_unwind, #endif - &vectors_page, + &suite__vectors_page, NULL, }; diff --git a/tools/perf/arch/arm64/tests/arch-tests.c b/tools/perf/arch/arm64/tests/arch-tests.c index bc327048b807..6d137138a2de 100644 --- a/tools/perf/arch/arm64/tests/arch-tests.c +++ b/tools/perf/arch/arm64/tests/arch-tests.c @@ -5,7 +5,7 @@ struct test *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT - &dwarf_unwind, + &suite__dwarf_unwind, #endif NULL, }; diff --git a/tools/perf/arch/powerpc/tests/arch-tests.c b/tools/perf/arch/powerpc/tests/arch-tests.c index bc327048b807..6d137138a2de 100644 --- a/tools/perf/arch/powerpc/tests/arch-tests.c +++ b/tools/perf/arch/powerpc/tests/arch-tests.c @@ -5,7 +5,7 @@ struct test *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT - &dwarf_unwind, + &suite__dwarf_unwind, #endif NULL, }; diff --git a/tools/perf/arch/x86/tests/arch-tests.c b/tools/perf/arch/x86/tests/arch-tests.c index f5e3195768a4..20b1c0d8ca66 100644 --- a/tools/perf/arch/x86/tests/arch-tests.c +++ b/tools/perf/arch/x86/tests/arch-tests.c @@ -14,17 +14,17 @@ DEFINE_SUITE("x86 bp modify", bp_modify); DEFINE_SUITE("x86 Sample parsing", x86_sample_parsing); struct test *arch_tests[] = { - &rdpmc, + &suite__rdpmc, #ifdef HAVE_DWARF_UNWIND_SUPPORT - &dwarf_unwind, + &suite__dwarf_unwind, #endif #ifdef HAVE_AUXTRACE_SUPPORT - &insn_x86, - &intel_pt_pkt_decoder, + &suite__insn_x86, + &suite__intel_pt_pkt_decoder, #endif #if defined(__x86_64__) - &bp_modify, + &suite__bp_modify, #endif - &x86_sample_parsing, + &suite__x86_sample_parsing, NULL, }; diff --git a/tools/perf/tests/api-io.c b/tools/perf/tests/api-io.c index 2ada86ad6084..af4913967514 100644 --- a/tools/perf/tests/api-io.c +++ b/tools/perf/tests/api-io.c @@ -289,8 +289,8 @@ static int test_get_dec(void) return ret; } -int test__api_io(struct test *test __maybe_unused, - int subtest __maybe_unused) +static int test__api_io(struct test *test __maybe_unused, + int subtest __maybe_unused) { int ret = 0; @@ -302,3 +302,5 @@ int test__api_io(struct test *test __maybe_unused, ret = TEST_FAIL; return ret; } + +DEFINE_SUITE("Test api io", api_io); diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 9b40a25376ae..f1461051f579 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -178,7 +178,7 @@ static int run_dir(const char *d, const char *perf) return system(cmd) ? TEST_FAIL : TEST_OK; } -int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused) { struct stat st; char path_perf[PATH_MAX]; @@ -207,3 +207,5 @@ int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused) return TEST_SKIP; } + +DEFINE_SUITE("Setup struct perf_event_attr", attr); diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 7447a4478991..131903a2054d 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -82,7 +82,7 @@ static int do_test(struct evlist *evlist, int mmap_pages, } -int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; char pid[16], sbuf[STRERR_BUFSIZE]; @@ -167,3 +167,5 @@ out_delete_evlist: evlist__delete(evlist); return ret; } + +DEFINE_SUITE("Read backward ring buffer", backward_ring_buffer); diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 12b805efdca0..13d1d1d6774f 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -40,7 +40,7 @@ static int test_bitmap(const char *str) return ret; } -int test__bitmap_print(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__bitmap_print(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to convert map", test_bitmap("1")); TEST_ASSERT_VAL("failed to convert map", test_bitmap("1,5")); @@ -51,3 +51,5 @@ int test__bitmap_print(struct test *test __maybe_unused, int subtest __maybe_unu TEST_ASSERT_VAL("failed to convert map", test_bitmap("1-10,12-20,22-30,32-40")); return 0; } + +DEFINE_SUITE("Print bitmap", bitmap_print); diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c index 489b50604cf2..76cf356ba13f 100644 --- a/tools/perf/tests/bp_account.c +++ b/tools/perf/tests/bp_account.c @@ -173,7 +173,7 @@ static int detect_share(int wp_cnt, int bp_cnt) * we create another watchpoint to ensure * the slot accounting is correct */ -int test__bp_accounting(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__bp_accounting(struct test *test __maybe_unused, int subtest __maybe_unused) { int has_ioctl = detect_ioctl(); int wp_cnt = detect_cnt(false); @@ -189,7 +189,7 @@ int test__bp_accounting(struct test *test __maybe_unused, int subtest __maybe_un return bp_accounting(wp_cnt, share); } -bool test__bp_account_is_supported(void) +static bool test__bp_account_is_supported(void) { /* * PowerPC and S390 do not support creation of instruction @@ -204,3 +204,9 @@ bool test__bp_account_is_supported(void) return true; #endif } + +struct test suite__bp_accounting = { + .desc = "Breakpoint accounting", + .func = test__bp_accounting, + .is_supported = test__bp_account_is_supported, +}; diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index ef37353636d8..c19b05488cfb 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -161,7 +161,7 @@ static long long bp_count(int fd) return count; } -int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unused) { struct sigaction sa; long long count1, count2, count3; @@ -311,3 +311,9 @@ bool test__bp_signal_is_supported(void) return true; #endif } + +struct test suite__bp_signal = { + .desc = "Breakpoint overflow signal handler", + .func = test__bp_signal, + .is_supported = test__bp_signal_is_supported, +}; diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index eb4dbbddf4ff..99c30d028f5e 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c @@ -59,7 +59,7 @@ static long long bp_count(int fd) #define EXECUTIONS 10000 #define THRESHOLD 100 -int test__bp_signal_overflow(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__bp_signal_overflow(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_event_attr pe; struct sigaction sa; @@ -133,3 +133,9 @@ int test__bp_signal_overflow(struct test *test __maybe_unused, int subtest __may return fails ? TEST_FAIL : TEST_OK; } + +struct test suite__bp_signal_overflow = { + .desc = "Breakpoint overflow sampling", + .func = test__bp_signal_overflow, + .is_supported = test__bp_signal_is_supported, +}; diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 2bf146e49ce8..3f936864d0ee 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -283,12 +283,12 @@ out: return ret; } -int test__bpf_subtest_get_nr(void) +static int test__bpf_subtest_get_nr(void) { return (int)ARRAY_SIZE(bpf_testcase_table); } -const char *test__bpf_subtest_get_desc(int i) +static const char *test__bpf_subtest_get_desc(int i) { if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table)) return NULL; @@ -325,7 +325,7 @@ static int check_env(void) return 0; } -int test__bpf(struct test *test __maybe_unused, int i) +static int test__bpf(struct test *test __maybe_unused, int i) { int err; @@ -345,19 +345,29 @@ int test__bpf(struct test *test __maybe_unused, int i) } #else -int test__bpf_subtest_get_nr(void) +static int test__bpf_subtest_get_nr(void) { return 0; } -const char *test__bpf_subtest_get_desc(int i __maybe_unused) +static const char *test__bpf_subtest_get_desc(int i __maybe_unused) { return NULL; } -int test__bpf(struct test *test __maybe_unused, int i __maybe_unused) +static int test__bpf(struct test *test __maybe_unused, int i __maybe_unused) { pr_debug("Skip BPF test because BPF support is not compiled\n"); return TEST_SKIP; } #endif + +struct test suite__bpf = { + .desc = "BPF filter", + .func = test__bpf, + .subtest = { + .skip_if_fail = true, + .get_nr = test__bpf_subtest_get_nr, + .get_desc = test__bpf_subtest_get_desc, + }, +}; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index b2cbc12a70a2..07467ec43100 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -34,220 +34,79 @@ struct test *__weak arch_tests[] = { NULL, }; -DEFINE_SUITE("vmlinux symtab matches kallsyms", vmlinux_matches_kallsyms); -DEFINE_SUITE("Detect openat syscall event", openat_syscall_event); -DEFINE_SUITE("Detect openat syscall event on all cpus", openat_syscall_event_on_all_cpus); -DEFINE_SUITE("Read samples using the mmap interface", basic_mmap); -DEFINE_SUITE("Test data source output", mem); -DEFINE_SUITE("Parse event definition strings", parse_events); -DEFINE_SUITE("Simple expression parser", expr); -DEFINE_SUITE("PERF_RECORD_* events & perf_sample fields", PERF_RECORD); -DEFINE_SUITE("Parse perf pmu format", pmu); -static struct test pmu_events = { - .desc = "PMU events", - .func = test__pmu_events, - .subtest = { - .skip_if_fail = false, - .get_nr = test__pmu_events_subtest_get_nr, - .get_desc = test__pmu_events_subtest_get_desc, - .skip_reason = test__pmu_events_subtest_skip_reason, - }, -}; -DEFINE_SUITE("DSO data read", dso_data); -DEFINE_SUITE("DSO data cache", dso_data_cache); -DEFINE_SUITE("DSO data reopen", dso_data_reopen); -DEFINE_SUITE("Roundtrip evsel->name", perf_evsel__roundtrip_name_test); -DEFINE_SUITE("Parse sched tracepoints fields", perf_evsel__tp_sched_test); -DEFINE_SUITE("syscalls:sys_enter_openat event fields", syscall_openat_tp_fields); -DEFINE_SUITE("Setup struct perf_event_attr", attr); -DEFINE_SUITE("Match and link multiple hists", hists_link); -DEFINE_SUITE("'import perf' in python", python_use); -static struct test bp_signal = { - .desc = "Breakpoint overflow signal handler", - .func = test__bp_signal, - .is_supported = test__bp_signal_is_supported, -}; -static struct test bp_signal_overflow = { - .desc = "Breakpoint overflow sampling", - .func = test__bp_signal_overflow, - .is_supported = test__bp_signal_is_supported, -}; -static struct test bp_accounting = { - .desc = "Breakpoint accounting", - .func = test__bp_accounting, - .is_supported = test__bp_account_is_supported, -}; -static struct test wp = { - .desc = "Watchpoint", - .func = test__wp, - .is_supported = test__wp_is_supported, - .subtest = { - .skip_if_fail = false, - .get_nr = test__wp_subtest_get_nr, - .get_desc = test__wp_subtest_get_desc, - .skip_reason = test__wp_subtest_skip_reason, - }, -}; -DEFINE_SUITE("Number of exit events of a simple workload", task_exit); -DEFINE_SUITE("Software clock events period values", sw_clock_freq); -DEFINE_SUITE("Object code reading", code_reading); -DEFINE_SUITE("Sample parsing", sample_parsing); -DEFINE_SUITE("Use a dummy software event to keep tracking", keep_tracking); -DEFINE_SUITE("Parse with no sample_id_all bit set", parse_no_sample_id_all); -DEFINE_SUITE("Filter hist entries", hists_filter); -DEFINE_SUITE("Lookup mmap thread", mmap_thread_lookup); -DEFINE_SUITE("Share thread maps", thread_maps_share); -DEFINE_SUITE("Sort output of hist entries", hists_output); -DEFINE_SUITE("Cumulate child hist entries", hists_cumulate); -DEFINE_SUITE("Track with sched_switch", switch_tracking); -DEFINE_SUITE("Filter fds with revents mask in a fdarray", fdarray__filter); -DEFINE_SUITE("Add fd to a fdarray, making it autogrow", fdarray__add); -DEFINE_SUITE("kmod_path__parse", kmod_path__parse); -DEFINE_SUITE("Thread map", thread_map); -static struct test llvm = { - .desc = "LLVM search and compile", - .func = test__llvm, - .subtest = { - .skip_if_fail = true, - .get_nr = test__llvm_subtest_get_nr, - .get_desc = test__llvm_subtest_get_desc, - }, -}; -DEFINE_SUITE("Session topology", session_topology); -static struct test bpf = { - .desc = "BPF filter", - .func = test__bpf, - .subtest = { - .skip_if_fail = true, - .get_nr = test__bpf_subtest_get_nr, - .get_desc = test__bpf_subtest_get_desc, - }, -}; -DEFINE_SUITE("Synthesize thread map", thread_map_synthesize); -DEFINE_SUITE("Remove thread map", thread_map_remove); -DEFINE_SUITE("Synthesize cpu map", cpu_map_synthesize); -DEFINE_SUITE("Synthesize stat config", synthesize_stat_config); -DEFINE_SUITE("Synthesize stat", synthesize_stat); -DEFINE_SUITE("Synthesize stat round", synthesize_stat_round); -DEFINE_SUITE("Synthesize attr update", event_update); -DEFINE_SUITE("Event times", event_times); -DEFINE_SUITE("Read backward ring buffer", backward_ring_buffer); -DEFINE_SUITE("Print cpu map", cpu_map_print); -DEFINE_SUITE("Merge cpu map", cpu_map_merge); -DEFINE_SUITE("Probe SDT events", sdt_event); -DEFINE_SUITE("is_printable_array", is_printable_array); -DEFINE_SUITE("Print bitmap", bitmap_print); -DEFINE_SUITE("perf hooks", perf_hooks); -static struct test clang = { - .desc = "builtin clang support", - .func = test__clang, - .subtest = { - .skip_if_fail = true, - .get_nr = test__clang_subtest_get_nr, - .get_desc = test__clang_subtest_get_desc, - } -}; -DEFINE_SUITE("unit_number__scnprintf", unit_number__scnprint); -DEFINE_SUITE("mem2node", mem2node); -DEFINE_SUITE("time utils", time_utils); -DEFINE_SUITE("Test jit_write_elf", jit_write_elf); -static struct test pfm = { - .desc = "Test libpfm4 support", - .func = test__pfm, - .subtest = { - .skip_if_fail = true, - .get_nr = test__pfm_subtest_get_nr, - .get_desc = test__pfm_subtest_get_desc, - } -}; -DEFINE_SUITE("Test api io", api_io); -DEFINE_SUITE("maps__merge_in", maps__merge_in); -DEFINE_SUITE("Demangle Java", demangle_java); -DEFINE_SUITE("Demangle OCaml", demangle_ocaml); -DEFINE_SUITE("Parse and process metrics", parse_metric); -DEFINE_SUITE("PE file support", pe_file_parsing); -DEFINE_SUITE("Event expansion for cgroups", expand_cgroup_events); -static struct test perf_time_to_tsc = { - .desc = "Convert perf time to TSC", - .func = test__perf_time_to_tsc, - .is_supported = test__tsc_is_supported, -}; -DEFINE_SUITE("dlfilter C API", dlfilter); - - static struct test *generic_tests[] = { - &vmlinux_matches_kallsyms, - &openat_syscall_event, - &openat_syscall_event_on_all_cpus, - &basic_mmap, - &mem, - &parse_events, - &expr, - &PERF_RECORD, - &pmu, - &pmu_events, - &dso_data, - &dso_data_cache, - &dso_data_reopen, - &perf_evsel__roundtrip_name_test, - &perf_evsel__tp_sched_test, - &syscall_openat_tp_fields, - &attr, - &hists_link, - &python_use, - &bp_signal, - &bp_signal_overflow, - &bp_accounting, - &wp, - &task_exit, - &sw_clock_freq, - &code_reading, - &sample_parsing, - &keep_tracking, - &parse_no_sample_id_all, - &hists_filter, - &mmap_thread_lookup, - &thread_maps_share, - &hists_output, - &hists_cumulate, - &switch_tracking, - &fdarray__filter, - &fdarray__add, - &kmod_path__parse, - &thread_map, - &llvm, - &session_topology, - &bpf, - &thread_map_synthesize, - &thread_map_remove, - &cpu_map_synthesize, - &synthesize_stat_config, - &synthesize_stat, - &synthesize_stat_round, - &event_update, - &event_times, - &backward_ring_buffer, - &cpu_map_print, - &cpu_map_merge, - &sdt_event, - &is_printable_array, - &bitmap_print, - &perf_hooks, - &clang, - &unit_number__scnprint, - &mem2node, - &time_utils, - &jit_write_elf, - &pfm, - &api_io, - &maps__merge_in, - &demangle_java, - &demangle_ocaml, - &parse_metric, - &pe_file_parsing, - &expand_cgroup_events, - &perf_time_to_tsc, - &dlfilter, + &suite__vmlinux_matches_kallsyms, + &suite__openat_syscall_event, + &suite__openat_syscall_event_on_all_cpus, + &suite__basic_mmap, + &suite__mem, + &suite__parse_events, + &suite__expr, + &suite__PERF_RECORD, + &suite__pmu, + &suite__pmu_events, + &suite__dso_data, + &suite__dso_data_cache, + &suite__dso_data_reopen, + &suite__perf_evsel__roundtrip_name_test, + &suite__perf_evsel__tp_sched_test, + &suite__syscall_openat_tp_fields, + &suite__attr, + &suite__hists_link, + &suite__python_use, + &suite__bp_signal, + &suite__bp_signal_overflow, + &suite__bp_accounting, + &suite__wp, + &suite__task_exit, + &suite__sw_clock_freq, + &suite__code_reading, + &suite__sample_parsing, + &suite__keep_tracking, + &suite__parse_no_sample_id_all, + &suite__hists_filter, + &suite__mmap_thread_lookup, + &suite__thread_maps_share, + &suite__hists_output, + &suite__hists_cumulate, + &suite__switch_tracking, + &suite__fdarray__filter, + &suite__fdarray__add, + &suite__kmod_path__parse, + &suite__thread_map, + &suite__llvm, + &suite__session_topology, + &suite__bpf, + &suite__thread_map_synthesize, + &suite__thread_map_remove, + &suite__cpu_map_synthesize, + &suite__synthesize_stat_config, + &suite__synthesize_stat, + &suite__synthesize_stat_round, + &suite__event_update, + &suite__event_times, + &suite__backward_ring_buffer, + &suite__cpu_map_print, + &suite__cpu_map_merge, + &suite__sdt_event, + &suite__is_printable_array, + &suite__bitmap_print, + &suite__perf_hooks, + &suite__clang, + &suite__unit_number__scnprint, + &suite__mem2node, + &suite__time_utils, + &suite__jit_write_elf, + &suite__pfm, + &suite__api_io, + &suite__maps__merge_in, + &suite__demangle_java, + &suite__demangle_ocaml, + &suite__parse_metric, + &suite__pe_file_parsing, + &suite__expand_cgroup_events, + &suite__perf_time_to_tsc, + &suite__dlfilter, NULL, }; diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index 2577d3ed1531..5052be1b5b20 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -19,12 +19,12 @@ static struct { #endif }; -int test__clang_subtest_get_nr(void) +static int test__clang_subtest_get_nr(void) { return (int)ARRAY_SIZE(clang_testcase_table); } -const char *test__clang_subtest_get_desc(int i) +static const char *test__clang_subtest_get_desc(int i) { if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) return NULL; @@ -32,15 +32,25 @@ const char *test__clang_subtest_get_desc(int i) } #ifndef HAVE_LIBCLANGLLVM_SUPPORT -int test__clang(struct test *test __maybe_unused, int i __maybe_unused) +static int test__clang(struct test *test __maybe_unused, int i __maybe_unused) { return TEST_SKIP; } #else -int test__clang(struct test *test __maybe_unused, int i) +static int test__clang(struct test *test __maybe_unused, int i) { if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) return TEST_FAIL; return clang_testcase_table[i].func(); } #endif + +struct test suite__clang = { + .desc = "builtin clang support", + .func = test__clang, + .subtest = { + .skip_if_fail = true, + .get_nr = test__clang_subtest_get_nr, + .get_desc = test__clang_subtest_get_desc, + } +}; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index f439bd49da19..e4199cb4d4bf 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -716,7 +716,7 @@ out_err: return err; } -int test__code_reading(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__code_reading(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret; @@ -743,3 +743,5 @@ int test__code_reading(struct test *test __maybe_unused, int subtest __maybe_unu return -1; }; } + +DEFINE_SUITE("Object code reading", code_reading); diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 0472b110fe65..6f2525fb9fd7 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -75,7 +75,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, } -int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_cpu_map *cpus; @@ -111,7 +111,7 @@ static int cpu_map_print(const char *str) return !strcmp(buf, str); } -int test__cpu_map_print(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__cpu_map_print(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1")); TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5")); @@ -123,7 +123,7 @@ int test__cpu_map_print(struct test *test __maybe_unused, int subtest __maybe_un return 0; } -int test__cpu_map_merge(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__cpu_map_merge(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_cpu_map *a = perf_cpu_map__new("4,2,1"); struct perf_cpu_map *b = perf_cpu_map__new("4,5,7"); @@ -137,3 +137,7 @@ int test__cpu_map_merge(struct test *test __maybe_unused, int subtest __maybe_un perf_cpu_map__put(c); return 0; } + +DEFINE_SUITE("Synthesize cpu map", cpu_map_synthesize); +DEFINE_SUITE("Print cpu map", cpu_map_print); +DEFINE_SUITE("Merge cpu map", cpu_map_merge); diff --git a/tools/perf/tests/demangle-java-test.c b/tools/perf/tests/demangle-java-test.c index 8f3b90832fb0..37f488e5c36d 100644 --- a/tools/perf/tests/demangle-java-test.c +++ b/tools/perf/tests/demangle-java-test.c @@ -7,7 +7,7 @@ #include "debug.h" #include "demangle-java.h" -int test__demangle_java(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__demangle_java(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret = TEST_OK; char *buf = NULL; @@ -40,3 +40,5 @@ int test__demangle_java(struct test *test __maybe_unused, int subtest __maybe_un return ret; } + +DEFINE_SUITE("Demangle Java", demangle_java); diff --git a/tools/perf/tests/demangle-ocaml-test.c b/tools/perf/tests/demangle-ocaml-test.c index 0043be812355..ee982cca7bbf 100644 --- a/tools/perf/tests/demangle-ocaml-test.c +++ b/tools/perf/tests/demangle-ocaml-test.c @@ -7,7 +7,7 @@ #include "debug.h" #include "demangle-ocaml.h" -int test__demangle_ocaml(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__demangle_ocaml(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret = TEST_OK; char *buf = NULL; @@ -41,3 +41,5 @@ int test__demangle_ocaml(struct test *test __maybe_unused, int subtest __maybe_u return ret; } + +DEFINE_SUITE("Demangle OCaml", demangle_ocaml); diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c index bc03b5df6828..378f5afc6032 100644 --- a/tools/perf/tests/dlfilter-test.c +++ b/tools/perf/tests/dlfilter-test.c @@ -398,7 +398,7 @@ static void test_data__free(struct test_data *td) } } -int test__dlfilter(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dlfilter(struct test *test __maybe_unused, int subtest __maybe_unused) { struct test_data td = {.fd = -1}; int pid = getpid(); @@ -414,3 +414,5 @@ int test__dlfilter(struct test *test __maybe_unused, int subtest __maybe_unused) test_data__free(&td); return err; } + +DEFINE_SUITE("dlfilter C API", dlfilter); diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 43e1b01e5afc..d9e060a7c1f6 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -113,7 +113,7 @@ static int dso__data_fd(struct dso *dso, struct machine *machine) return fd; } -int test__dso_data(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dso_data(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; struct dso *dso; @@ -248,7 +248,7 @@ static int set_fd_limit(int n) return setrlimit(RLIMIT_NOFILE, &rlim); } -int test__dso_data_cache(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dso_data_cache(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; long nr_end, nr = open_files_cnt(); @@ -318,7 +318,7 @@ static long new_limit(int count) return ret; } -int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; long nr_end, nr = open_files_cnt(), lim = new_limit(3); @@ -393,3 +393,7 @@ int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_ TEST_ASSERT_VAL("failed leaking files", nr == nr_end); return 0; } + +DEFINE_SUITE("DSO data read", dso_data); +DEFINE_SUITE("DSO data cache", dso_data_cache); +DEFINE_SUITE("DSO data reopen", dso_data_reopen); diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 38f16a53613f..6e0429012ed6 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -238,7 +238,4 @@ static int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __ma return err; } -struct test dwarf_unwind = { - .desc = "Test dwarf unwind", - .func = test__dwarf_unwind, -}; +DEFINE_SUITE("Test dwarf unwind", dwarf_unwind); diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 04ce4401f775..2ce8945931e7 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -216,7 +216,7 @@ out_err: * and checks that enabled and running times * match. */ -int test__event_times(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__event_times(struct test *test __maybe_unused, int subtest __maybe_unused) { int err, ret = 0; @@ -239,3 +239,5 @@ int test__event_times(struct test *test __maybe_unused, int subtest __maybe_unus #undef _T return ret; } + +DEFINE_SUITE("Event times", event_times); diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 44a50527f9d9..9dfb665f8ac9 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -83,7 +83,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, return 0; } -int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unused) { struct evsel *evsel; struct event_name tmp; @@ -123,3 +123,5 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu evlist__delete(evlist); return 0; } + +DEFINE_SUITE("Synthesize attr update", event_update); diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index 4e09f0a312af..82ff3c04d0bd 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -99,7 +99,8 @@ out_delete_evlist: #define perf_evsel__name_array_test(names, distance) \ __perf_evsel__name_array_test(names, ARRAY_SIZE(names), distance) -int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, + int subtest __maybe_unused) { int err = 0, ret = 0; @@ -120,3 +121,5 @@ int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, int return ret; } + +DEFINE_SUITE("Roundtrip evsel->name", perf_evsel__roundtrip_name_test); diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index f9e34bd26cf3..58f17d18e4d5 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -32,7 +32,8 @@ static int evsel__test_field(struct evsel *evsel, const char *name, int size, bo return ret; } -int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, + int subtest __maybe_unused) { struct evsel *evsel = evsel__newtp("sched", "sched_switch"); int ret = 0; @@ -87,3 +88,5 @@ int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtes evsel__delete(evsel); return ret; } + +DEFINE_SUITE("Parse sched tracepoints fields", perf_evsel__tp_sched_test); diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgroup.c index 80cff8a3558c..7bea14f0951e 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -221,8 +221,8 @@ out: return ret; } -int test__expand_cgroup_events(struct test *test __maybe_unused, - int subtest __maybe_unused) +static int test__expand_cgroup_events(struct test *test __maybe_unused, + int subtest __maybe_unused) { int ret; @@ -240,3 +240,5 @@ int test__expand_cgroup_events(struct test *test __maybe_unused, return ret; } + +DEFINE_SUITE("Event expansion for cgroups", expand_cgroup_events); diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 077783223ce0..8c6397d0c381 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -62,7 +62,7 @@ static int test(struct expr_parse_ctx *ctx, const char *e, double val2) return 0; } -int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) { struct expr_id_data *val_ptr; const char *p; @@ -155,3 +155,5 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) return 0; } + +DEFINE_SUITE("Simple expression parser", expr); diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c index d9eca8e86a6b..7b2f6c2ad705 100644 --- a/tools/perf/tests/fdarray.c +++ b/tools/perf/tests/fdarray.c @@ -28,7 +28,7 @@ static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE return printed + fdarray__fprintf(fda, fp); } -int test__fdarray__filter(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__fdarray__filter(struct test *test __maybe_unused, int subtest __maybe_unused) { int nr_fds, err = TEST_FAIL; struct fdarray *fda = fdarray__new(5, 5); @@ -89,7 +89,7 @@ out: return err; } -int test__fdarray__add(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__fdarray__add(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct fdarray *fda = fdarray__new(2, 2); @@ -158,3 +158,6 @@ out_delete: out: return err; } + +DEFINE_SUITE("Filter fds with revents mask in a fdarray", fdarray__filter); +DEFINE_SUITE("Add fd to a fdarray, making it autogrow", fdarray__add); diff --git a/tools/perf/tests/genelf.c b/tools/perf/tests/genelf.c index f797f9823e89..3c5ced5d9588 100644 --- a/tools/perf/tests/genelf.c +++ b/tools/perf/tests/genelf.c @@ -16,8 +16,8 @@ #define TEMPL "/tmp/perf-test-XXXXXX" -int test__jit_write_elf(struct test *test __maybe_unused, - int subtest __maybe_unused) +static int test__jit_write_elf(struct test *test __maybe_unused, + int subtest __maybe_unused) { #ifdef HAVE_JITDUMP static unsigned char x86_code[] = { @@ -49,3 +49,5 @@ int test__jit_write_elf(struct test *test __maybe_unused, return TEST_SKIP; #endif } + +DEFINE_SUITE("Test jit_write_elf", jit_write_elf); diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 890cb1f5bf53..f7a8d3d78389 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -689,7 +689,7 @@ out: return err; } -int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; @@ -736,3 +736,5 @@ out: return err; } + +DEFINE_SUITE("Cumulate child hist entries", hists_cumulate); diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index ca6120cd1d90..09e140191e5f 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -101,7 +101,7 @@ out: return TEST_FAIL; } -int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; @@ -325,3 +325,5 @@ out: return err; } + +DEFINE_SUITE("Filter hist entries", hists_filter); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index a024d3f3a412..08571f788884 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -264,7 +264,7 @@ static int validate_link(struct hists *leader, struct hists *other) return __validate_link(leader, 0) || __validate_link(other, 1); } -int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; struct hists *hists, *first_hists; @@ -339,3 +339,5 @@ out: return err; } + +DEFINE_SUITE("Match and link multiple hists", hists_link); diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 8973f35df604..b427df8ee94a 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -575,7 +575,7 @@ out: return err; } -int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; @@ -623,3 +623,5 @@ out: return err; } + +DEFINE_SUITE("Sort output of hist entries", hists_output); diff --git a/tools/perf/tests/is_printable_array.c b/tools/perf/tests/is_printable_array.c index 9c7b3baca4fe..8891b10fac5c 100644 --- a/tools/perf/tests/is_printable_array.c +++ b/tools/perf/tests/is_printable_array.c @@ -5,7 +5,7 @@ #include "debug.h" #include "print_binary.h" -int test__is_printable_array(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__is_printable_array(struct test *test __maybe_unused, int subtest __maybe_unused) { char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 }; char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 }; @@ -36,3 +36,5 @@ int test__is_printable_array(struct test *test __maybe_unused, int subtest __may return TEST_OK; } + +DEFINE_SUITE("is_printable_array", is_printable_array); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index a0438b0f0805..e723c976dc81 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -61,7 +61,7 @@ static int find_comm(struct evlist *evlist, const char *comm) * when an event is disabled but a dummy software event is not disabled. If the * test passes %0 is returned, otherwise %-1 is returned. */ -int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .mmap_pages = UINT_MAX, @@ -160,3 +160,5 @@ out_err: return err; } + +DEFINE_SUITE("Use a dummy software event to keep tracking", keep_tracking); diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c index e483210b176b..4935dd3182ed 100644 --- a/tools/perf/tests/kmod-path.c +++ b/tools/perf/tests/kmod-path.c @@ -47,7 +47,7 @@ static int test_is_kernel_module(const char *path, int cpumode, bool expect) #define M(path, c, e) \ TEST_ASSERT_VAL("failed", !test_is_kernel_module(path, c, e)) -int test__kmod_path__parse(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__kmod_path__parse(struct test *t __maybe_unused, int subtest __maybe_unused) { /* path alloc_name kmod comp name */ T("/xxxx/xxxx/x-x.ko", true , true, 0 , "[x_x]"); @@ -159,3 +159,5 @@ int test__kmod_path__parse(struct test *t __maybe_unused, int subtest __maybe_un return 0; } + +DEFINE_SUITE("kmod_path__parse", kmod_path__parse); diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 33e43cce9064..b605a71ad8d5 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -124,7 +124,7 @@ out: return ret; } -int test__llvm(struct test *test __maybe_unused, int subtest) +static int test__llvm(struct test *test __maybe_unused, int subtest) { int ret; void *obj_buf = NULL; @@ -149,12 +149,12 @@ int test__llvm(struct test *test __maybe_unused, int subtest) return ret; } -int test__llvm_subtest_get_nr(void) +static int test__llvm_subtest_get_nr(void) { return __LLVM_TESTCASE_MAX; } -const char *test__llvm_subtest_get_desc(int subtest) +static const char *test__llvm_subtest_get_desc(int subtest) { if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX)) return NULL; @@ -162,18 +162,28 @@ const char *test__llvm_subtest_get_desc(int subtest) return bpf_source_table[subtest].desc; } #else //HAVE_LIBBPF_SUPPORT -int test__llvm(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__llvm(struct test *test __maybe_unused, int subtest __maybe_unused) { return TEST_SKIP; } -int test__llvm_subtest_get_nr(void) +static int test__llvm_subtest_get_nr(void) { return 0; } -const char *test__llvm_subtest_get_desc(int subtest __maybe_unused) +static const char *test__llvm_subtest_get_desc(int subtest __maybe_unused) { return NULL; } #endif // HAVE_LIBBPF_SUPPORT + +struct test suite__llvm = { + .desc = "LLVM search and compile", + .func = test__llvm, + .subtest = { + .skip_if_fail = true, + .get_nr = test__llvm_subtest_get_nr, + .get_desc = test__llvm_subtest_get_desc, + }, +}; diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index 1ac72919fa35..4a2e6f312015 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -33,7 +33,7 @@ static int check_maps(struct map_def *merged, unsigned int size, struct maps *ma return TEST_OK; } -int test__maps__merge_in(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__maps__merge_in(struct test *t __maybe_unused, int subtest __maybe_unused) { struct maps maps; unsigned int i; @@ -120,3 +120,5 @@ int test__maps__merge_in(struct test *t __maybe_unused, int subtest __maybe_unus maps__exit(&maps); return TEST_OK; } + +DEFINE_SUITE("maps__merge_in", maps__merge_in); diff --git a/tools/perf/tests/mem.c b/tools/perf/tests/mem.c index 673a11a6cd1b..3af082508653 100644 --- a/tools/perf/tests/mem.c +++ b/tools/perf/tests/mem.c @@ -23,7 +23,7 @@ static int check(union perf_mem_data_src data_src, return 0; } -int test__mem(struct test *text __maybe_unused, int subtest __maybe_unused) +static int test__mem(struct test *text __maybe_unused, int subtest __maybe_unused) { int ret = 0; union perf_mem_data_src src; @@ -56,3 +56,5 @@ int test__mem(struct test *text __maybe_unused, int subtest __maybe_unused) return ret; } + +DEFINE_SUITE("Test data source output", mem); diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index e4d0d58b97f8..0a90e6084d81 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -43,7 +43,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) return bm && map ? bm : NULL; } -int test__mem2node(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__mem2node(struct test *t __maybe_unused, int subtest __maybe_unused) { struct mem2node map; struct memory_node nodes[3]; @@ -77,3 +77,5 @@ int test__mem2node(struct test *t __maybe_unused, int subtest __maybe_unused) mem2node__exit(&map); return 0; } + +DEFINE_SUITE("mem2node", mem2node); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index d38757db2dc2..86f34631312d 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -29,7 +29,7 @@ * Then it checks if the number of syscalls reported as perf events by * the kernel corresponds to the number of syscalls made. */ -int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; union perf_event *event; @@ -164,3 +164,5 @@ out_free_threads: perf_thread_map__put(threads); return err; } + +DEFINE_SUITE("Read samples using the mmap interface", basic_mmap); diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index 6f2da7a72f67..756a46c796f7 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -224,7 +224,7 @@ static int mmap_events(synth_cb synth) * * by using all thread objects. */ -int test__mmap_thread_lookup(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__mmap_thread_lookup(struct test *test __maybe_unused, int subtest __maybe_unused) { /* perf_event__synthesize_threads synthesize */ TEST_ASSERT_VAL("failed with sythesizing all", @@ -236,3 +236,5 @@ int test__mmap_thread_lookup(struct test *test __maybe_unused, int subtest __may return 0; } + +DEFINE_SUITE("Lookup mmap thread", mmap_thread_lookup); diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index f7dd6c463f04..28f3597ba531 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -19,7 +19,8 @@ #include "stat.h" #include "util/counts.h" -int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, + int subtest __maybe_unused) { int err = -1, fd, cpu; struct perf_cpu_map *cpus; @@ -127,3 +128,5 @@ out_thread_map_delete: perf_thread_map__put(threads); return err; } + +DEFINE_SUITE("Detect openat syscall event on all cpus", openat_syscall_event_on_all_cpus); diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 5e4af2f0f14a..cbb5c0fa40fe 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -22,7 +22,8 @@ #define AT_FDCWD -100 #endif -int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__syscall_openat_tp_fields(struct test *test __maybe_unused, + int subtest __maybe_unused) { struct record_opts opts = { .target = { @@ -142,3 +143,5 @@ out_delete_evlist: out: return err; } + +DEFINE_SUITE("syscalls:sys_enter_openat event fields", syscall_openat_tp_fields); diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 85a8f0fe7aea..8f904fcebe6f 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -13,7 +13,8 @@ #include "tests.h" #include "util/counts.h" -int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__openat_syscall_event(struct test *test __maybe_unused, + int subtest __maybe_unused) { int err = -1, fd; struct evsel *evsel; @@ -66,3 +67,5 @@ out_thread_map_delete: perf_thread_map__put(threads); return err; } + +DEFINE_SUITE("Detect openat syscall event", openat_syscall_event); diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 6af94639b14a..1522dd39dd0a 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -2276,7 +2276,7 @@ static int test_pmu_events_alias(char *event, char *alias) return test_event(&e); } -int test__parse_events(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__parse_events(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret1, ret2 = 0; char *event, *alias; @@ -2319,3 +2319,5 @@ do { \ return ret2; } + +DEFINE_SUITE("Parse event definition strings", parse_events); diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c index dfc797ecc750..999d37fc58f2 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -369,7 +369,7 @@ static int test_metric_group(void) return 0; } -int test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("IPC failed", test_ipc() == 0); TEST_ASSERT_VAL("frontend failed", test_frontend() == 0); @@ -383,3 +383,5 @@ int test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unu } return 0; } + +DEFINE_SUITE("Parse and process metrics", parse_metric); diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index 471273676701..2a5eec424a43 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -67,7 +67,8 @@ struct test_attr_event { * * Return: %0 on success, %-1 if the test fails. */ -int test__parse_no_sample_id_all(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__parse_no_sample_id_all(struct test *test __maybe_unused, + int subtest __maybe_unused) { int err; @@ -103,3 +104,5 @@ int test__parse_no_sample_id_all(struct test *test __maybe_unused, int subtest _ return 0; } + +DEFINE_SUITE("Parse with no sample_id_all bit set", parse_no_sample_id_all); diff --git a/tools/perf/tests/pe-file-parsing.c b/tools/perf/tests/pe-file-parsing.c index 58b90c42eb38..8d4fec99459a 100644 --- a/tools/perf/tests/pe-file-parsing.c +++ b/tools/perf/tests/pe-file-parsing.c @@ -68,7 +68,7 @@ static int run_dir(const char *d) return TEST_OK; } -int test__pe_file_parsing(struct test *test __maybe_unused, +static int test__pe_file_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) { struct stat st; @@ -89,10 +89,12 @@ int test__pe_file_parsing(struct test *test __maybe_unused, #else -int test__pe_file_parsing(struct test *test __maybe_unused, +static int test__pe_file_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) { return TEST_SKIP; } #endif + +DEFINE_SUITE("PE file support", pe_file_parsing); diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c index dd865e0bea12..61cb1d0a6eb9 100644 --- a/tools/perf/tests/perf-hooks.c +++ b/tools/perf/tests/perf-hooks.c @@ -26,7 +26,7 @@ static void the_hook(void *_hook_flags) raise(SIGSEGV); } -int test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unused) { int hook_flags = 0; @@ -45,3 +45,5 @@ int test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unuse return TEST_FAIL; return TEST_OK; } + +DEFINE_SUITE("perf hooks", perf_hooks); diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 0df471bf1590..24faa8487d8c 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -41,7 +41,7 @@ realloc: return cpu; } -int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .target = { @@ -332,3 +332,5 @@ out_delete_evlist: out: return (err < 0 || errs > 0) ? -1 : 0; } + +DEFINE_SUITE("PERF_RECORD_* events & perf_sample fields", PERF_RECORD); diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index 7c56bc1f4cff..dc2dcad7371f 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -45,7 +45,7 @@ * %0 is returned, otherwise %-1 is returned. If TSC conversion is not * supported then then the test passes but " (not supported)" is printed. */ -int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .mmap_pages = UINT_MAX, @@ -185,7 +185,7 @@ out_err: return err; } -bool test__tsc_is_supported(void) +static bool test__tsc_is_supported(void) { /* * Except x86_64/i386 and Arm64, other archs don't support TSC in perf. @@ -197,3 +197,9 @@ bool test__tsc_is_supported(void) return false; #endif } + +struct test suite__perf_time_to_tsc = { + .desc = "Convert perf time to TSC", + .func = test__perf_time_to_tsc, + .is_supported = test__tsc_is_supported, +}; diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c index e8fd0da0762b..83dc9742813a 100644 --- a/tools/perf/tests/pfm.c +++ b/tools/perf/tests/pfm.c @@ -189,19 +189,19 @@ static int test__pfm_group(void) } #endif -const char *test__pfm_subtest_get_desc(int i) +static const char *test__pfm_subtest_get_desc(int i) { if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) return NULL; return pfm_testcase_table[i].desc; } -int test__pfm_subtest_get_nr(void) +static int test__pfm_subtest_get_nr(void) { return (int)ARRAY_SIZE(pfm_testcase_table); } -int test__pfm(struct test *test __maybe_unused, int i __maybe_unused) +static int test__pfm(struct test *test __maybe_unused, int i __maybe_unused) { #ifdef HAVE_LIBPFM if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) @@ -211,3 +211,13 @@ int test__pfm(struct test *test __maybe_unused, int i __maybe_unused) return TEST_SKIP; #endif } + +struct test suite__pfm = { + .desc = "Test libpfm4 support", + .func = test__pfm, + .subtest = { + .skip_if_fail = true, + .get_nr = test__pfm_subtest_get_nr, + .get_desc = test__pfm_subtest_get_desc, + } +}; diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 9ae894c406d8..c3f32ddd8210 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -1090,7 +1090,7 @@ static const struct { }, }; -const char *test__pmu_events_subtest_get_desc(int subtest) +static const char *test__pmu_events_subtest_get_desc(int subtest) { if (subtest < 0 || subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table)) @@ -1098,7 +1098,7 @@ const char *test__pmu_events_subtest_get_desc(int subtest) return pmu_events_testcase_table[subtest].desc; } -const char *test__pmu_events_subtest_skip_reason(int subtest) +static const char *test__pmu_events_subtest_skip_reason(int subtest) { if (subtest < 0 || subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table)) @@ -1108,15 +1108,26 @@ const char *test__pmu_events_subtest_skip_reason(int subtest) return "some metrics failed"; } -int test__pmu_events_subtest_get_nr(void) +static int test__pmu_events_subtest_get_nr(void) { return (int)ARRAY_SIZE(pmu_events_testcase_table); } -int test__pmu_events(struct test *test __maybe_unused, int subtest) +static int test__pmu_events(struct test *test __maybe_unused, int subtest) { if (subtest < 0 || subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table)) return TEST_FAIL; return pmu_events_testcase_table[subtest].func(); } + +struct test suite__pmu_events = { + .desc = "PMU events", + .func = test__pmu_events, + .subtest = { + .skip_if_fail = false, + .get_nr = test__pmu_events_subtest_get_nr, + .get_desc = test__pmu_events_subtest_get_desc, + .skip_reason = test__pmu_events_subtest_skip_reason, + }, +}; diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index 714e6830a758..9a58dad67b27 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -137,7 +137,7 @@ static struct list_head *test_terms_list(void) return &terms; } -int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused) { char *format = test_format_dir_get(); LIST_HEAD(formats); @@ -177,3 +177,5 @@ int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused) test_format_dir_put(format); return ret; } + +DEFINE_SUITE("Parse perf pmu format", pmu); diff --git a/tools/perf/tests/python-use.c b/tools/perf/tests/python-use.c index 98c6d474aa6f..b667140688be 100644 --- a/tools/perf/tests/python-use.c +++ b/tools/perf/tests/python-use.c @@ -9,7 +9,7 @@ #include "tests.h" #include "util/debug.h" -int test__python_use(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__python_use(struct test *test __maybe_unused, int subtest __maybe_unused) { char *cmd; int ret; @@ -23,3 +23,5 @@ int test__python_use(struct test *test __maybe_unused, int subtest __maybe_unuse free(cmd); return ret; } + +DEFINE_SUITE("'import perf' in python", python_use); diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index c83a11514129..08453238c777 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -368,7 +368,7 @@ out_free: * checks sample format bits separately and together. If the test passes %0 is * returned, otherwise %-1 is returned. */ -int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) { const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15}; u64 sample_type; @@ -426,3 +426,5 @@ int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_u return 0; } + +DEFINE_SUITE("Sample parsing", sample_parsing); diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index ed76c693f65e..307615f1b6a7 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -76,7 +76,7 @@ static int search_cached_probe(const char *target, return ret; } -int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) +static int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) { int ret = TEST_FAIL; char __tempdir[] = "./test-buildid-XXXXXX"; @@ -114,9 +114,11 @@ error: return ret; } #else -int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) +static int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) { pr_debug("Skip SDT event test because SDT support is not compiled\n"); return TEST_SKIP; } #endif + +DEFINE_SUITE("Probe SDT events", sdt_event); diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c index c1911501c39c..2589f2f529ba 100644 --- a/tools/perf/tests/stat.c +++ b/tools/perf/tests/stat.c @@ -47,7 +47,8 @@ static int process_stat_config_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat_config(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__synthesize_stat_config(struct test *test __maybe_unused, + int subtest __maybe_unused) { struct perf_stat_config stat_config = { .aggr_mode = AGGR_CORE, @@ -77,7 +78,7 @@ static int process_stat_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__synthesize_stat(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_counts_values count; @@ -103,7 +104,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat_round(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__synthesize_stat_round(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to synthesize stat_config", !perf_event__synthesize_stat_round(NULL, 0xdeadbeef, PERF_STAT_ROUND_TYPE__INTERVAL, @@ -111,3 +112,7 @@ int test__synthesize_stat_round(struct test *test __maybe_unused, int subtest __ return 0; } + +DEFINE_SUITE("Synthesize stat config", synthesize_stat_config); +DEFINE_SUITE("Synthesize stat", synthesize_stat); +DEFINE_SUITE("Synthesize stat round", synthesize_stat_round); diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 74988846be1d..db1e339a0fbe 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -133,7 +133,7 @@ out_delete_evlist: return err; } -int test__sw_clock_freq(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__sw_clock_freq(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret; @@ -143,3 +143,5 @@ int test__sw_clock_freq(struct test *test __maybe_unused, int subtest __maybe_un return ret; } + +DEFINE_SUITE("Software clock events period values", sw_clock_freq); diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 62c0ec21aaa8..9b379aaddce4 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -321,7 +321,7 @@ out_free_nodes: * evsel->core.system_wide and evsel->tracking flags (respectively) with other events * sometimes enabled or disabled. */ -int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) { const char *sched_switch = "sched:sched_switch"; struct switch_tracking switch_tracking = { .tids = NULL, }; @@ -588,3 +588,5 @@ out_err: err = -1; goto out; } + +DEFINE_SUITE("Track with sched_switch", switch_tracking); diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 4c2969db59b0..197574230493 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -39,7 +39,7 @@ static void workload_exec_failed_signal(int signo __maybe_unused, * if the number of exit event reported by the kernel is 1 or not * in order to check the kernel returns correct number of event. */ -int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; union perf_event *event; @@ -151,3 +151,5 @@ out_delete_evlist: evlist__delete(evlist); return err; } + +DEFINE_SUITE("Number of exit events of a simple workload", task_exit); diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 8323a3c88284..f2efa331b32f 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -41,10 +41,10 @@ struct test { }; #define DECLARE_SUITE(name) \ - int test__##name(struct test *test, int subtest) + extern struct test suite__##name; #define DEFINE_SUITE(description, name) \ - static struct test name = { \ + struct test suite__##name = { \ .desc = description, \ .func = test__##name, \ } @@ -60,9 +60,6 @@ DECLARE_SUITE(perf_evsel__tp_sched_test); DECLARE_SUITE(syscall_openat_tp_fields); DECLARE_SUITE(pmu); DECLARE_SUITE(pmu_events); -const char *test__pmu_events_subtest_get_desc(int subtest); -const char *test__pmu_events_subtest_skip_reason(int subtest); -int test__pmu_events_subtest_get_nr(void); DECLARE_SUITE(attr); DECLARE_SUITE(dso_data); DECLARE_SUITE(dso_data_cache); @@ -74,9 +71,6 @@ DECLARE_SUITE(bp_signal); DECLARE_SUITE(bp_signal_overflow); DECLARE_SUITE(bp_accounting); DECLARE_SUITE(wp); -const char *test__wp_subtest_get_desc(int subtest); -const char *test__wp_subtest_skip_reason(int subtest); -int test__wp_subtest_get_nr(void); DECLARE_SUITE(task_exit); DECLARE_SUITE(mem); DECLARE_SUITE(sw_clock_freq); @@ -84,7 +78,7 @@ DECLARE_SUITE(code_reading); DECLARE_SUITE(sample_parsing); DECLARE_SUITE(keep_tracking); DECLARE_SUITE(parse_no_sample_id_all); -extern struct test dwarf_unwind; +DECLARE_SUITE(dwarf_unwind); DECLARE_SUITE(expr); DECLARE_SUITE(hists_filter); DECLARE_SUITE(mmap_thread_lookup); @@ -97,11 +91,7 @@ DECLARE_SUITE(fdarray__add); DECLARE_SUITE(kmod_path__parse); DECLARE_SUITE(thread_map); DECLARE_SUITE(llvm); -const char *test__llvm_subtest_get_desc(int subtest); -int test__llvm_subtest_get_nr(void); DECLARE_SUITE(bpf); -const char *test__bpf_subtest_get_desc(int subtest); -int test__bpf_subtest_get_nr(void); DECLARE_SUITE(session_topology); DECLARE_SUITE(thread_map_synthesize); DECLARE_SUITE(thread_map_remove); @@ -119,8 +109,6 @@ DECLARE_SUITE(is_printable_array); DECLARE_SUITE(bitmap_print); DECLARE_SUITE(perf_hooks); DECLARE_SUITE(clang); -const char *test__clang_subtest_get_desc(int subtest); -int test__clang_subtest_get_nr(void); DECLARE_SUITE(unit_number__scnprint); DECLARE_SUITE(mem2node); DECLARE_SUITE(maps__merge_in); @@ -130,8 +118,6 @@ DECLARE_SUITE(api_io); DECLARE_SUITE(demangle_java); DECLARE_SUITE(demangle_ocaml); DECLARE_SUITE(pfm); -const char *test__pfm_subtest_get_desc(int subtest); -int test__pfm_subtest_get_nr(void); DECLARE_SUITE(parse_metric); DECLARE_SUITE(pe_file_parsing); DECLARE_SUITE(expand_cgroup_events); @@ -139,9 +125,6 @@ DECLARE_SUITE(perf_time_to_tsc); DECLARE_SUITE(dlfilter); bool test__bp_signal_is_supported(void); -bool test__bp_account_is_supported(void); -bool test__wp_is_supported(void); -bool test__tsc_is_supported(void); #ifdef HAVE_DWARF_UNWIND_SUPPORT struct thread; diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index d1e208b4a571..7e2e8a72fa78 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -19,7 +19,7 @@ struct machine; #define NAME (const char *) "perf" #define NAMEUL (unsigned long) NAME -int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_thread_map *map; @@ -86,7 +86,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_thread_map *threads; @@ -106,7 +106,7 @@ int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __ return 0; } -int test__thread_map_remove(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__thread_map_remove(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_thread_map *threads; char *str; @@ -145,3 +145,7 @@ int test__thread_map_remove(struct test *test __maybe_unused, int subtest __mayb perf_thread_map__put(threads); return 0; } + +DEFINE_SUITE("Thread map", thread_map); +DEFINE_SUITE("Synthesize thread map", thread_map_synthesize); +DEFINE_SUITE("Remove thread map", thread_map_remove); diff --git a/tools/perf/tests/thread-maps-share.c b/tools/perf/tests/thread-maps-share.c index 9371484973f2..2821be0a9a05 100644 --- a/tools/perf/tests/thread-maps-share.c +++ b/tools/perf/tests/thread-maps-share.c @@ -4,7 +4,7 @@ #include "thread.h" #include "debug.h" -int test__thread_maps_share(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__thread_maps_share(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machines machines; struct machine *machine; @@ -96,3 +96,5 @@ int test__thread_maps_share(struct test *test __maybe_unused, int subtest __mayb machines__exit(&machines); return 0; } + +DEFINE_SUITE("Share thread maps", thread_maps_share); diff --git a/tools/perf/tests/time-utils-test.c b/tools/perf/tests/time-utils-test.c index fe57ca3b6e54..538100cb7541 100644 --- a/tools/perf/tests/time-utils-test.c +++ b/tools/perf/tests/time-utils-test.c @@ -131,7 +131,7 @@ out: return pass; } -int test__time_utils(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__time_utils(struct test *t __maybe_unused, int subtest __maybe_unused) { bool pass = true; @@ -249,3 +249,5 @@ int test__time_utils(struct test *t __maybe_unused, int subtest __maybe_unused) return pass ? 0 : TEST_FAIL; } + +DEFINE_SUITE("time utils", time_utils); diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 4574c46260d9..09e5fcdb646d 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -175,7 +175,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map) return 0; } -int test__session_topology(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__session_topology(struct test *test __maybe_unused, int subtest __maybe_unused) { char path[PATH_MAX]; struct perf_cpu_map *map; @@ -201,3 +201,5 @@ free_path: unlink(path); return ret; } + +DEFINE_SUITE("Session topology", session_topology); diff --git a/tools/perf/tests/unit_number__scnprintf.c b/tools/perf/tests/unit_number__scnprintf.c index 3721757435da..2ad78a9473d4 100644 --- a/tools/perf/tests/unit_number__scnprintf.c +++ b/tools/perf/tests/unit_number__scnprintf.c @@ -7,7 +7,7 @@ #include "units.h" #include "debug.h" -int test__unit_number__scnprint(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__unit_number__scnprint(struct test *t __maybe_unused, int subtest __maybe_unused) { struct { u64 n; @@ -38,3 +38,5 @@ int test__unit_number__scnprint(struct test *t __maybe_unused, int subtest __may return TEST_OK; } + +DEFINE_SUITE("unit_number__scnprintf", unit_number__scnprint); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 4f884aabc7f4..7f1b74bf4f13 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -111,7 +111,8 @@ static bool is_ignored_symbol(const char *name, char type) return false; } -int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, + int subtest __maybe_unused) { int err = -1; struct rb_node *nd; @@ -352,3 +353,5 @@ out: machine__exit(&vmlinux); return err; } + +DEFINE_SUITE("vmlinux symtab matches kallsyms", vmlinux_matches_kallsyms); diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c index 9387fa76faa5..16ab733cabce 100644 --- a/tools/perf/tests/wp.c +++ b/tools/perf/tests/wp.c @@ -209,19 +209,19 @@ static struct { }, }; -int test__wp_subtest_get_nr(void) +static int test__wp_subtest_get_nr(void) { return (int)ARRAY_SIZE(wp_testcase_table); } -const char *test__wp_subtest_get_desc(int i) +static const char *test__wp_subtest_get_desc(int i) { if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table)) return NULL; return wp_testcase_table[i].desc; } -const char *test__wp_subtest_skip_reason(int i) +static const char *test__wp_subtest_skip_reason(int i) { if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table)) return NULL; @@ -230,7 +230,7 @@ const char *test__wp_subtest_skip_reason(int i) return wp_testcase_table[i].skip_msg(); } -int test__wp(struct test *test __maybe_unused, int i) +static int test__wp(struct test *test __maybe_unused, int i) { if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table)) return TEST_FAIL; @@ -245,7 +245,7 @@ int test__wp(struct test *test __maybe_unused, int i) /* The s390 so far does not have support for * instruction breakpoint using the perf_event_open() system call. */ -bool test__wp_is_supported(void) +static bool test__wp_is_supported(void) { #if defined(__s390x__) return false; @@ -253,3 +253,15 @@ bool test__wp_is_supported(void) return true; #endif } + +struct test suite__wp = { + .desc = "Watchpoint", + .func = test__wp, + .is_supported = test__wp_is_supported, + .subtest = { + .skip_if_fail = false, + .get_nr = test__wp_subtest_get_nr, + .get_desc = test__wp_subtest_get_desc, + .skip_reason = test__wp_subtest_skip_reason, + }, +}; -- cgit v1.2.3 From 33f44bfd3c04e3559633c24b797044e849144fea Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:51 -0700 Subject: perf test: Rename struct test to test_suite This is to align with kunit's terminology. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm/include/arch-tests.h | 2 +- tools/perf/arch/arm/tests/arch-tests.c | 2 +- tools/perf/arch/arm/tests/vectors-page.c | 2 +- tools/perf/arch/arm64/include/arch-tests.h | 2 +- tools/perf/arch/arm64/tests/arch-tests.c | 2 +- tools/perf/arch/powerpc/include/arch-tests.h | 2 +- tools/perf/arch/powerpc/tests/arch-tests.c | 3 ++- tools/perf/arch/x86/include/arch-tests.h | 14 +++++++------- tools/perf/arch/x86/tests/arch-tests.c | 2 +- tools/perf/arch/x86/tests/bp-modify.c | 2 +- tools/perf/arch/x86/tests/insn-x86.c | 2 +- tools/perf/arch/x86/tests/intel-cqm.c | 2 +- .../perf/arch/x86/tests/intel-pt-pkt-decoder-test.c | 2 +- tools/perf/arch/x86/tests/rdpmc.c | 2 +- tools/perf/arch/x86/tests/sample-parsing.c | 2 +- tools/perf/tests/api-io.c | 2 +- tools/perf/tests/attr.c | 2 +- tools/perf/tests/backward-ring-buffer.c | 2 +- tools/perf/tests/bitmap.c | 2 +- tools/perf/tests/bp_account.c | 4 ++-- tools/perf/tests/bp_signal.c | 4 ++-- tools/perf/tests/bp_signal_overflow.c | 4 ++-- tools/perf/tests/bpf.c | 6 +++--- tools/perf/tests/builtin-test.c | 20 ++++++++++---------- tools/perf/tests/clang.c | 6 +++--- tools/perf/tests/code-reading.c | 2 +- tools/perf/tests/cpumap.c | 6 +++--- tools/perf/tests/demangle-java-test.c | 2 +- tools/perf/tests/demangle-ocaml-test.c | 2 +- tools/perf/tests/dlfilter-test.c | 2 +- tools/perf/tests/dso-data.c | 6 +++--- tools/perf/tests/dwarf-unwind.c | 3 ++- tools/perf/tests/event-times.c | 2 +- tools/perf/tests/event_update.c | 2 +- tools/perf/tests/evsel-roundtrip-name.c | 2 +- tools/perf/tests/evsel-tp-sched.c | 2 +- tools/perf/tests/expand-cgroup.c | 2 +- tools/perf/tests/expr.c | 2 +- tools/perf/tests/fdarray.c | 4 ++-- tools/perf/tests/genelf.c | 2 +- tools/perf/tests/hists_cumulate.c | 2 +- tools/perf/tests/hists_filter.c | 2 +- tools/perf/tests/hists_link.c | 2 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/is_printable_array.c | 2 +- tools/perf/tests/keep-tracking.c | 2 +- tools/perf/tests/kmod-path.c | 2 +- tools/perf/tests/llvm.c | 6 +++--- tools/perf/tests/maps.c | 2 +- tools/perf/tests/mem.c | 2 +- tools/perf/tests/mem2node.c | 2 +- tools/perf/tests/mmap-basic.c | 2 +- tools/perf/tests/mmap-thread-lookup.c | 2 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/tests/parse-events.c | 2 +- tools/perf/tests/parse-metric.c | 2 +- tools/perf/tests/parse-no-sample-id-all.c | 2 +- tools/perf/tests/pe-file-parsing.c | 4 ++-- tools/perf/tests/perf-hooks.c | 2 +- tools/perf/tests/perf-record.c | 2 +- tools/perf/tests/perf-time-to-tsc.c | 4 ++-- tools/perf/tests/pfm.c | 4 ++-- tools/perf/tests/pmu-events.c | 4 ++-- tools/perf/tests/pmu.c | 2 +- tools/perf/tests/python-use.c | 2 +- tools/perf/tests/sample-parsing.c | 2 +- tools/perf/tests/sdt.c | 4 ++-- tools/perf/tests/stat.c | 6 +++--- tools/perf/tests/sw-clock.c | 2 +- tools/perf/tests/switch-tracking.c | 2 +- tools/perf/tests/task-exit.c | 2 +- tools/perf/tests/tests.h | 8 ++++---- tools/perf/tests/thread-map.c | 6 +++--- tools/perf/tests/thread-maps-share.c | 2 +- tools/perf/tests/time-utils-test.c | 2 +- tools/perf/tests/topology.c | 2 +- tools/perf/tests/unit_number__scnprintf.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 2 +- tools/perf/tests/wp.c | 4 ++-- 81 files changed, 125 insertions(+), 123 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/arch/arm/include/arch-tests.h b/tools/perf/arch/arm/include/arch-tests.h index 37039e80f18b..452b3d904521 100644 --- a/tools/perf/arch/arm/include/arch-tests.h +++ b/tools/perf/arch/arm/include/arch-tests.h @@ -2,6 +2,6 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H -extern struct test *arch_tests[]; +extern struct test_suite *arch_tests[]; #endif diff --git a/tools/perf/arch/arm/tests/arch-tests.c b/tools/perf/arch/arm/tests/arch-tests.c index 2495b5770637..69561111cc6f 100644 --- a/tools/perf/arch/arm/tests/arch-tests.c +++ b/tools/perf/arch/arm/tests/arch-tests.c @@ -3,7 +3,7 @@ #include "tests/tests.h" #include "arch-tests.h" -struct test *arch_tests[] = { +struct test_suite *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT &suite__dwarf_unwind, #endif diff --git a/tools/perf/arch/arm/tests/vectors-page.c b/tools/perf/arch/arm/tests/vectors-page.c index dac7b32afb65..55a835837466 100644 --- a/tools/perf/arch/arm/tests/vectors-page.c +++ b/tools/perf/arch/arm/tests/vectors-page.c @@ -9,7 +9,7 @@ #define VECTORS__MAP_NAME "[vectors]" -static int test__vectors_page(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__vectors_page(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { void *start, *end; diff --git a/tools/perf/arch/arm64/include/arch-tests.h b/tools/perf/arch/arm64/include/arch-tests.h index 37039e80f18b..452b3d904521 100644 --- a/tools/perf/arch/arm64/include/arch-tests.h +++ b/tools/perf/arch/arm64/include/arch-tests.h @@ -2,6 +2,6 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H -extern struct test *arch_tests[]; +extern struct test_suite *arch_tests[]; #endif diff --git a/tools/perf/arch/arm64/tests/arch-tests.c b/tools/perf/arch/arm64/tests/arch-tests.c index 6d137138a2de..ad16b4f8f63e 100644 --- a/tools/perf/arch/arm64/tests/arch-tests.c +++ b/tools/perf/arch/arm64/tests/arch-tests.c @@ -3,7 +3,7 @@ #include "tests/tests.h" #include "arch-tests.h" -struct test *arch_tests[] = { +struct test_suite *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT &suite__dwarf_unwind, #endif diff --git a/tools/perf/arch/powerpc/include/arch-tests.h b/tools/perf/arch/powerpc/include/arch-tests.h index 37039e80f18b..452b3d904521 100644 --- a/tools/perf/arch/powerpc/include/arch-tests.h +++ b/tools/perf/arch/powerpc/include/arch-tests.h @@ -2,6 +2,6 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H -extern struct test *arch_tests[]; +extern struct test_suite *arch_tests[]; #endif diff --git a/tools/perf/arch/powerpc/tests/arch-tests.c b/tools/perf/arch/powerpc/tests/arch-tests.c index 6d137138a2de..eb98c57b5aeb 100644 --- a/tools/perf/arch/powerpc/tests/arch-tests.c +++ b/tools/perf/arch/powerpc/tests/arch-tests.c @@ -3,7 +3,8 @@ #include "tests/tests.h" #include "arch-tests.h" -struct test *arch_tests[] = { + +struct test_suite *arch_tests[] = { #ifdef HAVE_DWARF_UNWIND_SUPPORT &suite__dwarf_unwind, #endif diff --git a/tools/perf/arch/x86/include/arch-tests.h b/tools/perf/arch/x86/include/arch-tests.h index d6db9f72b6af..6a1a1b3c0827 100644 --- a/tools/perf/arch/x86/include/arch-tests.h +++ b/tools/perf/arch/x86/include/arch-tests.h @@ -2,15 +2,15 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H -struct test; +struct test_suite; /* Tests */ -int test__rdpmc(struct test *test, int subtest); -int test__insn_x86(struct test *test, int subtest); -int test__intel_pt_pkt_decoder(struct test *test, int subtest); -int test__bp_modify(struct test *test, int subtest); -int test__x86_sample_parsing(struct test *test, int subtest); +int test__rdpmc(struct test_suite *test, int subtest); +int test__insn_x86(struct test_suite *test, int subtest); +int test__intel_pt_pkt_decoder(struct test_suite *test, int subtest); +int test__bp_modify(struct test_suite *test, int subtest); +int test__x86_sample_parsing(struct test_suite *test, int subtest); -extern struct test *arch_tests[]; +extern struct test_suite *arch_tests[]; #endif diff --git a/tools/perf/arch/x86/tests/arch-tests.c b/tools/perf/arch/x86/tests/arch-tests.c index 20b1c0d8ca66..64fb73d14d2f 100644 --- a/tools/perf/arch/x86/tests/arch-tests.c +++ b/tools/perf/arch/x86/tests/arch-tests.c @@ -13,7 +13,7 @@ DEFINE_SUITE("x86 bp modify", bp_modify); #endif DEFINE_SUITE("x86 Sample parsing", x86_sample_parsing); -struct test *arch_tests[] = { +struct test_suite *arch_tests[] = { &suite__rdpmc, #ifdef HAVE_DWARF_UNWIND_SUPPORT &suite__dwarf_unwind, diff --git a/tools/perf/arch/x86/tests/bp-modify.c b/tools/perf/arch/x86/tests/bp-modify.c index dffcf9b52153..0924ccd9e36d 100644 --- a/tools/perf/arch/x86/tests/bp-modify.c +++ b/tools/perf/arch/x86/tests/bp-modify.c @@ -204,7 +204,7 @@ out: return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; } -int test__bp_modify(struct test *test __maybe_unused, +int test__bp_modify(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1()); diff --git a/tools/perf/arch/x86/tests/insn-x86.c b/tools/perf/arch/x86/tests/insn-x86.c index 0262b0d8ccf5..94b490c434d0 100644 --- a/tools/perf/arch/x86/tests/insn-x86.c +++ b/tools/perf/arch/x86/tests/insn-x86.c @@ -173,7 +173,7 @@ static int test_data_set(struct test_data *dat_set, int x86_64) * verbose (-v) option to see all the instructions and whether or not they * decoded successfully. */ -int test__insn_x86(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__insn_x86(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret = 0; diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 27dd8cf9e060..cb5b2c6c3b3b 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -37,7 +37,7 @@ static pid_t spawn(void) * the last read counter value to avoid triggering a WARN_ON_ONCE() in * smp_call_function_many() caused by sending IPIs from NMI context. */ -int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__intel_cqm_count_nmi_context(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct evlist *evlist = NULL; struct evsel *evsel = NULL; diff --git a/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c b/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c index c933e3dcd0a8..2fc882ab24c1 100644 --- a/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c +++ b/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c @@ -289,7 +289,7 @@ static int test_one(struct test_data *d) * This test feeds byte sequences to the Intel PT packet decoder and checks the * results. Changes to the packet context are also checked. */ -int test__intel_pt_pkt_decoder(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__intel_pt_pkt_decoder(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct test_data *d = data; int ret; diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index 1ea916656a2d..498413ad9c97 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c @@ -157,7 +157,7 @@ out_close: return 0; } -int test__rdpmc(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__rdpmc(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int status = 0; int wret = 0; diff --git a/tools/perf/arch/x86/tests/sample-parsing.c b/tools/perf/arch/x86/tests/sample-parsing.c index c92db87e4479..bfbd3662b69e 100644 --- a/tools/perf/arch/x86/tests/sample-parsing.c +++ b/tools/perf/arch/x86/tests/sample-parsing.c @@ -115,7 +115,7 @@ out_free: * For now, the PERF_SAMPLE_WEIGHT_STRUCT is the only X86 specific sample type. * The test only checks the PERF_SAMPLE_WEIGHT_STRUCT type. */ -int test__x86_sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__x86_sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { return do_test(PERF_SAMPLE_WEIGHT_STRUCT); } diff --git a/tools/perf/tests/api-io.c b/tools/perf/tests/api-io.c index af4913967514..e91cf2c127f1 100644 --- a/tools/perf/tests/api-io.c +++ b/tools/perf/tests/api-io.c @@ -289,7 +289,7 @@ static int test_get_dec(void) return ret; } -static int test__api_io(struct test *test __maybe_unused, +static int test__api_io(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret = 0; diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index f1461051f579..0f73e300f207 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -178,7 +178,7 @@ static int run_dir(const char *d, const char *perf) return system(cmd) ? TEST_FAIL : TEST_OK; } -static int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__attr(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct stat st; char path_perf[PATH_MAX]; diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 131903a2054d..79a980b1e786 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -82,7 +82,7 @@ static int do_test(struct evlist *evlist, int mmap_pages, } -static int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__backward_ring_buffer(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; char pid[16], sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 13d1d1d6774f..384856347236 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -40,7 +40,7 @@ static int test_bitmap(const char *str) return ret; } -static int test__bitmap_print(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__bitmap_print(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to convert map", test_bitmap("1")); TEST_ASSERT_VAL("failed to convert map", test_bitmap("1,5")); diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c index 76cf356ba13f..365120146d17 100644 --- a/tools/perf/tests/bp_account.c +++ b/tools/perf/tests/bp_account.c @@ -173,7 +173,7 @@ static int detect_share(int wp_cnt, int bp_cnt) * we create another watchpoint to ensure * the slot accounting is correct */ -static int test__bp_accounting(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__bp_accounting(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int has_ioctl = detect_ioctl(); int wp_cnt = detect_cnt(false); @@ -205,7 +205,7 @@ static bool test__bp_account_is_supported(void) #endif } -struct test suite__bp_accounting = { +struct test_suite suite__bp_accounting = { .desc = "Breakpoint accounting", .func = test__bp_accounting, .is_supported = test__bp_account_is_supported, diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index c19b05488cfb..3c269f81818a 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -161,7 +161,7 @@ static long long bp_count(int fd) return count; } -static int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__bp_signal(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct sigaction sa; long long count1, count2, count3; @@ -312,7 +312,7 @@ bool test__bp_signal_is_supported(void) #endif } -struct test suite__bp_signal = { +struct test_suite suite__bp_signal = { .desc = "Breakpoint overflow signal handler", .func = test__bp_signal, .is_supported = test__bp_signal_is_supported, diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index 99c30d028f5e..5ac6e1393cf4 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c @@ -59,7 +59,7 @@ static long long bp_count(int fd) #define EXECUTIONS 10000 #define THRESHOLD 100 -static int test__bp_signal_overflow(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__bp_signal_overflow(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct perf_event_attr pe; struct sigaction sa; @@ -134,7 +134,7 @@ static int test__bp_signal_overflow(struct test *test __maybe_unused, int subtes return fails ? TEST_FAIL : TEST_OK; } -struct test suite__bp_signal_overflow = { +struct test_suite suite__bp_signal_overflow = { .desc = "Breakpoint overflow sampling", .func = test__bp_signal_overflow, .is_supported = test__bp_signal_is_supported, diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 3f936864d0ee..442562d7b7e5 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -325,7 +325,7 @@ static int check_env(void) return 0; } -static int test__bpf(struct test *test __maybe_unused, int i) +static int test__bpf(struct test_suite *test __maybe_unused, int i) { int err; @@ -355,14 +355,14 @@ static const char *test__bpf_subtest_get_desc(int i __maybe_unused) return NULL; } -static int test__bpf(struct test *test __maybe_unused, int i __maybe_unused) +static int test__bpf(struct test_suite *test __maybe_unused, int i __maybe_unused) { pr_debug("Skip BPF test because BPF support is not compiled\n"); return TEST_SKIP; } #endif -struct test suite__bpf = { +struct test_suite suite__bpf = { .desc = "BPF filter", .func = test__bpf, .subtest = { diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 07467ec43100..7d52e2eb8147 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -30,11 +30,11 @@ static bool dont_fork; -struct test *__weak arch_tests[] = { +struct test_suite *__weak arch_tests[] = { NULL, }; -static struct test *generic_tests[] = { +static struct test_suite *generic_tests[] = { &suite__vmlinux_matches_kallsyms, &suite__openat_syscall_event, &suite__openat_syscall_event_on_all_cpus, @@ -110,7 +110,7 @@ static struct test *generic_tests[] = { NULL, }; -static struct test **tests[] = { +static struct test_suite **tests[] = { generic_tests, arch_tests, }; @@ -139,7 +139,7 @@ static bool perf_test__matches(const char *desc, int curr, int argc, const char return false; } -static int run_test(struct test *test, int subtest) +static int run_test(struct test_suite *test, int subtest) { int status, err = -1, child = dont_fork ? 0 : fork(); char sbuf[STRERR_BUFSIZE]; @@ -195,7 +195,7 @@ static int run_test(struct test *test, int subtest) for (j = 0; j < ARRAY_SIZE(tests); j++) \ for (k = 0, t = tests[j][k]; tests[j][k]; k++, t = tests[j][k]) -static int test_and_print(struct test *t, bool force_skip, int subtest) +static int test_and_print(struct test_suite *t, bool force_skip, int subtest) { int err; @@ -321,7 +321,7 @@ struct shell_test { const char *file; }; -static int shell_test__run(struct test *test, int subdir __maybe_unused) +static int shell_test__run(struct test_suite *test, int subdir __maybe_unused) { int err; char script[PATH_MAX]; @@ -363,7 +363,7 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width, for_each_shell_test(entlist, n_dirs, st.dir, ent) { int curr = i++; char desc[256]; - struct test test = { + struct test_suite test = { .desc = shell_test__description(desc, sizeof(desc), st.dir, ent->d_name), .func = shell_test__run, .priv = &st, @@ -391,7 +391,7 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width, static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) { - struct test *t; + struct test_suite *t; unsigned int j, k; int i = 0; int width = shell_tests__max_desc_width(); @@ -500,7 +500,7 @@ static int perf_test__list_shell(int argc, const char **argv, int i) for_each_shell_test(entlist, n_dirs, path, ent) { int curr = i++; char bf[256]; - struct test t = { + struct test_suite t = { .desc = shell_test__description(bf, sizeof(bf), path, ent->d_name), }; @@ -520,7 +520,7 @@ static int perf_test__list_shell(int argc, const char **argv, int i) static int perf_test__list(int argc, const char **argv) { unsigned int j, k; - struct test *t; + struct test_suite *t; int i = 0; for_each_test(j, k, t) { diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index 5052be1b5b20..a499fcf37bf9 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -32,12 +32,12 @@ static const char *test__clang_subtest_get_desc(int i) } #ifndef HAVE_LIBCLANGLLVM_SUPPORT -static int test__clang(struct test *test __maybe_unused, int i __maybe_unused) +static int test__clang(struct test_suite *test __maybe_unused, int i __maybe_unused) { return TEST_SKIP; } #else -static int test__clang(struct test *test __maybe_unused, int i) +static int test__clang(struct test_suite *test __maybe_unused, int i) { if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) return TEST_FAIL; @@ -45,7 +45,7 @@ static int test__clang(struct test *test __maybe_unused, int i) } #endif -struct test suite__clang = { +struct test_suite suite__clang = { .desc = "builtin clang support", .func = test__clang, .subtest = { diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index e4199cb4d4bf..5610767b407f 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -716,7 +716,7 @@ out_err: return err; } -static int test__code_reading(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__code_reading(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret; diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 6f2525fb9fd7..89a155092f85 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -75,7 +75,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, } -static int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__cpu_map_synthesize(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct perf_cpu_map *cpus; @@ -111,7 +111,7 @@ static int cpu_map_print(const char *str) return !strcmp(buf, str); } -static int test__cpu_map_print(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__cpu_map_print(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1")); TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5")); @@ -123,7 +123,7 @@ static int test__cpu_map_print(struct test *test __maybe_unused, int subtest __m return 0; } -static int test__cpu_map_merge(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__cpu_map_merge(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct perf_cpu_map *a = perf_cpu_map__new("4,2,1"); struct perf_cpu_map *b = perf_cpu_map__new("4,5,7"); diff --git a/tools/perf/tests/demangle-java-test.c b/tools/perf/tests/demangle-java-test.c index 37f488e5c36d..44d1be303b67 100644 --- a/tools/perf/tests/demangle-java-test.c +++ b/tools/perf/tests/demangle-java-test.c @@ -7,7 +7,7 @@ #include "debug.h" #include "demangle-java.h" -static int test__demangle_java(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__demangle_java(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret = TEST_OK; char *buf = NULL; diff --git a/tools/perf/tests/demangle-ocaml-test.c b/tools/perf/tests/demangle-ocaml-test.c index ee982cca7bbf..90a4285e2ad5 100644 --- a/tools/perf/tests/demangle-ocaml-test.c +++ b/tools/perf/tests/demangle-ocaml-test.c @@ -7,7 +7,7 @@ #include "debug.h" #include "demangle-ocaml.h" -static int test__demangle_ocaml(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__demangle_ocaml(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret = TEST_OK; char *buf = NULL; diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c index 378f5afc6032..84352d55347d 100644 --- a/tools/perf/tests/dlfilter-test.c +++ b/tools/perf/tests/dlfilter-test.c @@ -398,7 +398,7 @@ static void test_data__free(struct test_data *td) } } -static int test__dlfilter(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dlfilter(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct test_data td = {.fd = -1}; int pid = getpid(); diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index d9e060a7c1f6..3419a4ab5590 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -113,7 +113,7 @@ static int dso__data_fd(struct dso *dso, struct machine *machine) return fd; } -static int test__dso_data(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dso_data(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; struct dso *dso; @@ -248,7 +248,7 @@ static int set_fd_limit(int n) return setrlimit(RLIMIT_NOFILE, &rlim); } -static int test__dso_data_cache(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dso_data_cache(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; long nr_end, nr = open_files_cnt(); @@ -318,7 +318,7 @@ static long new_limit(int count) return ret; } -static int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dso_data_reopen(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; long nr_end, nr = open_files_cnt(), lim = new_limit(3); diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 6e0429012ed6..2dab2d262060 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -195,7 +195,8 @@ NO_TAIL_CALL_ATTRIBUTE noinline int test_dwarf_unwind__krava_1(struct thread *th return ret; } -static int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__dwarf_unwind(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { struct machine *machine; struct thread *thread; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 2ce8945931e7..7606eb3df92f 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -216,7 +216,7 @@ out_err: * and checks that enabled and running times * match. */ -static int test__event_times(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__event_times(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err, ret = 0; diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 9dfb665f8ac9..fbb68deba59f 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -83,7 +83,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, return 0; } -static int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__event_update(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct evsel *evsel; struct event_name tmp; diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index 82ff3c04d0bd..fdbf17642e45 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -99,7 +99,7 @@ out_delete_evlist: #define perf_evsel__name_array_test(names, distance) \ __perf_evsel__name_array_test(names, ARRAY_SIZE(names), distance) -static int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, +static int test__perf_evsel__roundtrip_name_test(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = 0, ret = 0; diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index 58f17d18e4d5..cf4da3d748c2 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -32,7 +32,7 @@ static int evsel__test_field(struct evsel *evsel, const char *name, int size, bo return ret; } -static int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, +static int test__perf_evsel__tp_sched_test(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct evsel *evsel = evsel__newtp("sched", "sched_switch"); diff --git a/tools/perf/tests/expand-cgroup.c b/tools/perf/tests/expand-cgroup.c index 7bea14f0951e..dfefe5b60eb2 100644 --- a/tools/perf/tests/expand-cgroup.c +++ b/tools/perf/tests/expand-cgroup.c @@ -221,7 +221,7 @@ out: return ret; } -static int test__expand_cgroup_events(struct test *test __maybe_unused, +static int test__expand_cgroup_events(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret; diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 8c6397d0c381..0c041ac707e6 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -62,7 +62,7 @@ static int test(struct expr_parse_ctx *ctx, const char *e, double val2) return 0; } -static int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_unused) { struct expr_id_data *val_ptr; const char *p; diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c index 7b2f6c2ad705..40983c3574b1 100644 --- a/tools/perf/tests/fdarray.c +++ b/tools/perf/tests/fdarray.c @@ -28,7 +28,7 @@ static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE return printed + fdarray__fprintf(fda, fp); } -static int test__fdarray__filter(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__fdarray__filter(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int nr_fds, err = TEST_FAIL; struct fdarray *fda = fdarray__new(5, 5); @@ -89,7 +89,7 @@ out: return err; } -static int test__fdarray__add(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__fdarray__add(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct fdarray *fda = fdarray__new(2, 2); diff --git a/tools/perf/tests/genelf.c b/tools/perf/tests/genelf.c index 3c5ced5d9588..95f3be1b683a 100644 --- a/tools/perf/tests/genelf.c +++ b/tools/perf/tests/genelf.c @@ -16,7 +16,7 @@ #define TEMPL "/tmp/perf-test-XXXXXX" -static int test__jit_write_elf(struct test *test __maybe_unused, +static int test__jit_write_elf(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { #ifdef HAVE_JITDUMP diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index f7a8d3d78389..17f4fcd6bdce 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -689,7 +689,7 @@ out: return err; } -static int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__hists_cumulate(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 09e140191e5f..08cbeb9e39ae 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -101,7 +101,7 @@ out: return TEST_FAIL; } -static int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__hists_filter(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 08571f788884..c575e13a850d 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -264,7 +264,7 @@ static int validate_link(struct hists *leader, struct hists *other) return __validate_link(leader, 0) || __validate_link(other, 1); } -static int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__hists_link(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = -1; struct hists *hists, *first_hists; diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index b427df8ee94a..0bde4a768c15 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -575,7 +575,7 @@ out: return err; } -static int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__hists_output(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/is_printable_array.c b/tools/perf/tests/is_printable_array.c index 8891b10fac5c..f72de2457ff1 100644 --- a/tools/perf/tests/is_printable_array.c +++ b/tools/perf/tests/is_printable_array.c @@ -5,7 +5,7 @@ #include "debug.h" #include "print_binary.h" -static int test__is_printable_array(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__is_printable_array(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 }; char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 }; diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index e723c976dc81..dd2067312452 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -61,7 +61,7 @@ static int find_comm(struct evlist *evlist, const char *comm) * when an event is disabled but a dummy software event is not disabled. If the * test passes %0 is returned, otherwise %-1 is returned. */ -static int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__keep_tracking(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .mmap_pages = UINT_MAX, diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c index 4935dd3182ed..dfe1bd5dabaa 100644 --- a/tools/perf/tests/kmod-path.c +++ b/tools/perf/tests/kmod-path.c @@ -47,7 +47,7 @@ static int test_is_kernel_module(const char *path, int cpumode, bool expect) #define M(path, c, e) \ TEST_ASSERT_VAL("failed", !test_is_kernel_module(path, c, e)) -static int test__kmod_path__parse(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__kmod_path__parse(struct test_suite *t __maybe_unused, int subtest __maybe_unused) { /* path alloc_name kmod comp name */ T("/xxxx/xxxx/x-x.ko", true , true, 0 , "[x_x]"); diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index b605a71ad8d5..057d6a59a8ea 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -124,7 +124,7 @@ out: return ret; } -static int test__llvm(struct test *test __maybe_unused, int subtest) +static int test__llvm(struct test_suite *test __maybe_unused, int subtest) { int ret; void *obj_buf = NULL; @@ -162,7 +162,7 @@ static const char *test__llvm_subtest_get_desc(int subtest) return bpf_source_table[subtest].desc; } #else //HAVE_LIBBPF_SUPPORT -static int test__llvm(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__llvm(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { return TEST_SKIP; } @@ -178,7 +178,7 @@ static const char *test__llvm_subtest_get_desc(int subtest __maybe_unused) } #endif // HAVE_LIBBPF_SUPPORT -struct test suite__llvm = { +struct test_suite suite__llvm = { .desc = "LLVM search and compile", .func = test__llvm, .subtest = { diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index 4a2e6f312015..e308a3296cef 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -33,7 +33,7 @@ static int check_maps(struct map_def *merged, unsigned int size, struct maps *ma return TEST_OK; } -static int test__maps__merge_in(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest __maybe_unused) { struct maps maps; unsigned int i; diff --git a/tools/perf/tests/mem.c b/tools/perf/tests/mem.c index 3af082508653..56014ec7d49d 100644 --- a/tools/perf/tests/mem.c +++ b/tools/perf/tests/mem.c @@ -23,7 +23,7 @@ static int check(union perf_mem_data_src data_src, return 0; } -static int test__mem(struct test *text __maybe_unused, int subtest __maybe_unused) +static int test__mem(struct test_suite *text __maybe_unused, int subtest __maybe_unused) { int ret = 0; union perf_mem_data_src src; diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index 0a90e6084d81..b17b86391383 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -43,7 +43,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) return bm && map ? bm : NULL; } -static int test__mem2node(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__mem2node(struct test_suite *t __maybe_unused, int subtest __maybe_unused) { struct mem2node map; struct memory_node nodes[3]; diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 86f34631312d..90b2feda31ac 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -29,7 +29,7 @@ * Then it checks if the number of syscalls reported as perf events by * the kernel corresponds to the number of syscalls made. */ -static int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = -1; union perf_event *event; diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index 756a46c796f7..a4301fc7b770 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -224,7 +224,7 @@ static int mmap_events(synth_cb synth) * * by using all thread objects. */ -static int test__mmap_thread_lookup(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__mmap_thread_lookup(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { /* perf_event__synthesize_threads synthesize */ TEST_ASSERT_VAL("failed with sythesizing all", diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 28f3597ba531..cd3dd463783f 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -19,7 +19,7 @@ #include "stat.h" #include "util/counts.h" -static int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, +static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = -1, fd, cpu; diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index cbb5c0fa40fe..a7b2800652e4 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -22,7 +22,7 @@ #define AT_FDCWD -100 #endif -static int test__syscall_openat_tp_fields(struct test *test __maybe_unused, +static int test__syscall_openat_tp_fields(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index 8f904fcebe6f..7f4c13c4b14d 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -13,7 +13,7 @@ #include "tests.h" #include "util/counts.h" -static int test__openat_syscall_event(struct test *test __maybe_unused, +static int test__openat_syscall_event(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = -1, fd; diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 1522dd39dd0a..a508f1dbcb2a 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -2276,7 +2276,7 @@ static int test_pmu_events_alias(char *event, char *alias) return test_event(&e); } -static int test__parse_events(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__parse_events(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret1, ret2 = 0; char *event, *alias; diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c index 999d37fc58f2..574b7e4efd3a 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -369,7 +369,7 @@ static int test_metric_group(void) return 0; } -static int test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__parse_metric(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("IPC failed", test_ipc() == 0); TEST_ASSERT_VAL("frontend failed", test_frontend() == 0); diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index 2a5eec424a43..d62e31595ab2 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -67,7 +67,7 @@ struct test_attr_event { * * Return: %0 on success, %-1 if the test fails. */ -static int test__parse_no_sample_id_all(struct test *test __maybe_unused, +static int test__parse_no_sample_id_all(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err; diff --git a/tools/perf/tests/pe-file-parsing.c b/tools/perf/tests/pe-file-parsing.c index 8d4fec99459a..c09a9fae1689 100644 --- a/tools/perf/tests/pe-file-parsing.c +++ b/tools/perf/tests/pe-file-parsing.c @@ -68,7 +68,7 @@ static int run_dir(const char *d) return TEST_OK; } -static int test__pe_file_parsing(struct test *test __maybe_unused, +static int test__pe_file_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct stat st; @@ -89,7 +89,7 @@ static int test__pe_file_parsing(struct test *test __maybe_unused, #else -static int test__pe_file_parsing(struct test *test __maybe_unused, +static int test__pe_file_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { return TEST_SKIP; diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c index 61cb1d0a6eb9..78cdeb89645e 100644 --- a/tools/perf/tests/perf-hooks.c +++ b/tools/perf/tests/perf-hooks.c @@ -26,7 +26,7 @@ static void the_hook(void *_hook_flags) raise(SIGSEGV); } -static int test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__perf_hooks(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int hook_flags = 0; diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 24faa8487d8c..6354465067b8 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -41,7 +41,7 @@ realloc: return cpu; } -static int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .target = { diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index dc2dcad7371f..d23740f80c7d 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -45,7 +45,7 @@ * %0 is returned, otherwise %-1 is returned. If TSC conversion is not * supported then then the test passes but " (not supported)" is printed. */ -static int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .mmap_pages = UINT_MAX, @@ -198,7 +198,7 @@ static bool test__tsc_is_supported(void) #endif } -struct test suite__perf_time_to_tsc = { +struct test_suite suite__perf_time_to_tsc = { .desc = "Convert perf time to TSC", .func = test__perf_time_to_tsc, .is_supported = test__tsc_is_supported, diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c index 83dc9742813a..f55e4ecdda71 100644 --- a/tools/perf/tests/pfm.c +++ b/tools/perf/tests/pfm.c @@ -201,7 +201,7 @@ static int test__pfm_subtest_get_nr(void) return (int)ARRAY_SIZE(pfm_testcase_table); } -static int test__pfm(struct test *test __maybe_unused, int i __maybe_unused) +static int test__pfm(struct test_suite *test __maybe_unused, int i __maybe_unused) { #ifdef HAVE_LIBPFM if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) @@ -212,7 +212,7 @@ static int test__pfm(struct test *test __maybe_unused, int i __maybe_unused) #endif } -struct test suite__pfm = { +struct test_suite suite__pfm = { .desc = "Test libpfm4 support", .func = test__pfm, .subtest = { diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index c3f32ddd8210..954d705534da 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -1113,7 +1113,7 @@ static int test__pmu_events_subtest_get_nr(void) return (int)ARRAY_SIZE(pmu_events_testcase_table); } -static int test__pmu_events(struct test *test __maybe_unused, int subtest) +static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest) { if (subtest < 0 || subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table)) @@ -1121,7 +1121,7 @@ static int test__pmu_events(struct test *test __maybe_unused, int subtest) return pmu_events_testcase_table[subtest].func(); } -struct test suite__pmu_events = { +struct test_suite suite__pmu_events = { .desc = "PMU events", .func = test__pmu_events, .subtest = { diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index 9a58dad67b27..8507bd615e97 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -137,7 +137,7 @@ static struct list_head *test_terms_list(void) return &terms; } -static int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__pmu(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { char *format = test_format_dir_get(); LIST_HEAD(formats); diff --git a/tools/perf/tests/python-use.c b/tools/perf/tests/python-use.c index b667140688be..6b990ee38575 100644 --- a/tools/perf/tests/python-use.c +++ b/tools/perf/tests/python-use.c @@ -9,7 +9,7 @@ #include "tests.h" #include "util/debug.h" -static int test__python_use(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__python_use(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { char *cmd; int ret; diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 08453238c777..b669d22f2b13 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -368,7 +368,7 @@ out_free: * checks sample format bits separately and together. If the test passes %0 is * returned, otherwise %-1 is returned. */ -static int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15}; u64 sample_type; diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index 307615f1b6a7..919712899251 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -76,7 +76,7 @@ static int search_cached_probe(const char *target, return ret; } -static int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) +static int test__sdt_event(struct test_suite *test __maybe_unused, int subtests __maybe_unused) { int ret = TEST_FAIL; char __tempdir[] = "./test-buildid-XXXXXX"; @@ -114,7 +114,7 @@ error: return ret; } #else -static int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) +static int test__sdt_event(struct test_suite *test __maybe_unused, int subtests __maybe_unused) { pr_debug("Skip SDT event test because SDT support is not compiled\n"); return TEST_SKIP; diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c index 2589f2f529ba..2eb096b5e6da 100644 --- a/tools/perf/tests/stat.c +++ b/tools/perf/tests/stat.c @@ -47,7 +47,7 @@ static int process_stat_config_event(struct perf_tool *tool __maybe_unused, return 0; } -static int test__synthesize_stat_config(struct test *test __maybe_unused, +static int test__synthesize_stat_config(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct perf_stat_config stat_config = { @@ -78,7 +78,7 @@ static int process_stat_event(struct perf_tool *tool __maybe_unused, return 0; } -static int test__synthesize_stat(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__synthesize_stat(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct perf_counts_values count; @@ -104,7 +104,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused, return 0; } -static int test__synthesize_stat_round(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__synthesize_stat_round(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to synthesize stat_config", !perf_event__synthesize_stat_round(NULL, 0xdeadbeef, PERF_STAT_ROUND_TYPE__INTERVAL, diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index db1e339a0fbe..9cd6fec375ee 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -133,7 +133,7 @@ out_delete_evlist: return err; } -static int test__sw_clock_freq(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__sw_clock_freq(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 9b379aaddce4..0c0c2328bf4e 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -321,7 +321,7 @@ out_free_nodes: * evsel->core.system_wide and evsel->tracking flags (respectively) with other events * sometimes enabled or disabled. */ -static int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__switch_tracking(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { const char *sched_switch = "sched:sched_switch"; struct switch_tracking switch_tracking = { .tids = NULL, }; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 197574230493..25f075fa9125 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -39,7 +39,7 @@ static void workload_exec_failed_signal(int signo __maybe_unused, * if the number of exit event reported by the kernel is 1 or not * in order to check the kernel returns correct number of event. */ -static int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__task_exit(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = -1; union perf_event *event; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index f2efa331b32f..c95b0de9f822 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -27,9 +27,9 @@ enum { TEST_SKIP = -2, }; -struct test { +struct test_suite { const char *desc; - int (*func)(struct test *test, int subtest); + int (*func)(struct test_suite *test, int subtest); struct { bool skip_if_fail; int (*get_nr)(void); @@ -41,10 +41,10 @@ struct test { }; #define DECLARE_SUITE(name) \ - extern struct test suite__##name; + extern struct test_suite suite__##name; #define DEFINE_SUITE(description, name) \ - struct test suite__##name = { \ + struct test_suite suite__##name = { \ .desc = description, \ .func = test__##name, \ } diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index 7e2e8a72fa78..e413c1387fcb 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -19,7 +19,7 @@ struct machine; #define NAME (const char *) "perf" #define NAMEUL (unsigned long) NAME -static int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__thread_map(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct perf_thread_map *map; @@ -86,7 +86,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, return 0; } -static int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__thread_map_synthesize(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct perf_thread_map *threads; @@ -106,7 +106,7 @@ static int test__thread_map_synthesize(struct test *test __maybe_unused, int sub return 0; } -static int test__thread_map_remove(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__thread_map_remove(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct perf_thread_map *threads; char *str; diff --git a/tools/perf/tests/thread-maps-share.c b/tools/perf/tests/thread-maps-share.c index 2821be0a9a05..84edd82c519e 100644 --- a/tools/perf/tests/thread-maps-share.c +++ b/tools/perf/tests/thread-maps-share.c @@ -4,7 +4,7 @@ #include "thread.h" #include "debug.h" -static int test__thread_maps_share(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__thread_maps_share(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct machines machines; struct machine *machine; diff --git a/tools/perf/tests/time-utils-test.c b/tools/perf/tests/time-utils-test.c index 538100cb7541..38df10373c1e 100644 --- a/tools/perf/tests/time-utils-test.c +++ b/tools/perf/tests/time-utils-test.c @@ -131,7 +131,7 @@ out: return pass; } -static int test__time_utils(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__time_utils(struct test_suite *t __maybe_unused, int subtest __maybe_unused) { bool pass = true; diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 09e5fcdb646d..869986139146 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -175,7 +175,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map) return 0; } -static int test__session_topology(struct test *test __maybe_unused, int subtest __maybe_unused) +static int test__session_topology(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { char path[PATH_MAX]; struct perf_cpu_map *map; diff --git a/tools/perf/tests/unit_number__scnprintf.c b/tools/perf/tests/unit_number__scnprintf.c index 2ad78a9473d4..88bcada1c78f 100644 --- a/tools/perf/tests/unit_number__scnprintf.c +++ b/tools/perf/tests/unit_number__scnprintf.c @@ -7,7 +7,7 @@ #include "units.h" #include "debug.h" -static int test__unit_number__scnprint(struct test *t __maybe_unused, int subtest __maybe_unused) +static int test__unit_number__scnprint(struct test_suite *t __maybe_unused, int subtest __maybe_unused) { struct { u64 n; diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 7f1b74bf4f13..e80df13c0420 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -111,7 +111,7 @@ static bool is_ignored_symbol(const char *name, char type) return false; } -static int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, +static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int err = -1; diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c index 16ab733cabce..904bdf2dcf81 100644 --- a/tools/perf/tests/wp.c +++ b/tools/perf/tests/wp.c @@ -230,7 +230,7 @@ static const char *test__wp_subtest_skip_reason(int i) return wp_testcase_table[i].skip_msg(); } -static int test__wp(struct test *test __maybe_unused, int i) +static int test__wp(struct test_suite *test __maybe_unused, int i) { if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table)) return TEST_FAIL; @@ -254,7 +254,7 @@ static bool test__wp_is_supported(void) #endif } -struct test suite__wp = { +struct test_suite suite__wp = { .desc = "Watchpoint", .func = test__wp, .is_supported = test__wp_is_supported, -- cgit v1.2.3 From f832044c8e8a92ab418bf11d10b18e7ffe024190 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:52 -0700 Subject: perf test: Add helper functions for abstraction. Abstract certain test features so that they can be refactored in later changes. No functional change. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 94 +++++++++++++++++++++++++++++------------ tools/perf/tests/tests.h | 6 ++- 2 files changed, 71 insertions(+), 29 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 7d52e2eb8147..96eb486ffbc9 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -115,6 +115,45 @@ static struct test_suite **tests[] = { arch_tests, }; +static int num_subtests(const struct test_suite *t) +{ + if (t->subtest.get_nr) + return t->subtest.get_nr(); + + return 0; +} + +static bool has_subtests(const struct test_suite *t) +{ + return t->subtest.get_nr || num_subtests(t) > 1; +} + +static const char *skip_reason(const struct test_suite *t, int subtest) +{ + if (t->subtest.skip_reason) + return t->subtest.skip_reason(subtest); + + return NULL; +} + +static const char *test_description(const struct test_suite *t, int subtest) +{ + if (subtest < 0 || !t->subtest.get_desc) + return t->desc; + + return t->subtest.get_desc(subtest); +} + +static bool is_supported(const struct test_suite *t) +{ + return !t->is_supported || t->is_supported(); +} + +static test_fnptr test_function(const struct test_suite *t, int subtest __maybe_unused) +{ + return t->func; +} + static bool perf_test__matches(const char *desc, int curr, int argc, const char *argv[]) { int i; @@ -171,7 +210,7 @@ static int run_test(struct test_suite *test, int subtest) } } - err = test->func(test, subtest); + err = test_function(test, subtest)(test, subtest); if (!dont_fork) exit(err); } @@ -208,7 +247,7 @@ static int test_and_print(struct test_suite *t, bool force_skip, int subtest) err = TEST_SKIP; } - if (!t->subtest.get_nr) + if (!has_subtests(t)) pr_debug("%s:", t->desc); else pr_debug("%s subtest %d:", t->desc, subtest + 1); @@ -218,11 +257,10 @@ static int test_and_print(struct test_suite *t, bool force_skip, int subtest) pr_info(" Ok\n"); break; case TEST_SKIP: { - const char *skip_reason = NULL; - if (t->subtest.skip_reason) - skip_reason = t->subtest.skip_reason(subtest); - if (skip_reason) - color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (%s)\n", skip_reason); + const char *reason = skip_reason(t, subtest); + + if (reason) + color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (%s)\n", reason); else color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n"); } @@ -397,7 +435,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) int width = shell_tests__max_desc_width(); for_each_test(j, k, t) { - int len = strlen(t->desc); + int len = strlen(test_description(t, -1)); if (width < len) width = len; @@ -407,17 +445,15 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) int curr = i++, err; int subi; - if (!perf_test__matches(t->desc, curr, argc, argv)) { + if (!perf_test__matches(test_description(t, -1), curr, argc, argv)) { bool skip = true; int subn; - if (!t->subtest.get_nr) - continue; - - subn = t->subtest.get_nr(); + subn = num_subtests(t); for (subi = 0; subi < subn; subi++) { - if (perf_test__matches(t->subtest.get_desc(subi), curr, argc, argv)) + if (perf_test__matches(test_description(t, subi), + curr, argc, argv)) skip = false; } @@ -425,22 +461,23 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) continue; } - if (t->is_supported && !t->is_supported()) { - pr_debug("%2d: %-*s: Disabled\n", i, width, t->desc); + if (!is_supported(t)) { + pr_debug("%2d: %-*s: Disabled\n", i, width, + test_description(t, -1)); continue; } - pr_info("%2d: %-*s:", i, width, t->desc); + pr_info("%2d: %-*s:", i, width, test_description(t, -1)); if (intlist__find(skiplist, i)) { color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); continue; } - if (!t->subtest.get_nr) { + if (!has_subtests(t)) { test_and_print(t, false, -1); } else { - int subn = t->subtest.get_nr(); + int subn = num_subtests(t); /* * minus 2 to align with normal testcases. * For subtest we print additional '.x' in number. @@ -460,18 +497,19 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) pr_info("\n"); for (subi = 0; subi < subn; subi++) { - int len = strlen(t->subtest.get_desc(subi)); + int len = strlen(test_description(t, subi)); if (subw < len) subw = len; } for (subi = 0; subi < subn; subi++) { - if (!perf_test__matches(t->subtest.get_desc(subi), curr, argc, argv)) + if (!perf_test__matches(test_description(t, subi), + curr, argc, argv)) continue; pr_info("%2d.%1d: %-*s:", i, subi + 1, subw, - t->subtest.get_desc(subi)); + test_description(t, subi)); err = test_and_print(t, skip, subi); if (err != TEST_OK && t->subtest.skip_if_fail) skip = true; @@ -526,19 +564,19 @@ static int perf_test__list(int argc, const char **argv) for_each_test(j, k, t) { int curr = i++; - if (!perf_test__matches(t->desc, curr, argc, argv) || - (t->is_supported && !t->is_supported())) + if (!perf_test__matches(test_description(t, -1), curr, argc, argv) || + !is_supported(t)) continue; - pr_info("%2d: %s\n", i, t->desc); + pr_info("%2d: %s\n", i, test_description(t, -1)); - if (t->subtest.get_nr) { - int subn = t->subtest.get_nr(); + if (has_subtests(t)) { + int subn = num_subtests(t); int subi; for (subi = 0; subi < subn; subi++) pr_info("%2d:%1d: %s\n", i, subi + 1, - t->subtest.get_desc(subi)); + test_description(t, subi)); } } diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index c95b0de9f822..5139e24973cc 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -27,9 +27,13 @@ enum { TEST_SKIP = -2, }; +struct test_suite; + +typedef int (*test_fnptr)(struct test_suite *, int); + struct test_suite { const char *desc; - int (*func)(struct test_suite *test, int subtest); + test_fnptr func; struct { bool skip_if_fail; int (*get_nr)(void); -- cgit v1.2.3 From 78244d2e21146b88faffe2653397f0fa176794f1 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:53 -0700 Subject: perf test: Add test case struct. Add a test case struct mirroring the 'struct kunit_case'. Use the struct with the DEFINE_SUITE macro, where the single test is turned into a test case. Update the helpers in builtin-test to handle test cases. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-8-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 30 ++++++++++++++++++++++++------ tools/perf/tests/tests.h | 26 ++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 10 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 96eb486ffbc9..a6d84feba483 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -117,10 +117,19 @@ static struct test_suite **tests[] = { static int num_subtests(const struct test_suite *t) { + int num; + if (t->subtest.get_nr) return t->subtest.get_nr(); - return 0; + if (!t->test_cases) + return 0; + + num = 0; + while (t->test_cases[num].name) + num++; + + return num; } static bool has_subtests(const struct test_suite *t) @@ -138,10 +147,13 @@ static const char *skip_reason(const struct test_suite *t, int subtest) static const char *test_description(const struct test_suite *t, int subtest) { - if (subtest < 0 || !t->subtest.get_desc) - return t->desc; + if (t->test_cases && subtest >= 0) + return t->test_cases[subtest].desc; - return t->subtest.get_desc(subtest); + if (t->subtest.get_desc && subtest >= 0) + return t->subtest.get_desc(subtest); + + return t->desc; } static bool is_supported(const struct test_suite *t) @@ -149,9 +161,15 @@ static bool is_supported(const struct test_suite *t) return !t->is_supported || t->is_supported(); } -static test_fnptr test_function(const struct test_suite *t, int subtest __maybe_unused) +static test_fnptr test_function(const struct test_suite *t, int subtest) { - return t->func; + if (t->func) + return t->func; + + if (subtest <= 0) + return t->test_cases[0].run_case; + + return t->test_cases[subtest].run_case; } static bool perf_test__matches(const char *desc, int curr, int argc, const char *argv[]) diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 5139e24973cc..71b8d2c88e5c 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -31,6 +31,12 @@ struct test_suite; typedef int (*test_fnptr)(struct test_suite *, int); +struct test_case { + const char *name; + const char *desc; + test_fnptr run_case; +}; + struct test_suite { const char *desc; test_fnptr func; @@ -40,6 +46,7 @@ struct test_suite { const char *(*get_desc)(int subtest); const char *(*skip_reason)(int subtest); } subtest; + struct test_case *test_cases; bool (*is_supported)(void); void *priv; }; @@ -47,10 +54,21 @@ struct test_suite { #define DECLARE_SUITE(name) \ extern struct test_suite suite__##name; -#define DEFINE_SUITE(description, name) \ - struct test_suite suite__##name = { \ - .desc = description, \ - .func = test__##name, \ +#define TEST_CASE(description, _name) \ + { \ + .name = #_name, \ + .desc = description, \ + .run_case = test__##_name, \ + } + +#define DEFINE_SUITE(description, _name) \ + struct test_case tests__##_name[] = { \ + TEST_CASE(description, _name), \ + { .name = NULL, } \ + }; \ + struct test_suite suite__##_name = { \ + .desc = description, \ + .test_cases = tests__##_name, \ } /* Tests */ -- cgit v1.2.3 From 9be56d30802f6da22c7afe7e70a77a3bdda6561b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:54 -0700 Subject: perf test: Add skip reason to test case. This doesn't exist in kunit, but will ease the transition from perf tests. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-9-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 3 +++ tools/perf/tests/tests.h | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index a6d84feba483..db76d7d10749 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -142,6 +142,9 @@ static const char *skip_reason(const struct test_suite *t, int subtest) if (t->subtest.skip_reason) return t->subtest.skip_reason(subtest); + if (t->test_cases && subtest >= 0) + return t->test_cases[subtest].skip_reason; + return NULL; } diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 71b8d2c88e5c..f87129b63d92 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -34,6 +34,7 @@ typedef int (*test_fnptr)(struct test_suite *, int); struct test_case { const char *name; const char *desc; + const char *skip_reason; test_fnptr run_case; }; @@ -61,7 +62,15 @@ struct test_suite { .run_case = test__##_name, \ } -#define DEFINE_SUITE(description, _name) \ +#define TEST_CASE_REASON(description, _name, _reason) \ + { \ + .name = #_name, \ + .desc = description, \ + .run_case = test__##_name, \ + .skip_reason = _reason, \ + } + +#define DEFINE_SUITE(description, _name) \ struct test_case tests__##_name[] = { \ TEST_CASE(description, _name), \ { .name = NULL, } \ -- cgit v1.2.3 From 039f3555455dedeb63a363c2e32f66a8d0d0795e Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:55 -0700 Subject: perf test: Convert pfm tests to use test cases. Use null terminated array of test cases rather than the previous sub test functions. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-10-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/pfm.c | 66 +++++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 47 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c index f55e4ecdda71..651fee4ef819 100644 --- a/tools/perf/tests/pfm.c +++ b/tools/perf/tests/pfm.c @@ -11,27 +11,6 @@ #include -#ifdef HAVE_LIBPFM -static int test__pfm_events(void); -static int test__pfm_group(void); -#endif - -static const struct { - int (*func)(void); - const char *desc; -} pfm_testcase_table[] = { -#ifdef HAVE_LIBPFM - { - .func = test__pfm_events, - .desc = "test of individual --pfm-events", - }, - { - .func = test__pfm_group, - .desc = "test groups of --pfm-events", - }, -#endif -}; - #ifdef HAVE_LIBPFM static int count_pfm_events(struct perf_evlist *evlist) { @@ -44,7 +23,8 @@ static int count_pfm_events(struct perf_evlist *evlist) return count; } -static int test__pfm_events(void) +static int test__pfm_events(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { struct evlist *evlist; struct option opt; @@ -104,7 +84,8 @@ static int test__pfm_events(void) return 0; } -static int test__pfm_group(void) +static int test__pfm_group(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { struct evlist *evlist; struct option opt; @@ -187,37 +168,28 @@ static int test__pfm_group(void) } return 0; } -#endif - -static const char *test__pfm_subtest_get_desc(int i) -{ - if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) - return NULL; - return pfm_testcase_table[i].desc; -} - -static int test__pfm_subtest_get_nr(void) +#else +static int test__pfm_events(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { - return (int)ARRAY_SIZE(pfm_testcase_table); + return TEST_SKIP; } -static int test__pfm(struct test_suite *test __maybe_unused, int i __maybe_unused) +static int test__pfm_group(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { -#ifdef HAVE_LIBPFM - if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table)) - return TEST_FAIL; - return pfm_testcase_table[i].func(); -#else return TEST_SKIP; -#endif } +#endif + +static struct test_case pfm_tests[] = { + TEST_CASE_REASON("test of individual --pfm-events", pfm_events, "not compiled in"), + TEST_CASE_REASON("test groups of --pfm-events", pfm_group, "not compiled in"), + { .name = NULL, } +}; struct test_suite suite__pfm = { .desc = "Test libpfm4 support", - .func = test__pfm, - .subtest = { - .skip_if_fail = true, - .get_nr = test__pfm_subtest_get_nr, - .get_desc = test__pfm_subtest_get_desc, - } + .test_cases = pfm_tests, + .subtest = { .skip_if_fail = true } }; -- cgit v1.2.3 From 2a74fe82831e3c8cadd1b2d2c594f1750a9decdc Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:56 -0700 Subject: perf test: Convert pmu event tests to test cases. Use null terminated array of test cases rather than the previous sub test functions. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-11-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/pmu-events.c | 78 +++++++++---------------------------------- 1 file changed, 16 insertions(+), 62 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 954d705534da..df1c9a3cc05b 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -418,7 +418,8 @@ static int compare_alias_to_test_event(struct perf_pmu_alias *alias, } /* Verify generated events from pmu-events.c are as expected */ -static int test_pmu_event_table(void) +static int test__pmu_event_table(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { const struct pmu_event *sys_event_tables = __test_pmu_get_sys_events_table(); const struct pmu_events_map *map = __test_pmu_get_events_map(); @@ -705,7 +706,8 @@ static struct perf_pmu_test_pmu test_pmus[] = { }; /* Test that aliases generated are as expected */ -static int test_aliases(void) +static int test__aliases(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { struct perf_pmu *pmu = NULL; unsigned long i; @@ -892,7 +894,8 @@ out_err: } -static int test_parsing(void) +static int test__parsing(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { const struct pmu_events_map *cpus_map = pmu_events_map__find(); const struct pmu_events_map *map; @@ -1034,7 +1037,8 @@ out: * or all defined cpus via the 'fake_pmu' * in parse_events. */ -static int test_parsing_fake(void) +static int test__parsing_fake(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { const struct pmu_events_map *map; const struct pmu_event *pe; @@ -1068,66 +1072,16 @@ static int test_parsing_fake(void) return 0; } -static const struct { - int (*func)(void); - const char *desc; -} pmu_events_testcase_table[] = { - { - .func = test_pmu_event_table, - .desc = "PMU event table sanity", - }, - { - .func = test_aliases, - .desc = "PMU event map aliases", - }, - { - .func = test_parsing, - .desc = "Parsing of PMU event table metrics", - }, - { - .func = test_parsing_fake, - .desc = "Parsing of PMU event table metrics with fake PMUs", - }, +static struct test_case pmu_events_tests[] = { + TEST_CASE("PMU event table sanity", pmu_event_table), + TEST_CASE("PMU event map aliases", aliases), + TEST_CASE_REASON("Parsing of PMU event table metrics", parsing, + "some metrics failed"), + TEST_CASE("Parsing of PMU event table metrics with fake PMUs", parsing_fake), + { .name = NULL, } }; -static const char *test__pmu_events_subtest_get_desc(int subtest) -{ - if (subtest < 0 || - subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table)) - return NULL; - return pmu_events_testcase_table[subtest].desc; -} - -static const char *test__pmu_events_subtest_skip_reason(int subtest) -{ - if (subtest < 0 || - subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table)) - return NULL; - if (pmu_events_testcase_table[subtest].func != test_parsing) - return NULL; - return "some metrics failed"; -} - -static int test__pmu_events_subtest_get_nr(void) -{ - return (int)ARRAY_SIZE(pmu_events_testcase_table); -} - -static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest) -{ - if (subtest < 0 || - subtest >= (int)ARRAY_SIZE(pmu_events_testcase_table)) - return TEST_FAIL; - return pmu_events_testcase_table[subtest].func(); -} - struct test_suite suite__pmu_events = { .desc = "PMU events", - .func = test__pmu_events, - .subtest = { - .skip_if_fail = false, - .get_nr = test__pmu_events_subtest_get_nr, - .get_desc = test__pmu_events_subtest_get_desc, - .skip_reason = test__pmu_events_subtest_skip_reason, - }, + .test_cases = pmu_events_tests, }; -- cgit v1.2.3 From e47c6ecaae1df54aec9211f3c12d6f4f5bb09346 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:57 -0700 Subject: perf test: Convert watch point tests to test cases. Use null terminated array of test cases rather than the previous sub test functions. Committer notes: On s/390x we don't use __event(), so wrap it with __s390x__ Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-12-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/wp.c | 130 +++++++++++++------------------------------------- 1 file changed, 32 insertions(+), 98 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/wp.c b/tools/perf/tests/wp.c index 904bdf2dcf81..820d942b30c3 100644 --- a/tools/perf/tests/wp.c +++ b/tools/perf/tests/wp.c @@ -48,6 +48,7 @@ static void get__perf_event_attr(struct perf_event_attr *attr, int wp_type, attr->exclude_hv = 1; } +#ifndef __s390x__ static int __event(int wp_type, void *wp_addr, unsigned long wp_len) { int fd; @@ -61,9 +62,14 @@ static int __event(int wp_type, void *wp_addr, unsigned long wp_len) return fd; } +#endif -static int wp_ro_test(void) +static int test__wp_ro(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { +#if defined(__s390x__) || defined(__x86_64__) || defined(__i386__) + return TEST_SKIP; +#else int fd; unsigned long tmp, tmp1 = rand(); @@ -79,10 +85,15 @@ static int wp_ro_test(void) close(fd); return 0; +#endif } -static int wp_wo_test(void) +static int test__wp_wo(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { +#if defined(__s390x__) + return TEST_SKIP; +#else int fd; unsigned long tmp, tmp1 = rand(); @@ -98,10 +109,15 @@ static int wp_wo_test(void) close(fd); return 0; +#endif } -static int wp_rw_test(void) +static int test__wp_rw(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { +#if defined(__s390x__) + return TEST_SKIP; +#else int fd; unsigned long tmp, tmp1 = rand(); @@ -118,10 +134,15 @@ static int wp_rw_test(void) close(fd); return 0; +#endif } -static int wp_modify_test(void) +static int test__wp_modify(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { +#if defined(__s390x__) + return TEST_SKIP; +#else int fd, ret; unsigned long tmp = rand(); struct perf_event_attr new_attr; @@ -163,105 +184,18 @@ static int wp_modify_test(void) close(fd); return 0; -} - -static bool wp_ro_supported(void) -{ -#if defined (__x86_64__) || defined (__i386__) - return false; -#else - return true; -#endif -} - -static const char *wp_ro_skip_msg(void) -{ -#if defined (__x86_64__) || defined (__i386__) - return "missing hardware support"; -#else - return NULL; #endif } -static struct { - const char *desc; - int (*target_func)(void); - bool (*is_supported)(void); - const char *(*skip_msg)(void); -} wp_testcase_table[] = { - { - .desc = "Read Only Watchpoint", - .target_func = &wp_ro_test, - .is_supported = &wp_ro_supported, - .skip_msg = &wp_ro_skip_msg, - }, - { - .desc = "Write Only Watchpoint", - .target_func = &wp_wo_test, - }, - { - .desc = "Read / Write Watchpoint", - .target_func = &wp_rw_test, - }, - { - .desc = "Modify Watchpoint", - .target_func = &wp_modify_test, - }, +static struct test_case wp_tests[] = { + TEST_CASE_REASON("Read Only Watchpoint", wp_ro, "missing hardware support"), + TEST_CASE_REASON("Write Only Watchpoint", wp_wo, "missing hardware support"), + TEST_CASE_REASON("Read / Write Watchpoint", wp_rw, "missing hardware support"), + TEST_CASE_REASON("Modify Watchpoint", wp_modify, "missing hardware support"), + { .name = NULL, } }; -static int test__wp_subtest_get_nr(void) -{ - return (int)ARRAY_SIZE(wp_testcase_table); -} - -static const char *test__wp_subtest_get_desc(int i) -{ - if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table)) - return NULL; - return wp_testcase_table[i].desc; -} - -static const char *test__wp_subtest_skip_reason(int i) -{ - if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table)) - return NULL; - if (!wp_testcase_table[i].skip_msg) - return NULL; - return wp_testcase_table[i].skip_msg(); -} - -static int test__wp(struct test_suite *test __maybe_unused, int i) -{ - if (i < 0 || i >= (int)ARRAY_SIZE(wp_testcase_table)) - return TEST_FAIL; - - if (wp_testcase_table[i].is_supported && - !wp_testcase_table[i].is_supported()) - return TEST_SKIP; - - return !wp_testcase_table[i].target_func() ? TEST_OK : TEST_FAIL; -} - -/* The s390 so far does not have support for - * instruction breakpoint using the perf_event_open() system call. - */ -static bool test__wp_is_supported(void) -{ -#if defined(__s390x__) - return false; -#else - return true; -#endif -} - struct test_suite suite__wp = { .desc = "Watchpoint", - .func = test__wp, - .is_supported = test__wp_is_supported, - .subtest = { - .skip_if_fail = false, - .get_nr = test__wp_subtest_get_nr, - .get_desc = test__wp_subtest_get_desc, - .skip_reason = test__wp_subtest_skip_reason, - }, + .test_cases = wp_tests, }; -- cgit v1.2.3 From 44a8528c241b5c1178e091eab56e6b1aefcbb283 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:58 -0700 Subject: perf test: Convert clang tests to test cases. Use null terminated array of test cases rather than the previous sub test functions. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-13-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/clang.c | 57 ++++++++++++-------------------------- tools/perf/util/c++/clang-c.h | 8 ++---- tools/perf/util/c++/clang-test.cpp | 6 ++-- 3 files changed, 24 insertions(+), 47 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index a499fcf37bf9..ba06a2257574 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -3,54 +3,31 @@ #include "c++/clang-c.h" #include -static struct { - int (*func)(void); - const char *desc; -} clang_testcase_table[] = { -#ifdef HAVE_LIBCLANGLLVM_SUPPORT - { - .func = test__clang_to_IR, - .desc = "builtin clang compile C source to IR", - }, - { - .func = test__clang_to_obj, - .desc = "builtin clang compile C source to ELF object", - }, -#endif -}; - -static int test__clang_subtest_get_nr(void) -{ - return (int)ARRAY_SIZE(clang_testcase_table); -} - -static const char *test__clang_subtest_get_desc(int i) -{ - if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) - return NULL; - return clang_testcase_table[i].desc; -} - #ifndef HAVE_LIBCLANGLLVM_SUPPORT -static int test__clang(struct test_suite *test __maybe_unused, int i __maybe_unused) +static int test__clang_to_IR(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { return TEST_SKIP; } -#else -static int test__clang(struct test_suite *test __maybe_unused, int i) + +static int test__clang_to_obj(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { - if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) - return TEST_FAIL; - return clang_testcase_table[i].func(); + return TEST_SKIP; } #endif +static struct test_case clang_tests[] = { + TEST_CASE_REASON("builtin clang compile C source to IR", clang_to_IR, + "not compiled in"), + TEST_CASE_REASON("builtin clang compile C source to ELF object", + clang_to_obj, + "not compiled in"), + { .name = NULL, } +}; + struct test_suite suite__clang = { .desc = "builtin clang support", - .func = test__clang, - .subtest = { - .skip_if_fail = true, - .get_nr = test__clang_subtest_get_nr, - .get_desc = test__clang_subtest_get_desc, - } + .test_cases = clang_tests, + .subtest = { .skip_if_fail = true, }, }; diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h index 2df8a45bd088..d3731a876b6c 100644 --- a/tools/perf/util/c++/clang-c.h +++ b/tools/perf/util/c++/clang-c.h @@ -12,8 +12,9 @@ extern "C" { extern void perf_clang__init(void); extern void perf_clang__cleanup(void); -extern int test__clang_to_IR(void); -extern int test__clang_to_obj(void); +struct test_suite; +extern int test__clang_to_IR(struct test_suite *test, int subtest); +extern int test__clang_to_obj(struct test_suite *test, int subtest); extern int perf_clang__compile_bpf(const char *filename, void **p_obj_buf, @@ -26,9 +27,6 @@ extern int perf_clang__compile_bpf(const char *filename, static inline void perf_clang__init(void) { } static inline void perf_clang__cleanup(void) { } -static inline int test__clang_to_IR(void) { return -1; } -static inline int test__clang_to_obj(void) { return -1;} - static inline int perf_clang__compile_bpf(const char *filename __maybe_unused, void **p_obj_buf __maybe_unused, diff --git a/tools/perf/util/c++/clang-test.cpp b/tools/perf/util/c++/clang-test.cpp index 21b23605f78b..a4683ca53697 100644 --- a/tools/perf/util/c++/clang-test.cpp +++ b/tools/perf/util/c++/clang-test.cpp @@ -35,7 +35,8 @@ __test__clang_to_IR(void) } extern "C" { -int test__clang_to_IR(void) +int test__clang_to_IR(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { perf_clang_scope _scope; @@ -48,7 +49,8 @@ int test__clang_to_IR(void) return -1; } -int test__clang_to_obj(void) +int test__clang_to_obj(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { perf_clang_scope _scope; -- cgit v1.2.3 From 5801e96b88bb861d0e300881ddd2c21910bc8f33 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:41:59 -0700 Subject: perf test: Convert bpf tests to test cases. Use null terminated array of test cases rather than the previous sub test functions. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-14-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bpf.c | 72 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 29 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 442562d7b7e5..e6691ed7201c 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -62,7 +62,6 @@ static int llseek_loop(void) static struct { enum test_llvm__testcase prog_id; - const char *desc; const char *name; const char *msg_compile_fail; const char *msg_load_fail; @@ -72,7 +71,6 @@ static struct { } bpf_testcase_table[] = { { .prog_id = LLVM_TESTCASE_BASE, - .desc = "Basic BPF filtering", .name = "[basic_bpf_test]", .msg_compile_fail = "fix 'perf test LLVM' first", .msg_load_fail = "load bpf object failed", @@ -81,7 +79,6 @@ static struct { }, { .prog_id = LLVM_TESTCASE_BASE, - .desc = "BPF pinning", .name = "[bpf_pinning]", .msg_compile_fail = "fix kbuild first", .msg_load_fail = "check your vmlinux setting?", @@ -92,7 +89,6 @@ static struct { #ifdef HAVE_BPF_PROLOGUE { .prog_id = LLVM_TESTCASE_BPF_PROLOGUE, - .desc = "BPF prologue generation", .name = "[bpf_prologue_test]", .msg_compile_fail = "fix kbuild first", .msg_load_fail = "check your vmlinux setting?", @@ -283,18 +279,6 @@ out: return ret; } -static int test__bpf_subtest_get_nr(void) -{ - return (int)ARRAY_SIZE(bpf_testcase_table); -} - -static const char *test__bpf_subtest_get_desc(int i) -{ - if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table)) - return NULL; - return bpf_testcase_table[i].desc; -} - static int check_env(void) { int err; @@ -325,7 +309,7 @@ static int check_env(void) return 0; } -static int test__bpf(struct test_suite *test __maybe_unused, int i) +static int test__bpf(int i) { int err; @@ -343,31 +327,61 @@ static int test__bpf(struct test_suite *test __maybe_unused, int i) err = __test__bpf(i); return err; } +#endif -#else -static int test__bpf_subtest_get_nr(void) +static int test__basic_bpf_test(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { - return 0; +#ifdef HAVE_LIBBPF_SUPPORT + return test__bpf(0); +#else + pr_debug("Skip BPF test because BPF support is not compiled\n"); + return TEST_SKIP; +#endif } -static const char *test__bpf_subtest_get_desc(int i __maybe_unused) +static int test__bpf_pinning(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { - return NULL; +#ifdef HAVE_LIBBPF_SUPPORT + return test__bpf(1); +#else + pr_debug("Skip BPF test because BPF support is not compiled\n"); + return TEST_SKIP; +#endif } -static int test__bpf(struct test_suite *test __maybe_unused, int i __maybe_unused) +static int test__bpf_prologue_test(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { +#if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_BPF_PROLOGUE) + return test__bpf(2); +#else pr_debug("Skip BPF test because BPF support is not compiled\n"); return TEST_SKIP; +#endif } + + +static struct test_case bpf_tests[] = { +#ifdef HAVE_LIBBPF_SUPPORT + TEST_CASE("Basic BPF filtering", basic_bpf_test), + TEST_CASE("BPF pinning", bpf_pinning), +#ifdef HAVE_BPF_PROLOGUE + TEST_CASE("BPF prologue generation", bpf_prologue_test), +#else + TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test, "not compiled in"), #endif +#else + TEST_CASE_REASON("Basic BPF filtering", basic_bpf_test, "not compiled in"), + TEST_CASE_REASON("BPF pinning", bpf_pinning, "not compiled in"), + TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test, "not compiled in"), +#endif + { .name = NULL, } +}; struct test_suite suite__bpf = { .desc = "BPF filter", - .func = test__bpf, - .subtest = { - .skip_if_fail = true, - .get_nr = test__bpf_subtest_get_nr, - .get_desc = test__bpf_subtest_get_desc, - }, + .test_cases = bpf_tests, + .subtest = { .skip_if_fail = true, }, }; -- cgit v1.2.3 From e65bc1fa29dcdb499e327376e8cb57b9272b4193 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:00 -0700 Subject: perf test: Convert llvm tests to test cases. Use null terminated array of test cases rather than the previous sub test functions. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-15-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/llvm.c | 77 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 23 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 057d6a59a8ea..f27ef00d65e9 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -124,7 +124,7 @@ out: return ret; } -static int test__llvm(struct test_suite *test __maybe_unused, int subtest) +static int test__llvm(int subtest) { int ret; void *obj_buf = NULL; @@ -148,42 +148,73 @@ static int test__llvm(struct test_suite *test __maybe_unused, int subtest) return ret; } +#endif //HAVE_LIBBPF_SUPPORT -static int test__llvm_subtest_get_nr(void) +static int test__llvm__bpf_base_prog(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { - return __LLVM_TESTCASE_MAX; +#ifdef HAVE_LIBBPF_SUPPORT + return test__llvm(LLVM_TESTCASE_BASE); +#else + pr_debug("Skip LLVM test because BPF support is not compiled\n"); + return TEST_SKIP; +#endif } -static const char *test__llvm_subtest_get_desc(int subtest) -{ - if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX)) - return NULL; - - return bpf_source_table[subtest].desc; -} -#else //HAVE_LIBBPF_SUPPORT -static int test__llvm(struct test_suite *test __maybe_unused, int subtest __maybe_unused) +static int test__llvm__bpf_test_kbuild_prog(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { +#ifdef HAVE_LIBBPF_SUPPORT + return test__llvm(LLVM_TESTCASE_KBUILD); +#else + pr_debug("Skip LLVM test because BPF support is not compiled\n"); return TEST_SKIP; +#endif } -static int test__llvm_subtest_get_nr(void) +static int test__llvm__bpf_test_prologue_prog(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { - return 0; +#ifdef HAVE_LIBBPF_SUPPORT + return test__llvm(LLVM_TESTCASE_BPF_PROLOGUE); +#else + pr_debug("Skip LLVM test because BPF support is not compiled\n"); + return TEST_SKIP; +#endif } -static const char *test__llvm_subtest_get_desc(int subtest __maybe_unused) +static int test__llvm__bpf_test_relocation(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) { - return NULL; +#ifdef HAVE_LIBBPF_SUPPORT + return test__llvm(LLVM_TESTCASE_BPF_RELOCATION); +#else + pr_debug("Skip LLVM test because BPF support is not compiled\n"); + return TEST_SKIP; +#endif } -#endif // HAVE_LIBBPF_SUPPORT + + +static struct test_case llvm_tests[] = { +#ifdef HAVE_LIBBPF_SUPPORT + TEST_CASE("Basic BPF llvm compile", llvm__bpf_base_prog), + TEST_CASE("kbuild searching", llvm__bpf_test_kbuild_prog), + TEST_CASE("Compile source for BPF prologue generation", + llvm__bpf_test_prologue_prog), + TEST_CASE("Compile source for BPF relocation", llvm__bpf_test_relocation), +#else + TEST_CASE_REASON("Basic BPF llvm compile", llvm__bpf_base_prog, "not compiled in"), + TEST_CASE_REASON("kbuild searching", llvm__bpf_test_kbuild_prog, "not compiled in"), + TEST_CASE_REASON("Compile source for BPF prologue generation", + llvm__bpf_test_prologue_prog, "not compiled in"), + TEST_CASE_REASON("Compile source for BPF relocation", + llvm__bpf_test_relocation, "not compiled in"), +#endif + { .name = NULL, } +}; struct test_suite suite__llvm = { .desc = "LLVM search and compile", - .func = test__llvm, - .subtest = { - .skip_if_fail = true, - .get_nr = test__llvm_subtest_get_nr, - .get_desc = test__llvm_subtest_get_desc, - }, + .test_cases = llvm_tests, + .subtest = { .skip_if_fail = true, }, }; -- cgit v1.2.3 From 94e11fc771298523f0caf6802d1eb65b17ef484b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:01 -0700 Subject: perf test: Remove now unused subtest helpers Replaced by null terminated test case array. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-16-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 11 +---------- tools/perf/tests/tests.h | 3 --- 2 files changed, 1 insertion(+), 13 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index db76d7d10749..62e97faa90f0 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -119,9 +119,6 @@ static int num_subtests(const struct test_suite *t) { int num; - if (t->subtest.get_nr) - return t->subtest.get_nr(); - if (!t->test_cases) return 0; @@ -134,14 +131,11 @@ static int num_subtests(const struct test_suite *t) static bool has_subtests(const struct test_suite *t) { - return t->subtest.get_nr || num_subtests(t) > 1; + return num_subtests(t) > 1; } static const char *skip_reason(const struct test_suite *t, int subtest) { - if (t->subtest.skip_reason) - return t->subtest.skip_reason(subtest); - if (t->test_cases && subtest >= 0) return t->test_cases[subtest].skip_reason; @@ -153,9 +147,6 @@ static const char *test_description(const struct test_suite *t, int subtest) if (t->test_cases && subtest >= 0) return t->test_cases[subtest].desc; - if (t->subtest.get_desc && subtest >= 0) - return t->subtest.get_desc(subtest); - return t->desc; } diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index f87129b63d92..9bf448f7429a 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -43,9 +43,6 @@ struct test_suite { test_fnptr func; struct { bool skip_if_fail; - int (*get_nr)(void); - const char *(*get_desc)(int subtest); - const char *(*skip_reason)(int subtest); } subtest; struct test_case *test_cases; bool (*is_supported)(void); -- cgit v1.2.3 From e329f03a1f1b547c858a308b2cfcd5d6e8dd8740 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:02 -0700 Subject: perf test: bp tests use test case Migration toward kunit style test cases. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-17-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bp_account.c | 7 ++++++- tools/perf/tests/bp_signal.c | 7 ++++++- tools/perf/tests/bp_signal_overflow.c | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c index 365120146d17..e4f7b635ffef 100644 --- a/tools/perf/tests/bp_account.c +++ b/tools/perf/tests/bp_account.c @@ -205,8 +205,13 @@ static bool test__bp_account_is_supported(void) #endif } +static struct test_case bp_accounting_tests[] = { + TEST_CASE("Breakpoint accounting", bp_accounting), + { .name = NULL, } +}; + struct test_suite suite__bp_accounting = { .desc = "Breakpoint accounting", - .func = test__bp_accounting, + .test_cases = bp_accounting_tests, .is_supported = test__bp_account_is_supported, }; diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 3c269f81818a..1676e3a11906 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -312,8 +312,13 @@ bool test__bp_signal_is_supported(void) #endif } +static struct test_case bp_signal_tests[] = { + TEST_CASE("Breakpoint overflow signal handler", bp_signal), + { .name = NULL, } +}; + struct test_suite suite__bp_signal = { .desc = "Breakpoint overflow signal handler", - .func = test__bp_signal, + .test_cases = bp_signal_tests, .is_supported = test__bp_signal_is_supported, }; diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index 5ac6e1393cf4..bc1f13851750 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c @@ -134,8 +134,13 @@ static int test__bp_signal_overflow(struct test_suite *test __maybe_unused, int return fails ? TEST_FAIL : TEST_OK; } +static struct test_case bp_signal_overflow_tests[] = { + TEST_CASE("Breakpoint overflow sampling", bp_signal_overflow), + { .name = NULL, } +}; + struct test_suite suite__bp_signal_overflow = { .desc = "Breakpoint overflow sampling", - .func = test__bp_signal_overflow, + .test_cases = bp_signal_overflow_tests, .is_supported = test__bp_signal_is_supported, }; -- cgit v1.2.3 From 1870356f3532c2e9ac00557ff911b94bdbba4602 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:03 -0700 Subject: perf test: Convert time to tsc test to test case. Migration toward kunit style test cases. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-18-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/perf-time-to-tsc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index d23740f80c7d..594013e94ed0 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -198,8 +198,13 @@ static bool test__tsc_is_supported(void) #endif } +static struct test_case perf_time_to_tsc_tests[] = { + TEST_CASE("Convert perf time to TSC", perf_time_to_tsc), + { .name = NULL, } +}; + struct test_suite suite__perf_time_to_tsc = { .desc = "Convert perf time to TSC", - .func = test__perf_time_to_tsc, + .test_cases = perf_time_to_tsc_tests, .is_supported = test__tsc_is_supported, }; -- cgit v1.2.3 From c76ec1cf25d5240ded2e17384101890ff46b8797 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:04 -0700 Subject: perf test: Remove non test case style support. Convert shell tests to also run using test case style. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-19-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 25 ++++++++++++++++--------- tools/perf/tests/tests.h | 1 - 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 62e97faa90f0..1d9c0e03b8db 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -157,9 +157,6 @@ static bool is_supported(const struct test_suite *t) static test_fnptr test_function(const struct test_suite *t, int subtest) { - if (t->func) - return t->func; - if (subtest <= 0) return t->test_cases[0].run_case; @@ -413,24 +410,34 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width, for_each_shell_test(entlist, n_dirs, st.dir, ent) { int curr = i++; char desc[256]; - struct test_suite test = { - .desc = shell_test__description(desc, sizeof(desc), st.dir, ent->d_name), - .func = shell_test__run, + struct test_case test_cases[] = { + { + .desc = shell_test__description(desc, + sizeof(desc), + st.dir, + ent->d_name), + .run_case = shell_test__run, + }, + { .name = NULL, } + }; + struct test_suite test_suite = { + .desc = test_cases[0].desc, + .test_cases = test_cases, .priv = &st, }; - if (!perf_test__matches(test.desc, curr, argc, argv)) + if (!perf_test__matches(test_suite.desc, curr, argc, argv)) continue; st.file = ent->d_name; - pr_info("%2d: %-*s:", i, width, test.desc); + pr_info("%2d: %-*s:", i, width, test_suite.desc); if (intlist__find(skiplist, i)) { color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); continue; } - test_and_print(&test, false, -1); + test_and_print(&test_suite, false, 0); } for (e = 0; e < n_dirs; e++) diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 9bf448f7429a..cae33c375d55 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -40,7 +40,6 @@ struct test_case { struct test_suite { const char *desc; - test_fnptr func; struct { bool skip_if_fail; } subtest; -- cgit v1.2.3 From 4935e2cd1b980cad8f3c8b78302740f6543d8dc9 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:05 -0700 Subject: perf test: BP tests, remove is_supported use Migrate the is_supported functionality to returning TEST_SKIP. Motivation is kunit has no is_supported function. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-20-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bp_account.c | 45 +++++++++++++++-------------------- tools/perf/tests/bp_signal.c | 43 +++++---------------------------- tools/perf/tests/bp_signal_overflow.c | 16 +++++-------- tools/perf/tests/tests.h | 21 +++++++++++++++- 4 files changed, 51 insertions(+), 74 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c index e4f7b635ffef..d1ebb5561e5b 100644 --- a/tools/perf/tests/bp_account.c +++ b/tools/perf/tests/bp_account.c @@ -19,6 +19,19 @@ #include "../perf-sys.h" #include "cloexec.h" +/* + * PowerPC and S390 do not support creation of instruction breakpoints using the + * perf_event interface. + * + * Just disable the test for these architectures until these issues are + * resolved. + */ +#if defined(__powerpc__) || defined(__s390x__) +#define BP_ACCOUNT_IS_SUPPORTED 0 +#else +#define BP_ACCOUNT_IS_SUPPORTED 1 +#endif + static volatile long the_var; static noinline int test_function(void) @@ -180,6 +193,11 @@ static int test__bp_accounting(struct test_suite *test __maybe_unused, int subte int bp_cnt = detect_cnt(true); int share = detect_share(wp_cnt, bp_cnt); + if (!BP_ACCOUNT_IS_SUPPORTED) { + pr_debug("Test not supported on this architecture"); + return TEST_SKIP; + } + pr_debug("watchpoints count %d, breakpoints count %d, has_ioctl %d, share %d\n", wp_cnt, bp_cnt, has_ioctl, share); @@ -189,29 +207,4 @@ static int test__bp_accounting(struct test_suite *test __maybe_unused, int subte return bp_accounting(wp_cnt, share); } -static bool test__bp_account_is_supported(void) -{ - /* - * PowerPC and S390 do not support creation of instruction - * breakpoints using the perf_event interface. - * - * Just disable the test for these architectures until these - * issues are resolved. - */ -#if defined(__powerpc__) || defined(__s390x__) - return false; -#else - return true; -#endif -} - -static struct test_case bp_accounting_tests[] = { - TEST_CASE("Breakpoint accounting", bp_accounting), - { .name = NULL, } -}; - -struct test_suite suite__bp_accounting = { - .desc = "Breakpoint accounting", - .test_cases = bp_accounting_tests, - .is_supported = test__bp_account_is_supported, -}; +DEFINE_SUITE("Breakpoint accounting", bp_accounting); diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 1676e3a11906..1f2908f02389 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -166,6 +166,11 @@ static int test__bp_signal(struct test_suite *test __maybe_unused, int subtest _ struct sigaction sa; long long count1, count2, count3; + if (!BP_SIGNAL_IS_SUPPORTED) { + pr_debug("Test not supported on this architecture"); + return TEST_SKIP; + } + /* setup SIGIO signal handler */ memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction = (void *) sig_handler; @@ -285,40 +290,4 @@ static int test__bp_signal(struct test_suite *test __maybe_unused, int subtest _ TEST_OK : TEST_FAIL; } -bool test__bp_signal_is_supported(void) -{ - /* - * PowerPC and S390 do not support creation of instruction - * breakpoints using the perf_event interface. - * - * ARM requires explicit rounding down of the instruction - * pointer in Thumb mode, and then requires the single-step - * to be handled explicitly in the overflow handler to avoid - * stepping into the SIGIO handler and getting stuck on the - * breakpointed instruction. - * - * Since arm64 has the same issue with arm for the single-step - * handling, this case also gets stuck on the breakpointed - * instruction. - * - * Just disable the test for these architectures until these - * issues are resolved. - */ -#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__) || \ - defined(__aarch64__) - return false; -#else - return true; -#endif -} - -static struct test_case bp_signal_tests[] = { - TEST_CASE("Breakpoint overflow signal handler", bp_signal), - { .name = NULL, } -}; - -struct test_suite suite__bp_signal = { - .desc = "Breakpoint overflow signal handler", - .test_cases = bp_signal_tests, - .is_supported = test__bp_signal_is_supported, -}; +DEFINE_SUITE("Breakpoint overflow signal handler", bp_signal); diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index bc1f13851750..4e897c2cf26b 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c @@ -66,6 +66,11 @@ static int test__bp_signal_overflow(struct test_suite *test __maybe_unused, int long long count; int fd, i, fails = 0; + if (!BP_SIGNAL_IS_SUPPORTED) { + pr_debug("Test not supported on this architecture"); + return TEST_SKIP; + } + /* setup SIGIO signal handler */ memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction = (void *) sig_handler; @@ -134,13 +139,4 @@ static int test__bp_signal_overflow(struct test_suite *test __maybe_unused, int return fails ? TEST_FAIL : TEST_OK; } -static struct test_case bp_signal_overflow_tests[] = { - TEST_CASE("Breakpoint overflow sampling", bp_signal_overflow), - { .name = NULL, } -}; - -struct test_suite suite__bp_signal_overflow = { - .desc = "Breakpoint overflow sampling", - .test_cases = bp_signal_overflow_tests, - .is_supported = test__bp_signal_is_supported, -}; +DEFINE_SUITE("Breakpoint overflow sampling", bp_signal_overflow); diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index cae33c375d55..958f94dcc94c 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -151,7 +151,26 @@ DECLARE_SUITE(expand_cgroup_events); DECLARE_SUITE(perf_time_to_tsc); DECLARE_SUITE(dlfilter); -bool test__bp_signal_is_supported(void); +/* + * PowerPC and S390 do not support creation of instruction breakpoints using the + * perf_event interface. + * + * ARM requires explicit rounding down of the instruction pointer in Thumb mode, + * and then requires the single-step to be handled explicitly in the overflow + * handler to avoid stepping into the SIGIO handler and getting stuck on the + * breakpointed instruction. + * + * Since arm64 has the same issue with arm for the single-step handling, this + * case also gets stuck on the breakpointed instruction. + * + * Just disable the test for these architectures until these issues are + * resolved. + */ +#if defined(__powerpc__) || defined(__s390x__) || defined(__arm__) || defined(__aarch64__) +#define BP_SIGNAL_IS_SUPPORTED 0 +#else +#define BP_SIGNAL_IS_SUPPORTED 1 +#endif #ifdef HAVE_DWARF_UNWIND_SUPPORT struct thread; -- cgit v1.2.3 From e74dd9cb33326628fd6ef8be246f00f7bccbea68 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:06 -0700 Subject: perf test: TSC test, remove is_supported use Migrate the is_supported functionality to returning TEST_SKIP. Motivation is kunit has no is_supported function. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-21-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/perf-time-to-tsc.c | 39 +++++++++++++++---------------------- 1 file changed, 16 insertions(+), 23 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index 594013e94ed0..d12d0ad81801 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -23,6 +23,16 @@ #include "pmu.h" #include "pmu-hybrid.h" +/* + * Except x86_64/i386 and Arm64, other archs don't support TSC in perf. Just + * enable the test for x86_64/i386 and Arm64 archs. + */ +#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) +#define TSC_IS_SUPPORTED 1 +#else +#define TSC_IS_SUPPORTED 0 +#endif + #define CHECK__(x) { \ while ((x) < 0) { \ pr_debug(#x " failed!\n"); \ @@ -69,6 +79,11 @@ static int test__perf_time_to_tsc(struct test_suite *test __maybe_unused, int su u64 test_time, comm1_time = 0, comm2_time = 0; struct mmap *md; + if (!TSC_IS_SUPPORTED) { + pr_debug("Test not supported on this architecture"); + return TEST_SKIP; + } + threads = thread_map__new(-1, getpid(), UINT_MAX); CHECK_NOT_NULL__(threads); @@ -185,26 +200,4 @@ out_err: return err; } -static bool test__tsc_is_supported(void) -{ - /* - * Except x86_64/i386 and Arm64, other archs don't support TSC in perf. - * Just enable the test for x86_64/i386 and Arm64 archs. - */ -#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) - return true; -#else - return false; -#endif -} - -static struct test_case perf_time_to_tsc_tests[] = { - TEST_CASE("Convert perf time to TSC", perf_time_to_tsc), - { .name = NULL, } -}; - -struct test_suite suite__perf_time_to_tsc = { - .desc = "Convert perf time to TSC", - .test_cases = perf_time_to_tsc_tests, - .is_supported = test__tsc_is_supported, -}; +DEFINE_SUITE("Convert perf time to TSC", perf_time_to_tsc); -- cgit v1.2.3 From 848ddf5999d224050f6cde8c165630fd7671085f Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:07 -0700 Subject: perf test: Remove is_supported function All tests now return TEST_SKIP if not supported. Removing this function brings perf's test_suite struct more inline with kunit. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-22-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 14 +------------- tools/perf/tests/tests.h | 1 - 2 files changed, 1 insertion(+), 14 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 1d9c0e03b8db..19b1228dbd5d 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -150,11 +150,6 @@ static const char *test_description(const struct test_suite *t, int subtest) return t->desc; } -static bool is_supported(const struct test_suite *t) -{ - return !t->is_supported || t->is_supported(); -} - static test_fnptr test_function(const struct test_suite *t, int subtest) { if (subtest <= 0) @@ -480,12 +475,6 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) continue; } - if (!is_supported(t)) { - pr_debug("%2d: %-*s: Disabled\n", i, width, - test_description(t, -1)); - continue; - } - pr_info("%2d: %-*s:", i, width, test_description(t, -1)); if (intlist__find(skiplist, i)) { @@ -583,8 +572,7 @@ static int perf_test__list(int argc, const char **argv) for_each_test(j, k, t) { int curr = i++; - if (!perf_test__matches(test_description(t, -1), curr, argc, argv) || - !is_supported(t)) + if (!perf_test__matches(test_description(t, -1), curr, argc, argv)) continue; pr_info("%2d: %s\n", i, test_description(t, -1)); diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 958f94dcc94c..15051801c790 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -44,7 +44,6 @@ struct test_suite { bool skip_if_fail; } subtest; struct test_case *test_cases; - bool (*is_supported)(void); void *priv; }; -- cgit v1.2.3 From b47d2fb40f507a531417f3a893aa822be355ae5f Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 3 Nov 2021 23:42:08 -0700 Subject: perf test: Remove skip_if_fail Remove optionality, always run tests in a suite even if one fails. This brings perf's test more inline with kunit that lacks this notion. Signed-off-by: Ian Rogers Tested-by: Sohaib Mohamed Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Brendan Higgins Cc: Daniel Latypov Cc: David Gow Cc: Ingo Molnar Cc: Jin Yao Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul Clarke Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211104064208.3156807-23-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bpf.c | 1 - tools/perf/tests/builtin-test.c | 24 ++++++++---------------- tools/perf/tests/clang.c | 1 - tools/perf/tests/llvm.c | 1 - tools/perf/tests/pfm.c | 1 - tools/perf/tests/tests.h | 3 --- 6 files changed, 8 insertions(+), 23 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index e6691ed7201c..2048c9a08e8f 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -383,5 +383,4 @@ static struct test_case bpf_tests[] = { struct test_suite suite__bpf = { .desc = "BPF filter", .test_cases = bpf_tests, - .subtest = { .skip_if_fail = true, }, }; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 19b1228dbd5d..8cb5a1c3489e 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -238,18 +238,13 @@ static int run_test(struct test_suite *test, int subtest) for (j = 0; j < ARRAY_SIZE(tests); j++) \ for (k = 0, t = tests[j][k]; tests[j][k]; k++, t = tests[j][k]) -static int test_and_print(struct test_suite *t, bool force_skip, int subtest) +static int test_and_print(struct test_suite *t, int subtest) { int err; - if (!force_skip) { - pr_debug("\n--- start ---\n"); - err = run_test(t, subtest); - pr_debug("---- end ----\n"); - } else { - pr_debug("\n--- force skipped ---\n"); - err = TEST_SKIP; - } + pr_debug("\n--- start ---\n"); + err = run_test(t, subtest); + pr_debug("---- end ----\n"); if (!has_subtests(t)) pr_debug("%s:", t->desc); @@ -432,7 +427,7 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width, continue; } - test_and_print(&test_suite, false, 0); + test_and_print(&test_suite, 0); } for (e = 0; e < n_dirs; e++) @@ -456,7 +451,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) } for_each_test(j, k, t) { - int curr = i++, err; + int curr = i++; int subi; if (!perf_test__matches(test_description(t, -1), curr, argc, argv)) { @@ -483,7 +478,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) } if (!has_subtests(t)) { - test_and_print(t, false, -1); + test_and_print(t, -1); } else { int subn = num_subtests(t); /* @@ -495,7 +490,6 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) * 35.1: Basic BPF llvm compiling test : Ok */ int subw = width > 2 ? width - 2 : width; - bool skip = false; if (subn <= 0) { color_fprintf(stderr, PERF_COLOR_YELLOW, @@ -518,9 +512,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) pr_info("%2d.%1d: %-*s:", i, subi + 1, subw, test_description(t, subi)); - err = test_and_print(t, skip, subi); - if (err != TEST_OK && t->subtest.skip_if_fail) - skip = true; + test_and_print(t, subi); } } } diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index ba06a2257574..a7111005d5b9 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -29,5 +29,4 @@ static struct test_case clang_tests[] = { struct test_suite suite__clang = { .desc = "builtin clang support", .test_cases = clang_tests, - .subtest = { .skip_if_fail = true, }, }; diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index f27ef00d65e9..8ac0a3a457ef 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -216,5 +216,4 @@ static struct test_case llvm_tests[] = { struct test_suite suite__llvm = { .desc = "LLVM search and compile", .test_cases = llvm_tests, - .subtest = { .skip_if_fail = true, }, }; diff --git a/tools/perf/tests/pfm.c b/tools/perf/tests/pfm.c index 651fee4ef819..71b76deb1f92 100644 --- a/tools/perf/tests/pfm.c +++ b/tools/perf/tests/pfm.c @@ -191,5 +191,4 @@ static struct test_case pfm_tests[] = { struct test_suite suite__pfm = { .desc = "Test libpfm4 support", .test_cases = pfm_tests, - .subtest = { .skip_if_fail = true } }; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 15051801c790..8f65098110fc 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -40,9 +40,6 @@ struct test_case { struct test_suite { const char *desc; - struct { - bool skip_if_fail; - } subtest; struct test_case *test_cases; void *priv; }; -- cgit v1.2.3 From 604ce2f00465efdf6efa9708c0b9b1fc302f46f0 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 10 Nov 2021 16:21:02 -0800 Subject: perf test: Add expr test for events with hyphens An example of such an event is topdown-fe-bound. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul A . Clarke Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Wan Jiabing Cc: Yury Norov Link: https://lore.kernel.org/r/20211111002109.194172-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/expr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 0c041ac707e6..48c62d0789c5 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -134,6 +134,16 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT2,param=3@", (void **)&val_ptr)); + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("find ids", + expr__find_ids("dash\\-event1 - dash\\-event2", + NULL, ctx) == 0); + TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 2); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "dash-event1", + (void **)&val_ptr)); + TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "dash-event2", + (void **)&val_ptr)); + /* Only EVENT1 or EVENT2 need be measured depending on the value of smt_on. */ expr__ctx_clear(ctx); TEST_ASSERT_VAL("find ids", -- cgit v1.2.3 From 48f07b0b2a3ebe3278ff4257e540084157f8b4dc Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 10 Nov 2021 16:21:03 -0800 Subject: perf cputopo: Update to use pakage_cpus core_siblings_list is the deprecated topology name for package_cpus_list, update the code to try the non-deprecated path first. Adjust variable names to match topology name. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul A . Clarke Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Wan Jiabing Cc: Yury Norov Link: https://lore.kernel.org/r/20211111002109.194172-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cputopo.c | 26 ++++++++++++++++---------- tools/perf/util/cputopo.h | 11 +++++++++-- tools/perf/util/header.c | 6 +++--- 3 files changed, 28 insertions(+), 15 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index ec77e2a7b3ca..f72a7de19e02 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -14,7 +14,9 @@ #include "env.h" #include "pmu-hybrid.h" -#define CORE_SIB_FMT \ +#define PACKAGE_CPUS_FMT \ + "%s/devices/system/cpu/cpu%d/topology/package_cpus_list" +#define PACKAGE_CPUS_FMT_OLD \ "%s/devices/system/cpu/cpu%d/topology/core_siblings_list" #define DIE_SIB_FMT \ "%s/devices/system/cpu/cpu%d/topology/die_cpus_list" @@ -39,8 +41,12 @@ static int build_cpu_topology(struct cpu_topology *tp, int cpu) u32 i = 0; int ret = -1; - scnprintf(filename, MAXPATHLEN, CORE_SIB_FMT, + scnprintf(filename, MAXPATHLEN, PACKAGE_CPUS_FMT, sysfs__mountpoint(), cpu); + if (access(filename, F_OK) == -1) { + scnprintf(filename, MAXPATHLEN, PACKAGE_CPUS_FMT_OLD, + sysfs__mountpoint(), cpu); + } fp = fopen(filename, "r"); if (!fp) goto try_dies; @@ -54,13 +60,13 @@ static int build_cpu_topology(struct cpu_topology *tp, int cpu) if (p) *p = '\0'; - for (i = 0; i < tp->core_sib; i++) { - if (!strcmp(buf, tp->core_siblings[i])) + for (i = 0; i < tp->package_cpus_lists; i++) { + if (!strcmp(buf, tp->package_cpus_list[i])) break; } - if (i == tp->core_sib) { - tp->core_siblings[i] = buf; - tp->core_sib++; + if (i == tp->package_cpus_lists) { + tp->package_cpus_list[i] = buf; + tp->package_cpus_lists++; buf = NULL; len = 0; } @@ -139,8 +145,8 @@ void cpu_topology__delete(struct cpu_topology *tp) if (!tp) return; - for (i = 0 ; i < tp->core_sib; i++) - zfree(&tp->core_siblings[i]); + for (i = 0 ; i < tp->package_cpus_lists; i++) + zfree(&tp->package_cpus_list[i]); if (tp->die_sib) { for (i = 0 ; i < tp->die_sib; i++) @@ -205,7 +211,7 @@ struct cpu_topology *cpu_topology__new(void) tp = addr; addr += sizeof(*tp); - tp->core_siblings = addr; + tp->package_cpus_list = addr; addr += sz; if (has_die) { tp->die_siblings = addr; diff --git a/tools/perf/util/cputopo.h b/tools/perf/util/cputopo.h index d9af97177068..4ec9cb192c3d 100644 --- a/tools/perf/util/cputopo.h +++ b/tools/perf/util/cputopo.h @@ -5,10 +5,17 @@ #include struct cpu_topology { - u32 core_sib; + /* The number of unique package_cpus_lists below. */ + u32 package_cpus_lists; u32 die_sib; u32 thread_sib; - char **core_siblings; + /* + * An array of strings where each string is unique and read from + * /sys/devices/system/cpu/cpuX/topology/package_cpus_list. From the ABI + * each of these is a human-readable list of CPUs sharing the same + * physical_package_id. The format is like 0-3, 8-11, 14,17. + */ + const char **package_cpus_list; char **die_siblings; char **thread_siblings; }; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 56511db8fa03..4e89cd35345b 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -583,12 +583,12 @@ static int write_cpu_topology(struct feat_fd *ff, if (!tp) return -1; - ret = do_write(ff, &tp->core_sib, sizeof(tp->core_sib)); + ret = do_write(ff, &tp->package_cpus_lists, sizeof(tp->package_cpus_lists)); if (ret < 0) goto done; - for (i = 0; i < tp->core_sib; i++) { - ret = do_write_string(ff, tp->core_siblings[i]); + for (i = 0; i < tp->package_cpus_lists; i++) { + ret = do_write_string(ff, tp->package_cpus_list[i]); if (ret < 0) goto done; } -- cgit v1.2.3 From 406018dcc12142f486a9b97bb958d43376bc7bb0 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 10 Nov 2021 16:21:04 -0800 Subject: perf cputopo: Match die_siblings to topology ABI name The topology name for die_siblings is die_cpus_list, use this for consistency and add documentation. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul A . Clarke Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Wan Jiabing Cc: Yury Norov Link: https://lore.kernel.org/r/20211111002109.194172-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cputopo.c | 26 ++++++++++++-------------- tools/perf/util/cputopo.h | 11 +++++++++-- tools/perf/util/header.c | 8 ++++---- 3 files changed, 25 insertions(+), 20 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index f72a7de19e02..420aeda16fbb 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -18,7 +18,7 @@ "%s/devices/system/cpu/cpu%d/topology/package_cpus_list" #define PACKAGE_CPUS_FMT_OLD \ "%s/devices/system/cpu/cpu%d/topology/core_siblings_list" -#define DIE_SIB_FMT \ +#define DIE_CPUS_FMT \ "%s/devices/system/cpu/cpu%d/topology/die_cpus_list" #define THRD_SIB_FMT \ "%s/devices/system/cpu/cpu%d/topology/thread_siblings_list" @@ -73,10 +73,10 @@ static int build_cpu_topology(struct cpu_topology *tp, int cpu) ret = 0; try_dies: - if (!tp->die_siblings) + if (!tp->die_cpus_list) goto try_threads; - scnprintf(filename, MAXPATHLEN, DIE_SIB_FMT, + scnprintf(filename, MAXPATHLEN, DIE_CPUS_FMT, sysfs__mountpoint(), cpu); fp = fopen(filename, "r"); if (!fp) @@ -91,13 +91,13 @@ try_dies: if (p) *p = '\0'; - for (i = 0; i < tp->die_sib; i++) { - if (!strcmp(buf, tp->die_siblings[i])) + for (i = 0; i < tp->die_cpus_lists; i++) { + if (!strcmp(buf, tp->die_cpus_list[i])) break; } - if (i == tp->die_sib) { - tp->die_siblings[i] = buf; - tp->die_sib++; + if (i == tp->die_cpus_lists) { + tp->die_cpus_list[i] = buf; + tp->die_cpus_lists++; buf = NULL; len = 0; } @@ -148,10 +148,8 @@ void cpu_topology__delete(struct cpu_topology *tp) for (i = 0 ; i < tp->package_cpus_lists; i++) zfree(&tp->package_cpus_list[i]); - if (tp->die_sib) { - for (i = 0 ; i < tp->die_sib; i++) - zfree(&tp->die_siblings[i]); - } + for (i = 0 ; i < tp->die_cpus_lists; i++) + zfree(&tp->die_cpus_list[i]); for (i = 0 ; i < tp->thread_sib; i++) zfree(&tp->thread_siblings[i]); @@ -170,7 +168,7 @@ static bool has_die_topology(void) if (strncmp(uts.machine, "x86_64", 6)) return false; - scnprintf(filename, MAXPATHLEN, DIE_SIB_FMT, + scnprintf(filename, MAXPATHLEN, DIE_CPUS_FMT, sysfs__mountpoint(), 0); if (access(filename, F_OK) == -1) return false; @@ -214,7 +212,7 @@ struct cpu_topology *cpu_topology__new(void) tp->package_cpus_list = addr; addr += sz; if (has_die) { - tp->die_siblings = addr; + tp->die_cpus_list = addr; addr += sz; } tp->thread_siblings = addr; diff --git a/tools/perf/util/cputopo.h b/tools/perf/util/cputopo.h index 4ec9cb192c3d..a3e01c367853 100644 --- a/tools/perf/util/cputopo.h +++ b/tools/perf/util/cputopo.h @@ -7,7 +7,8 @@ struct cpu_topology { /* The number of unique package_cpus_lists below. */ u32 package_cpus_lists; - u32 die_sib; + /* The number of unique die_cpu_lists below. */ + u32 die_cpus_lists; u32 thread_sib; /* * An array of strings where each string is unique and read from @@ -16,7 +17,13 @@ struct cpu_topology { * physical_package_id. The format is like 0-3, 8-11, 14,17. */ const char **package_cpus_list; - char **die_siblings; + /* + * An array of string where each string is unique and from + * /sys/devices/system/cpu/cpuX/topology/die_cpus_list. From the ABI + * each of these is a human-readable list of CPUs within the same die. + * The format is like 0-3, 8-11, 14,17. + */ + const char **die_cpus_list; char **thread_siblings; }; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 4e89cd35345b..e2ba261d1583 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -617,15 +617,15 @@ static int write_cpu_topology(struct feat_fd *ff, return ret; } - if (!tp->die_sib) + if (!tp->die_cpus_lists) goto done; - ret = do_write(ff, &tp->die_sib, sizeof(tp->die_sib)); + ret = do_write(ff, &tp->die_cpus_lists, sizeof(tp->die_cpus_lists)); if (ret < 0) goto done; - for (i = 0; i < tp->die_sib; i++) { - ret = do_write_string(ff, tp->die_siblings[i]); + for (i = 0; i < tp->die_cpus_lists; i++) { + ret = do_write_string(ff, tp->die_cpus_list[i]); if (ret < 0) goto done; } -- cgit v1.2.3 From 0b6b84cca6740e318ef241bb07775b506c507bc0 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 10 Nov 2021 16:21:05 -0800 Subject: perf cputopo: Match thread_siblings to topology ABI name The topology name for thread_siblings is core_cpus_list, use this for consistency and add documentation. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul A . Clarke Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Wan Jiabing Cc: Yury Norov Link: https://lore.kernel.org/r/20211111002109.194172-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cputopo.c | 26 +++++++++++++------------- tools/perf/util/cputopo.h | 11 +++++++++-- tools/perf/util/header.c | 6 +++--- 3 files changed, 25 insertions(+), 18 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index 420aeda16fbb..51b429c86f98 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c @@ -20,10 +20,10 @@ "%s/devices/system/cpu/cpu%d/topology/core_siblings_list" #define DIE_CPUS_FMT \ "%s/devices/system/cpu/cpu%d/topology/die_cpus_list" -#define THRD_SIB_FMT \ - "%s/devices/system/cpu/cpu%d/topology/thread_siblings_list" -#define THRD_SIB_FMT_NEW \ +#define CORE_CPUS_FMT \ "%s/devices/system/cpu/cpu%d/topology/core_cpus_list" +#define CORE_CPUS_FMT_OLD \ + "%s/devices/system/cpu/cpu%d/topology/thread_siblings_list" #define NODE_ONLINE_FMT \ "%s/devices/system/node/online" #define NODE_MEMINFO_FMT \ @@ -104,10 +104,10 @@ try_dies: ret = 0; try_threads: - scnprintf(filename, MAXPATHLEN, THRD_SIB_FMT_NEW, + scnprintf(filename, MAXPATHLEN, CORE_CPUS_FMT, sysfs__mountpoint(), cpu); if (access(filename, F_OK) == -1) { - scnprintf(filename, MAXPATHLEN, THRD_SIB_FMT, + scnprintf(filename, MAXPATHLEN, CORE_CPUS_FMT_OLD, sysfs__mountpoint(), cpu); } fp = fopen(filename, "r"); @@ -121,13 +121,13 @@ try_threads: if (p) *p = '\0'; - for (i = 0; i < tp->thread_sib; i++) { - if (!strcmp(buf, tp->thread_siblings[i])) + for (i = 0; i < tp->core_cpus_lists; i++) { + if (!strcmp(buf, tp->core_cpus_list[i])) break; } - if (i == tp->thread_sib) { - tp->thread_siblings[i] = buf; - tp->thread_sib++; + if (i == tp->core_cpus_lists) { + tp->core_cpus_list[i] = buf; + tp->core_cpus_lists++; buf = NULL; } ret = 0; @@ -151,8 +151,8 @@ void cpu_topology__delete(struct cpu_topology *tp) for (i = 0 ; i < tp->die_cpus_lists; i++) zfree(&tp->die_cpus_list[i]); - for (i = 0 ; i < tp->thread_sib; i++) - zfree(&tp->thread_siblings[i]); + for (i = 0 ; i < tp->core_cpus_lists; i++) + zfree(&tp->core_cpus_list[i]); free(tp); } @@ -215,7 +215,7 @@ struct cpu_topology *cpu_topology__new(void) tp->die_cpus_list = addr; addr += sz; } - tp->thread_siblings = addr; + tp->core_cpus_list = addr; for (i = 0; i < nr; i++) { if (!cpu_map__has(map, i)) diff --git a/tools/perf/util/cputopo.h b/tools/perf/util/cputopo.h index a3e01c367853..854e18f9041e 100644 --- a/tools/perf/util/cputopo.h +++ b/tools/perf/util/cputopo.h @@ -9,7 +9,8 @@ struct cpu_topology { u32 package_cpus_lists; /* The number of unique die_cpu_lists below. */ u32 die_cpus_lists; - u32 thread_sib; + /* The number of unique core_cpu_lists below. */ + u32 core_cpus_lists; /* * An array of strings where each string is unique and read from * /sys/devices/system/cpu/cpuX/topology/package_cpus_list. From the ABI @@ -24,7 +25,13 @@ struct cpu_topology { * The format is like 0-3, 8-11, 14,17. */ const char **die_cpus_list; - char **thread_siblings; + /* + * An array of string where each string is unique and from + * /sys/devices/system/cpu/cpuX/topology/core_cpus_list. From the ABI + * each of these is a human-readable list of CPUs within the same + * core. The format is like 0-3, 8-11, 14,17. + */ + const char **core_cpus_list; }; struct numa_topology_node { diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index e2ba261d1583..fda8d14c891f 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -592,12 +592,12 @@ static int write_cpu_topology(struct feat_fd *ff, if (ret < 0) goto done; } - ret = do_write(ff, &tp->thread_sib, sizeof(tp->thread_sib)); + ret = do_write(ff, &tp->core_cpus_lists, sizeof(tp->core_cpus_lists)); if (ret < 0) goto done; - for (i = 0; i < tp->thread_sib; i++) { - ret = do_write_string(ff, tp->thread_siblings[i]); + for (i = 0; i < tp->core_cpus_lists; i++) { + ret = do_write_string(ff, tp->core_cpus_list[i]); if (ret < 0) break; } -- cgit v1.2.3 From 3613f6c1180b4af432ee607f8b43da381cd03fae Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 10 Nov 2021 16:21:06 -0800 Subject: perf expr: Add literal values starting with # It is useful to have literal values for constants relating to topologies, SMT, etc. Make the parsing of literals shared code and add a lookup function. Move #smt_on to this function. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul A . Clarke Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Wan Jiabing Cc: Yury Norov Link: https://lore.kernel.org/r/20211111002109.194172-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/expr.c | 11 +++++++++++ tools/perf/util/expr.h | 1 + tools/perf/util/expr.l | 15 ++++++++++++++- tools/perf/util/expr.y | 9 ++++----- 4 files changed, 30 insertions(+), 6 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c index 77c6ad81a923..7464739c2890 100644 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@ -9,9 +9,11 @@ #include "expr.h" #include "expr-bison.h" #include "expr-flex.h" +#include "smt.h" #include #include #include +#include #ifdef PARSER_DEBUG extern int expr_debug; @@ -370,3 +372,12 @@ double expr_id_data__value(const struct expr_id_data *data) assert(data->kind == EXPR_ID_DATA__REF_VALUE); return data->ref.val; } + +double expr__get_literal(const char *literal) +{ + if (!strcmp("#smt_on", literal)) + return smt_on() > 0 ? 1.0 : 0.0; + + pr_err("Unrecognized literal '%s'", literal); + return NAN; +} diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h index cf81f9166dbb..a6ab7f2b23d1 100644 --- a/tools/perf/util/expr.h +++ b/tools/perf/util/expr.h @@ -55,5 +55,6 @@ int expr__find_ids(const char *expr, const char *one, struct expr_parse_ctx *ids); double expr_id_data__value(const struct expr_id_data *data); +double expr__get_literal(const char *literal); #endif diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l index bd20f33418ba..cf6e3c710502 100644 --- a/tools/perf/util/expr.l +++ b/tools/perf/util/expr.l @@ -6,6 +6,7 @@ #include #include "expr.h" #include "expr-bison.h" +#include char *expr_get_text(yyscan_t yyscanner); YYSTYPE *expr_get_lval(yyscan_t yyscanner); @@ -77,6 +78,17 @@ static int str(yyscan_t scanner, int token, int runtime) yylval->str = normalize(yylval->str, runtime); return token; } + +static int literal(yyscan_t scanner) +{ + YYSTYPE *yylval = expr_get_lval(scanner); + + yylval->num = expr__get_literal(expr_get_text(scanner)); + if (isnan(yylval->num)) + return EXPR_ERROR; + + return LITERAL; +} %} number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+) @@ -85,6 +97,7 @@ sch [-,=] spec \\{sch} sym [0-9a-zA-Z_\.:@?]+ symbol ({spec}|{sym})+ +literal #[0-9a-zA-Z_\.\-]+ %% struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner); @@ -94,7 +107,7 @@ max { return MAX; } min { return MIN; } if { return IF; } else { return ELSE; } -#smt_on { return SMT_ON; } +{literal} { return literal(yyscanner); } {number} { return value(yyscanner); } {symbol} { return str(yyscanner, ID, sctx->runtime); } "|" { return '|'; } diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index f969dfa525bd..ba6c6dbf30c8 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -4,7 +4,6 @@ #include #include #include "util/debug.h" -#include "smt.h" #define IN_EXPR_Y 1 #include "expr.h" %} @@ -37,7 +36,7 @@ } ids; } -%token ID NUMBER MIN MAX IF ELSE SMT_ON D_RATIO EXPR_ERROR +%token ID NUMBER MIN MAX IF ELSE LITERAL D_RATIO EXPR_ERROR %left MIN MAX IF %left '|' %left '^' @@ -46,7 +45,7 @@ %left '-' '+' %left '*' '/' '%' %left NEG NOT -%type NUMBER +%type NUMBER LITERAL %type ID %destructor { free ($$); } %type expr if_expr @@ -280,9 +279,9 @@ expr: NUMBER $$ = union_expr($3, $5); } } -| SMT_ON +| LITERAL { - $$.val = smt_on() > 0 ? 1.0 : 0.0; + $$.val = $1; $$.ids = NULL; } ; -- cgit v1.2.3 From fdf1e29b6118c18fbf2003321fcf474d4bb778ec Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 10 Nov 2021 16:21:07 -0800 Subject: perf expr: Add metric literals for topology. Allow the number of cpus, cores, dies and packages to be queried by a metric expression. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul A . Clarke Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Wan Jiabing Cc: Yury Norov Link: https://lore.kernel.org/r/20211111002109.194172-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/expr.c | 12 +++++++++++- tools/perf/util/expr.c | 27 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 48c62d0789c5..ed95ebda49a7 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -66,7 +66,7 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u { struct expr_id_data *val_ptr; const char *p; - double val; + double val, num_cpus, num_cores, num_dies, num_packages; int ret; struct expr_parse_ctx *ctx; @@ -161,6 +161,16 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u NULL, ctx) == 0); TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 0); + /* Test toplogy constants appear well ordered. */ + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("#num_cpus", expr__parse(&num_cpus, ctx, "#num_cpus") == 0); + TEST_ASSERT_VAL("#num_cores", expr__parse(&num_cores, ctx, "#num_cores") == 0); + TEST_ASSERT_VAL("#num_cpus >= #num_cores", num_cpus >= num_cores); + TEST_ASSERT_VAL("#num_dies", expr__parse(&num_dies, ctx, "#num_dies") == 0); + TEST_ASSERT_VAL("#num_cores >= #num_dies", num_cores >= num_dies); + TEST_ASSERT_VAL("#num_packages", expr__parse(&num_packages, ctx, "#num_packages") == 0); + TEST_ASSERT_VAL("#num_dies >= #num_packages", num_dies >= num_packages); + expr__ctx_free(ctx); return 0; diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c index 7464739c2890..15af8b8ef5e7 100644 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@ -5,6 +5,8 @@ #include #include #include "metricgroup.h" +#include "cpumap.h" +#include "cputopo.h" #include "debug.h" #include "expr.h" #include "expr-bison.h" @@ -375,9 +377,34 @@ double expr_id_data__value(const struct expr_id_data *data) double expr__get_literal(const char *literal) { + static struct cpu_topology *topology; + if (!strcmp("#smt_on", literal)) return smt_on() > 0 ? 1.0 : 0.0; + if (!strcmp("#num_cpus", literal)) + return cpu__max_present_cpu(); + + /* + * Assume that topology strings are consistent, such as CPUs "0-1" + * wouldn't be listed as "0,1", and so after deduplication the number of + * these strings gives an indication of the number of packages, dies, + * etc. + */ + if (!topology) { + topology = cpu_topology__new(); + if (!topology) { + pr_err("Error creating CPU topology"); + return NAN; + } + } + if (!strcmp("#num_packages", literal)) + return topology->package_cpus_lists; + if (!strcmp("#num_dies", literal)) + return topology->die_cpus_lists; + if (!strcmp("#num_cores", literal)) + return topology->core_cpus_lists; + pr_err("Unrecognized literal '%s'", literal); return NAN; } -- cgit v1.2.3 From 1e7ab82975995d2238db8d8bad64e3aed34cfa26 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 10 Nov 2021 16:21:08 -0800 Subject: perf expr: Move ID handling to its own function This will facilitate sharing in a follow-on change. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul A . Clarke Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Wan Jiabing Cc: Yury Norov Link: https://lore.kernel.org/r/20211111002109.194172-8-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/expr.y | 61 +++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 26 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index ba6c6dbf30c8..1ec9c9b195e8 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -3,6 +3,7 @@ #define YYDEBUG 1 #include #include +#include #include "util/debug.h" #define IN_EXPR_Y 1 #include "expr.h" @@ -82,6 +83,39 @@ static struct ids union_expr(struct ids ids1, struct ids ids2) return result; } +static struct ids handle_id(struct expr_parse_ctx *ctx, char *id, + bool compute_ids) +{ + struct ids result; + + if (!compute_ids) { + /* + * Compute the event's value from ID. If the ID isn't known then + * it isn't used to compute the formula so set to NAN. + */ + struct expr_id_data *data; + + result.val = NAN; + if (expr__resolve_id(ctx, id, &data) == 0) + result.val = expr_id_data__value(data); + + result.ids = NULL; + free(id); + } else { + /* + * Set the value to BOTTOM to show that any value is possible + * when the event is computed. Create a set of just the ID. + */ + result.val = BOTTOM; + result.ids = ids__new(); + if (!result.ids || ids__insert(result.ids, id)) { + pr_err("Error creating IDs for '%s'", id); + free(id); + } + } + return result; +} + /* * If we're not computing ids or $1 and $3 are constants, compute the new * constant value using OP. Its invariant that there are no ids. If computing @@ -167,32 +201,7 @@ expr: NUMBER $$.val = $1; $$.ids = NULL; } -| ID -{ - if (!compute_ids) { - /* - * Compute the event's value from ID. If the ID isn't known then - * it isn't used to compute the formula so set to NAN. - */ - struct expr_id_data *data; - - $$.val = NAN; - if (expr__resolve_id(ctx, $1, &data) == 0) - $$.val = expr_id_data__value(data); - - $$.ids = NULL; - free($1); - } else { - /* - * Set the value to BOTTOM to show that any value is possible - * when the event is computed. Create a set of just the ID. - */ - $$.val = BOTTOM; - $$.ids = ids__new(); - if (!$$.ids || ids__insert($$.ids, $1)) - YYABORT; - } -} +| ID { $$ = handle_id(ctx, $1, compute_ids); } | expr '|' expr { BINARY_LONG_OP($$, |, $1, $3); } | expr '&' expr { BINARY_LONG_OP($$, &, $1, $3); } | expr '^' expr { BINARY_LONG_OP($$, ^, $1, $3); } -- cgit v1.2.3 From 9aba0adae8c773ba0c0adc7c4d97768e044166cb Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 10 Nov 2021 16:21:09 -0800 Subject: perf expr: Add source_count for aggregating events Events like uncore_imc/cas_count_read/ on Skylake open multiple events and then aggregate in the metric leader. To determine the average value per event the number of these events is needed. Add a source_count function that returns this value by counting the number of events with the given metric leader. For most events the value is 1 but for uncore_imc/cas_count_read/ it can yield values like 6. Add a generic test, but manually tested with a test metric that uses the function. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Namhyung Kim Cc: Paul A . Clarke Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Wan Jiabing Cc: Yury Norov Link: https://lore.kernel.org/r/20211111002109.194172-9-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/expr.c | 12 ++++++++++++ tools/perf/util/evsel.c | 12 ++++++++++++ tools/perf/util/evsel.h | 1 + tools/perf/util/expr.c | 27 ++++++++++++++++++++++----- tools/perf/util/expr.h | 3 +++ tools/perf/util/expr.l | 1 + tools/perf/util/expr.y | 15 +++++++++------ tools/perf/util/stat-shadow.c | 7 ++++++- 8 files changed, 66 insertions(+), 12 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index ed95ebda49a7..c895de481fe1 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -171,6 +171,18 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u TEST_ASSERT_VAL("#num_packages", expr__parse(&num_packages, ctx, "#num_packages") == 0); TEST_ASSERT_VAL("#num_dies >= #num_packages", num_dies >= num_packages); + /* + * Source count returns the number of events aggregating in a leader + * event including the leader. Check parsing yields an id. + */ + expr__ctx_clear(ctx); + TEST_ASSERT_VAL("source count", + expr__find_ids("source_count(EVENT1)", + NULL, ctx) == 0); + TEST_ASSERT_VAL("source count", hashmap__size(ctx->ids) == 1); + TEST_ASSERT_VAL("source count", hashmap__find(ctx->ids, "EVENT1", + (void **)&val_ptr)); + expr__ctx_free(ctx); return 0; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ec967fb8d7d9..a59fb2ecb84e 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3037,3 +3037,15 @@ void evsel__set_leader(struct evsel *evsel, struct evsel *leader) { evsel->core.leader = &leader->core; } + +int evsel__source_count(const struct evsel *evsel) +{ + struct evsel *pos; + int count = 0; + + evlist__for_each_entry(evsel->evlist, pos) { + if (pos->metric_leader == evsel) + count++; + } + return count; +} diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 3ea687141afa..29d49a8c1e92 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -489,6 +489,7 @@ struct evsel *evsel__leader(struct evsel *evsel); bool evsel__has_leader(struct evsel *evsel, struct evsel *leader); bool evsel__is_leader(struct evsel *evsel); void evsel__set_leader(struct evsel *evsel, struct evsel *leader); +int evsel__source_count(const struct evsel *evsel); /* * Macro to swap the bit-field postition and size. diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c index 15af8b8ef5e7..1d532b9fed29 100644 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@ -23,7 +23,10 @@ extern int expr_debug; struct expr_id_data { union { - double val; + struct { + double val; + int source_count; + } val; struct { double val; const char *metric_name; @@ -140,6 +143,13 @@ int expr__add_id(struct expr_parse_ctx *ctx, const char *id) /* Caller must make sure id is allocated */ int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val) +{ + return expr__add_id_val_source_count(ctx, id, val, /*source_count=*/1); +} + +/* Caller must make sure id is allocated */ +int expr__add_id_val_source_count(struct expr_parse_ctx *ctx, const char *id, + double val, int source_count) { struct expr_id_data *data_ptr = NULL, *old_data = NULL; char *old_key = NULL; @@ -148,7 +158,8 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val) data_ptr = malloc(sizeof(*data_ptr)); if (!data_ptr) return -ENOMEM; - data_ptr->val = val; + data_ptr->val.val = val; + data_ptr->val.source_count = source_count; data_ptr->kind = EXPR_ID_DATA__VALUE; ret = hashmap__set(ctx->ids, id, data_ptr, @@ -244,7 +255,7 @@ int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id, switch (data->kind) { case EXPR_ID_DATA__VALUE: - pr_debug2("lookup(%s): val %f\n", id, data->val); + pr_debug2("lookup(%s): val %f\n", id, data->val.val); break; case EXPR_ID_DATA__REF: pr_debug2("lookup(%s): ref metric name %s\n", id, @@ -255,7 +266,7 @@ int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id, pr_debug("%s failed to count\n", id); return -1; } - pr_debug("processing metric: %s EXIT: %f\n", id, data->val); + pr_debug("processing metric: %s EXIT: %f\n", id, data->ref.val); break; case EXPR_ID_DATA__REF_VALUE: pr_debug2("lookup(%s): ref val %f metric name %s\n", id, @@ -370,11 +381,17 @@ int expr__find_ids(const char *expr, const char *one, double expr_id_data__value(const struct expr_id_data *data) { if (data->kind == EXPR_ID_DATA__VALUE) - return data->val; + return data->val.val; assert(data->kind == EXPR_ID_DATA__REF_VALUE); return data->ref.val; } +double expr_id_data__source_count(const struct expr_id_data *data) +{ + assert(data->kind == EXPR_ID_DATA__VALUE); + return data->val.source_count; +} + double expr__get_literal(const char *literal) { static struct cpu_topology *topology; diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h index a6ab7f2b23d1..bd2116983bbb 100644 --- a/tools/perf/util/expr.h +++ b/tools/perf/util/expr.h @@ -40,6 +40,8 @@ void expr__ctx_free(struct expr_parse_ctx *ctx); void expr__del_id(struct expr_parse_ctx *ctx, const char *id); int expr__add_id(struct expr_parse_ctx *ctx, const char *id); int expr__add_id_val(struct expr_parse_ctx *ctx, const char *id, double val); +int expr__add_id_val_source_count(struct expr_parse_ctx *ctx, const char *id, + double val, int source_count); int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref); int expr__get_id(struct expr_parse_ctx *ctx, const char *id, struct expr_id_data **data); @@ -55,6 +57,7 @@ int expr__find_ids(const char *expr, const char *one, struct expr_parse_ctx *ids); double expr_id_data__value(const struct expr_id_data *data); +double expr_id_data__source_count(const struct expr_id_data *data); double expr__get_literal(const char *literal); #endif diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l index cf6e3c710502..0a13eb20c814 100644 --- a/tools/perf/util/expr.l +++ b/tools/perf/util/expr.l @@ -107,6 +107,7 @@ max { return MAX; } min { return MIN; } if { return IF; } else { return ELSE; } +source_count { return SOURCE_COUNT; } {literal} { return literal(yyscanner); } {number} { return value(yyscanner); } {symbol} { return str(yyscanner, ID, sctx->runtime); } diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 1ec9c9b195e8..a30b825adb7b 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -37,7 +37,7 @@ } ids; } -%token ID NUMBER MIN MAX IF ELSE LITERAL D_RATIO EXPR_ERROR +%token ID NUMBER MIN MAX IF ELSE LITERAL D_RATIO SOURCE_COUNT EXPR_ERROR %left MIN MAX IF %left '|' %left '^' @@ -84,7 +84,7 @@ static struct ids union_expr(struct ids ids1, struct ids ids2) } static struct ids handle_id(struct expr_parse_ctx *ctx, char *id, - bool compute_ids) + bool compute_ids, bool source_count) { struct ids result; @@ -96,9 +96,11 @@ static struct ids handle_id(struct expr_parse_ctx *ctx, char *id, struct expr_id_data *data; result.val = NAN; - if (expr__resolve_id(ctx, id, &data) == 0) - result.val = expr_id_data__value(data); - + if (expr__resolve_id(ctx, id, &data) == 0) { + result.val = source_count + ? expr_id_data__source_count(data) + : expr_id_data__value(data); + } result.ids = NULL; free(id); } else { @@ -201,7 +203,8 @@ expr: NUMBER $$.val = $1; $$.ids = NULL; } -| ID { $$ = handle_id(ctx, $1, compute_ids); } +| ID { $$ = handle_id(ctx, $1, compute_ids, /*source_count=*/false); } +| SOURCE_COUNT '(' ID ')' { $$ = handle_id(ctx, $3, compute_ids, /*source_count=*/true); } | expr '|' expr { BINARY_LONG_OP($$, |, $1, $3); } | expr '&' expr { BINARY_LONG_OP($$, &, $1, $3); } | expr '^' expr { BINARY_LONG_OP($$, ^, $1, $3); } diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index e4fb02b05130..5c7308efa768 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -829,10 +829,12 @@ static int prepare_metric(struct evsel **metric_events, struct saved_value *v; struct stats *stats; u64 metric_total = 0; + int source_count; if (!strcmp(metric_events[i]->name, "duration_time")) { stats = &walltime_nsecs_stats; scale = 1e-9; + source_count = 1; } else { v = saved_value_lookup(metric_events[i], cpu, false, STAT_NONE, 0, st, @@ -841,6 +843,7 @@ static int prepare_metric(struct evsel **metric_events, break; stats = &v->stats; scale = 1.0; + source_count = evsel__source_count(metric_events[i]); if (v->metric_other) metric_total = v->metric_total; @@ -849,7 +852,9 @@ static int prepare_metric(struct evsel **metric_events, if (!n) return -ENOMEM; - expr__add_id_val(pctx, n, metric_total ? : avg_stats(stats) * scale); + expr__add_id_val_source_count(pctx, n, + metric_total ? : avg_stats(stats) * scale, + source_count); } for (j = 0; metric_refs && metric_refs[j].metric_name; j++) { -- cgit v1.2.3 From 0901b56028725a68459c99f41d1172f80449c9e6 Mon Sep 17 00:00:00 2001 From: German Gomez Date: Tue, 9 Nov 2021 16:30:07 +0000 Subject: perf arm-spe: Add snapshot mode support This patch enables support for snapshot mode of arm_spe events, including the implementation of the necessary callbacks (excluding find_snapshot, which is to be included in a followup commit). Reviewed-by: James Clark Reviewed-by: Leo Yan Signed-off-by: German Gomez Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211109163009.92072-2-german.gomez@arm.com Tested-by: Leo Yan Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/util/arm-spe.c | 130 +++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index a4420d4df503..f8b03d164b42 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -84,6 +84,55 @@ static int arm_spe_info_fill(struct auxtrace_record *itr, return 0; } +static void +arm_spe_snapshot_resolve_auxtrace_defaults(struct record_opts *opts, + bool privileged) +{ + /* + * The default snapshot size is the auxtrace mmap size. If neither auxtrace mmap size nor + * snapshot size is specified, then the default is 4MiB for privileged users, 128KiB for + * unprivileged users. + * + * The default auxtrace mmap size is 4MiB/page_size for privileged users, 128KiB for + * unprivileged users. If an unprivileged user does not specify mmap pages, the mmap pages + * will be reduced from the default 512KiB/page_size to 256KiB/page_size, otherwise the + * user is likely to get an error as they exceed their mlock limmit. + */ + + /* + * No size were given to '-S' or '-m,', so go with the default + */ + if (!opts->auxtrace_snapshot_size && !opts->auxtrace_mmap_pages) { + if (privileged) { + opts->auxtrace_mmap_pages = MiB(4) / page_size; + } else { + opts->auxtrace_mmap_pages = KiB(128) / page_size; + if (opts->mmap_pages == UINT_MAX) + opts->mmap_pages = KiB(256) / page_size; + } + } else if (!opts->auxtrace_mmap_pages && !privileged && opts->mmap_pages == UINT_MAX) { + opts->mmap_pages = KiB(256) / page_size; + } + + /* + * '-m,xyz' was specified but no snapshot size, so make the snapshot size as big as the + * auxtrace mmap area. + */ + if (!opts->auxtrace_snapshot_size) + opts->auxtrace_snapshot_size = opts->auxtrace_mmap_pages * (size_t)page_size; + + /* + * '-Sxyz' was specified but no auxtrace mmap area, so make the auxtrace mmap area big + * enough to fit the requested snapshot size. + */ + if (!opts->auxtrace_mmap_pages) { + size_t sz = opts->auxtrace_snapshot_size; + + sz = round_up(sz, page_size) / page_size; + opts->auxtrace_mmap_pages = roundup_pow_of_two(sz); + } +} + static int arm_spe_recording_options(struct auxtrace_record *itr, struct evlist *evlist, struct record_opts *opts) @@ -115,6 +164,36 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, if (!opts->full_auxtrace) return 0; + /* + * we are in snapshot mode. + */ + if (opts->auxtrace_snapshot_mode) { + /* + * Command arguments '-Sxyz' and/or '-m,xyz' are missing, so fill those in with + * default values. + */ + if (!opts->auxtrace_snapshot_size || !opts->auxtrace_mmap_pages) + arm_spe_snapshot_resolve_auxtrace_defaults(opts, privileged); + + /* + * Snapshot size can't be bigger than the auxtrace area. + */ + if (opts->auxtrace_snapshot_size > opts->auxtrace_mmap_pages * (size_t)page_size) { + pr_err("Snapshot size %zu must not be greater than AUX area tracing mmap size %zu\n", + opts->auxtrace_snapshot_size, + opts->auxtrace_mmap_pages * (size_t)page_size); + return -EINVAL; + } + + /* + * Something went wrong somewhere - this shouldn't happen. + */ + if (!opts->auxtrace_snapshot_size || !opts->auxtrace_mmap_pages) { + pr_err("Failed to calculate default snapshot size and/or AUX area tracing mmap pages\n"); + return -EINVAL; + } + } + /* We are in full trace mode but '-m,xyz' wasn't specified */ if (!opts->auxtrace_mmap_pages) { if (privileged) { @@ -138,6 +217,9 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, } } + if (opts->auxtrace_snapshot_mode) + pr_debug2("%sx snapshot size: %zu\n", ARM_SPE_PMU_NAME, + opts->auxtrace_snapshot_size); /* * To obtain the auxtrace buffer file descriptor, the auxtrace event @@ -172,6 +254,51 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, return 0; } +static int arm_spe_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused, + struct record_opts *opts, + const char *str) +{ + unsigned long long snapshot_size = 0; + char *endptr; + + if (str) { + snapshot_size = strtoull(str, &endptr, 0); + if (*endptr || snapshot_size > SIZE_MAX) + return -1; + } + + opts->auxtrace_snapshot_mode = true; + opts->auxtrace_snapshot_size = snapshot_size; + + return 0; +} + +static int arm_spe_snapshot_start(struct auxtrace_record *itr) +{ + struct arm_spe_recording *ptr = + container_of(itr, struct arm_spe_recording, itr); + struct evsel *evsel; + + evlist__for_each_entry(ptr->evlist, evsel) { + if (evsel->core.attr.type == ptr->arm_spe_pmu->type) + return evsel__disable(evsel); + } + return -EINVAL; +} + +static int arm_spe_snapshot_finish(struct auxtrace_record *itr) +{ + struct arm_spe_recording *ptr = + container_of(itr, struct arm_spe_recording, itr); + struct evsel *evsel; + + evlist__for_each_entry(ptr->evlist, evsel) { + if (evsel->core.attr.type == ptr->arm_spe_pmu->type) + return evsel__enable(evsel); + } + return -EINVAL; +} + static u64 arm_spe_reference(struct auxtrace_record *itr __maybe_unused) { struct timespec ts; @@ -207,6 +334,9 @@ struct auxtrace_record *arm_spe_recording_init(int *err, sper->arm_spe_pmu = arm_spe_pmu; sper->itr.pmu = arm_spe_pmu; + sper->itr.snapshot_start = arm_spe_snapshot_start; + sper->itr.snapshot_finish = arm_spe_snapshot_finish; + sper->itr.parse_snapshot_options = arm_spe_parse_snapshot_options; sper->itr.recording_options = arm_spe_recording_options; sper->itr.info_priv_size = arm_spe_info_priv_size; sper->itr.info_fill = arm_spe_info_fill; -- cgit v1.2.3 From 56c31cdff7c2a640f4afcfe0ac4e4ca6dc47c5fd Mon Sep 17 00:00:00 2001 From: German Gomez Date: Tue, 9 Nov 2021 16:30:08 +0000 Subject: perf arm-spe: Implement find_snapshot callback The head pointer of the AUX buffer managed by the arm_spe_pmu.c driver is not monotonically increasing, therefore the find_snapshot callback is needed in order to find the trace data within the AUX buffer and avoid wasting space in the perf.data file. The pointer is assumed to have wrapped if the buffer contains non-zero data at the end. If it has wrapped, the entire contents of the AUX buffer are stored in the perf.data file. Otherwise only the data up to the head pointer is stored. Reviewed-by: James Clark Reviewed-by: Leo Yan Signed-off-by: German Gomez Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211109163009.92072-3-german.gomez@arm.com Tested-by: Leo Yan Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/util/arm-spe.c | 145 +++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index f8b03d164b42..56785034fc84 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -23,6 +23,7 @@ #include "../../../util/auxtrace.h" #include "../../../util/record.h" #include "../../../util/arm-spe.h" +#include // reallocarray #define KiB(x) ((x) * 1024) #define MiB(x) ((x) * 1024 * 1024) @@ -31,6 +32,8 @@ struct arm_spe_recording { struct auxtrace_record itr; struct perf_pmu *arm_spe_pmu; struct evlist *evlist; + int wrapped_cnt; + bool *wrapped; }; static void arm_spe_set_timestamp(struct auxtrace_record *itr, @@ -299,6 +302,146 @@ static int arm_spe_snapshot_finish(struct auxtrace_record *itr) return -EINVAL; } +static int arm_spe_alloc_wrapped_array(struct arm_spe_recording *ptr, int idx) +{ + bool *wrapped; + int cnt = ptr->wrapped_cnt, new_cnt, i; + + /* + * No need to allocate, so return early. + */ + if (idx < cnt) + return 0; + + /* + * Make ptr->wrapped as big as idx. + */ + new_cnt = idx + 1; + + /* + * Free'ed in arm_spe_recording_free(). + */ + wrapped = reallocarray(ptr->wrapped, new_cnt, sizeof(bool)); + if (!wrapped) + return -ENOMEM; + + /* + * init new allocated values. + */ + for (i = cnt; i < new_cnt; i++) + wrapped[i] = false; + + ptr->wrapped_cnt = new_cnt; + ptr->wrapped = wrapped; + + return 0; +} + +static bool arm_spe_buffer_has_wrapped(unsigned char *buffer, + size_t buffer_size, u64 head) +{ + u64 i, watermark; + u64 *buf = (u64 *)buffer; + size_t buf_size = buffer_size; + + /* + * Defensively handle the case where head might be continually increasing - if its value is + * equal or greater than the size of the ring buffer, then we can safely determine it has + * wrapped around. Otherwise, continue to detect if head might have wrapped. + */ + if (head >= buffer_size) + return true; + + /* + * We want to look the very last 512 byte (chosen arbitrarily) in the ring buffer. + */ + watermark = buf_size - 512; + + /* + * The value of head is somewhere within the size of the ring buffer. This can be that there + * hasn't been enough data to fill the ring buffer yet or the trace time was so long that + * head has numerically wrapped around. To find we need to check if we have data at the + * very end of the ring buffer. We can reliably do this because mmap'ed pages are zeroed + * out and there is a fresh mapping with every new session. + */ + + /* + * head is less than 512 byte from the end of the ring buffer. + */ + if (head > watermark) + watermark = head; + + /* + * Speed things up by using 64 bit transactions (see "u64 *buf" above) + */ + watermark /= sizeof(u64); + buf_size /= sizeof(u64); + + /* + * If we find trace data at the end of the ring buffer, head has been there and has + * numerically wrapped around at least once. + */ + for (i = watermark; i < buf_size; i++) + if (buf[i]) + return true; + + return false; +} + +static int arm_spe_find_snapshot(struct auxtrace_record *itr, int idx, + struct auxtrace_mmap *mm, unsigned char *data, + u64 *head, u64 *old) +{ + int err; + bool wrapped; + struct arm_spe_recording *ptr = + container_of(itr, struct arm_spe_recording, itr); + + /* + * Allocate memory to keep track of wrapping if this is the first + * time we deal with this *mm. + */ + if (idx >= ptr->wrapped_cnt) { + err = arm_spe_alloc_wrapped_array(ptr, idx); + if (err) + return err; + } + + /* + * Check to see if *head has wrapped around. If it hasn't only the + * amount of data between *head and *old is snapshot'ed to avoid + * bloating the perf.data file with zeros. But as soon as *head has + * wrapped around the entire size of the AUX ring buffer it taken. + */ + wrapped = ptr->wrapped[idx]; + if (!wrapped && arm_spe_buffer_has_wrapped(data, mm->len, *head)) { + wrapped = true; + ptr->wrapped[idx] = true; + } + + pr_debug3("%s: mmap index %d old head %zu new head %zu size %zu\n", + __func__, idx, (size_t)*old, (size_t)*head, mm->len); + + /* + * No wrap has occurred, we can just use *head and *old. + */ + if (!wrapped) + return 0; + + /* + * *head has wrapped around - adjust *head and *old to pickup the + * entire content of the AUX buffer. + */ + if (*head >= mm->len) { + *old = *head - mm->len; + } else { + *head += mm->len; + *old = *head - mm->len; + } + + return 0; +} + static u64 arm_spe_reference(struct auxtrace_record *itr __maybe_unused) { struct timespec ts; @@ -313,6 +456,7 @@ static void arm_spe_recording_free(struct auxtrace_record *itr) struct arm_spe_recording *sper = container_of(itr, struct arm_spe_recording, itr); + free(sper->wrapped); free(sper); } @@ -336,6 +480,7 @@ struct auxtrace_record *arm_spe_recording_init(int *err, sper->itr.pmu = arm_spe_pmu; sper->itr.snapshot_start = arm_spe_snapshot_start; sper->itr.snapshot_finish = arm_spe_snapshot_finish; + sper->itr.find_snapshot = arm_spe_find_snapshot; sper->itr.parse_snapshot_options = arm_spe_parse_snapshot_options; sper->itr.recording_options = arm_spe_recording_options; sper->itr.info_priv_size = arm_spe_info_priv_size; -- cgit v1.2.3 From 6b1b208bef5b9a53a591f13df98f72435b69c3e8 Mon Sep 17 00:00:00 2001 From: German Gomez Date: Tue, 9 Nov 2021 16:30:09 +0000 Subject: perf arm-spe: Snapshot mode test Shell script test_arm_spe.sh has been added to test the recording of SPE tracing events in snapshot mode. Reviewed-by: Leo Yan Signed-off-by: German Gomez Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211109163009.92072-4-german.gomez@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/test_arm_spe.sh | 89 ++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100755 tools/perf/tests/shell/test_arm_spe.sh (limited to 'tools/perf') diff --git a/tools/perf/tests/shell/test_arm_spe.sh b/tools/perf/tests/shell/test_arm_spe.sh new file mode 100755 index 000000000000..e59044edc406 --- /dev/null +++ b/tools/perf/tests/shell/test_arm_spe.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# Check Arm SPE trace data recording and synthesized samples + +# Uses the 'perf record' to record trace data of Arm SPE events; +# then verify if any SPE event samples are generated by SPE with +# 'perf script' and 'perf report' commands. + +# SPDX-License-Identifier: GPL-2.0 +# German Gomez , 2021 + +skip_if_no_arm_spe_event() { + perf list | egrep -q 'arm_spe_[0-9]+//' && return 0 + + # arm_spe event doesn't exist + return 2 +} + +skip_if_no_arm_spe_event || exit 2 + +perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) +glb_err=0 + +cleanup_files() +{ + rm -f ${perfdata} + exit $glb_err +} + +trap cleanup_files exit term int + +arm_spe_report() { + if [ $2 != 0 ]; then + echo "$1: FAIL" + glb_err=$2 + else + echo "$1: PASS" + fi +} + +perf_script_samples() { + echo "Looking at perf.data file for dumping samples:" + + # from arm-spe.c/arm_spe_synth_events() + events="(ld1-miss|ld1-access|llc-miss|lld-access|tlb-miss|tlb-access|branch-miss|remote-access|memory)" + + # Below is an example of the samples dumping: + # dd 3048 [002] 1 l1d-access: ffffaa64999c __GI___libc_write+0x3c (/lib/aarch64-linux-gnu/libc-2.27.so) + # dd 3048 [002] 1 tlb-access: ffffaa64999c __GI___libc_write+0x3c (/lib/aarch64-linux-gnu/libc-2.27.so) + # dd 3048 [002] 1 memory: ffffaa64999c __GI___libc_write+0x3c (/lib/aarch64-linux-gnu/libc-2.27.so) + perf script -F,-time -i ${perfdata} 2>&1 | \ + egrep " +$1 +[0-9]+ .* +${events}:(.*:)? +" > /dev/null 2>&1 +} + +perf_report_samples() { + echo "Looking at perf.data file for reporting samples:" + + # Below is an example of the samples reporting: + # 73.04% 73.04% dd libc-2.27.so [.] _dl_addr + # 7.71% 7.71% dd libc-2.27.so [.] getenv + # 2.59% 2.59% dd ld-2.27.so [.] strcmp + perf report --stdio -i ${perfdata} 2>&1 | \ + egrep " +[0-9]+\.[0-9]+% +[0-9]+\.[0-9]+% +$1 " > /dev/null 2>&1 +} + +arm_spe_snapshot_test() { + echo "Recording trace with snapshot mode $perfdata" + perf record -o ${perfdata} -e arm_spe// -S \ + -- dd if=/dev/zero of=/dev/null > /dev/null 2>&1 & + PERFPID=$! + + # Wait for perf program + sleep 1 + + # Send signal to snapshot trace data + kill -USR2 $PERFPID + + # Stop perf program + kill $PERFPID + wait $PERFPID + + perf_script_samples dd && + perf_report_samples dd + + err=$? + arm_spe_report "SPE snapshot testing" $err +} + +arm_spe_snapshot_test +exit $glb_err -- cgit v1.2.3 From d54e50b7c9a4a3d30eba5075528c7b0a187667bb Mon Sep 17 00:00:00 2001 From: Andrew Kilroy Date: Tue, 9 Nov 2021 14:21:52 +0000 Subject: perf cs-etm: Print size using consistent format Since the size is already printed earlier in hex, print the same data using the same format, in hex. Reviewed-by: James Clark Reviewed-by: Leo Yan Reviewed-by: Mathieu Poirier Signed-off-by: Andrew Kilroy Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211109142153.56546-2-german.gomez@arm.com Signed-off-by: German Gomez Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index f323adb1af85..4f672f7d008c 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -537,7 +537,7 @@ static void cs_etm__dump_event(struct cs_etm_queue *etmq, fprintf(stdout, "\n"); color_fprintf(stdout, color, - ". ... CoreSight %s Trace data: size %zu bytes\n", + ". ... CoreSight %s Trace data: size %#zx bytes\n", cs_etm_decoder__get_name(etmq->decoder), buffer->size); do { -- cgit v1.2.3 From 09e9afac8cea99429b103fc21836dae693a56b17 Mon Sep 17 00:00:00 2001 From: Andrew Kilroy Date: Tue, 9 Nov 2021 14:21:53 +0000 Subject: perf arm-spe: Print size using consistent format Since the size is already printed earlier in hex, print the same data using the same format, in hex. Reviewed-by: James Clark Reviewed-by: Leo Yan Signed-off-by: Andrew Kilroy Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211109142153.56546-3-german.gomez@arm.com Signed-off-by: German Gomez Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/arm-spe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 58b7069c5a5f..2196291976d9 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -100,7 +100,7 @@ static void arm_spe_dump(struct arm_spe *spe __maybe_unused, const char *color = PERF_COLOR_BLUE; color_fprintf(stdout, color, - ". ... ARM SPE data: size %zu bytes\n", + ". ... ARM SPE data: size %#zx bytes\n", len); while (len) { -- cgit v1.2.3 From 438f1a9f54a99368957c150496b582a02cc6c305 Mon Sep 17 00:00:00 2001 From: Like Xu Date: Tue, 9 Nov 2021 17:01:47 +0800 Subject: perf design.txt: Synchronize the definition of enum perf_hw_id with code We're not surprised that there are tons of Linux users who only read the documentation to learn about the kernel. Let's update the perf part for common hardware events since three new *generic* hardware events were added. Signed-off-by: Like Xu Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20211109090147.56978-1-likexu@tencent.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/design.txt | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/design.txt b/tools/perf/design.txt index a42fab308ff6..aa8cfeabb743 100644 --- a/tools/perf/design.txt +++ b/tools/perf/design.txt @@ -106,6 +106,9 @@ enum perf_hw_id { PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4, PERF_COUNT_HW_BRANCH_MISSES = 5, PERF_COUNT_HW_BUS_CYCLES = 6, + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7, + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8, + PERF_COUNT_HW_REF_CPU_CYCLES = 9, }; These are standardized types of events that work relatively uniformly -- cgit v1.2.3 From 3ca3af7d1f230d1f93ba4cd8cd9d054870f2406f Mon Sep 17 00:00:00 2001 From: Kajol Jain Date: Mon, 8 Nov 2021 11:30:10 +0530 Subject: perf vendor events power10: Add metric events JSON file for power10 platform Add PMU metric JSON file for power10 platform. Signed-off-by: Kajol Jain Reviewed-by: Paul Clarke Cc: Athira Jajeev Cc: Jiri Olsa Cc: Madhavan Srinivasan Cc: Nageswara R Sastry Cc: linuxppc-dev@lists.ozlabs.org Link: http://lore.kernel.org/lkml/20211108060010.177517-1-kjain@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- .../pmu-events/arch/powerpc/power10/metrics.json | 676 +++++++++++++++++++++ 1 file changed, 676 insertions(+) create mode 100644 tools/perf/pmu-events/arch/powerpc/power10/metrics.json (limited to 'tools/perf') diff --git a/tools/perf/pmu-events/arch/powerpc/power10/metrics.json b/tools/perf/pmu-events/arch/powerpc/power10/metrics.json new file mode 100644 index 000000000000..b57526fa44f2 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power10/metrics.json @@ -0,0 +1,676 @@ +[ + { + "BriefDescription": "Percentage of cycles that are run cycles", + "MetricExpr": "PM_RUN_CYC / PM_CYC * 100", + "MetricGroup": "General", + "MetricName": "RUN_CYCLES_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Average cycles per completed instruction", + "MetricExpr": "PM_CYC / PM_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "CYCLES_PER_INSTRUCTION" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled for any reason", + "MetricExpr": "PM_DISP_STALL_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled because there was a flush", + "MetricExpr": "PM_DISP_STALL_FLUSH / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_FLUSH_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled because the MMU was handling a translation miss", + "MetricExpr": "PM_DISP_STALL_TRANSLATION / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_TRANSLATION_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled waiting to resolve an instruction ERAT miss", + "MetricExpr": "PM_DISP_STALL_IERAT_ONLY_MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_IERAT_ONLY_MISS_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled waiting to resolve an instruction TLB miss", + "MetricExpr": "PM_DISP_STALL_ITLB_MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_ITLB_MISS_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled due to an icache miss", + "MetricExpr": "PM_DISP_STALL_IC_MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_IC_MISS_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled while the instruction was fetched from the local L2", + "MetricExpr": "PM_DISP_STALL_IC_L2 / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_IC_L2_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled while the instruction was fetched from the local L3", + "MetricExpr": "PM_DISP_STALL_IC_L3 / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_IC_L3_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled while the instruction was fetched from any source beyond the local L3", + "MetricExpr": "PM_DISP_STALL_IC_L3MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_IC_L3MISS_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled due to an icache miss after a branch mispredict", + "MetricExpr": "PM_DISP_STALL_BR_MPRED_ICMISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_BR_MPRED_ICMISS_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled while instruction was fetched from the local L2 after suffering a branch mispredict", + "MetricExpr": "PM_DISP_STALL_BR_MPRED_IC_L2 / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_BR_MPRED_IC_L2_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled while instruction was fetched from the local L3 after suffering a branch mispredict", + "MetricExpr": "PM_DISP_STALL_BR_MPRED_IC_L3 / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_BR_MPRED_IC_L3_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled while instruction was fetched from any source beyond the local L3 after suffering a branch mispredict", + "MetricExpr": "PM_DISP_STALL_BR_MPRED_IC_L3MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_BR_MPRED_IC_L3MISS_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled due to a branch mispredict", + "MetricExpr": "PM_DISP_STALL_BR_MPRED / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_BR_MPRED_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch for any reason", + "MetricExpr": "PM_DISP_STALL_HELD_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_HELD_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch because of a synchronizing instruction that requires the ICT to be empty before dispatch", + "MetricExpr": "PM_DISP_STALL_HELD_SYNC_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISP_HELD_STALL_SYNC_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch while waiting on the scoreboard", + "MetricExpr": "PM_DISP_STALL_HELD_SCOREBOARD_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISP_HELD_STALL_SCOREBOARD_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch due to issue queue full", + "MetricExpr": "PM_DISP_STALL_HELD_ISSQ_FULL_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISP_HELD_STALL_ISSQ_FULL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch because the mapper/SRB was full", + "MetricExpr": "PM_DISP_STALL_HELD_RENAME_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_HELD_RENAME_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch because the STF mapper/SRB was full", + "MetricExpr": "PM_DISP_STALL_HELD_STF_MAPPER_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_HELD_STF_MAPPER_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch because the XVFC mapper/SRB was full", + "MetricExpr": "PM_DISP_STALL_HELD_XVFC_MAPPER_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_HELD_XVFC_MAPPER_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch for any other reason", + "MetricExpr": "PM_DISP_STALL_HELD_OTHER_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_HELD_OTHER_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction has been dispatched but not issued for any reason", + "MetricExpr": "PM_ISSUE_STALL / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "ISSUE_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting to be finished in one of the execution units", + "MetricExpr": "PM_EXEC_STALL / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "EXECUTION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction spent executing an NTC instruction that gets flushed some time after dispatch", + "MetricExpr": "PM_EXEC_STALL_NTC_FLUSH / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "NTC_FLUSH_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTF instruction finishes at dispatch", + "MetricExpr": "PM_EXEC_STALL_FIN_AT_DISP / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "FIN_AT_DISP_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is executing in the branch unit", + "MetricExpr": "PM_EXEC_STALL_BRU / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "BRU_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a simple fixed point instruction that is executing in the LSU", + "MetricExpr": "PM_EXEC_STALL_SIMPLE_FX / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "SIMPLE_FX_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is executing in the VSU", + "MetricExpr": "PM_EXEC_STALL_VSU / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "VSU_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting to be finished in one of the execution units", + "MetricExpr": "PM_EXEC_STALL_TRANSLATION / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "TRANSLATION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a load or store that suffered a translation miss", + "MetricExpr": "PM_EXEC_STALL_DERAT_ONLY_MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DERAT_ONLY_MISS_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is recovering from a TLB miss", + "MetricExpr": "PM_EXEC_STALL_DERAT_DTLB_MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DERAT_DTLB_MISS_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is executing in the LSU", + "MetricExpr": "PM_EXEC_STALL_LSU / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "LSU_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a load that is executing in the LSU", + "MetricExpr": "PM_EXEC_STALL_LOAD / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "LOAD_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting for a load miss to resolve from either the local L2 or local L3", + "MetricExpr": "PM_EXEC_STALL_DMISS_L2L3 / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DMISS_L2L3_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting for a load miss to resolve from either the local L2 or local L3, with an RC dispatch conflict", + "MetricExpr": "PM_EXEC_STALL_DMISS_L2L3_CONFLICT / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DMISS_L2L3_CONFLICT_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting for a load miss to resolve from either the local L2 or local L3, without an RC dispatch conflict", + "MetricExpr": "PM_EXEC_STALL_DMISS_L2L3_NOCONFLICT / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DMISS_L2L3_NOCONFLICT_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting for a load miss to resolve from a source beyond the local L2 and local L3", + "MetricExpr": "PM_EXEC_STALL_DMISS_L3MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DMISS_L3MISS_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting for a load miss to resolve from a neighbor chiplet's L2 or L3 in the same chip", + "MetricExpr": "PM_EXEC_STALL_DMISS_L21_L31 / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DMISS_L21_L31_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting for a load miss to resolve from L4, local memory or OpenCAPI chip", + "MetricExpr": "PM_EXEC_STALL_DMISS_LMEM / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DMISS_LMEM_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting for a load miss to resolve from a remote chip (cache, L4, memory or OpenCAPI) in the same group", + "MetricExpr": "PM_EXEC_STALL_DMISS_OFF_CHIP / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DMISS_OFF_CHIP_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is waiting for a load miss to resolve from a distant chip (cache, L4, memory or OpenCAPI chip)", + "MetricExpr": "PM_EXEC_STALL_DMISS_OFF_NODE / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DMISS_OFF_NODE_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is executing a TLBIEL instruction", + "MetricExpr": "PM_EXEC_STALL_TLBIEL / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "TLBIEL_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is finishing a load after its data has been reloaded from a data source beyond the local L1, OR when the LSU is processing an L1-hit, OR when the NTF instruction merged with another load in the LMQ", + "MetricExpr": "PM_EXEC_STALL_LOAD_FINISH / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "LOAD_FINISH_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a store that is executing in the LSU", + "MetricExpr": "PM_EXEC_STALL_STORE / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "STORE_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is in the store unit outside of handling store misses or other special store operations", + "MetricExpr": "PM_EXEC_STALL_STORE_PIPE / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "STORE_PIPE_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a store whose cache line was not resident in the L1 and had to wait for allocation of the missing line into the L1", + "MetricExpr": "PM_EXEC_STALL_STORE_MISS / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "STORE_MISS_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a TLBIE instruction waiting for a response from the L2", + "MetricExpr": "PM_EXEC_STALL_TLBIE / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "TLBIE_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is executing a PTESYNC instruction", + "MetricExpr": "PM_EXEC_STALL_PTESYNC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "PTESYNC_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction cannot complete because the thread was blocked", + "MetricExpr": "PM_CMPL_STALL / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "COMPLETION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction cannot complete because it was interrupted by ANY exception", + "MetricExpr": "PM_CMPL_STALL_EXCEPTION / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "EXCEPTION_COMPLETION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is stuck at finish waiting for the non-speculative finish of either a STCX instruction waiting for its result or a load waiting for non-critical sectors of data and ECC", + "MetricExpr": "PM_CMPL_STALL_MEM_ECC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "MEM_ECC_COMPLETION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a STCX instruction waiting for resolution from the nest", + "MetricExpr": "PM_CMPL_STALL_STCX / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "STCX_COMPLETION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a LWSYNC instruction waiting to complete", + "MetricExpr": "PM_CMPL_STALL_LWSYNC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "LWSYNC_COMPLETION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction is a HWSYNC instruction stuck at finish waiting for a response from the L2", + "MetricExpr": "PM_CMPL_STALL_HWSYNC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "HWSYNC_COMPLETION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction required special handling before completion", + "MetricExpr": "PM_CMPL_STALL_SPECIAL / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "SPECIAL_COMPLETION_STALL_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when dispatch was stalled because fetch was being held, so there was nothing in the pipeline for this thread", + "MetricExpr": "PM_DISP_STALL_FETCH / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_FETCH_CPI" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTC instruction was held at dispatch because of power management", + "MetricExpr": "PM_DISP_STALL_HELD_HALT_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "CPI", + "MetricName": "DISPATCHED_HELD_HALT_CPI" + }, + { + "BriefDescription": "Percentage of flushes per completed instruction", + "MetricExpr": "PM_FLUSH / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Others", + "MetricName": "FLUSH_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of flushes due to a branch mispredict per completed instruction", + "MetricExpr": "PM_FLUSH_MPRED / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Others", + "MetricName": "BR_MPRED_FLUSH_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of branch mispredictions per completed instruction", + "MetricExpr": "PM_BR_MPRED_CMPL / PM_RUN_INST_CMPL", + "MetricGroup": "Others", + "MetricName": "BRANCH_MISPREDICTION_RATE" + }, + { + "BriefDescription": "Percentage of finished loads that missed in the L1", + "MetricExpr": "PM_LD_MISS_L1 / PM_LD_REF_L1 * 100", + "MetricGroup": "Others", + "MetricName": "L1_LD_MISS_RATIO", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of completed instructions that were loads that missed the L1", + "MetricExpr": "PM_LD_MISS_L1 / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Others", + "MetricName": "L1_LD_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of completed instructions when the DPTEG required for the load/store instruction in execution was missing from the TLB", + "MetricExpr": "PM_DTLB_MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Others", + "MetricName": "DTLB_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Average number of completed instructions dispatched per instruction completed", + "MetricExpr": "PM_INST_DISP / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "DISPATCH_PER_INST_CMPL" + }, + { + "BriefDescription": "Percentage of completed instructions that were a demand load that did not hit in the L1 or L2", + "MetricExpr": "PM_DATA_FROM_L2MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "General", + "MetricName": "L2_LD_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of completed instructions that were demand fetches that missed the L1 icache", + "MetricExpr": "PM_L1_ICACHE_MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Instruction_Misses", + "MetricName": "L1_INST_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of completed instructions that were demand fetches that reloaded from beyond the L3 icache", + "MetricExpr": "PM_INST_FROM_L3MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "General", + "MetricName": "L3_INST_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Average number of completed instructions per cycle", + "MetricExpr": "PM_INST_CMPL / PM_CYC", + "MetricGroup": "General", + "MetricName": "IPC" + }, + { + "BriefDescription": "Average number of cycles per completed instruction group", + "MetricExpr": "PM_CYC / PM_1PLUS_PPC_CMPL", + "MetricGroup": "General", + "MetricName": "CYCLES_PER_COMPLETED_INSTRUCTIONS_SET" + }, + { + "BriefDescription": "Percentage of cycles when at least 1 instruction dispatched", + "MetricExpr": "PM_1PLUS_PPC_DISP / PM_RUN_CYC * 100", + "MetricGroup": "General", + "MetricName": "CYCLES_ATLEAST_ONE_INST_DISPATCHED", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Average number of finished loads per completed instruction", + "MetricExpr": "PM_LD_REF_L1 / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "LOADS_PER_INST" + }, + { + "BriefDescription": "Average number of finished stores per completed instruction", + "MetricExpr": "PM_ST_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "STORES_PER_INST" + }, + { + "BriefDescription": "Percentage of demand loads that reloaded from beyond the L2 per completed instruction", + "MetricExpr": "PM_DATA_FROM_L2MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "dL1_Reloads", + "MetricName": "DL1_RELOAD_FROM_L2_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of demand loads that reloaded from beyond the L3 per completed instruction", + "MetricExpr": "PM_DATA_FROM_L3MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "dL1_Reloads", + "MetricName": "DL1_RELOAD_FROM_L3_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of DERAT misses with 4k page size per completed instruction", + "MetricExpr": "PM_DERAT_MISS_4K / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Translation", + "MetricName": "DERAT_4K_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of DERAT misses with 64k page size per completed instruction", + "MetricExpr": "PM_DERAT_MISS_64K / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Translation", + "MetricName": "DERAT_64K_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Average number of run cycles per completed instruction", + "MetricExpr": "PM_RUN_CYC / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "RUN_CPI" + }, + { + "BriefDescription": "Percentage of DERAT misses per completed instruction", + "MetricExpr": "PM_DERAT_MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Translation", + "MetricName": "DERAT_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Average number of completed instructions per run cycle", + "MetricExpr": "PM_RUN_INST_CMPL / PM_RUN_CYC", + "MetricGroup": "General", + "MetricName": "RUN_IPC" + }, + { + "BriefDescription": "Average number of completed instructions per instruction group", + "MetricExpr": "PM_RUN_INST_CMPL / PM_1PLUS_PPC_CMPL", + "MetricGroup": "General", + "MetricName": "AVERAGE_COMPLETED_INSTRUCTION_SET_SIZE" + }, + { + "BriefDescription": "Average number of finished instructions per completed instructions", + "MetricExpr": "PM_INST_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "INST_FIN_PER_CMPL" + }, + { + "BriefDescription": "Average cycles per completed instruction when the NTF instruction is completing and the finish was overlooked", + "MetricExpr": "PM_EXEC_STALL_UNKNOWN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "EXEC_STALL_UNKOWN_CPI" + }, + { + "BriefDescription": "Percentage of finished branches that were taken", + "MetricExpr": "PM_BR_TAKEN_CMPL / PM_BR_FIN * 100", + "MetricGroup": "General", + "MetricName": "TAKEN_BRANCHES", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of completed instructions that were a demand load that did not hit in the L1, L2, or the L3", + "MetricExpr": "PM_DATA_FROM_L3MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "General", + "MetricName": "L3_LD_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Average number of finished branches per completed instruction", + "MetricExpr": "PM_BR_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "BRANCHES_PER_INST" + }, + { + "BriefDescription": "Average number of instructions finished in the LSU per completed instruction", + "MetricExpr": "PM_LSU_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "LSU_PER_INST" + }, + { + "BriefDescription": "Average number of instructions finished in the VSU per completed instruction", + "MetricExpr": "PM_VSU_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "VSU_PER_INST" + }, + { + "BriefDescription": "Average number of TLBIE instructions finished in the LSU per completed instruction", + "MetricExpr": "PM_TLBIE_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "TLBIE_PER_INST" + }, + { + "BriefDescription": "Average number of STCX instructions finshed per completed instruction", + "MetricExpr": "PM_STCX_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "STXC_PER_INST" + }, + { + "BriefDescription": "Average number of LARX instructions finshed per completed instruction", + "MetricExpr": "PM_LARX_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "LARX_PER_INST" + }, + { + "BriefDescription": "Average number of PTESYNC instructions finshed per completed instruction", + "MetricExpr": "PM_PTESYNC_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "PTESYNC_PER_INST" + }, + { + "BriefDescription": "Average number of simple fixed-point instructions finshed in the store unit per completed instruction", + "MetricExpr": "PM_FX_LSU_FIN / PM_RUN_INST_CMPL", + "MetricGroup": "General", + "MetricName": "FX_PER_INST" + }, + { + "BriefDescription": "Percentage of demand load misses that reloaded the L1 cache", + "MetricExpr": "PM_LD_DEMAND_MISS_L1 / PM_LD_MISS_L1 * 100", + "MetricGroup": "General", + "MetricName": "DL1_MISS_RELOADS", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of demand load misses that reloaded from beyond the local L2", + "MetricExpr": "PM_DATA_FROM_L2MISS / PM_LD_DEMAND_MISS_L1 * 100", + "MetricGroup": "dL1_Reloads", + "MetricName": "DL1_RELOAD_FROM_L2_MISS", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of demand load misses that reloaded from beyond the local L3", + "MetricExpr": "PM_DATA_FROM_L3MISS / PM_LD_DEMAND_MISS_L1 * 100", + "MetricGroup": "dL1_Reloads", + "MetricName": "DL1_RELOAD_FROM_L3_MISS", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of cycles stalled due to the NTC instruction waiting for a load miss to resolve from a source beyond the local L2 and local L3", + "MetricExpr": "DMISS_L3MISS_STALL_CPI / RUN_CPI * 100", + "MetricGroup": "General", + "MetricName": "DCACHE_MISS_CPI", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of DERAT misses with 2M page size per completed instruction", + "MetricExpr": "PM_DERAT_MISS_2M / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Translation", + "MetricName": "DERAT_2M_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of DERAT misses with 16M page size per completed instruction", + "MetricExpr": "PM_DERAT_MISS_16M / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Translation", + "MetricName": "DERAT_16M_MISS_RATE", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "DERAT miss ratio for 4K page size", + "MetricExpr": "PM_DERAT_MISS_4K / PM_DERAT_MISS", + "MetricGroup": "Translation", + "MetricName": "DERAT_4K_MISS_RATIO" + }, + { + "BriefDescription": "DERAT miss ratio for 2M page size", + "MetricExpr": "PM_DERAT_MISS_2M / PM_DERAT_MISS", + "MetricGroup": "Translation", + "MetricName": "DERAT_2M_MISS_RATIO" + }, + { + "BriefDescription": "DERAT miss ratio for 16M page size", + "MetricExpr": "PM_DERAT_MISS_16M / PM_DERAT_MISS", + "MetricGroup": "Translation", + "MetricName": "DERAT_16M_MISS_RATIO" + }, + { + "BriefDescription": "DERAT miss ratio for 64K page size", + "MetricExpr": "PM_DERAT_MISS_64K / PM_DERAT_MISS", + "MetricGroup": "Translation", + "MetricName": "DERAT_64K_MISS_RATIO" + }, + { + "BriefDescription": "Percentage of DERAT misses that resulted in TLB reloads", + "MetricExpr": "PM_DTLB_MISS / PM_DERAT_MISS * 100", + "MetricGroup": "Translation", + "MetricName": "DERAT_MISS_RELOAD", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of icache misses that were reloaded from beyond the local L3", + "MetricExpr": "PM_INST_FROM_L3MISS / PM_L1_ICACHE_MISS * 100", + "MetricGroup": "Instruction_Misses", + "MetricName": "INST_FROM_L3_MISS", + "ScaleUnit": "1%" + }, + { + "BriefDescription": "Percentage of icache reloads from the beyond the L3 per completed instruction", + "MetricExpr": "PM_INST_FROM_L3MISS / PM_RUN_INST_CMPL * 100", + "MetricGroup": "Instruction_Misses", + "MetricName": "INST_FROM_L3_MISS_RATE", + "ScaleUnit": "1%" + } +] -- cgit v1.2.3 From 9dc9855f18ba25d2bc536ea5ba6682855e385d66 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 11 Nov 2021 13:36:22 +0000 Subject: perf arm-spe: Track task context switch for cpu-mode events When perf report synthesize events from ARM SPE data, it refers to current cpu, pid and tid in the machine. But there's no place to set them in the ARM SPE decoder. I'm seeing all pid/tid is set to -1 and user symbols are not resolved in the output. # perf record -a -e arm_spe_0/ts_enable=1/ sleep 1 # perf report -q | head 8.77% 8.77% :-1 [kernel.kallsyms] [k] format_decode 7.02% 7.02% :-1 [kernel.kallsyms] [k] seq_printf 7.02% 7.02% :-1 [unknown] [.] 0x0000ffff9f687c34 5.26% 5.26% :-1 [kernel.kallsyms] [k] vsnprintf 3.51% 3.51% :-1 [kernel.kallsyms] [k] string 3.51% 3.51% :-1 [unknown] [.] 0x0000ffff9f66ae20 3.51% 3.51% :-1 [unknown] [.] 0x0000ffff9f670b3c 3.51% 3.51% :-1 [unknown] [.] 0x0000ffff9f67c040 1.75% 1.75% :-1 [kernel.kallsyms] [k] ___cache_free 1.75% 1.75% :-1 [kernel.kallsyms] [k] __count_memcg_events Like Intel PT, add context switch records to track task info. As ARM SPE support was added later than PERF_RECORD_SWITCH_CPU_WIDE, I think we can safely set the attr.context_switch bit and use it. Reviewed-by: Leo Yan Signed-off-by: German Gomez Signed-off-by: Namhyung Kim Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211111133625.193568-2-german.gomez@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/util/arm-spe.c | 6 +++++- tools/perf/util/arm-spe.c | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 56785034fc84..d32431ac15cc 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -251,8 +251,12 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, tracking_evsel->core.attr.sample_period = 1; /* In per-cpu case, always need the time of mmap events etc */ - if (!perf_cpu_map__empty(cpus)) + if (!perf_cpu_map__empty(cpus)) { evsel__set_sample_bit(tracking_evsel, TIME); + evsel__set_sample_bit(tracking_evsel, CPU); + /* also track task context switch */ + tracking_evsel->core.attr.context_switch = 1; + } return 0; } diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 2196291976d9..9e3a6c54801d 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -681,6 +681,25 @@ static int arm_spe_process_timeless_queues(struct arm_spe *spe, pid_t tid, return 0; } +static int arm_spe_context_switch(struct arm_spe *spe, union perf_event *event, + struct perf_sample *sample) +{ + pid_t pid, tid; + int cpu; + + if (!(event->header.misc & PERF_RECORD_MISC_SWITCH_OUT)) + return 0; + + pid = event->context_switch.next_prev_pid; + tid = event->context_switch.next_prev_tid; + cpu = sample->cpu; + + if (tid == -1) + pr_warning("context_switch event has no tid\n"); + + return machine__set_current_tid(spe->machine, cpu, pid, tid); +} + static int arm_spe_process_event(struct perf_session *session, union perf_event *event, struct perf_sample *sample, @@ -718,6 +737,12 @@ static int arm_spe_process_event(struct perf_session *session, } } else if (timestamp) { err = arm_spe_process_queues(spe, timestamp); + if (err) + return err; + + if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE || + event->header.type == PERF_RECORD_SWITCH) + err = arm_spe_context_switch(spe, event, sample); } return err; -- cgit v1.2.3 From 455c988225c7eee84c7a2f86984404825a1830bb Mon Sep 17 00:00:00 2001 From: German Gomez Date: Thu, 11 Nov 2021 13:36:23 +0000 Subject: perf arm-spe: Update --switch-events docs in 'perf record' Update 'perf record' docs and ARM SPE recording options so that they are consistent. This includes supporting the --no-switch-events flag in ARM SPE as well. Reviewed-by: Leo Yan Signed-off-by: German Gomez Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211111133625.193568-3-german.gomez@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 2 +- tools/perf/arch/arm64/util/arm-spe.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 2d7df8703cf2..3cf7bac67239 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -469,7 +469,7 @@ This option sets the time out limit. The default value is 500 ms. --switch-events:: Record context switch events i.e. events of type PERF_RECORD_SWITCH or -PERF_RECORD_SWITCH_CPU_WIDE. In some cases (e.g. Intel PT or CoreSight) +PERF_RECORD_SWITCH_CPU_WIDE. In some cases (e.g. Intel PT, CoreSight or Arm SPE) switch events will be enabled automatically, which can be suppressed by by the option --no-switch-events. diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index d32431ac15cc..2100d46ccf5e 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -254,8 +254,10 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, if (!perf_cpu_map__empty(cpus)) { evsel__set_sample_bit(tracking_evsel, TIME); evsel__set_sample_bit(tracking_evsel, CPU); + /* also track task context switch */ - tracking_evsel->core.attr.context_switch = 1; + if (!record_opts__no_switch_events(opts)) + tracking_evsel->core.attr.context_switch = 1; } return 0; -- cgit v1.2.3 From 169de64f5dc22d9984d45c1f119fb644fa16d64a Mon Sep 17 00:00:00 2001 From: German Gomez Date: Thu, 11 Nov 2021 13:36:24 +0000 Subject: perf arm-spe: Save context ID in record This patch is to save context ID in record, this will be used to set TID for samples. Reviewed-by: Leo Yan Signed-off-by: German Gomez Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211111133625.193568-4-german.gomez@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/arm-spe-decoder/arm-spe-decoder.c | 2 ++ tools/perf/util/arm-spe-decoder/arm-spe-decoder.h | 1 + 2 files changed, 3 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c index 32fe41835fa6..3fc528c9270c 100644 --- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c @@ -151,6 +151,7 @@ static int arm_spe_read_record(struct arm_spe_decoder *decoder) u64 payload, ip; memset(&decoder->record, 0x0, sizeof(decoder->record)); + decoder->record.context_id = (u64)-1; while (1) { err = arm_spe_get_next_packet(decoder); @@ -180,6 +181,7 @@ static int arm_spe_read_record(struct arm_spe_decoder *decoder) case ARM_SPE_COUNTER: break; case ARM_SPE_CONTEXT: + decoder->record.context_id = payload; break; case ARM_SPE_OP_TYPE: if (idx == SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC) { diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h index 59bdb7309674..46a8556a9e95 100644 --- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h @@ -38,6 +38,7 @@ struct arm_spe_record { u64 timestamp; u64 virt_addr; u64 phys_addr; + u64 context_id; }; struct arm_spe_insn; -- cgit v1.2.3 From 27d113cfe892867885ab1d75abe5f42c228ef8a9 Mon Sep 17 00:00:00 2001 From: German Gomez Date: Thu, 11 Nov 2021 13:36:25 +0000 Subject: perf arm-spe: Support hardware-based PID tracing If ARM SPE traces contains CONTEXT packets with TID info, use these values for tracking the TID of samples. Otherwise fall back to using context switch events and display a message warning to the user of possible timing inaccuracies [1]. [1] https://lore.kernel.org/lkml/f877cfa6-9b25-6445-3806-ca44a4042eaf@arm.com/ Signed-off-by: German Gomez Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mathieu Poirier Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20211111133625.193568-5-german.gomez@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/arm-spe.c | 99 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 29 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 9e3a6c54801d..4748bcfe61de 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -71,6 +71,7 @@ struct arm_spe { u64 kernel_start; unsigned long num_events; + u8 use_ctx_pkt_for_pid; }; struct arm_spe_queue { @@ -226,6 +227,44 @@ static inline u8 arm_spe_cpumode(struct arm_spe *spe, u64 ip) PERF_RECORD_MISC_USER; } +static void arm_spe_set_pid_tid_cpu(struct arm_spe *spe, + struct auxtrace_queue *queue) +{ + struct arm_spe_queue *speq = queue->priv; + pid_t tid; + + tid = machine__get_current_tid(spe->machine, speq->cpu); + if (tid != -1) { + speq->tid = tid; + thread__zput(speq->thread); + } else + speq->tid = queue->tid; + + if ((!speq->thread) && (speq->tid != -1)) { + speq->thread = machine__find_thread(spe->machine, -1, + speq->tid); + } + + if (speq->thread) { + speq->pid = speq->thread->pid_; + if (queue->cpu == -1) + speq->cpu = speq->thread->cpu; + } +} + +static int arm_spe_set_tid(struct arm_spe_queue *speq, pid_t tid) +{ + struct arm_spe *spe = speq->spe; + int err = machine__set_current_tid(spe->machine, speq->cpu, -1, tid); + + if (err) + return err; + + arm_spe_set_pid_tid_cpu(spe, &spe->queues.queue_array[speq->queue_nr]); + + return 0; +} + static void arm_spe_prep_sample(struct arm_spe *spe, struct arm_spe_queue *speq, union perf_event *event, @@ -460,6 +499,19 @@ static int arm_spe_run_decoder(struct arm_spe_queue *speq, u64 *timestamp) * can correlate samples between Arm SPE trace data and other * perf events with correct time ordering. */ + + /* + * Update pid/tid info. + */ + record = &speq->decoder->record; + if (!spe->timeless_decoding && record->context_id != (u64)-1) { + ret = arm_spe_set_tid(speq, record->context_id); + if (ret) + return ret; + + spe->use_ctx_pkt_for_pid = true; + } + ret = arm_spe_sample(speq); if (ret) return ret; @@ -586,31 +638,6 @@ static bool arm_spe__is_timeless_decoding(struct arm_spe *spe) return timeless_decoding; } -static void arm_spe_set_pid_tid_cpu(struct arm_spe *spe, - struct auxtrace_queue *queue) -{ - struct arm_spe_queue *speq = queue->priv; - pid_t tid; - - tid = machine__get_current_tid(spe->machine, speq->cpu); - if (tid != -1) { - speq->tid = tid; - thread__zput(speq->thread); - } else - speq->tid = queue->tid; - - if ((!speq->thread) && (speq->tid != -1)) { - speq->thread = machine__find_thread(spe->machine, -1, - speq->tid); - } - - if (speq->thread) { - speq->pid = speq->thread->pid_; - if (queue->cpu == -1) - speq->cpu = speq->thread->cpu; - } -} - static int arm_spe_process_queues(struct arm_spe *spe, u64 timestamp) { unsigned int queue_nr; @@ -641,7 +668,12 @@ static int arm_spe_process_queues(struct arm_spe *spe, u64 timestamp) ts = timestamp; } - arm_spe_set_pid_tid_cpu(spe, queue); + /* + * A previous context-switch event has set pid/tid in the machine's context, so + * here we need to update the pid/tid in the thread and SPE queue. + */ + if (!spe->use_ctx_pkt_for_pid) + arm_spe_set_pid_tid_cpu(spe, queue); ret = arm_spe_run_decoder(speq, &ts); if (ret < 0) { @@ -740,8 +772,9 @@ static int arm_spe_process_event(struct perf_session *session, if (err) return err; - if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE || - event->header.type == PERF_RECORD_SWITCH) + if (!spe->use_ctx_pkt_for_pid && + (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE || + event->header.type == PERF_RECORD_SWITCH)) err = arm_spe_context_switch(spe, event, sample); } @@ -808,7 +841,15 @@ static int arm_spe_flush(struct perf_session *session __maybe_unused, return arm_spe_process_timeless_queues(spe, -1, MAX_TIMESTAMP - 1); - return arm_spe_process_queues(spe, MAX_TIMESTAMP); + ret = arm_spe_process_queues(spe, MAX_TIMESTAMP); + if (ret) + return ret; + + if (!spe->use_ctx_pkt_for_pid) + ui__warning("Arm SPE CONTEXT packets not found in the traces.\n" + "Matching of TIDs to SPE events could be inaccurate.\n"); + + return 0; } static void arm_spe_free_queue(void *priv) -- cgit v1.2.3 From f08a8fccd7eafe06ca48df57bf32cfb753218923 Mon Sep 17 00:00:00 2001 From: Guo Zhengkui Date: Mon, 8 Nov 2021 15:07:52 +0800 Subject: perf test bpf: Use ARRAY_CHECK() instead of ad-hoc equivalent, addressing array_size.cocci warning Address following coccicheck warnings: ./tools/perf/tests/bpf.c:316:22-23: WARNING: Use ARRAY_SIZE. Signed-off-by: Guo Zhengkui Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Ian Rogers Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Song Liu Cc: Thomas Richter Cc: Yonghong Song Cc: bpf@vger.kernel.org Cc: kernel@vivo.com Cc: netdev@vger.kernel.org Link: http://lore.kernel.org/lkml/20211108070801.5540-1-guozhengkui@vivo.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 2048c9a08e8f..329f77f592f4 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -297,7 +297,7 @@ static int check_env(void) } err = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns, - sizeof(insns) / sizeof(insns[0]), + ARRAY_SIZE(insns), license, kver_int, NULL, 0); if (err < 0) { pr_err("Missing basic BPF support, skip this test: %s\n", -- cgit v1.2.3 From 7380aa89904f3e243e2f339c022e597bf3a77191 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 8 Sep 2021 16:09:08 -0300 Subject: tools headers UAPI: Sync files changed by new futex_waitv syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To pick the changes in these csets: 039c0ec9bb77446d ("futex,x86: Wire up sys_futex_waitv()") bf69bad38cf63d98 ("futex: Implement sys_futex_waitv()") That add support for this new syscall in tools such as 'perf trace'. For instance, this is now possible: # perf trace -e futex_waitv ^C# # perf trace -v -e futex_waitv Using CPUID AuthenticAMD-25-21-0 event qualifier tracepoint filter: (common_pid != 807333 && common_pid != 3564) && (id == 449) mmap size 528384B ^C# # perf trace -v -e futex* --max-events 10 Using CPUID AuthenticAMD-25-21-0 event qualifier tracepoint filter: (common_pid != 812168 && common_pid != 3564) && (id == 202 || id == 449) mmap size 528384B ? ( ): Timer/219310 ... [continued]: futex()) = -1 ETIMEDOUT (Connection timed out) 0.012 ( 0.002 ms): Timer/219310 futex(uaddr: 0x7fd0b152d3c8, op: WAKE|PRIVATE_FLAG, val: 1) = 0 0.024 ( 0.060 ms): Timer/219310 futex(uaddr: 0x7fd0b152d420, op: WAIT_BITSET|PRIVATE_FLAG, utime: 0x7fd0b1657840, val3: MATCH_ANY) = 0 0.086 ( 0.001 ms): Timer/219310 futex(uaddr: 0x7fd0b152d3c8, op: WAKE|PRIVATE_FLAG, val: 1) = 0 0.088 ( ): Timer/219310 futex(uaddr: 0x7fd0b152d424, op: WAIT_BITSET|PRIVATE_FLAG, utime: 0x7fd0b1657840, val3: MATCH_ANY) ... 0.075 ( 0.005 ms): Web Content/219299 futex(uaddr: 0x7fd0b152d420, op: WAKE|PRIVATE_FLAG, val: 1) = 1 0.169 ( 0.004 ms): Web Content/219299 futex(uaddr: 0x7fd0b152d424, op: WAKE|PRIVATE_FLAG, val: 1) = 1 0.088 ( 0.089 ms): Timer/219310 ... [continued]: futex()) = 0 0.179 ( 0.001 ms): Timer/219310 futex(uaddr: 0x7fd0b152d3c8, op: WAKE|PRIVATE_FLAG, val: 1) = 0 0.181 ( ): Timer/219310 futex(uaddr: 0x7fd0b152d420, op: WAIT_BITSET|PRIVATE_FLAG, utime: 0x7fd0b1657840, val3: MATCH_ANY) ... # That is the filter expression attached to the raw_syscalls:sys_{enter,exit} tracepoints. $ grep futex_waitv tools/perf/arch/x86/entry/syscalls/syscall_64.tbl 449 common futex_waitv sys_futex_waitv $ This addresses these perf build warnings: Warning: Kernel ABI header at 'tools/include/uapi/asm-generic/unistd.h' differs from latest version at 'include/uapi/asm-generic/unistd.h' diff -u tools/include/uapi/asm-generic/unistd.h include/uapi/asm-generic/unistd.h Warning: Kernel ABI header at 'tools/perf/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl' diff -u tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl Cc: André Almeida Cc: Peter Zijlstra Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/asm-generic/unistd.h | 5 ++++- tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h index 1c5fb86d455a..4557a8b6086f 100644 --- a/tools/include/uapi/asm-generic/unistd.h +++ b/tools/include/uapi/asm-generic/unistd.h @@ -880,8 +880,11 @@ __SYSCALL(__NR_memfd_secret, sys_memfd_secret) #define __NR_process_mrelease 448 __SYSCALL(__NR_process_mrelease, sys_process_mrelease) +#define __NR_futex_waitv 449 +__SYSCALL(__NR_futex_waitv, sys_futex_waitv) + #undef __NR_syscalls -#define __NR_syscalls 449 +#define __NR_syscalls 450 /* * 32 bit systems traditionally used different diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl index 18b5500ea8bf..fe8f8dd157b4 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl @@ -370,6 +370,7 @@ 446 common landlock_restrict_self sys_landlock_restrict_self 447 common memfd_secret sys_memfd_secret 448 common process_mrelease sys_process_mrelease +449 common futex_waitv sys_futex_waitv # # Due to a historical design error, certain syscalls are numbered differently -- cgit v1.2.3 From bd9acd9cc6d71262d06847241f2b341787b40e15 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 11 Nov 2021 19:51:22 -0800 Subject: perf symbols: Add documentation to 'struct symbol' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor some existing comments and then infer the rest. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kajol Jain Cc: Mark Rutland Cc: Martin Liška Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211112035124.94327-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 166196686f2e..3586fa549f44 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -40,22 +40,33 @@ Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp, const char *name, size_t *idx); #endif -/** struct symbol - symtab entry - * - * @ignore - resolvable but tools ignore it (e.g. idle routines) +/** + * A symtab entry. When allocated this may be preceded by an annotation (see + * symbol__annotation), a browser_index (see symbol__browser_index) and rb_node + * to sort by name (see struct symbol_name_rb_node). */ struct symbol { struct rb_node rb_node; + /** Range of symbol [start, end). */ u64 start; u64 end; + /** Length of the string name. */ u16 namelen; + /** ELF symbol type as defined for st_info. E.g STT_OBJECT or STT_FUNC. */ u8 type:4; + /** ELF binding type as defined for st_info. E.g. STB_WEAK or STB_GLOBAL. */ u8 binding:4; + /** Set true for kernel symbols of idle routines. */ u8 idle:1; + /** Resolvable but tools ignore it (e.g. idle routines). */ u8 ignore:1; + /** Symbol for an inlined function. */ u8 inlined:1; + /** Architecture specific. Unused except on PPC where it holds st_other. */ u8 arch_sym; + /** Has symbol__annotate2 been performed. */ bool annotate2; + /** The name of length namelen associated with the symbol. */ char name[]; }; -- cgit v1.2.3 From 42704567042d852c13da11447b223e34e22fbdb1 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 11 Nov 2021 19:51:23 -0800 Subject: perf symbols: Bit pack to save a byte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a bit field alongside the earlier bit fields. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kajol Jain Cc: Mark Rutland Cc: Martin Liška Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211112035124.94327-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 +- tools/perf/util/symbol.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 8511af55fc3a..5d982933b3a2 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3132,7 +3132,7 @@ int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel, notes->nr_events = nr_pcnt; annotation__update_column_widths(notes); - sym->annotate2 = true; + sym->annotate2 = 1; return 0; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 3586fa549f44..fbf866d82dcc 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -62,10 +62,10 @@ struct symbol { u8 ignore:1; /** Symbol for an inlined function. */ u8 inlined:1; + /** Has symbol__annotate2 been performed. */ + u8 annotate2:1; /** Architecture specific. Unused except on PPC where it holds st_other. */ u8 arch_sym; - /** Has symbol__annotate2 been performed. */ - bool annotate2; /** The name of length namelen associated with the symbol. */ char name[]; }; -- cgit v1.2.3 From 4f74f187892e3aa53047974e4949fd2d26663001 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 11 Nov 2021 19:51:24 -0800 Subject: perf symbols: Factor out annotation init/exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The exit function fixes a memory leak with the src field as detected by leak sanitizer. An example of which is: Indirect leak of 25133184 byte(s) in 207 object(s) allocated from: #0 0x7f199ecfe987 in __interceptor_calloc libsanitizer/asan/asan_malloc_linux.cpp:154 #1 0x55defe638224 in annotated_source__alloc_histograms util/annotate.c:803 #2 0x55defe6397e4 in symbol__hists util/annotate.c:952 #3 0x55defe639908 in symbol__inc_addr_samples util/annotate.c:968 #4 0x55defe63aa29 in hist_entry__inc_addr_samples util/annotate.c:1119 #5 0x55defe499a79 in hist_iter__report_callback tools/perf/builtin-report.c:182 #6 0x55defe7a859d in hist_entry_iter__add util/hist.c:1236 #7 0x55defe49aa63 in process_sample_event tools/perf/builtin-report.c:315 #8 0x55defe731bc8 in evlist__deliver_sample util/session.c:1473 #9 0x55defe731e38 in machines__deliver_event util/session.c:1510 #10 0x55defe732a23 in perf_session__deliver_event util/session.c:1590 #11 0x55defe72951e in ordered_events__deliver_event util/session.c:183 #12 0x55defe740082 in do_flush util/ordered-events.c:244 #13 0x55defe7407cb in __ordered_events__flush util/ordered-events.c:323 #14 0x55defe740a61 in ordered_events__flush util/ordered-events.c:341 #15 0x55defe73837f in __perf_session__process_events util/session.c:2390 #16 0x55defe7385ff in perf_session__process_events util/session.c:2420 ... Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: Kajol Jain Cc: Mark Rutland Cc: Martin Liška Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20211112035124.94327-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 11 +++++++++++ tools/perf/util/annotate.h | 3 +++ tools/perf/util/symbol.c | 9 ++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 5d982933b3a2..01900689dc00 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1255,6 +1255,17 @@ int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool r return ins__scnprintf(&dl->ins, bf, size, &dl->ops, max_ins_name); } +void annotation__init(struct annotation *notes) +{ + pthread_mutex_init(¬es->lock, NULL); +} + +void annotation__exit(struct annotation *notes) +{ + annotated_source__delete(notes->src); + pthread_mutex_destroy(¬es->lock); +} + static void annotation_line__add(struct annotation_line *al, struct list_head *head) { list_add_tail(&al->node, head); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 3757416bcf46..986f2bbe4870 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -299,6 +299,9 @@ struct annotation { struct annotated_source *src; }; +void annotation__init(struct annotation *notes); +void annotation__exit(struct annotation *notes); + static inline int annotation__cycles_width(struct annotation *notes) { if (notes->have_cycles && notes->options->show_minmax_cycle) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index aa1b7c12fd61..b2ed3140a1fa 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -274,7 +274,7 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const char * if (symbol_conf.priv_size) { if (symbol_conf.init_annotation) { struct annotation *notes = (void *)sym; - pthread_mutex_init(¬es->lock, NULL); + annotation__init(notes); } sym = ((void *)sym) + symbol_conf.priv_size; } @@ -294,6 +294,13 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const char * void symbol__delete(struct symbol *sym) { + if (symbol_conf.priv_size) { + if (symbol_conf.init_annotation) { + struct annotation *notes = symbol__annotation(sym); + + annotation__exit(notes); + } + } free(((void *)sym) - symbol_conf.priv_size); } -- cgit v1.2.3 From 4924b1f7c46711762fd0e65c135ccfbcfd6ded1f Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 11 Nov 2021 23:45:25 -0800 Subject: perf bpf: Avoid memory leak from perf_env__insert_btf() perf_env__insert_btf() doesn't insert if a duplicate BTF id is encountered and this causes a memory leak. Modify the function to return a success/error value and then free the memory if insertion didn't happen. v2. Adds a return -1 when the insertion error occurs in perf_env__fetch_btf. This doesn't affect anything as the result is never checked. Fixes: 3792cb2ff43b1b19 ("perf bpf: Save BTF in a rbtree in perf_env") Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: Stephane Eranian Cc: Tiezhu Yang Cc: Yonghong Song Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: http://lore.kernel.org/lkml/20211112074525.121633-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-event.c | 6 +++++- tools/perf/util/env.c | 5 ++++- tools/perf/util/env.h | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 4d3b4cdce176..d49cdff8fb39 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -119,7 +119,11 @@ static int perf_env__fetch_btf(struct perf_env *env, node->data_size = data_size; memcpy(node->data, data, data_size); - perf_env__insert_btf(env, node); + if (!perf_env__insert_btf(env, node)) { + /* Insertion failed because of a duplicate. */ + free(node); + return -1; + } return 0; } diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index 17f1dd0680b4..b9904896eb97 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -75,12 +75,13 @@ out: return node; } -void perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) +bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) { struct rb_node *parent = NULL; __u32 btf_id = btf_node->id; struct btf_node *node; struct rb_node **p; + bool ret = true; down_write(&env->bpf_progs.lock); p = &env->bpf_progs.btfs.rb_node; @@ -94,6 +95,7 @@ void perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) p = &(*p)->rb_right; } else { pr_debug("duplicated btf %u\n", btf_id); + ret = false; goto out; } } @@ -103,6 +105,7 @@ void perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) env->bpf_progs.btfs_cnt++; out: up_write(&env->bpf_progs.lock); + return ret; } struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id) diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h index 1383876f72b3..163e5ec503a2 100644 --- a/tools/perf/util/env.h +++ b/tools/perf/util/env.h @@ -167,7 +167,7 @@ void perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node); struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, __u32 prog_id); -void perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node); +bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node); struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id); int perf_env__numa_node(struct perf_env *env, int cpu); -- cgit v1.2.3 From 2a4898fc264a0a9d92eb901d54068d4801720526 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 9 Nov 2021 15:07:06 +0100 Subject: perf tools: Add more weak libbpf functions We hit the window where perf uses libbpf functions, that did not make it to the official libbpf release yet and it's breaking perf build with dynamicly linked libbpf. Fixing this by providing the new interface as weak functions which calls the original libbpf functions. Fortunatelly the changes were just renames. Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andrii Nakryiko Cc: Ian Rogers Cc: Mark Rutland Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20211109140707.1689940-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-event.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index d49cdff8fb39..a517eaa51eb3 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -33,6 +33,33 @@ struct btf * __weak btf__load_from_kernel_by_id(__u32 id) return err ? ERR_PTR(err) : btf; } +struct bpf_program * __weak +bpf_object__next_program(const struct bpf_object *obj, struct bpf_program *prev) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + return bpf_program__next(prev, obj); +#pragma GCC diagnostic pop +} + +struct bpf_map * __weak +bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *prev) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + return bpf_map__next(prev, obj); +#pragma GCC diagnostic pop +} + +const void * __weak +btf__raw_data(const struct btf *btf_ro, __u32 *size) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + return btf__get_raw_data(btf_ro, size); +#pragma GCC diagnostic pop +} + static int snprintf_hex(char *buf, size_t size, unsigned char *data, size_t len) { int ret = 0; -- cgit v1.2.3 From 88e48238d53682281c9de2a0b65d24d3b64542a0 Mon Sep 17 00:00:00 2001 From: Sohaib Mohamed Date: Fri, 12 Nov 2021 22:11:33 +0200 Subject: perf bench futex: Fix memory leak of perf_cpu_map__new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ASan reports memory leaks while running: $ sudo ./perf bench futex all The leaks are caused by perf_cpu_map__new not being freed. This patch adds the missing perf_cpu_map__put since it calls cpu_map_delete implicitly. Fixes: 9c3516d1b850ea93 ("libperf: Add perf_cpu_map__new()/perf_cpu_map__read() functions") Signed-off-by: Sohaib Mohamed Cc: Alexander Shishkin Cc: André Almeida Cc: Darren Hart Cc: Davidlohr Bueso Cc: Ian Rogers Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Sohaib Mohamed Cc: Thomas Gleixner Link: http://lore.kernel.org/lkml/20211112201134.77892-1-sohaib.amhmd@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/futex-lock-pi.c | 1 + tools/perf/bench/futex-requeue.c | 1 + tools/perf/bench/futex-wake-parallel.c | 1 + tools/perf/bench/futex-wake.c | 1 + 4 files changed, 4 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 5d1fe9c35807..137890f78e17 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -233,6 +233,7 @@ int bench_futex_lock_pi(int argc, const char **argv) print_summary(); free(worker); + perf_cpu_map__put(cpu); return ret; err: usage_with_options(bench_futex_lock_pi_usage, options); diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 97fe31fd3a23..f7a5ffebb940 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -294,6 +294,7 @@ int bench_futex_requeue(int argc, const char **argv) print_summary(); free(worker); + perf_cpu_map__put(cpu); return ret; err: usage_with_options(bench_futex_requeue_usage, options); diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index e970e6b9ad53..0983f40b4b40 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -329,6 +329,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) print_summary(); free(blocked_worker); + perf_cpu_map__put(cpu); return ret; } #endif /* HAVE_PTHREAD_BARRIER */ diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 77f058a47790..2226a475e782 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -222,5 +222,6 @@ int bench_futex_wake(int argc, const char **argv) print_summary(); free(worker); + perf_cpu_map__put(cpu); return ret; } -- cgit v1.2.3 From c8b947642d2339ce74c6a1ce56726089539f48d9 Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 28 Oct 2021 14:48:25 +0100 Subject: perf test: Remove bash construct from stat_bpf_counters.sh test Currently the test skips with an error because == only works in bash: $ ./perf test 91 -v Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc 91: perf stat --bpf-counters test : --- start --- test child forked, pid 44586 ./tests/shell/stat_bpf_counters.sh: 26: [: -v: unexpected operator test child finished with -2 ---- end ---- perf stat --bpf-counters test: Skip Changing == to = does the same thing, but doesn't result in an error: ./perf test 91 -v Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc 91: perf stat --bpf-counters test : --- start --- test child forked, pid 45833 Skipping: --bpf-counters not supported Error: unknown option `bpf-counters' [...] test child finished with -2 ---- end ---- perf stat --bpf-counters test: Skip Signed-off-by: James Clark Cc: Alexander Shishkin Cc: Florian Fainelli Cc: Ian Rogers Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Song Liu Cc: Sumanth Korikkar Cc: Thomas Richter Cc: Yonghong Song Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20211028134828.65774-2-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/stat_bpf_counters.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/shell/stat_bpf_counters.sh b/tools/perf/tests/shell/stat_bpf_counters.sh index 2aed20dc2262..13473aeba489 100755 --- a/tools/perf/tests/shell/stat_bpf_counters.sh +++ b/tools/perf/tests/shell/stat_bpf_counters.sh @@ -23,7 +23,7 @@ compare_number() # skip if --bpf-counters is not supported if ! perf stat --bpf-counters true > /dev/null 2>&1; then - if [ "$1" == "-v" ]; then + if [ "$1" = "-v" ]; then echo "Skipping: --bpf-counters not supported" perf --no-pager stat --bpf-counters true || true fi -- cgit v1.2.3 From a9cdc1c5e3700a5200e5ca1f90b6958b6483845b Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 28 Oct 2021 14:48:26 +0100 Subject: perf tests: Remove bash construct from record+zstd_comp_decomp.sh Commit 463538a383a2 ("perf tests: Fix test 68 zstd compression for s390") inadvertently removed the -g flag from all platforms rather than just s390, because the [[ ]] construct fails in sh. Changing to single brackets restores testing of call graphs and removes the following error from the output: $ ./perf test -v 85 85: Zstd perf.data compression/decompression : --- start --- test child forked, pid 50643 Collecting compressed record file: ./tests/shell/record+zstd_comp_decomp.sh: 15: [[: not found Fixes: 463538a383a2 ("perf tests: Fix test 68 zstd compression for s390") Signed-off-by: James Clark Cc: Alexander Shishkin Cc: Florian Fainelli Cc: Ian Rogers Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Song Liu Cc: Sumanth Korikkar Cc: Thomas Richter Cc: Yonghong Song Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20211028134828.65774-3-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/record+zstd_comp_decomp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/shell/record+zstd_comp_decomp.sh b/tools/perf/tests/shell/record+zstd_comp_decomp.sh index 8a168cf8bacc..49bd875d5122 100755 --- a/tools/perf/tests/shell/record+zstd_comp_decomp.sh +++ b/tools/perf/tests/shell/record+zstd_comp_decomp.sh @@ -12,7 +12,7 @@ skip_if_no_z_record() { collect_z_record() { echo "Collecting compressed record file:" - [[ "$(uname -m)" != s390x ]] && gflag='-g' + [ "$(uname -m)" != s390x ] && gflag='-g' $perf_tool record -o $trace_file $gflag -z -F 5000 -- \ dd count=500 if=/dev/urandom of=/dev/null } -- cgit v1.2.3 From ac96f463cc9aebb00ca7bbee47efb0794dfd0f3f Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 28 Oct 2021 14:48:27 +0100 Subject: perf tests: Remove bash constructs from stat_all_pmu.sh The tests were passing but without testing and were printing the following: $ ./perf test -v 90 90: perf all PMU test : --- start --- test child forked, pid 51650 Testing cpu/branch-instructions/ ./tests/shell/stat_all_pmu.sh: 10: [: Performance counter stats for 'true': 137,307 cpu/branch-instructions/ 0.001686672 seconds time elapsed 0.001376000 seconds user 0.000000000 seconds sys: unexpected operator Changing the regexes to a grep works in sh and prints this: $ ./perf test -v 90 90: perf all PMU test : --- start --- test child forked, pid 60186 [...] Testing tlb_flush.stlb_any test child finished with 0 ---- end ---- perf all PMU test: Ok Signed-off-by: James Clark Cc: Alexander Shishkin Cc: Florian Fainelli Cc: Ian Rogers Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Song Liu Cc: Sumanth Korikkar Cc: Thomas Richter Cc: Yonghong Song Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20211028134828.65774-4-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/stat_all_pmu.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/shell/stat_all_pmu.sh b/tools/perf/tests/shell/stat_all_pmu.sh index 2de7fd0394fd..b30dba455f36 100755 --- a/tools/perf/tests/shell/stat_all_pmu.sh +++ b/tools/perf/tests/shell/stat_all_pmu.sh @@ -7,11 +7,11 @@ set -e for p in $(perf list --raw-dump pmu); do echo "Testing $p" result=$(perf stat -e "$p" true 2>&1) - if [[ ! "$result" =~ "$p" ]] && [[ ! "$result" =~ "" ]]; then + if ! echo "$result" | grep -q "$p" && ! echo "$result" | grep -q "" ; then # We failed to see the event and it is supported. Possibly the workload was # too small so retry with something longer. result=$(perf stat -e "$p" perf bench internals synthesize 2>&1) - if [[ ! "$result" =~ "$p" ]]; then + if ! echo "$result" | grep -q "$p" ; then echo "Event '$p' not printed in:" echo "$result" exit 1 -- cgit v1.2.3