diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index fadcff52cd0944e7501b761a855e18e8771e2965..6214d2b220b29db937e8f2faf8082d243cb1afe2 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -637,7 +637,19 @@ static int __run_perf_stat(int argc, const char **argv) if (verbose > 0) ui__warning("%s\n", msg); goto try_again; - } + } else if (target__has_per_thread(&target) && + evsel_list->threads && + evsel_list->threads->err_thread != -1) { + /* + * For global --per-thread case, skip current + * error thread. + */ + if (!thread_map__remove(evsel_list->threads, + evsel_list->threads->err_thread)) { + evsel_list->threads->err_thread = -1; + goto try_again; + } + } perf_evsel__open_strerror(counter, &target, errno, msg, sizeof(msg)); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ef351688b79798a1c46b95094fb078c6daee14aa..b56e1c2ddaee2e320a7ce437434557f901a8dc47 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1915,6 +1915,9 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, goto fallback_missing_features; } out_close: + if (err) + threads->err_thread = thread; + do { while (--thread >= 0) { close(FD(evsel, cpu, thread)); diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 729dad8f412d62ac700a8801ffc79c67c8025bc6..5d467d8ae9abf9bee19b5cb02b01d1849af5f32d 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -32,6 +32,7 @@ static void thread_map__reset(struct thread_map *map, int start, int nr) size_t size = (nr - start) * sizeof(map->map[0]); memset(&map->map[start], 0, size); + map->err_thread = -1; } static struct thread_map *thread_map__realloc(struct thread_map *map, int nr) diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index 5ec91cfd18696b9f1efccdf824bfc4a9ec32b122..2f689c90a8c6d59c5e52a7d2627c9c793df55834 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -14,6 +14,7 @@ struct thread_map_data { struct thread_map { refcount_t refcnt; int nr; + int err_thread; struct thread_map_data map[]; };