From 1d98cdf7fa2bc6e8063c0a692a1c091d8ebe3a75 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 6 Jun 2022 17:08:51 -0700 Subject: perf unwind: Fix uninitialized variable The 'ret' variable may be uninitialized on error goto paths. Fixes: dc2cf4ca866f5715 ("perf unwind: Fix segbase for ld.lld linked objects") Reported-by: Sedat Dilek Reviewed-by: Fangrui Song Signed-off-by: Ian Rogers Tested-by: Sedat Dilek # LLVM-14 (x86-64) Cc: Fangrui Song Cc: Ingo Molnar Cc: llvm@lists.linux.dev Cc: Peter Zijlstra Cc: Sebastian Ullrich Link: https://lore.kernel.org/r/20220607000851.39798-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/unwind-libunwind-local.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 37622699c91a..6e5b8cce47bf 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -174,7 +174,7 @@ static int elf_section_address_and_offset(int fd, const char *name, u64 *address Elf *elf; GElf_Ehdr ehdr; GElf_Shdr shdr; - int ret; + int ret = -1; elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); if (elf == NULL) -- cgit v1.2.3 From ec906102e5b7d3393cfe83e606b48cf0c1fcb122 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Fri, 3 Jun 2022 13:30:34 +0200 Subject: perf test: Fix "perf stat CSV output linter" test on s390 perf test -F 83 ("perf stat CSV output linter") fails on s390. Reason is the wrong number of fields for certain CPU core/die/socket related output. On x84_64 the output of command: # ./perf stat -x, -A -a --no-merge true CPU0,1.50,msec,cpu-clock,1502781,100.00,1.052,CPUs utilized CPU1,1.48,msec,cpu-clock,1476113,100.00,1.034,CPUs utilized ... results in 8 fields with 7 comma separators. On s390 the output of command: # ./perf stat -x, -A -a --no-merge -- true 0.95,msec,cpu-clock,949800,100.00,1.060,CPUs utilized ... results in 7 fields with 6 comma separators. Therefore this tests fails on s390. Similar issues exist for per-die and per-socket output which is not supported on s390. I have rewritten the python program to count commas in each output line into a bash function to achieve the same result. I hope this makes it a bit easier. Output before: # ./perf test -F 83 83: perf stat CSV output linter : Checking CSV output: no args [Success] Checking CSV output: system wide [Success] Checking CSV output: system wide Checking CSV output: \ system wide no aggregation 6.92,msec,cpu-clock,\ 6918131,100.00,6.972,CPUs utilized ... RuntimeError: wrong number of fields. expected 7 in \ 6.92,msec,cpu-clock,6918131,100.00,6.972,CPUs utilized FAILED! # Output after: # ./perf test -F 83 83: perf stat CSV output linter : Checking CSV output: no args [Success] Checking CSV output: system wide [Success] Checking CSV output: system wide Checking CSV output:\ system wide no aggregation [Success] Checking CSV output: interval [Success] Checking CSV output: event [Success] Checking CSV output: per core [Success] Checking CSV output: per thread [Success] Checking CSV output: per die [Success] Checking CSV output: per node [Success] Checking CSV output: per socket [Success] Ok # Committer notes: Continues to work on x86_64 $ perf test lint 89: perf stat CSV output linter : Ok $ perf test -v lint Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc 89: perf stat CSV output linter : --- start --- test child forked, pid 53133 Checking CSV output: no args [Success] Checking CSV output: system wide [Skip] paranoid and not root Checking CSV output: system wide [Skip] paranoid and not root Checking CSV output: interval [Success] Checking CSV output: event [Success] Checking CSV output: per core [Skip] paranoid and not root Checking CSV output: per thread [Skip] paranoid and not root Checking CSV output: per die [Skip] paranoid and not root Checking CSV output: per node [Skip] paranoid and not root Checking CSV output: per socket [Skip] paranoid and not root test child finished with 0 ---- end ---- perf stat CSV output linter: Ok $ Signed-off-by: Thomas Richter Acked-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Cc: Claire Jensen Cc: Heiko Carstens Cc: Sumanth Korikkar Cc: Sven Schnelle Cc: Vasily Gorbik Cc: linux390-list@tuxmaker.boeblingen.de.ibm.com Link: https://lore.kernel.org/r/20220603113034.2009728-1-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/lib/perf_csv_output_lint.py | 48 --------------- tools/perf/tests/shell/stat+csv_output.sh | 69 ++++++++++++++-------- 2 files changed, 45 insertions(+), 72 deletions(-) delete mode 100644 tools/perf/tests/shell/lib/perf_csv_output_lint.py (limited to 'tools/perf') diff --git a/tools/perf/tests/shell/lib/perf_csv_output_lint.py b/tools/perf/tests/shell/lib/perf_csv_output_lint.py deleted file mode 100644 index 714f283cfb1b..000000000000 --- a/tools/perf/tests/shell/lib/perf_csv_output_lint.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/python -# SPDX-License-Identifier: GPL-2.0 - -import argparse -import sys - -# Basic sanity check of perf CSV output as specified in the man page. -# Currently just checks the number of fields per line in output. - -ap = argparse.ArgumentParser() -ap.add_argument('--no-args', action='store_true') -ap.add_argument('--interval', action='store_true') -ap.add_argument('--system-wide-no-aggr', action='store_true') -ap.add_argument('--system-wide', action='store_true') -ap.add_argument('--event', action='store_true') -ap.add_argument('--per-core', action='store_true') -ap.add_argument('--per-thread', action='store_true') -ap.add_argument('--per-die', action='store_true') -ap.add_argument('--per-node', action='store_true') -ap.add_argument('--per-socket', action='store_true') -ap.add_argument('--separator', default=',', nargs='?') -args = ap.parse_args() - -Lines = sys.stdin.readlines() - -def check_csv_output(exp): - for line in Lines: - if 'failed' not in line: - count = line.count(args.separator) - if count != exp: - sys.stdout.write(''.join(Lines)) - raise RuntimeError(f'wrong number of fields. expected {exp} in {line}') - -try: - if args.no_args or args.system_wide or args.event: - expected_items = 6 - elif args.interval or args.per_thread or args.system_wide_no_aggr: - expected_items = 7 - elif args.per_core or args.per_socket or args.per_node or args.per_die: - expected_items = 8 - else: - ap.print_help() - raise RuntimeError('No checking option specified') - check_csv_output(expected_items) - -except: - sys.stdout.write('Test failed for input: ' + ''.join(Lines)) - raise diff --git a/tools/perf/tests/shell/stat+csv_output.sh b/tools/perf/tests/shell/stat+csv_output.sh index 983220ef3cb4..38c26f3ef4c1 100755 --- a/tools/perf/tests/shell/stat+csv_output.sh +++ b/tools/perf/tests/shell/stat+csv_output.sh @@ -6,20 +6,41 @@ set -e -pythonchecker=$(dirname $0)/lib/perf_csv_output_lint.py -if [ "x$PYTHON" == "x" ] -then - if which python3 > /dev/null - then - PYTHON=python3 - elif which python > /dev/null - then - PYTHON=python - else - echo Skipping test, python not detected please set environment variable PYTHON. - exit 2 - fi -fi +function commachecker() +{ + local -i cnt=0 exp=0 + + case "$1" + in "--no-args") exp=6 + ;; "--system-wide") exp=6 + ;; "--event") exp=6 + ;; "--interval") exp=7 + ;; "--per-thread") exp=7 + ;; "--system-wide-no-aggr") exp=7 + [ $(uname -m) = "s390x" ] && exp=6 + ;; "--per-core") exp=8 + ;; "--per-socket") exp=8 + ;; "--per-node") exp=8 + ;; "--per-die") exp=8 + esac + + while read line + do + # Check for lines beginning with Failed + x=${line:0:6} + [ "$x" = "Failed" ] && continue + + # Count the number of commas + x=$(echo $line | tr -d -c ',') + cnt="${#x}" + # echo $line $cnt + [ "$cnt" -ne "$exp" ] && { + echo "wrong number of fields. expected $exp in $line" 1>&2 + exit 1; + } + done + return 0 +} # Return true if perf_event_paranoid is > $1 and not running as root. function ParanoidAndNotRoot() @@ -30,7 +51,7 @@ function ParanoidAndNotRoot() check_no_args() { echo -n "Checking CSV output: no args " - perf stat -x, true 2>&1 | $PYTHON $pythonchecker --no-args + perf stat -x, true 2>&1 | commachecker --no-args echo "[Success]" } @@ -42,7 +63,7 @@ check_system_wide() echo "[Skip] paranoid and not root" return fi - perf stat -x, -a true 2>&1 | $PYTHON $pythonchecker --system-wide + perf stat -x, -a true 2>&1 | commachecker --system-wide echo "[Success]" } @@ -55,14 +76,14 @@ check_system_wide_no_aggr() return fi echo -n "Checking CSV output: system wide no aggregation " - perf stat -x, -A -a --no-merge true 2>&1 | $PYTHON $pythonchecker --system-wide-no-aggr + perf stat -x, -A -a --no-merge true 2>&1 | commachecker --system-wide-no-aggr echo "[Success]" } check_interval() { echo -n "Checking CSV output: interval " - perf stat -x, -I 1000 true 2>&1 | $PYTHON $pythonchecker --interval + perf stat -x, -I 1000 true 2>&1 | commachecker --interval echo "[Success]" } @@ -70,7 +91,7 @@ check_interval() check_event() { echo -n "Checking CSV output: event " - perf stat -x, -e cpu-clock true 2>&1 | $PYTHON $pythonchecker --event + perf stat -x, -e cpu-clock true 2>&1 | commachecker --event echo "[Success]" } @@ -82,7 +103,7 @@ check_per_core() echo "[Skip] paranoid and not root" return fi - perf stat -x, --per-core -a true 2>&1 | $PYTHON $pythonchecker --per-core + perf stat -x, --per-core -a true 2>&1 | commachecker --per-core echo "[Success]" } @@ -94,7 +115,7 @@ check_per_thread() echo "[Skip] paranoid and not root" return fi - perf stat -x, --per-thread -a true 2>&1 | $PYTHON $pythonchecker --per-thread + perf stat -x, --per-thread -a true 2>&1 | commachecker --per-thread echo "[Success]" } @@ -106,7 +127,7 @@ check_per_die() echo "[Skip] paranoid and not root" return fi - perf stat -x, --per-die -a true 2>&1 | $PYTHON $pythonchecker --per-die + perf stat -x, --per-die -a true 2>&1 | commachecker --per-die echo "[Success]" } @@ -118,7 +139,7 @@ check_per_node() echo "[Skip] paranoid and not root" return fi - perf stat -x, --per-node -a true 2>&1 | $PYTHON $pythonchecker --per-node + perf stat -x, --per-node -a true 2>&1 | commachecker --per-node echo "[Success]" } @@ -130,7 +151,7 @@ check_per_socket() echo "[Skip] paranoid and not root" return fi - perf stat -x, --per-socket -a true 2>&1 | $PYTHON $pythonchecker --per-socket + perf stat -x, --per-socket -a true 2>&1 | commachecker --per-socket echo "[Success]" } -- cgit v1.2.3 From cc2145526c9889e3dbddc210c21bc3a080b2a29f Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 10 Jun 2022 11:02:47 -0700 Subject: perf test: Fix variable length array undefined behavior in bp_account Fix: tests/bp_account.c:154:9: runtime error: variable length array bound evaluates to non-positive value 0 by switching from a variable length to an allocated array. Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: https://lore.kernel.org/r/20220610180247.444798-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/bp_account.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c index d1ebb5561e5b..6f921db33cf9 100644 --- a/tools/perf/tests/bp_account.c +++ b/tools/perf/tests/bp_account.c @@ -151,11 +151,21 @@ static int detect_ioctl(void) static int detect_share(int wp_cnt, int bp_cnt) { struct perf_event_attr attr; - int i, fd[wp_cnt + bp_cnt], ret; + int i, *fd = NULL, ret = -1; + + if (wp_cnt + bp_cnt == 0) + return 0; + + fd = malloc(sizeof(int) * (wp_cnt + bp_cnt)); + if (!fd) + return -1; for (i = 0; i < wp_cnt; i++) { fd[i] = wp_event((void *)&the_var, &attr); - TEST_ASSERT_VAL("failed to create wp\n", fd[i] != -1); + if (fd[i] == -1) { + pr_err("failed to create wp\n"); + goto out; + } } for (; i < (bp_cnt + wp_cnt); i++) { @@ -166,9 +176,11 @@ static int detect_share(int wp_cnt, int bp_cnt) ret = i != (bp_cnt + wp_cnt); +out: while (i--) close(fd[i]); + free(fd); return ret; } -- cgit v1.2.3 From 67e7d771580e9f365e75e1cc3690401526cfbb29 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 19 Jun 2021 10:09:08 -0300 Subject: perf beauty: Update copy of linux/socket.h with the kernel sources To pick the changes in: f94fd25cb0aaf77f ("tcp: pass back data left in socket after receive") That don't result in any changes in the tables generated from that header. This silences this perf build warning: Warning: Kernel ABI header at 'tools/perf/trace/beauty/include/linux/socket.h' differs from latest version at 'include/linux/socket.h' diff -u tools/perf/trace/beauty/include/linux/socket.h include/linux/socket.h Cc: Jakub Kicinski Cc: Jens Axboe Link: https://lore.kernel.org/all/YqORj9d58AiGYl8b@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/include/linux/socket.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/trace/beauty/include/linux/socket.h b/tools/perf/trace/beauty/include/linux/socket.h index 6f85f5d957ef..17311ad9f9af 100644 --- a/tools/perf/trace/beauty/include/linux/socket.h +++ b/tools/perf/trace/beauty/include/linux/socket.h @@ -50,6 +50,9 @@ struct linger { struct msghdr { void *msg_name; /* ptr to socket address structure */ int msg_namelen; /* size of socket address structure */ + + int msg_inq; /* output, data left in socket */ + struct iov_iter msg_iter; /* data */ /* @@ -62,8 +65,9 @@ struct msghdr { void __user *msg_control_user; }; bool msg_control_is_user : 1; - __kernel_size_t msg_controllen; /* ancillary data buffer length */ + bool msg_get_inq : 1;/* return INQ after receive */ unsigned int msg_flags; /* flags on received message */ + __kernel_size_t msg_controllen; /* ancillary data buffer length */ struct kiocb *msg_iocb; /* ptr to iocb for async requests */ }; @@ -434,6 +438,7 @@ extern struct file *do_accept(struct file *file, unsigned file_flags, extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen, int flags); extern int __sys_socket(int family, int type, int protocol); +extern struct file *__sys_socket_file(int family, int type, int protocol); extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); extern int __sys_connect_file(struct file *file, struct sockaddr_storage *addr, int addrlen, int file_flags); -- cgit v1.2.3 From 72dcae8efd42699bbfd55e1ef187310c4e2e5dcb Mon Sep 17 00:00:00 2001 From: Michael Petlan Date: Tue, 14 Jun 2022 12:52:07 +0200 Subject: perf test: Record only user callchains on the "Check Arm64 callgraphs are complete in fp mode" test The testcase 'Check Arm64 callgraphs are complete in fp mode' wants to see the following output: 610 leaf 62f parent 648 main However, without excluding kernel callchains, the output might look like: ffffc2ff40ef1b5c arch_local_irq_enable ffffc2ff419d032c __schedule ffffc2ff419d06c0 schedule ffffc2ff40e4da30 do_notify_resume ffffc2ff40e421b0 work_pending 610 leaf 62f parent 648 main Adding '--user-callchains' leaves only the wanted symbols in the chain. Fixes: cd6382d82752737e ("perf test arm64: Test unwinding using fame-pointer (fp) mode") Suggested-by: German Gomez Reviewed-by: German Gomez Reviewed-by: Leo Yan Signed-off-by: Michael Petlan Cc: German Gomez Cc: Jiri Olsa Link: https://lore.kernel.org/r/20220614105207.26223-1-mpetlan@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/test_arm_callgraph_fp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/shell/test_arm_callgraph_fp.sh b/tools/perf/tests/shell/test_arm_callgraph_fp.sh index 6ffbb27afaba..ec108d45d3c6 100755 --- a/tools/perf/tests/shell/test_arm_callgraph_fp.sh +++ b/tools/perf/tests/shell/test_arm_callgraph_fp.sh @@ -43,7 +43,7 @@ CFLAGS="-g -O0 -fno-inline -fno-omit-frame-pointer" cc $CFLAGS $TEST_PROGRAM_SOURCE -o $TEST_PROGRAM || exit 1 # Add a 1 second delay to skip samples that are not in the leaf() function -perf record -o $PERF_DATA --call-graph fp -e cycles//u -D 1000 -- $TEST_PROGRAM 2> /dev/null & +perf record -o $PERF_DATA --call-graph fp -e cycles//u -D 1000 --user-callchains -- $TEST_PROGRAM 2> /dev/null & PID=$! echo " + Recording (PID=$PID)..." -- cgit v1.2.3 From b236371421df57b93fc49c4b9d0e53bd1aab2b2e Mon Sep 17 00:00:00 2001 From: Athira Rajeev Date: Fri, 10 Jun 2022 19:29:39 +0530 Subject: perf test topology: Use !strncmp(right platform) to fix guest PPC comparision check commit cfd7092c31aed728 ("perf test session topology: Fix test to skip the test in guest environment") added check to skip the testcase if the socket_id can't be fetched from topology info. But the condition check uses strncmp which should be changed to !strncmp and to correctly match platform. Fix this condition check. Fixes: cfd7092c31aed728 ("perf test session topology: Fix test to skip the test in guest environment") Reported-by: Thomas Richter Signed-off-by: Athira Jajeev Acked-by: Ian Rogers Cc: Athira Rajeev Cc: Disha Goel Cc: Jiri Olsa Cc: Kajol Jain Cc: linuxppc-dev@lists.ozlabs.org Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Nageswara R Sastry Link: https://lore.kernel.org/r/20220610135939.63361-1-atrajeev@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index d23a9e322ff5..0b4f61b6cc6b 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -115,7 +115,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map) * physical_package_id will be set to -1. Hence skip this * test if physical_package_id returns -1 for cpu from perf_cpu_map. */ - if (strncmp(session->header.env.arch, "powerpc", 7)) { + if (!strncmp(session->header.env.arch, "ppc64le", 7)) { if (cpu__get_socket_id(perf_cpu_map__cpu(map, 0)) == -1) return TEST_SKIP; } -- cgit v1.2.3 From e5287e6dd3b07e28e6bca5e33a3813a5e83bbc4c Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 26 May 2022 19:06:53 -0700 Subject: perf expr: Allow exponents on floating point values Pass the optional exponent component through to strtod that already supports it. We already have exponents in ScaleUnit and so this adds uniformity. Reported-by: Zhengjun Xing Reviewed-By: Kajol Jain Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Richter Link: https://lore.kernel.org/r/20220527020653.4160884-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/expr.c | 2 ++ tools/perf/util/expr.l | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index d54c5371c6a6..5c0032fe93ae 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -97,6 +97,8 @@ static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_u ret |= test(ctx, "2.2 > 2.2", 0); ret |= test(ctx, "2.2 < 1.1", 0); ret |= test(ctx, "1.1 > 2.2", 0); + ret |= test(ctx, "1.1e10 < 1.1e100", 1); + ret |= test(ctx, "1.1e2 > 1.1e-2", 1); if (ret) { expr__ctx_free(ctx); diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l index 0a13eb20c814..4dc8edbfd9ce 100644 --- a/tools/perf/util/expr.l +++ b/tools/perf/util/expr.l @@ -91,7 +91,7 @@ static int literal(yyscan_t scanner) } %} -number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+) +number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)(e-?[0-9]+)? sch [-,=] spec \\{sch} -- cgit v1.2.3 From 51ba539f5bdb5a8cc7b1dedd5e73ac54564a7602 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Tue, 17 May 2022 02:03:25 +0000 Subject: perf arm-spe: Don't set data source if it's not a memory operation Except for memory load and store operations, ARM SPE records also can support other operation types, bug when set the data source field the current code assumes a record is a either load operation or store operation, this leads to wrongly synthesize memory samples. This patch strictly checks the record operation type, it only sets data source only for the operation types ARM_SPE_LD and ARM_SPE_ST, otherwise, returns zero for data source. Therefore, we can synthesize memory samples only when data source is a non-zero value, the function arm_spe__is_memory_event() is useless and removed. Fixes: e55ed3423c1bb29f ("perf arm-spe: Synthesize memory event") Reviewed-by: Ali Saidi Reviewed-by: German Gomez Signed-off-by: Leo Yan Tested-by: Ali Saidi Cc: Alexander Shishkin Cc: alisaidi@amazon.com Cc: Andrew Kilroy Cc: Benjamin Herrenschmidt Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Leo Yan Cc: Li Huafei Cc: linux-arm-kernel@lists.infradead.org Cc: Mark Rutland Cc: Mathieu Poirier Cc: Namhyung Kim Cc: Nick Forrington Cc: Peter Zijlstra Cc: Will Deacon Link: http://lore.kernel.org/lkml/20220517020326.18580-5-alisaidi@amazon.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/arm-spe.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 1a80151baed9..d040406f3314 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c @@ -387,26 +387,16 @@ static int arm_spe__synth_instruction_sample(struct arm_spe_queue *speq, return arm_spe_deliver_synth_event(spe, speq, event, &sample); } -#define SPE_MEM_TYPE (ARM_SPE_L1D_ACCESS | ARM_SPE_L1D_MISS | \ - ARM_SPE_LLC_ACCESS | ARM_SPE_LLC_MISS | \ - ARM_SPE_REMOTE_ACCESS) - -static bool arm_spe__is_memory_event(enum arm_spe_sample_type type) -{ - if (type & SPE_MEM_TYPE) - return true; - - return false; -} - static u64 arm_spe__synth_data_source(const struct arm_spe_record *record) { union perf_mem_data_src data_src = { 0 }; if (record->op == ARM_SPE_LD) data_src.mem_op = PERF_MEM_OP_LOAD; - else + else if (record->op == ARM_SPE_ST) data_src.mem_op = PERF_MEM_OP_STORE; + else + return 0; if (record->type & (ARM_SPE_LLC_ACCESS | ARM_SPE_LLC_MISS)) { data_src.mem_lvl = PERF_MEM_LVL_L3; @@ -510,7 +500,11 @@ static int arm_spe_sample(struct arm_spe_queue *speq) return err; } - if (spe->sample_memory && arm_spe__is_memory_event(record->type)) { + /* + * When data_src is zero it means the record is not a memory operation, + * skip to synthesize memory sample for this case. + */ + if (spe->sample_memory && data_src) { err = arm_spe__synth_mem_sample(speq, spe->memory_id, data_src); if (err) return err; -- cgit v1.2.3 From c788ef61ef2ae51dc9cbd589e118f827585c156f Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 17 Jun 2022 18:39:57 -0700 Subject: perf metrics: Ensure at least 1 id per metric We may have no events for a metric evaluated to a constant. In such a case ensure a tool event is at least evaluated for metric parsing and displaying. Fixes: 8586d2744ff3065e ("perf metrics: Don't add all tool events for sharing") Signed-off-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Xing Zhengjun Link: https://lore.kernel.org/r/20220618013957.999321-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/metricgroup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index ee8fcfa115e5..8f7baeabc5cf 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -1372,6 +1372,7 @@ static int parse_ids(bool metric_no_merge, struct perf_pmu *fake_pmu, *out_evlist = NULL; if (!metric_no_merge || hashmap__size(ids->ids) == 0) { + bool added_event = false; int i; /* * We may fail to share events between metrics because a tool @@ -1393,8 +1394,16 @@ static int parse_ids(bool metric_no_merge, struct perf_pmu *fake_pmu, if (!tmp) return -ENOMEM; ids__insert(ids->ids, tmp); + added_event = true; } } + if (!added_event && hashmap__size(ids->ids) == 0) { + char *tmp = strdup("duration_time"); + + if (!tmp) + return -ENOMEM; + ids__insert(ids->ids, tmp); + } } ret = metricgroup__build_event_string(&events, ids, modifier, has_constraint); -- cgit v1.2.3 From 342cb0d80613719c5e5ac30619e54b9a3fd83625 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 20 Jun 2022 13:39:04 +0300 Subject: perf inject: Fix missing free in copy_kcore_dir() Free string allocated by asprintf(). Fixes: d8fc08550929bb84 ("perf inject: Keep a copy of kcore_dir") Signed-off-by: Adrian Hunter Cc: Adrian Hunter Cc: Jiri Olsa Link: https://lore.kernel.org/r/20220620103904.7960-1-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index a75bf11585b5..063f74f5b8db 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -891,7 +891,9 @@ static int copy_kcore_dir(struct perf_inject *inject) if (ret < 0) return ret; pr_debug("%s\n", cmd); - return system(cmd); + ret = system(cmd); + free(cmd); + return ret; } static int output_fd(struct perf_inject *inject) -- cgit v1.2.3 From ab66fdace8581ef3b4e7cf5381a168ed4058d779 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 21 Jun 2022 15:51:44 +0300 Subject: perf build-id: Fix caching files with a wrong build ID Build ID events associate a file name with a build ID. However, when using perf inject, there is no guarantee that the file on the current machine at the current time has that build ID. Fix by comparing the build IDs and skip adding to the cache if they are different. Example: $ echo "int main() {return 0;}" > prog.c $ gcc -o prog prog.c $ perf record --buildid-all ./prog [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.019 MB perf.data ] $ file-buildid() { file $1 | awk -F= '{print $2}' | awk -F, '{print $1}' ; } $ file-buildid prog 444ad9be165d8058a48ce2ffb4e9f55854a3293e $ file-buildid ~/.debug/$(pwd)/prog/444ad9be165d8058a48ce2ffb4e9f55854a3293e/elf 444ad9be165d8058a48ce2ffb4e9f55854a3293e $ echo "int main() {return 1;}" > prog.c $ gcc -o prog prog.c $ file-buildid prog 885524d5aaa24008a3e2b06caa3ea95d013c0fc5 Before: $ perf buildid-cache --purge $(pwd)/prog $ perf inject -i perf.data -o junk $ file-buildid ~/.debug/$(pwd)/prog/444ad9be165d8058a48ce2ffb4e9f55854a3293e/elf 885524d5aaa24008a3e2b06caa3ea95d013c0fc5 $ After: $ perf buildid-cache --purge $(pwd)/prog $ perf inject -i perf.data -o junk $ file-buildid ~/.debug/$(pwd)/prog/444ad9be165d8058a48ce2ffb4e9f55854a3293e/elf $ Fixes: 454c407ec17a0c63 ("perf: add perf-inject builtin") Signed-off-by: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Tom Zanussi Link: https://lore.kernel.org/r/20220621125144.5623-1-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/build-id.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 82f3d46bea70..328668f38c69 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -872,6 +872,30 @@ out_free: return err; } +static int filename__read_build_id_ns(const char *filename, + struct build_id *bid, + struct nsinfo *nsi) +{ + struct nscookie nsc; + int ret; + + nsinfo__mountns_enter(nsi, &nsc); + ret = filename__read_build_id(filename, bid); + nsinfo__mountns_exit(&nsc); + + return ret; +} + +static bool dso__build_id_mismatch(struct dso *dso, const char *name) +{ + struct build_id bid; + + if (filename__read_build_id_ns(name, &bid, dso->nsinfo) < 0) + return false; + + return !dso__build_id_equal(dso, &bid); +} + static int dso__cache_build_id(struct dso *dso, struct machine *machine, void *priv __maybe_unused) { @@ -886,6 +910,10 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine, is_kallsyms = true; name = machine->mmap_name; } + + if (!is_kallsyms && dso__build_id_mismatch(dso, name)) + return 0; + return build_id_cache__add_b(&dso->bid, name, dso->nsinfo, is_kallsyms, is_vdso); } -- cgit v1.2.3 From 3713e2494b6ab98f0476bb575b22323775f7d77a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 21 Jun 2022 12:34:37 -0300 Subject: perf trace beauty: Fix generation of errno id->str table on ALT Linux For some reason using: cat < Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/arch_errno_names.sh | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/trace/beauty/arch_errno_names.sh b/tools/perf/trace/beauty/arch_errno_names.sh index 2c5f72fa8108..37c53bac5f56 100755 --- a/tools/perf/trace/beauty/arch_errno_names.sh +++ b/tools/perf/trace/beauty/arch_errno_names.sh @@ -33,23 +33,13 @@ create_errno_lookup_func() local arch=$(arch_string "$1") local nr name - cat < Date: Tue, 21 Jun 2022 15:27:25 +0000 Subject: perf inject: Adjust output data offset for backward compatibility When 'perf inject' creates a new file, it reuses the data offset from the input file. If there has been a change on the size of the header, as happened in v5.12 -> v5.13, the new offsets will be wrong, resulting in a corrupted output file. This change adds the function perf_session__data_offset to compute the data offset based on the current header size, and uses that instead of the offset from the original input file. Signed-off-by: Raul Silvera Acked-by: Adrian Hunter Cc: Alexander Shishkin Cc: Athira Jajeev Cc: Colin Ian King Cc: Dave Marchevsky Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20220621152725.2668041-1-rsilvera@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 2 +- tools/perf/util/header.c | 14 ++++++++++++++ tools/perf/util/header.h | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 063f74f5b8db..54d4e508a092 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -918,7 +918,7 @@ static int __cmd_inject(struct perf_inject *inject) inject->tool.tracing_data = perf_event__repipe_tracing_data; } - output_data_offset = session->header.data_offset; + output_data_offset = perf_session__data_offset(session->evlist); if (inject->build_id_all) { inject->tool.mmap = perf_event__repipe_buildid_mmap; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 53332da100e8..6ad629db63b7 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3686,6 +3686,20 @@ int perf_session__write_header(struct perf_session *session, return perf_session__do_write_header(session, evlist, fd, at_exit, NULL); } +size_t perf_session__data_offset(const struct evlist *evlist) +{ + struct evsel *evsel; + size_t data_offset; + + data_offset = sizeof(struct perf_file_header); + evlist__for_each_entry(evlist, evsel) { + data_offset += evsel->core.ids * sizeof(u64); + } + data_offset += evlist->core.nr_entries * sizeof(struct perf_file_attr); + + return data_offset; +} + int perf_session__inject_header(struct perf_session *session, struct evlist *evlist, int fd, diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 08563c1f1bff..56916dabce7b 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -136,6 +136,8 @@ int perf_session__inject_header(struct perf_session *session, int fd, struct feat_copier *fc); +size_t perf_session__data_offset(const struct evlist *evlist); + void perf_header__set_feat(struct perf_header *header, int feat); void perf_header__clear_feat(struct perf_header *header, int feat); bool perf_header__has_feat(const struct perf_header *header, int feat); -- cgit v1.2.3 From 448ce0e6ea93ae99e0b36055e5f5a3f723fe3665 Mon Sep 17 00:00:00 2001 From: Gang Li Date: Wed, 22 Jun 2022 11:00:37 +0800 Subject: perf stat: Enable ignore_missing_thread perf already support ignore_missing_thread for -p, but not yet applied to `perf stat -p `. This patch enables ignore_missing_thread for `perf stat -p `. Committer notes: And here is a refresher about the 'ignore_missing_thread' knob, from a previous patch using it: ca8000684ec4e66f ("perf evsel: Enable ignore_missing_thread for pid option") --- While monitoring a multithread process with pid option, perf sometimes may return sys_perf_event_open failure with 3(No such process) if any of the process's threads die before we open the event. However, we want perf continue monitoring the remaining threads and do not exit with error. --- Signed-off-by: Gang Li Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20220622030037.15005-1-ligang.bdlg@bytedance.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/perf') diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 4ce87a8eb7d7..d2ecd4d29624 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2586,6 +2586,8 @@ int cmd_stat(int argc, const char **argv) if (evlist__initialize_ctlfd(evsel_list, stat_config.ctl_fd, stat_config.ctl_fd_ack)) goto out; + /* Enable ignoring missing threads when -p option is defined. */ + evlist__first(evsel_list)->ignore_missing_thread = target.pid; status = 0; for (run_idx = 0; forever || run_idx < stat_config.run_count; run_idx++) { if (stat_config.run_count != 1 && verbose > 0) -- cgit v1.2.3 From d6838ec44b4513280a3f43fcc402e246d543fb53 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 24 Jun 2022 16:13:08 -0700 Subject: perf offcpu: Fix build failure on old kernels Old kernels have a 'struct task_struct' which contains a "state" field and newer kernels have "__state" instead. While the get_task_state() in the BPF code handles that in some way, it assumed the current kernel has the new definition and it caused a build error on old kernels. We should not assume anything and access them carefully. Do not use 'task struct' directly access it instead using new and old definitions in a row. Fixes: edc41a1099c2d08c ("perf record: Enable off-cpu analysis with BPF") Reported-by: Ian Rogers Signed-off-by: Namhyung Kim Cc: Blake Jones Cc: Hao Luo Cc: Jiri Olsa Cc: Milian Wolff Cc: Peter Zijlstra Cc: Song Liu Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20220624231313.367909-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf_skel/off_cpu.bpf.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/bpf_skel/off_cpu.bpf.c b/tools/perf/util/bpf_skel/off_cpu.bpf.c index 792ae2847080..cc6d7fd55118 100644 --- a/tools/perf/util/bpf_skel/off_cpu.bpf.c +++ b/tools/perf/util/bpf_skel/off_cpu.bpf.c @@ -71,6 +71,11 @@ struct { __uint(max_entries, 1); } cgroup_filter SEC(".maps"); +/* new kernel task_struct definition */ +struct task_struct___new { + long __state; +} __attribute__((preserve_access_index)); + /* old kernel task_struct definition */ struct task_struct___old { long state; @@ -93,14 +98,17 @@ const volatile bool uses_cgroup_v1 = false; */ static inline int get_task_state(struct task_struct *t) { - if (bpf_core_field_exists(t->__state)) - return BPF_CORE_READ(t, __state); + /* recast pointer to capture new type for compiler */ + struct task_struct___new *t_new = (void *)t; - /* recast pointer to capture task_struct___old type for compiler */ - struct task_struct___old *t_old = (void *)t; + if (bpf_core_field_exists(t_new->__state)) { + return BPF_CORE_READ(t_new, __state); + } else { + /* recast pointer to capture old type for compiler */ + struct task_struct___old *t_old = (void *)t; - /* now use old "state" name of the field */ - return BPF_CORE_READ(t_old, state); + return BPF_CORE_READ(t_old, state); + } } static inline __u64 get_cgroup_id(struct task_struct *t) -- cgit v1.2.3 From 49c692b7dfc9b6c06a1dc11359a8780575b16d4a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 24 Jun 2022 16:13:09 -0700 Subject: perf offcpu: Accept allowed sample types only As offcpu-time event is synthesized at the end, it could not get the all the sample info. Define OFFCPU_SAMPLE_TYPES for allowed ones and mask out others in evsel__config() to prevent parse errors. Because perf sample parsing assumes a specific ordering with the sample types, setting unsupported one would make it fail to read data like perf record -d/--data. Fixes: edc41a1099c2d08c ("perf record: Enable off-cpu analysis with BPF") Signed-off-by: Namhyung Kim Cc: Blake Jones Cc: Hao Luo Cc: Ian Rogers Cc: Jiri Olsa Cc: Milian Wolff Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20220624231313.367909-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf_off_cpu.c | 7 ++++++- tools/perf/util/evsel.c | 9 +++++++++ tools/perf/util/off_cpu.h | 9 +++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c index b73e84a02264..f289b7713598 100644 --- a/tools/perf/util/bpf_off_cpu.c +++ b/tools/perf/util/bpf_off_cpu.c @@ -265,6 +265,12 @@ int off_cpu_write(struct perf_session *session) sample_type = evsel->core.attr.sample_type; + if (sample_type & ~OFFCPU_SAMPLE_TYPES) { + pr_err("not supported sample type: %llx\n", + (unsigned long long)sample_type); + return -1; + } + if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) { if (evsel->core.id) sid = evsel->core.id[0]; @@ -319,7 +325,6 @@ int off_cpu_write(struct perf_session *session) } if (sample_type & PERF_SAMPLE_CGROUP) data.array[n++] = key.cgroup_id; - /* TODO: handle more sample types */ size = n * sizeof(u64); data.hdr.size = size; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ce499c5da8d7..094b0a9c0bc0 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -48,6 +48,7 @@ #include "util.h" #include "hashmap.h" #include "pmu-hybrid.h" +#include "off_cpu.h" #include "../perf-sys.h" #include "util/parse-branch-options.h" #include @@ -1102,6 +1103,11 @@ static void evsel__set_default_freq_period(struct record_opts *opts, } } +static bool evsel__is_offcpu_event(struct evsel *evsel) +{ + return evsel__is_bpf_output(evsel) && !strcmp(evsel->name, OFFCPU_EVENT); +} + /* * The enable_on_exec/disabled value strategy: * @@ -1366,6 +1372,9 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts, */ if (evsel__is_dummy_event(evsel)) evsel__reset_sample_bit(evsel, BRANCH_STACK); + + if (evsel__is_offcpu_event(evsel)) + evsel->core.attr.sample_type &= OFFCPU_SAMPLE_TYPES; } int evsel__set_filter(struct evsel *evsel, const char *filter) diff --git a/tools/perf/util/off_cpu.h b/tools/perf/util/off_cpu.h index 548008f74d42..2dd67c60f211 100644 --- a/tools/perf/util/off_cpu.h +++ b/tools/perf/util/off_cpu.h @@ -1,6 +1,8 @@ #ifndef PERF_UTIL_OFF_CPU_H #define PERF_UTIL_OFF_CPU_H +#include + struct evlist; struct target; struct perf_session; @@ -8,6 +10,13 @@ struct record_opts; #define OFFCPU_EVENT "offcpu-time" +#define OFFCPU_SAMPLE_TYPES (PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_IP | \ + PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \ + PERF_SAMPLE_ID | PERF_SAMPLE_CPU | \ + PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN | \ + PERF_SAMPLE_CGROUP) + + #ifdef HAVE_BPF_SKEL int off_cpu_prepare(struct evlist *evlist, struct target *target, struct record_opts *opts); -- cgit v1.2.3 From 579d6c6d77a7b55d74db8a506d5fc0c77fb1a5e1 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 13 Jun 2022 18:47:14 -0700 Subject: perf bpf: 8 byte align bpil data bpil data is accessed assuming 64-bit alignment resulting in undefined behavior as the data is just byte aligned. With an -fsanitize=undefined build the following errors are observed: $ sudo perf record -a sleep 1 util/bpf-event.c:310:22: runtime error: load of misaligned address 0x55f61084520f for type '__u64', which requires 8 byte alignment 0x55f61084520f: note: pointer points here a8 fe ff ff 3c 51 d3 c0 ff ff ff ff 04 84 d3 c0 ff ff ff ff d8 aa d3 c0 ff ff ff ff a4 c0 d3 c0 ^ util/bpf-event.c:311:20: runtime error: load of misaligned address 0x55f61084522f for type '__u32', which requires 4 byte alignment 0x55f61084522f: note: pointer points here ff ff ff ff c7 17 00 00 f1 02 00 00 1f 04 00 00 58 04 00 00 00 00 00 00 0f 00 00 00 63 02 00 00 ^ util/bpf-event.c:198:33: runtime error: member access within misaligned address 0x55f61084523f for type 'const struct bpf_func_info', which requires 4 byte alignment 0x55f61084523f: note: pointer points here 58 04 00 00 00 00 00 00 0f 00 00 00 63 02 00 00 3b 00 00 00 ab 02 00 00 44 00 00 00 14 03 00 00 Correct this by rouding up the data sizes and aligning the pointers. Signed-off-by: Ian Rogers Acked-by: Andrii Nakryiko Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Dave Marchevsky Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Quentin Monnet Cc: Song Liu Cc: Stephane Eranian Cc: Yonghong Song Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20220614014714.1407239-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-utils.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c index e271e05e51bc..80b1d2b3729b 100644 --- a/tools/perf/util/bpf-utils.c +++ b/tools/perf/util/bpf-utils.c @@ -149,11 +149,10 @@ get_bpf_prog_info_linear(int fd, __u64 arrays) count = bpf_prog_info_read_offset_u32(&info, desc->count_offset); size = bpf_prog_info_read_offset_u32(&info, desc->size_offset); - data_len += count * size; + data_len += roundup(count * size, sizeof(__u64)); } /* step 3: allocate continuous memory */ - data_len = roundup(data_len, sizeof(__u64)); info_linear = malloc(sizeof(struct perf_bpil) + data_len); if (!info_linear) return ERR_PTR(-ENOMEM); @@ -180,7 +179,7 @@ get_bpf_prog_info_linear(int fd, __u64 arrays) bpf_prog_info_set_offset_u64(&info_linear->info, desc->array_offset, ptr_to_u64(ptr)); - ptr += count * size; + ptr += roundup(count * size, sizeof(__u64)); } /* step 5: call syscall again to get required arrays */ -- cgit v1.2.3 From 5eb502b2e1ae1ab052cdf6bdd7615217e8517360 Mon Sep 17 00:00:00 2001 From: Ivan Babrou Date: Fri, 1 Jul 2022 11:20:46 -0700 Subject: perf unwind: Fix unitialized 'offset' variable on aarch64 Commit dc2cf4ca866f5715 ("perf unwind: Fix segbase for ld.lld linked objects") uncovered the following issue on aarch64: util/unwind-libunwind-local.c: In function 'find_proc_info': util/unwind-libunwind-local.c:386:28: error: 'offset' may be used uninitialized in this function [-Werror=maybe-uninitialized] 386 | if (ofs > 0) { | ^ util/unwind-libunwind-local.c:199:22: note: 'offset' was declared here 199 | u64 address, offset; | ^~~~~~ util/unwind-libunwind-local.c:371:20: error: 'offset' may be used uninitialized in this function [-Werror=maybe-uninitialized] 371 | if (ofs <= 0) { | ^ util/unwind-libunwind-local.c:199:22: note: 'offset' was declared here 199 | u64 address, offset; | ^~~~~~ util/unwind-libunwind-local.c:363:20: error: 'offset' may be used uninitialized in this function [-Werror=maybe-uninitialized] 363 | if (ofs <= 0) { | ^ util/unwind-libunwind-local.c:199:22: note: 'offset' was declared here 199 | u64 address, offset; | ^~~~~~ In file included from util/libunwind/arm64.c:37: Fixes: dc2cf4ca866f5715 ("perf unwind: Fix segbase for ld.lld linked objects") Signed-off-by: Ivan Babrou Cc: Alexander Shishkin Cc: Fangrui Song Cc: Ian Rogers Cc: James Clark Cc: Jiri Olsa Cc: kernel-team@cloudflare.com Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20220701182046.12589-1-ivan@cloudflare.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/unwind-libunwind-local.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf') diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 6e5b8cce47bf..81b6bd6e1536 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -197,7 +197,7 @@ out_err: #ifndef NO_LIBUNWIND_DEBUG_FRAME static u64 elf_section_offset(int fd, const char *name) { - u64 address, offset; + u64 address, offset = 0; if (elf_section_address_and_offset(fd, name, &address, &offset)) return 0; -- cgit v1.2.3 From 363afa3aef24f5e08df6a539f5dc3aae4cddcc1a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 1 Jul 2022 13:54:57 -0700 Subject: perf synthetic-events: Don't sort the task scan result from /proc It should not sort the result as procfs already returns a proper ordering of tasks. Actually sorting the order caused problems that it doesn't guararantee to process the main thread first. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20220701205458.985106-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/synthetic-events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 27acdc5e5723..a068f42833c3 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -754,7 +754,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, snprintf(filename, sizeof(filename), "%s/proc/%d/task", machine->root_dir, pid); - n = scandir(filename, &dirent, filter_task, alphasort); + n = scandir(filename, &dirent, filter_task, NULL); if (n < 0) return n; @@ -987,7 +987,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, return 0; snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); - n = scandir(proc_path, &dirent, filter_task, alphasort); + n = scandir(proc_path, &dirent, filter_task, NULL); if (n < 0) return err; -- cgit v1.2.3 From ff898552fb32d255517fb0676f9fa500664c484d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 1 Jul 2022 13:54:58 -0700 Subject: perf synthetic-events: Ignore dead threads during event synthesis When it synthesize various task events, it scans the list of task first and then accesses later. There's a window threads can die between the two and proc entries may not be available. Instead of bailing out, we can ignore that thread and move on. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20220701205458.985106-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/synthetic-events.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index a068f42833c3..84d17bd4efae 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -767,11 +767,12 @@ static int __event__synthesize_thread(union perf_event *comm_event, if (*end) continue; - rc = -1; + /* some threads may exit just after scan, ignore it */ if (perf_event__prepare_comm(comm_event, pid, _pid, machine, &tgid, &ppid, &kernel_thread) != 0) - break; + continue; + rc = -1; if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, ppid, process, machine) < 0) break; -- cgit v1.2.3