Commit 56f81458 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'perf-tools-fixes-for-v6.2-1-2023-01-06' of...

Merge tag 'perf-tools-fixes-for-v6.2-1-2023-01-06' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull perf tools fixes from Arnaldo Carvalho de Melo:

 - Fix segfault when trying to process tracepoints present in a
   perf.data file and not linked with libtraceevent.

 - Fix build on uClibc systems by adding missing sys/types.h include,
   that was being obtained indirectly which stopped being the case when
   tools/lib/traceevent was removed.

 - Don't show commands in 'perf help' that depend on linking with
   libtraceevent when not building with that library, which is now a
   possibility since we no longer ship a copy in tools/lib/traceevent.

 - Fix failure in 'perf test' entry testing the combination of 'perf
   probe' user space function + 'perf record' + 'perf script' where it
   expects a backtrace leading to glibc's inet_pton() from 'ping' that
   now happens more than once with glibc 2.35 for IPv6 addreses.

 - Fix for the inet_pton perf test on s/390 where
   'text_to_binary_address' now appears on the backtrace.

 - Fix build error on riscv due to missing header for 'struct
   perf_sample'.

 - Fix 'make -C tools perf_install' install variant by not propagating
   the 'subdir' to submakes for the 'install_headers' targets.

 - Fix handling of unsupported cgroup events when using BPF counters in
   'perf stat'.

 - Count all cgroups, not just the last one when using 'perf stat' and
   combining --for-each-cgroup with --bpf-counters.

   This makes the output using BPF counters match the output without
   using it, which was the intention all along, the output should be the
   same using --bpf-counters or not.

 - Fix 'perf lock contention' core dump related to not finding the
   "__sched_text_end" symbol on s/390.

 - Fix build failure when HEAD is signed: exclude the signature from the
   version string.

 - Add missing closedir() calls to in perf_data__open_dir(), plugging a
   fd leak.

* tag 'perf-tools-fixes-for-v6.2-1-2023-01-06' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux:
  perf tools: Fix build on uClibc systems by adding missing sys/types.h include
  perf stat: Fix handling of --for-each-cgroup with --bpf-counters to match non BPF mode
  perf stat: Fix handling of unsupported cgroup events when using BPF counters
  perf test record_probe_libc_inet_pton: Fix test on s/390 where 'text_to_binary_address' now appears on the backtrace
  perf lock contention: Fix core dump related to not finding the "__sched_text_end" symbol on s/390
  perf build: Don't propagate subdir to submakes for install_headers
  perf test record_probe_libc_inet_pton: Fix failure due to extra inet_pton() backtrace in glibc >= 2.35
  perf tools: Fix segfault when trying to process tracepoints in perf.data and not linked with libtraceevent
  perf tools: Don't include signature in version strings
  perf help: Use HAVE_LIBTRACEEVENT to filter out unsupported commands
  perf tools riscv: Fix build error on riscv due to missing header for 'struct perf_sample'
  perf tools: Fix resources leak in perf_data__open_dir()
