Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf stat: Remove --per-thread pid/tid limitation

Currently, if we execute 'perf stat --per-thread' without specifying
pid/tid, perf will return error.

root@skl:/tmp# perf stat --per-thread
The --per-thread option is only available when monitoring via -p -t options.
-p, --pid <pid> stat events on existing process id
-t, --tid <tid> stat events on existing thread id

This patch removes this limitation. If no pid/tid specified, it returns
all threads (get threads from /proc).

Note that it doesn't support cpu_list yet so if it's a cpu_list case,
then skip.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1512482591-4646-11-git-send-email-yao.jin@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jin Yao and committed by
Arnaldo Carvalho de Melo
1d9f8d1b 73c0ca1e

+22 -8
+15 -8
tools/perf/builtin-stat.c
··· 277 277 attr->enable_on_exec = 1; 278 278 } 279 279 280 - if (target__has_cpu(&target)) 280 + if (target__has_cpu(&target) && !target__has_per_thread(&target)) 281 281 return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); 282 282 283 283 return perf_evsel__open_per_thread(evsel, evsel_list->threads); ··· 340 340 int nthreads = thread_map__nr(evsel_list->threads); 341 341 int ncpus, cpu, thread; 342 342 343 - if (target__has_cpu(&target)) 343 + if (target__has_cpu(&target) && !target__has_per_thread(&target)) 344 344 ncpus = perf_evsel__nr_cpus(counter); 345 345 else 346 346 ncpus = 1; ··· 2743 2743 run_count = 1; 2744 2744 } 2745 2745 2746 - if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) { 2747 - fprintf(stderr, "The --per-thread option is only available " 2748 - "when monitoring via -p -t options.\n"); 2749 - parse_options_usage(NULL, stat_options, "p", 1); 2750 - parse_options_usage(NULL, stat_options, "t", 1); 2751 - goto out; 2746 + if ((stat_config.aggr_mode == AGGR_THREAD) && 2747 + !target__has_task(&target)) { 2748 + if (!target.system_wide || target.cpu_list) { 2749 + fprintf(stderr, "The --per-thread option is only " 2750 + "available when monitoring via -p -t -a " 2751 + "options or only --per-thread.\n"); 2752 + parse_options_usage(NULL, stat_options, "p", 1); 2753 + parse_options_usage(NULL, stat_options, "t", 1); 2754 + goto out; 2755 + } 2752 2756 } 2753 2757 2754 2758 /* ··· 2775 2771 goto out; 2776 2772 2777 2773 target__validate(&target); 2774 + 2775 + if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide)) 2776 + target.per_thread = true; 2778 2777 2779 2778 if (perf_evlist__create_maps(evsel_list, &target) < 0) { 2780 2779 if (target__has_task(&target)) {
+7
tools/perf/util/target.h
··· 64 64 return !target__has_task(target) && !target__has_cpu(target); 65 65 } 66 66 67 + static inline bool target__has_per_thread(struct target *target) 68 + { 69 + return target->system_wide && target->per_thread; 70 + } 71 + 67 72 static inline bool target__uses_dummy_map(struct target *target) 68 73 { 69 74 bool use_dummy = false; ··· 77 72 use_dummy = target->per_thread ? true : false; 78 73 else if (target__has_task(target) || 79 74 (!target__has_cpu(target) && !target->uses_mmap)) 75 + use_dummy = true; 76 + else if (target__has_per_thread(target)) 80 77 use_dummy = true; 81 78 82 79 return use_dummy;