aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c86
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
176struct perf_evlist *evsel_list; 176static struct perf_evlist *evsel_list;
177 177
178static bool system_wide = false; 178static struct perf_target target = {
179static int run_idx = 0; 179 .uid = UINT_MAX,
180};
180 181
182static int run_idx = 0;
181static int run_count = 1; 183static int run_count = 1;
182static bool no_inherit = false; 184static bool no_inherit = false;
183static bool scale = true; 185static bool scale = true;
184static bool no_aggr = false; 186static bool no_aggr = false;
185static const char *target_pid;
186static const char *target_tid;
187static pid_t child_pid = -1; 187static pid_t child_pid = -1;
188static bool null_run = false; 188static bool null_run = false;
189static int detailed_run = 0; 189static int detailed_run = 0;
190static bool sync_run = false; 190static bool sync_run = false;
191static bool big_num = true; 191static bool big_num = true;
192static int big_num_opt = -1; 192static int big_num_opt = -1;
193static const char *cpu_list;
194static const char *csv_sep = NULL; 193static const char *csv_sep = NULL;
195static bool csv_output = false; 194static bool csv_output = false;
196static bool group = false; 195static 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
268struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 267static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
269struct stats runtime_cycles_stats[MAX_NR_CPUS]; 268static struct stats runtime_cycles_stats[MAX_NR_CPUS];
270struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS]; 269static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
271struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS]; 270static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS];
272struct stats runtime_branches_stats[MAX_NR_CPUS]; 271static struct stats runtime_branches_stats[MAX_NR_CPUS];
273struct stats runtime_cacherefs_stats[MAX_NR_CPUS]; 272static struct stats runtime_cacherefs_stats[MAX_NR_CPUS];
274struct stats runtime_l1_dcache_stats[MAX_NR_CPUS]; 273static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS];
275struct stats runtime_l1_icache_stats[MAX_NR_CPUS]; 274static struct stats runtime_l1_icache_stats[MAX_NR_CPUS];
276struct stats runtime_ll_cache_stats[MAX_NR_CPUS]; 275static struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
277struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; 276static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
278struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; 277static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
279struct stats walltime_nsecs_stats; 278static struct stats walltime_nsecs_stats;
280 279
281static int create_perf_stat_counter(struct perf_evsel *evsel, 280static 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 }