From a198fdc52ad48ad1b78b1543aad3eb289a39388d Mon Sep 17 00:00:00 2001 From: Li Linhang Date: Wed, 19 Mar 2025 12:57:20 +0800 Subject: [PATCH] anolis: perf stat: Enable and fix on "enable ignore_missing_thread" on perf 5.10 ANBZ: #19874 This patch enables and fixes ignore_missing_thread for perf stat by cherry-picking commit 448ce0e6ea93ae99e0b36055e5f5a3f723fe3665, and making it work on multiple-event monitoring case. The commit 448ce0e enables ignore_missing_thread on perf stat, but only enables it on the first evsel in evlist. It works only when thread dies before the first event is opened. When a thread dies when opening the following events while monitoring more than one events, perf still returns a sys_perf_event_open failure with 3(No such process). This patch makes it work on all events, by enable ignore_missing_thread on all evsels, and fix fd using when fd is removed by ignore_missing_thread. Signed-off-by: Li Linhang --- tools/lib/perf/evsel.c | 10 +++++++--- tools/perf/builtin-stat.c | 5 +++++ tools/perf/util/evsel.c | 6 +++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c index 1c28c7cc06ca..742ae0a7f28e 100644 --- a/tools/lib/perf/evsel.c +++ b/tools/lib/perf/evsel.c @@ -204,11 +204,15 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ioc, void *arg, int cpu) { - int thread; + int thread, err; for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { - int fd = FD(evsel, cpu, thread), - err = ioctl(fd, ioc, arg); + int fd = FD(evsel, cpu, thread); + + if (fd < 0) + return -1; + + err = ioctl(fd, ioc, arg); if (err) return err; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 5782ca279fc4..7c16cbf7f95a 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2090,6 +2090,7 @@ int cmd_stat(int argc, const char **argv) FILE *output = stderr; unsigned int interval, timeout; const char * const stat_subcommands[] = { "record", "report" }; + struct evsel *evsel; setlocale(LC_ALL, ""); @@ -2376,6 +2377,10 @@ 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__for_each_entry(evsel_list, evsel) { + evsel->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) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 073682703fcc..7cf22ae199b8 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1605,9 +1605,11 @@ static int get_group_fd(struct evsel *evsel, int cpu, int thread) static void evsel__remove_fd(struct evsel *pos, int nr_cpus, int nr_threads, int thread_idx) { - for (int cpu = 0; cpu < nr_cpus; cpu++) + for (int cpu = 0; cpu < nr_cpus; cpu++) { for (int thread = thread_idx; thread < nr_threads - 1; thread++) FD(pos, cpu, thread) = FD(pos, cpu, thread + 1); + FD(pos, cpu, nr_threads - 1) = -1; + } } static int update_fds(struct evsel *evsel, @@ -2820,6 +2822,8 @@ static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist) for (thread = 0; thread < xyarray__max_y(evsel->core.fd); thread++) { int fd = FD(evsel, cpu, thread); + if (fd < 0) + continue; if (perf_evlist__id_add_fd(&evlist->core, &evsel->core, cpu, thread, fd) < 0) -- Gitee