diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 6aae10ff954c72847d9648e25e45e7b1d2a7ea1e..cbb9fac27fa7625f9318c29d25f7ce9000613d3a 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 4fad92213609f3923a12daf74df70caf412765e3..66242ac676cb0d3754446b49eb65e8ea5a04b0da 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,