diff options
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r-- | tools/perf/builtin-stat.c | 86 |
1 files changed, 38 insertions, 48 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 1e5e9b270f5e..62ae30d34fa6 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -173,24 +173,23 @@ static struct perf_event_attr very_very_detailed_attrs[] = { | |||
173 | 173 | ||
174 | 174 | ||
175 | 175 | ||
176 | struct perf_evlist *evsel_list; | 176 | static struct perf_evlist *evsel_list; |
177 | 177 | ||
178 | static bool system_wide = false; | 178 | static struct perf_target target = { |
179 | static int run_idx = 0; | 179 | .uid = UINT_MAX, |
180 | }; | ||
180 | 181 | ||
182 | static int run_idx = 0; | ||
181 | static int run_count = 1; | 183 | static int run_count = 1; |
182 | static bool no_inherit = false; | 184 | static bool no_inherit = false; |
183 | static bool scale = true; | 185 | static bool scale = true; |
184 | static bool no_aggr = false; | 186 | static bool no_aggr = false; |
185 | static const char *target_pid; | ||
186 | static const char *target_tid; | ||
187 | static pid_t child_pid = -1; | 187 | static pid_t child_pid = -1; |
188 | static bool null_run = false; | 188 | static bool null_run = false; |
189 | static int detailed_run = 0; | 189 | static int detailed_run = 0; |
190 | static bool sync_run = false; | 190 | static bool sync_run = false; |
191 | static bool big_num = true; | 191 | static bool big_num = true; |
192 | static int big_num_opt = -1; | 192 | static int big_num_opt = -1; |
193 | static const char *cpu_list; | ||
194 | static const char *csv_sep = NULL; | 193 | static const char *csv_sep = NULL; |
195 | static bool csv_output = false; | 194 | static bool csv_output = false; |
196 | static bool group = false; | 195 | static bool group = false; |
@@ -265,18 +264,18 @@ static double stddev_stats(struct stats *stats) | |||
265 | return sqrt(variance_mean); | 264 | return sqrt(variance_mean); |
266 | } | 265 | } |
267 | 266 | ||
268 | struct stats runtime_nsecs_stats[MAX_NR_CPUS]; | 267 | static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; |
269 | struct stats runtime_cycles_stats[MAX_NR_CPUS]; | 268 | static struct stats runtime_cycles_stats[MAX_NR_CPUS]; |
270 | struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS]; | 269 | static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS]; |
271 | struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS]; | 270 | static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS]; |
272 | struct stats runtime_branches_stats[MAX_NR_CPUS]; | 271 | static struct stats runtime_branches_stats[MAX_NR_CPUS]; |
273 | struct stats runtime_cacherefs_stats[MAX_NR_CPUS]; | 272 | static struct stats runtime_cacherefs_stats[MAX_NR_CPUS]; |
274 | struct stats runtime_l1_dcache_stats[MAX_NR_CPUS]; | 273 | static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS]; |
275 | struct stats runtime_l1_icache_stats[MAX_NR_CPUS]; | 274 | static struct stats runtime_l1_icache_stats[MAX_NR_CPUS]; |
276 | struct stats runtime_ll_cache_stats[MAX_NR_CPUS]; | 275 | static struct stats runtime_ll_cache_stats[MAX_NR_CPUS]; |
277 | struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; | 276 | static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; |
278 | struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; | 277 | static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; |
279 | struct stats walltime_nsecs_stats; | 278 | static struct stats walltime_nsecs_stats; |
280 | 279 | ||
281 | static int create_perf_stat_counter(struct perf_evsel *evsel, | 280 | static int create_perf_stat_counter(struct perf_evsel *evsel, |
282 | struct perf_evsel *first) | 281 | struct perf_evsel *first) |
@@ -299,15 +298,15 @@ retry: | |||
299 | if (exclude_guest_missing) | 298 | if (exclude_guest_missing) |
300 | evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; | 299 | evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; |
301 | 300 | ||
302 | if (system_wide) { | 301 | if (perf_target__has_cpu(&target)) { |
303 | ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus, | 302 | ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus, |
304 | group, group_fd); | 303 | group, group_fd); |
305 | if (ret) | 304 | if (ret) |
306 | goto check_ret; | 305 | goto check_ret; |
307 | return 0; | 306 | return 0; |
308 | } | 307 | } |
309 | 308 | ||
310 | if (!target_pid && !target_tid && (!group || evsel == first)) { | 309 | if (!perf_target__has_task(&target) && (!group || evsel == first)) { |
311 | attr->disabled = 1; | 310 | attr->disabled = 1; |
312 | attr->enable_on_exec = 1; | 311 | attr->enable_on_exec = 1; |
313 | } | 312 | } |
@@ -471,7 +470,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
471 | exit(-1); | 470 | exit(-1); |
472 | } | 471 | } |
473 | 472 | ||
474 | if (!target_tid && !target_pid && !system_wide) | 473 | if (perf_target__none(&target)) |
475 | evsel_list->threads->map[0] = child_pid; | 474 | evsel_list->threads->map[0] = child_pid; |
476 | 475 | ||
477 | /* | 476 | /* |
@@ -506,7 +505,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
506 | error("You may not have permission to collect %sstats.\n" | 505 | error("You may not have permission to collect %sstats.\n" |
507 | "\t Consider tweaking" | 506 | "\t Consider tweaking" |
508 | " /proc/sys/kernel/perf_event_paranoid or running as root.", | 507 | " /proc/sys/kernel/perf_event_paranoid or running as root.", |
509 | system_wide ? "system-wide " : ""); | 508 | target.system_wide ? "system-wide " : ""); |
510 | } else { | 509 | } else { |
511 | error("open_counter returned with %d (%s). " | 510 | error("open_counter returned with %d (%s). " |
512 | "/bin/dmesg may provide additional information.\n", | 511 | "/bin/dmesg may provide additional information.\n", |
@@ -998,14 +997,14 @@ static void print_stat(int argc, const char **argv) | |||
998 | if (!csv_output) { | 997 | if (!csv_output) { |
999 | fprintf(output, "\n"); | 998 | fprintf(output, "\n"); |
1000 | fprintf(output, " Performance counter stats for "); | 999 | fprintf(output, " Performance counter stats for "); |
1001 | if (!target_pid && !target_tid) { | 1000 | if (!perf_target__has_task(&target)) { |
1002 | fprintf(output, "\'%s", argv[0]); | 1001 | fprintf(output, "\'%s", argv[0]); |
1003 | for (i = 1; i < argc; i++) | 1002 | for (i = 1; i < argc; i++) |
1004 | fprintf(output, " %s", argv[i]); | 1003 | fprintf(output, " %s", argv[i]); |
1005 | } else if (target_pid) | 1004 | } else if (target.pid) |
1006 | fprintf(output, "process id \'%s", target_pid); | 1005 | fprintf(output, "process id \'%s", target.pid); |
1007 | else | 1006 | else |
1008 | fprintf(output, "thread id \'%s", target_tid); | 1007 | fprintf(output, "thread id \'%s", target.tid); |
1009 | 1008 | ||
1010 | fprintf(output, "\'"); | 1009 | fprintf(output, "\'"); |
1011 | if (run_count > 1) | 1010 | if (run_count > 1) |
@@ -1079,11 +1078,11 @@ static const struct option options[] = { | |||
1079 | "event filter", parse_filter), | 1078 | "event filter", parse_filter), |
1080 | OPT_BOOLEAN('i', "no-inherit", &no_inherit, | 1079 | OPT_BOOLEAN('i', "no-inherit", &no_inherit, |
1081 | "child tasks do not inherit counters"), | 1080 | "child tasks do not inherit counters"), |
1082 | OPT_STRING('p', "pid", &target_pid, "pid", | 1081 | OPT_STRING('p', "pid", &target.pid, "pid", |
1083 | "stat events on existing process id"), | 1082 | "stat events on existing process id"), |
1084 | OPT_STRING('t', "tid", &target_tid, "tid", | 1083 | OPT_STRING('t', "tid", &target.tid, "tid", |
1085 | "stat events on existing thread id"), | 1084 | "stat events on existing thread id"), |
1086 | OPT_BOOLEAN('a', "all-cpus", &system_wide, | 1085 | OPT_BOOLEAN('a', "all-cpus", &target.system_wide, |
1087 | "system-wide collection from all CPUs"), | 1086 | "system-wide collection from all CPUs"), |
1088 | OPT_BOOLEAN('g', "group", &group, | 1087 | OPT_BOOLEAN('g', "group", &group, |
1089 | "put the counters into a counter group"), | 1088 | "put the counters into a counter group"), |
@@ -1102,7 +1101,7 @@ static const struct option options[] = { | |||
1102 | OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, | 1101 | OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, |
1103 | "print large numbers with thousands\' separators", | 1102 | "print large numbers with thousands\' separators", |
1104 | stat__set_big_num), | 1103 | stat__set_big_num), |
1105 | OPT_STRING('C', "cpu", &cpu_list, "cpu", | 1104 | OPT_STRING('C', "cpu", &target.cpu_list, "cpu", |
1106 | "list of cpus to monitor in system-wide"), | 1105 | "list of cpus to monitor in system-wide"), |
1107 | OPT_BOOLEAN('A', "no-aggr", &no_aggr, | 1106 | OPT_BOOLEAN('A', "no-aggr", &no_aggr, |
1108 | "disable CPU count aggregation"), | 1107 | "disable CPU count aggregation"), |
@@ -1220,13 +1219,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
1220 | } else if (big_num_opt == 0) /* User passed --no-big-num */ | 1219 | } else if (big_num_opt == 0) /* User passed --no-big-num */ |
1221 | big_num = false; | 1220 | big_num = false; |
1222 | 1221 | ||
1223 | if (!argc && !target_pid && !target_tid) | 1222 | if (!argc && !perf_target__has_task(&target)) |
1224 | usage_with_options(stat_usage, options); | 1223 | usage_with_options(stat_usage, options); |
1225 | if (run_count <= 0) | 1224 | if (run_count <= 0) |
1226 | usage_with_options(stat_usage, options); | 1225 | usage_with_options(stat_usage, options); |
1227 | 1226 | ||
1228 | /* no_aggr, cgroup are for system-wide only */ | 1227 | /* no_aggr, cgroup are for system-wide only */ |
1229 | if ((no_aggr || nr_cgroups) && !system_wide) { | 1228 | if ((no_aggr || nr_cgroups) && !perf_target__has_cpu(&target)) { |
1230 | fprintf(stderr, "both cgroup and no-aggregation " | 1229 | fprintf(stderr, "both cgroup and no-aggregation " |
1231 | "modes only available in system-wide mode\n"); | 1230 | "modes only available in system-wide mode\n"); |
1232 | 1231 | ||
@@ -1236,23 +1235,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
1236 | if (add_default_attributes()) | 1235 | if (add_default_attributes()) |
1237 | goto out; | 1236 | goto out; |
1238 | 1237 | ||
1239 | if (target_pid) | 1238 | perf_target__validate(&target); |
1240 | target_tid = target_pid; | ||
1241 | 1239 | ||
1242 | evsel_list->threads = thread_map__new_str(target_pid, | 1240 | if (perf_evlist__create_maps(evsel_list, &target) < 0) { |
1243 | target_tid, UINT_MAX); | 1241 | if (perf_target__has_task(&target)) |
1244 | if (evsel_list->threads == NULL) { | 1242 | pr_err("Problems finding threads of monitor\n"); |
1245 | pr_err("Problems finding threads of monitor\n"); | 1243 | if (perf_target__has_cpu(&target)) |
1246 | usage_with_options(stat_usage, options); | 1244 | perror("failed to parse CPUs map"); |
1247 | } | ||
1248 | |||
1249 | if (system_wide) | ||
1250 | evsel_list->cpus = cpu_map__new(cpu_list); | ||
1251 | else | ||
1252 | evsel_list->cpus = cpu_map__dummy_new(); | ||
1253 | 1245 | ||
1254 | if (evsel_list->cpus == NULL) { | ||
1255 | perror("failed to parse CPUs map"); | ||
1256 | usage_with_options(stat_usage, options); | 1246 | usage_with_options(stat_usage, options); |
1257 | return -1; | 1247 | return -1; |
1258 | } | 1248 | } |