parents d7a0853d 481028db
...@@ -267,7 +267,7 @@ $(OUTPUT)%.xml : %.txt ...@@ -267,7 +267,7 @@ $(OUTPUT)%.xml : %.txt
$(ASCIIDOC) -b docbook -d manpage \ $(ASCIIDOC) -b docbook -d manpage \
$(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) \ $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) \
-aperf_date=$(shell git log -1 --pretty="format:%cd" \ -aperf_date=$(shell git log -1 --pretty="format:%cd" \
--date=short $<) \ --date=short --no-show-signature $<) \
-o $@+ $< && \ -o $@+ $< && \
mv $@+ $@ mv $@+ $@
......
...@@ -819,7 +819,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) ...@@ -819,7 +819,7 @@ $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h)
$(LIBAPI): FORCE | $(LIBAPI_OUTPUT) $(LIBAPI): FORCE | $(LIBAPI_OUTPUT)
$(Q)$(MAKE) -C $(LIBAPI_DIR) O=$(LIBAPI_OUTPUT) \ $(Q)$(MAKE) -C $(LIBAPI_DIR) O=$(LIBAPI_OUTPUT) \
DESTDIR=$(LIBAPI_DESTDIR) prefix= \ DESTDIR=$(LIBAPI_DESTDIR) prefix= subdir= \
$@ install_headers $@ install_headers
$(LIBAPI)-clean: $(LIBAPI)-clean:
...@@ -828,7 +828,7 @@ $(LIBAPI)-clean: ...@@ -828,7 +828,7 @@ $(LIBAPI)-clean:
$(LIBBPF): FORCE | $(LIBBPF_OUTPUT) $(LIBBPF): FORCE | $(LIBBPF_OUTPUT)
$(Q)$(MAKE) -C $(LIBBPF_DIR) FEATURES_DUMP=$(FEATURE_DUMP_EXPORT) \ $(Q)$(MAKE) -C $(LIBBPF_DIR) FEATURES_DUMP=$(FEATURE_DUMP_EXPORT) \
O= OUTPUT=$(LIBBPF_OUTPUT)/ DESTDIR=$(LIBBPF_DESTDIR) prefix= \ O= OUTPUT=$(LIBBPF_OUTPUT)/ DESTDIR=$(LIBBPF_DESTDIR) prefix= subdir= \
$@ install_headers $@ install_headers
$(LIBBPF)-clean: $(LIBBPF)-clean:
...@@ -837,7 +837,7 @@ $(LIBBPF)-clean: ...@@ -837,7 +837,7 @@ $(LIBBPF)-clean:
$(LIBPERF): FORCE | $(LIBPERF_OUTPUT) $(LIBPERF): FORCE | $(LIBPERF_OUTPUT)
$(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(LIBPERF_OUTPUT) \ $(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(LIBPERF_OUTPUT) \
DESTDIR=$(LIBPERF_DESTDIR) prefix= \ DESTDIR=$(LIBPERF_DESTDIR) prefix= subdir= \
$@ install_headers $@ install_headers
$(LIBPERF)-clean: $(LIBPERF)-clean:
...@@ -846,7 +846,7 @@ $(LIBPERF)-clean: ...@@ -846,7 +846,7 @@ $(LIBPERF)-clean:
$(LIBSUBCMD): FORCE | $(LIBSUBCMD_OUTPUT) $(LIBSUBCMD): FORCE | $(LIBSUBCMD_OUTPUT)
$(Q)$(MAKE) -C $(LIBSUBCMD_DIR) O=$(LIBSUBCMD_OUTPUT) \ $(Q)$(MAKE) -C $(LIBSUBCMD_DIR) O=$(LIBSUBCMD_OUTPUT) \
DESTDIR=$(LIBSUBCMD_DESTDIR) prefix= \ DESTDIR=$(LIBSUBCMD_DESTDIR) prefix= subdir= \
$@ install_headers $@ install_headers
$(LIBSUBCMD)-clean: $(LIBSUBCMD)-clean:
...@@ -855,7 +855,7 @@ $(LIBSUBCMD)-clean: ...@@ -855,7 +855,7 @@ $(LIBSUBCMD)-clean:
$(LIBSYMBOL): FORCE | $(LIBSYMBOL_OUTPUT) $(LIBSYMBOL): FORCE | $(LIBSYMBOL_OUTPUT)
$(Q)$(MAKE) -C $(LIBSYMBOL_DIR) O=$(LIBSYMBOL_OUTPUT) \ $(Q)$(MAKE) -C $(LIBSYMBOL_DIR) O=$(LIBSYMBOL_OUTPUT) \
DESTDIR=$(LIBSYMBOL_DESTDIR) prefix= \ DESTDIR=$(LIBSYMBOL_DESTDIR) prefix= subdir= \
$@ install_headers $@ install_headers
$(LIBSYMBOL)-clean: $(LIBSYMBOL)-clean:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include <elfutils/libdwfl.h> #include <elfutils/libdwfl.h>
#include "../../util/unwind-libdw.h" #include "../../util/unwind-libdw.h"
#include "../../util/perf_regs.h" #include "../../util/perf_regs.h"
#include "../../util/event.h" #include "../../util/sample.h"
bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
{ {
......
...@@ -1670,6 +1670,7 @@ static int __cmd_report(bool display_info) ...@@ -1670,6 +1670,7 @@ static int __cmd_report(bool display_info)
/* for lock function check */ /* for lock function check */
symbol_conf.sort_by_name = true; symbol_conf.sort_by_name = true;
symbol_conf.allow_aliases = true;
symbol__init(&session->header.env); symbol__init(&session->header.env);
if (!data.is_pipe) { if (!data.is_pipe) {
...@@ -1757,6 +1758,7 @@ static int __cmd_contention(int argc, const char **argv) ...@@ -1757,6 +1758,7 @@ static int __cmd_contention(int argc, const char **argv)
/* for lock function check */ /* for lock function check */
symbol_conf.sort_by_name = true; symbol_conf.sort_by_name = true;
symbol_conf.allow_aliases = true;
symbol__init(&session->header.env); symbol__init(&session->header.env);
if (use_bpf) { if (use_bpf) {
......
...@@ -16,20 +16,20 @@ perf-ftrace mainporcelain common ...@@ -16,20 +16,20 @@ perf-ftrace mainporcelain common
perf-inject mainporcelain common perf-inject mainporcelain common
perf-iostat mainporcelain common perf-iostat mainporcelain common
perf-kallsyms mainporcelain common perf-kallsyms mainporcelain common
perf-kmem mainporcelain common perf-kmem mainporcelain traceevent
perf-kvm mainporcelain common perf-kvm mainporcelain common
perf-kwork mainporcelain common perf-kwork mainporcelain traceevent
perf-list mainporcelain common perf-list mainporcelain common
perf-lock mainporcelain common perf-lock mainporcelain traceevent
perf-mem mainporcelain common perf-mem mainporcelain common
perf-probe mainporcelain full perf-probe mainporcelain full
perf-record mainporcelain common perf-record mainporcelain common
perf-report mainporcelain common perf-report mainporcelain common
perf-sched mainporcelain common perf-sched mainporcelain traceevent
perf-script mainporcelain common perf-script mainporcelain common
perf-stat mainporcelain common perf-stat mainporcelain common
perf-test mainporcelain common perf-test mainporcelain common
perf-timechart mainporcelain common perf-timechart mainporcelain traceevent
perf-top mainporcelain common perf-top mainporcelain common
perf-trace mainporcelain audit perf-trace mainporcelain audit
perf-version mainporcelain common perf-version mainporcelain common
......
...@@ -37,6 +37,7 @@ trace_libc_inet_pton_backtrace() { ...@@ -37,6 +37,7 @@ trace_libc_inet_pton_backtrace() {
case "$(uname -m)" in case "$(uname -m)" in
s390x) s390x)
eventattr='call-graph=dwarf,max-stack=4' eventattr='call-graph=dwarf,max-stack=4'
echo "text_to_binary_address.*\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected
echo "gaih_inet.*\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected echo "gaih_inet.*\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected
echo "(__GI_)?getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected echo "(__GI_)?getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected
echo "main\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected echo "main\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected
...@@ -57,7 +58,7 @@ trace_libc_inet_pton_backtrace() { ...@@ -57,7 +58,7 @@ trace_libc_inet_pton_backtrace() {
perf_data=`mktemp -u /tmp/perf.data.XXX` perf_data=`mktemp -u /tmp/perf.data.XXX`
perf_script=`mktemp -u /tmp/perf.script.XXX` perf_script=`mktemp -u /tmp/perf.script.XXX`
perf record -e $event_name/$eventattr/ -o $perf_data ping -6 -c 1 ::1 > /dev/null 2>&1 perf record -e $event_name/$eventattr/ -o $perf_data ping -6 -c 1 ::1 > /dev/null 2>&1
perf script -i $perf_data > $perf_script perf script -i $perf_data | tac | grep -m1 ^ping -B9 | tac > $perf_script
exec 3<$perf_script exec 3<$perf_script
exec 4<$expected exec 4<$expected
......
...@@ -19,7 +19,7 @@ TAG= ...@@ -19,7 +19,7 @@ TAG=
if test -d ../../.git -o -f ../../.git if test -d ../../.git -o -f ../../.git
then then
TAG=$(MAKEFLAGS= make -sC ../.. kernelversion) TAG=$(MAKEFLAGS= make -sC ../.. kernelversion)
CID=$(git log -1 --abbrev=12 --pretty=format:"%h" 2>/dev/null) && CID="-g$CID" CID=$(git log -1 --abbrev=12 --pretty=format:"%h" --no-show-signature 2>/dev/null) && CID="-g$CID"
elif test -f ../../PERF-VERSION-FILE elif test -f ../../PERF-VERSION-FILE
then then
TAG=$(cut -d' ' -f3 ../../PERF-VERSION-FILE | sed -e 's/\"//g') TAG=$(cut -d' ' -f3 ../../PERF-VERSION-FILE | sed -e 's/\"//g')
......
...@@ -116,27 +116,19 @@ static int bperf_load_program(struct evlist *evlist) ...@@ -116,27 +116,19 @@ static int bperf_load_program(struct evlist *evlist)
/* open single copy of the events w/o cgroup */ /* open single copy of the events w/o cgroup */
err = evsel__open_per_cpu(evsel, evsel->core.cpus, -1); err = evsel__open_per_cpu(evsel, evsel->core.cpus, -1);
if (err) { if (err == 0)
pr_err("Failed to open first cgroup events\n"); evsel->supported = true;
goto out;
}
map_fd = bpf_map__fd(skel->maps.events); map_fd = bpf_map__fd(skel->maps.events);
perf_cpu_map__for_each_cpu(cpu, j, evsel->core.cpus) { perf_cpu_map__for_each_cpu(cpu, j, evsel->core.cpus) {
int fd = FD(evsel, j); int fd = FD(evsel, j);
__u32 idx = evsel->core.idx * total_cpus + cpu.cpu; __u32 idx = evsel->core.idx * total_cpus + cpu.cpu;
err = bpf_map_update_elem(map_fd, &idx, &fd, bpf_map_update_elem(map_fd, &idx, &fd, BPF_ANY);
BPF_ANY);
if (err < 0) {
pr_err("Failed to update perf_event fd\n");
goto out;
}
} }
evsel->cgrp = leader_cgrp; evsel->cgrp = leader_cgrp;
} }
evsel->supported = true;
if (evsel->cgrp == cgrp) if (evsel->cgrp == cgrp)
continue; continue;
......
...@@ -224,6 +224,19 @@ static int add_cgroup_name(const char *fpath, const struct stat *sb __maybe_unus ...@@ -224,6 +224,19 @@ static int add_cgroup_name(const char *fpath, const struct stat *sb __maybe_unus
return 0; return 0;
} }
static int check_and_add_cgroup_name(const char *fpath)
{
struct cgroup_name *cn;
list_for_each_entry(cn, &cgroup_list, list) {
if (!strcmp(cn->name, fpath))
return 0;
}
/* pretend if it's added by ftw() */
return add_cgroup_name(fpath, NULL, FTW_D, NULL);
}
static void release_cgroup_list(void) static void release_cgroup_list(void)
{ {
struct cgroup_name *cn; struct cgroup_name *cn;
...@@ -242,7 +255,7 @@ static int list_cgroups(const char *str) ...@@ -242,7 +255,7 @@ static int list_cgroups(const char *str)
struct cgroup_name *cn; struct cgroup_name *cn;
char *s; char *s;
/* use given name as is - for testing purpose */ /* use given name as is when no regex is given */
for (;;) { for (;;) {
p = strchr(str, ','); p = strchr(str, ',');
e = p ? p : eos; e = p ? p : eos;
...@@ -253,13 +266,13 @@ static int list_cgroups(const char *str) ...@@ -253,13 +266,13 @@ static int list_cgroups(const char *str)
s = strndup(str, e - str); s = strndup(str, e - str);
if (!s) if (!s)
return -1; return -1;
/* pretend if it's added by ftw() */
ret = add_cgroup_name(s, NULL, FTW_D, NULL); ret = check_and_add_cgroup_name(s);
free(s); free(s);
if (ret) if (ret < 0)
return -1; return -1;
} else { } else {
if (add_cgroup_name("", NULL, FTW_D, NULL) < 0) if (check_and_add_cgroup_name("/") < 0)
return -1; return -1;
} }
......
...@@ -132,6 +132,7 @@ int perf_data__open_dir(struct perf_data *data) ...@@ -132,6 +132,7 @@ int perf_data__open_dir(struct perf_data *data)
file->size = st.st_size; file->size = st.st_size;
} }
closedir(dir);
if (!files) if (!files)
return -EINVAL; return -EINVAL;
...@@ -140,6 +141,7 @@ int perf_data__open_dir(struct perf_data *data) ...@@ -140,6 +141,7 @@ int perf_data__open_dir(struct perf_data *data)
return 0; return 0;
out_err: out_err:
closedir(dir);
close_dir(files, nr); close_dir(files, nr);
return ret; return ret;
} }
......
...@@ -38,7 +38,7 @@ do ...@@ -38,7 +38,7 @@ do
done done
echo "#endif /* HAVE_LIBELF_SUPPORT */" echo "#endif /* HAVE_LIBELF_SUPPORT */"
echo "#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)" echo "#if defined(HAVE_LIBTRACEEVENT) && (defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT))"
sed -n -e 's/^perf-\([^ ]*\)[ ].* audit*/\1/p' command-list.txt | sed -n -e 's/^perf-\([^ ]*\)[ ].* audit*/\1/p' command-list.txt |
sort | sort |
while read cmd while read cmd
...@@ -51,5 +51,20 @@ do ...@@ -51,5 +51,20 @@ do
p p
}' "Documentation/perf-$cmd.txt" }' "Documentation/perf-$cmd.txt"
done done
echo "#endif /* HAVE_LIBELF_SUPPORT */" echo "#endif /* HAVE_LIBTRACEEVENT && (HAVE_LIBAUDIT_SUPPORT || HAVE_SYSCALL_TABLE_SUPPORT) */"
echo "#ifdef HAVE_LIBTRACEEVENT"
sed -n -e 's/^perf-\([^ ]*\)[ ].* traceevent.*/\1/p' command-list.txt |
sort |
while read cmd
do
sed -n '
/^NAME/,/perf-'"$cmd"'/H
${
x
s/.*perf-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/
p
}' "Documentation/perf-$cmd.txt"
done
echo "#endif /* HAVE_LIBTRACEEVENT */"
echo "};" echo "};"
...@@ -2971,6 +2971,18 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok, ...@@ -2971,6 +2971,18 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok,
ret = add_all_matching_fields(evlist, field_name, raw_trace, level); ret = add_all_matching_fields(evlist, field_name, raw_trace, level);
goto out; goto out;
} }
#else
evlist__for_each_entry(evlist, evsel) {
if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
pr_err("%s %s", ret ? "," : "This perf binary isn't linked with libtraceevent, can't process", evsel__name(evsel));
ret = -ENOTSUP;
}
}
if (ret) {
pr_err("\n");
goto out;
}
#endif #endif
evsel = find_evsel(evlist, event_name); evsel = find_evsel(evlist, event_name);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h>
#include <linux/types.h> #include <linux/types.h>
struct evlist; struct evlist;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment