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>
This commit is contained in:
parent
73c0ca1eee
commit
1d9f8d1b82
|
@ -277,7 +277,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
|
||||||
attr->enable_on_exec = 1;
|
attr->enable_on_exec = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target__has_cpu(&target))
|
if (target__has_cpu(&target) && !target__has_per_thread(&target))
|
||||||
return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
|
return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
|
||||||
|
|
||||||
return perf_evsel__open_per_thread(evsel, evsel_list->threads);
|
return perf_evsel__open_per_thread(evsel, evsel_list->threads);
|
||||||
|
@ -340,7 +340,7 @@ static int read_counter(struct perf_evsel *counter)
|
||||||
int nthreads = thread_map__nr(evsel_list->threads);
|
int nthreads = thread_map__nr(evsel_list->threads);
|
||||||
int ncpus, cpu, thread;
|
int ncpus, cpu, thread;
|
||||||
|
|
||||||
if (target__has_cpu(&target))
|
if (target__has_cpu(&target) && !target__has_per_thread(&target))
|
||||||
ncpus = perf_evsel__nr_cpus(counter);
|
ncpus = perf_evsel__nr_cpus(counter);
|
||||||
else
|
else
|
||||||
ncpus = 1;
|
ncpus = 1;
|
||||||
|
@ -2743,12 +2743,16 @@ int cmd_stat(int argc, const char **argv)
|
||||||
run_count = 1;
|
run_count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) {
|
if ((stat_config.aggr_mode == AGGR_THREAD) &&
|
||||||
fprintf(stderr, "The --per-thread option is only available "
|
!target__has_task(&target)) {
|
||||||
"when monitoring via -p -t options.\n");
|
if (!target.system_wide || target.cpu_list) {
|
||||||
parse_options_usage(NULL, stat_options, "p", 1);
|
fprintf(stderr, "The --per-thread option is only "
|
||||||
parse_options_usage(NULL, stat_options, "t", 1);
|
"available when monitoring via -p -t -a "
|
||||||
goto out;
|
"options or only --per-thread.\n");
|
||||||
|
parse_options_usage(NULL, stat_options, "p", 1);
|
||||||
|
parse_options_usage(NULL, stat_options, "t", 1);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2772,6 +2776,9 @@ int cmd_stat(int argc, const char **argv)
|
||||||
|
|
||||||
target__validate(&target);
|
target__validate(&target);
|
||||||
|
|
||||||
|
if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide))
|
||||||
|
target.per_thread = true;
|
||||||
|
|
||||||
if (perf_evlist__create_maps(evsel_list, &target) < 0) {
|
if (perf_evlist__create_maps(evsel_list, &target) < 0) {
|
||||||
if (target__has_task(&target)) {
|
if (target__has_task(&target)) {
|
||||||
pr_err("Problems finding threads of monitor\n");
|
pr_err("Problems finding threads of monitor\n");
|
||||||
|
|
|
@ -64,6 +64,11 @@ static inline bool target__none(struct target *target)
|
||||||
return !target__has_task(target) && !target__has_cpu(target);
|
return !target__has_task(target) && !target__has_cpu(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool target__has_per_thread(struct target *target)
|
||||||
|
{
|
||||||
|
return target->system_wide && target->per_thread;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool target__uses_dummy_map(struct target *target)
|
static inline bool target__uses_dummy_map(struct target *target)
|
||||||
{
|
{
|
||||||
bool use_dummy = false;
|
bool use_dummy = false;
|
||||||
|
@ -73,6 +78,8 @@ static inline bool target__uses_dummy_map(struct target *target)
|
||||||
else if (target__has_task(target) ||
|
else if (target__has_task(target) ||
|
||||||
(!target__has_cpu(target) && !target->uses_mmap))
|
(!target__has_cpu(target) && !target->uses_mmap))
|
||||||
use_dummy = true;
|
use_dummy = true;
|
||||||
|
else if (target__has_per_thread(target))
|
||||||
|
use_dummy = true;
|
||||||
|
|
||||||
return use_dummy;
|
return use_dummy;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue