From a5b883bc00b37971bd0889d0eb45bb5d420c88dd Mon Sep 17 00:00:00 2001 From: Li Linhang Date: Tue, 15 Apr 2025 11:43:53 +0800 Subject: [PATCH] anolis: perf stat: Enable and fix on "enable ignore_missing_thread" on perf 4.19 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/perf/builtin-stat.c | 8 ++++++++ tools/perf/util/evsel.c | 17 ++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 6aae10ff954c..cbb9fac27fa7 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -517,6 +517,8 @@ static int __store_counter_ids(struct perf_evsel *counter) for (thread = 0; thread < xyarray__max_y(counter->fd); thread++) { int fd = FD(counter, cpu, thread); + if (fd < 0) + continue; if (perf_evlist__id_add_fd(evsel_list, counter, cpu, thread, fd) < 0) @@ -2839,6 +2841,7 @@ int cmd_stat(int argc, const char **argv) FILE *output = stderr; unsigned int interval, timeout; const char * const stat_subcommands[] = { "record", "report" }; + struct perf_evsel *counter; setlocale(LC_ALL, ""); @@ -3084,6 +3087,11 @@ int cmd_stat(int argc, const char **argv) signal(SIGALRM, skip_signal); signal(SIGABRT, skip_signal); + /* Enable ignoring missing threads when -p option is defined. */ + evlist__for_each_entry(evsel_list, counter) { + counter->ignore_missing_thread = target.pid; + } + status = 0; for (run_idx = 0; forever || run_idx < run_count; run_idx++) { if (run_count != 1 && verbose > 0) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 4fad92213609..66242ac676cb 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1144,12 +1144,16 @@ static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthread static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ioc, void *arg) { - int cpu, thread; + int cpu, thread, err; for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { 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; @@ -1271,7 +1275,8 @@ void perf_evsel__close_fd(struct perf_evsel *evsel) for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) { - close(FD(evsel, cpu, thread)); + if (FD(evsel, cpu, thread) >= 0) + close(FD(evsel, cpu, thread)); FD(evsel, cpu, thread) = -1; } } @@ -1670,9 +1675,11 @@ static void perf_evsel__remove_fd(struct perf_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 perf_evsel *evsel, -- Gitee