xref: /linux/tools/perf/builtin-stat.c (revision f850548ef88e5ff9e40bae9e1a7140bef0653e6b)
1 /*
2  * builtin-stat.c
3  *
4  * Builtin stat command: Give a precise performance counters summary
5  * overview about any workload, CPU or specific PID.
6  *
7  * Sample output:
8 
9    $ perf stat ~/hackbench 10
10    Time: 0.104
11 
12     Performance counter stats for '/home/mingo/hackbench':
13 
14        1255.538611  task clock ticks     #      10.143 CPU utilization factor
15              54011  context switches     #       0.043 M/sec
16                385  CPU migrations       #       0.000 M/sec
17              17755  pagefaults           #       0.014 M/sec
18         3808323185  CPU cycles           #    3033.219 M/sec
19         1575111190  instructions         #    1254.530 M/sec
20           17367895  cache references     #      13.833 M/sec
21            7674421  cache misses         #       6.112 M/sec
22 
23     Wall-clock time elapsed:   123.786620 msecs
24 
25  *
26  * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
27  *
28  * Improvements and fixes by:
29  *
30  *   Arjan van de Ven <arjan@linux.intel.com>
31  *   Yanmin Zhang <yanmin.zhang@intel.com>
32  *   Wu Fengguang <fengguang.wu@intel.com>
33  *   Mike Galbraith <efault@gmx.de>
34  *   Paul Mackerras <paulus@samba.org>
35  *   Jaswinder Singh Rajput <jaswinder@kernel.org>
36  *
37  * Released under the GPL v2. (and only v2, not any later version)
38  */
39 
40 #include "perf.h"
41 #include "builtin.h"
42 #include "util/util.h"
43 #include "util/parse-options.h"
44 #include "util/parse-events.h"
45 #include "util/event.h"
46 #include "util/evlist.h"
47 #include "util/evsel.h"
48 #include "util/debug.h"
49 #include "util/header.h"
50 #include "util/cpumap.h"
51 #include "util/thread.h"
52 #include "util/thread_map.h"
53 
54 #include <sys/prctl.h>
55 #include <math.h>
56 #include <locale.h>
57 
58 #define DEFAULT_SEPARATOR	" "
59 
60 static struct perf_event_attr default_attrs[] = {
61 
62   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
63   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
64   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
65   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
66 
67   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
68   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
69   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
70   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
71   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_REFERENCES	},
72   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_MISSES		},
73 
74 };
75 
76 struct perf_evlist		*evsel_list;
77 
78 static bool			system_wide			=  false;
79 static int			run_idx				=  0;
80 
81 static int			run_count			=  1;
82 static bool			no_inherit			= false;
83 static bool			scale				=  true;
84 static bool			no_aggr				= false;
85 static pid_t			target_pid			= -1;
86 static pid_t			target_tid			= -1;
87 static pid_t			child_pid			= -1;
88 static bool			null_run			=  false;
89 static bool			big_num				=  true;
90 static int			big_num_opt			=  -1;
91 static const char		*cpu_list;
92 static const char		*csv_sep			= NULL;
93 static bool			csv_output			= false;
94 
95 static volatile int done = 0;
96 
97 struct stats
98 {
99 	double n, mean, M2;
100 };
101 
102 struct perf_stat {
103 	struct stats	  res_stats[3];
104 };
105 
106 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
107 {
108 	evsel->priv = zalloc(sizeof(struct perf_stat));
109 	return evsel->priv == NULL ? -ENOMEM : 0;
110 }
111 
112 static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
113 {
114 	free(evsel->priv);
115 	evsel->priv = NULL;
116 }
117 
118 static void update_stats(struct stats *stats, u64 val)
119 {
120 	double delta;
121 
122 	stats->n++;
123 	delta = val - stats->mean;
124 	stats->mean += delta / stats->n;
125 	stats->M2 += delta*(val - stats->mean);
126 }
127 
128 static double avg_stats(struct stats *stats)
129 {
130 	return stats->mean;
131 }
132 
133 /*
134  * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
135  *
136  *       (\Sum n_i^2) - ((\Sum n_i)^2)/n
137  * s^2 = -------------------------------
138  *                  n - 1
139  *
140  * http://en.wikipedia.org/wiki/Stddev
141  *
142  * The std dev of the mean is related to the std dev by:
143  *
144  *             s
145  * s_mean = -------
146  *          sqrt(n)
147  *
148  */
149 static double stddev_stats(struct stats *stats)
150 {
151 	double variance = stats->M2 / (stats->n - 1);
152 	double variance_mean = variance / stats->n;
153 
154 	return sqrt(variance_mean);
155 }
156 
157 struct stats			runtime_nsecs_stats[MAX_NR_CPUS];
158 struct stats			runtime_cycles_stats[MAX_NR_CPUS];
159 struct stats			runtime_branches_stats[MAX_NR_CPUS];
160 struct stats			walltime_nsecs_stats;
161 
162 static int create_perf_stat_counter(struct perf_evsel *evsel)
163 {
164 	struct perf_event_attr *attr = &evsel->attr;
165 
166 	if (scale)
167 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
168 				    PERF_FORMAT_TOTAL_TIME_RUNNING;
169 
170 	attr->inherit = !no_inherit;
171 
172 	if (system_wide)
173 		return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, false);
174 
175 	if (target_pid == -1 && target_tid == -1) {
176 		attr->disabled = 1;
177 		attr->enable_on_exec = 1;
178 	}
179 
180 	return perf_evsel__open_per_thread(evsel, evsel_list->threads, false);
181 }
182 
183 /*
184  * Does the counter have nsecs as a unit?
185  */
186 static inline int nsec_counter(struct perf_evsel *evsel)
187 {
188 	if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
189 	    perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
190 		return 1;
191 
192 	return 0;
193 }
194 
195 /*
196  * Read out the results of a single counter:
197  * aggregate counts across CPUs in system-wide mode
198  */
199 static int read_counter_aggr(struct perf_evsel *counter)
200 {
201 	struct perf_stat *ps = counter->priv;
202 	u64 *count = counter->counts->aggr.values;
203 	int i;
204 
205 	if (__perf_evsel__read(counter, evsel_list->cpus->nr,
206 			       evsel_list->threads->nr, scale) < 0)
207 		return -1;
208 
209 	for (i = 0; i < 3; i++)
210 		update_stats(&ps->res_stats[i], count[i]);
211 
212 	if (verbose) {
213 		fprintf(stderr, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
214 			event_name(counter), count[0], count[1], count[2]);
215 	}
216 
217 	/*
218 	 * Save the full runtime - to allow normalization during printout:
219 	 */
220 	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
221 		update_stats(&runtime_nsecs_stats[0], count[0]);
222 	if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
223 		update_stats(&runtime_cycles_stats[0], count[0]);
224 	if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
225 		update_stats(&runtime_branches_stats[0], count[0]);
226 
227 	return 0;
228 }
229 
230 /*
231  * Read out the results of a single counter:
232  * do not aggregate counts across CPUs in system-wide mode
233  */
234 static int read_counter(struct perf_evsel *counter)
235 {
236 	u64 *count;
237 	int cpu;
238 
239 	for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) {
240 		if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0)
241 			return -1;
242 
243 		count = counter->counts->cpu[cpu].values;
244 
245 		if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
246 			update_stats(&runtime_nsecs_stats[cpu], count[0]);
247 		if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
248 			update_stats(&runtime_cycles_stats[cpu], count[0]);
249 		if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
250 			update_stats(&runtime_branches_stats[cpu], count[0]);
251 	}
252 
253 	return 0;
254 }
255 
256 static int run_perf_stat(int argc __used, const char **argv)
257 {
258 	unsigned long long t0, t1;
259 	struct perf_evsel *counter;
260 	int status = 0;
261 	int child_ready_pipe[2], go_pipe[2];
262 	const bool forks = (argc > 0);
263 	char buf;
264 
265 	if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
266 		perror("failed to create pipes");
267 		exit(1);
268 	}
269 
270 	if (forks) {
271 		if ((child_pid = fork()) < 0)
272 			perror("failed to fork");
273 
274 		if (!child_pid) {
275 			close(child_ready_pipe[0]);
276 			close(go_pipe[1]);
277 			fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
278 
279 			/*
280 			 * Do a dummy execvp to get the PLT entry resolved,
281 			 * so we avoid the resolver overhead on the real
282 			 * execvp call.
283 			 */
284 			execvp("", (char **)argv);
285 
286 			/*
287 			 * Tell the parent we're ready to go
288 			 */
289 			close(child_ready_pipe[1]);
290 
291 			/*
292 			 * Wait until the parent tells us to go.
293 			 */
294 			if (read(go_pipe[0], &buf, 1) == -1)
295 				perror("unable to read pipe");
296 
297 			execvp(argv[0], (char **)argv);
298 
299 			perror(argv[0]);
300 			exit(-1);
301 		}
302 
303 		if (target_tid == -1 && target_pid == -1 && !system_wide)
304 			evsel_list->threads->map[0] = child_pid;
305 
306 		/*
307 		 * Wait for the child to be ready to exec.
308 		 */
309 		close(child_ready_pipe[1]);
310 		close(go_pipe[0]);
311 		if (read(child_ready_pipe[0], &buf, 1) == -1)
312 			perror("unable to read pipe");
313 		close(child_ready_pipe[0]);
314 	}
315 
316 	list_for_each_entry(counter, &evsel_list->entries, node) {
317 		if (create_perf_stat_counter(counter) < 0) {
318 			if (errno == -EPERM || errno == -EACCES) {
319 				error("You may not have permission to collect %sstats.\n"
320 				      "\t Consider tweaking"
321 				      " /proc/sys/kernel/perf_event_paranoid or running as root.",
322 				      system_wide ? "system-wide " : "");
323 			} else if (errno == ENOENT) {
324 				error("%s event is not supported. ", event_name(counter));
325 			} else {
326 				error("open_counter returned with %d (%s). "
327 				      "/bin/dmesg may provide additional information.\n",
328 				       errno, strerror(errno));
329 			}
330 			if (child_pid != -1)
331 				kill(child_pid, SIGTERM);
332 			die("Not all events could be opened.\n");
333 			return -1;
334 		}
335 	}
336 
337 	if (perf_evlist__set_filters(evsel_list)) {
338 		error("failed to set filter with %d (%s)\n", errno,
339 			strerror(errno));
340 		return -1;
341 	}
342 
343 	/*
344 	 * Enable counters and exec the command:
345 	 */
346 	t0 = rdclock();
347 
348 	if (forks) {
349 		close(go_pipe[1]);
350 		wait(&status);
351 	} else {
352 		while(!done) sleep(1);
353 	}
354 
355 	t1 = rdclock();
356 
357 	update_stats(&walltime_nsecs_stats, t1 - t0);
358 
359 	if (no_aggr) {
360 		list_for_each_entry(counter, &evsel_list->entries, node) {
361 			read_counter(counter);
362 			perf_evsel__close_fd(counter, evsel_list->cpus->nr, 1);
363 		}
364 	} else {
365 		list_for_each_entry(counter, &evsel_list->entries, node) {
366 			read_counter_aggr(counter);
367 			perf_evsel__close_fd(counter, evsel_list->cpus->nr,
368 					     evsel_list->threads->nr);
369 		}
370 	}
371 
372 	return WEXITSTATUS(status);
373 }
374 
375 static void print_noise(struct perf_evsel *evsel, double avg)
376 {
377 	struct perf_stat *ps;
378 
379 	if (run_count == 1)
380 		return;
381 
382 	ps = evsel->priv;
383 	fprintf(stderr, "   ( +- %7.3f%% )",
384 			100 * stddev_stats(&ps->res_stats[0]) / avg);
385 }
386 
387 static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
388 {
389 	double msecs = avg / 1e6;
390 	char cpustr[16] = { '\0', };
391 	const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-24s";
392 
393 	if (no_aggr)
394 		sprintf(cpustr, "CPU%*d%s",
395 			csv_output ? 0 : -4,
396 			evsel_list->cpus->map[cpu], csv_sep);
397 
398 	fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel));
399 
400 	if (evsel->cgrp)
401 		fprintf(stderr, "%s%s", csv_sep, evsel->cgrp->name);
402 
403 	if (csv_output)
404 		return;
405 
406 	if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
407 		fprintf(stderr, " # %10.3f CPUs ",
408 				avg / avg_stats(&walltime_nsecs_stats));
409 }
410 
411 static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
412 {
413 	double total, ratio = 0.0;
414 	char cpustr[16] = { '\0', };
415 	const char *fmt;
416 
417 	if (csv_output)
418 		fmt = "%s%.0f%s%s";
419 	else if (big_num)
420 		fmt = "%s%'18.0f%s%-24s";
421 	else
422 		fmt = "%s%18.0f%s%-24s";
423 
424 	if (no_aggr)
425 		sprintf(cpustr, "CPU%*d%s",
426 			csv_output ? 0 : -4,
427 			evsel_list->cpus->map[cpu], csv_sep);
428 	else
429 		cpu = 0;
430 
431 	fprintf(stderr, fmt, cpustr, avg, csv_sep, event_name(evsel));
432 
433 	if (evsel->cgrp)
434 		fprintf(stderr, "%s%s", csv_sep, evsel->cgrp->name);
435 
436 	if (csv_output)
437 		return;
438 
439 	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
440 		total = avg_stats(&runtime_cycles_stats[cpu]);
441 
442 		if (total)
443 			ratio = avg / total;
444 
445 		fprintf(stderr, " # %10.3f IPC  ", ratio);
446 	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
447 			runtime_branches_stats[cpu].n != 0) {
448 		total = avg_stats(&runtime_branches_stats[cpu]);
449 
450 		if (total)
451 			ratio = avg * 100 / total;
452 
453 		fprintf(stderr, " # %10.3f %%    ", ratio);
454 
455 	} else if (runtime_nsecs_stats[cpu].n != 0) {
456 		total = avg_stats(&runtime_nsecs_stats[cpu]);
457 
458 		if (total)
459 			ratio = 1000.0 * avg / total;
460 
461 		fprintf(stderr, " # %10.3f M/sec", ratio);
462 	}
463 }
464 
465 /*
466  * Print out the results of a single counter:
467  * aggregated counts in system-wide mode
468  */
469 static void print_counter_aggr(struct perf_evsel *counter)
470 {
471 	struct perf_stat *ps = counter->priv;
472 	double avg = avg_stats(&ps->res_stats[0]);
473 	int scaled = counter->counts->scaled;
474 
475 	if (scaled == -1) {
476 		fprintf(stderr, "%*s%s%*s",
477 			csv_output ? 0 : 18,
478 			"<not counted>",
479 			csv_sep,
480 			csv_output ? 0 : -24,
481 			event_name(counter));
482 
483 		if (counter->cgrp)
484 			fprintf(stderr, "%s%s", csv_sep, counter->cgrp->name);
485 
486 		fputc('\n', stderr);
487 		return;
488 	}
489 
490 	if (nsec_counter(counter))
491 		nsec_printout(-1, counter, avg);
492 	else
493 		abs_printout(-1, counter, avg);
494 
495 	if (csv_output) {
496 		fputc('\n', stderr);
497 		return;
498 	}
499 
500 	print_noise(counter, avg);
501 
502 	if (scaled) {
503 		double avg_enabled, avg_running;
504 
505 		avg_enabled = avg_stats(&ps->res_stats[1]);
506 		avg_running = avg_stats(&ps->res_stats[2]);
507 
508 		fprintf(stderr, "  (scaled from %.2f%%)",
509 				100 * avg_running / avg_enabled);
510 	}
511 	fprintf(stderr, "\n");
512 }
513 
514 /*
515  * Print out the results of a single counter:
516  * does not use aggregated count in system-wide
517  */
518 static void print_counter(struct perf_evsel *counter)
519 {
520 	u64 ena, run, val;
521 	int cpu;
522 
523 	for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) {
524 		val = counter->counts->cpu[cpu].val;
525 		ena = counter->counts->cpu[cpu].ena;
526 		run = counter->counts->cpu[cpu].run;
527 		if (run == 0 || ena == 0) {
528 			fprintf(stderr, "CPU%*d%s%*s%s%*s",
529 				csv_output ? 0 : -4,
530 				evsel_list->cpus->map[cpu], csv_sep,
531 				csv_output ? 0 : 18,
532 				"<not counted>", csv_sep,
533 				csv_output ? 0 : -24,
534 				event_name(counter));
535 
536 			if (counter->cgrp)
537 				fprintf(stderr, "%s%s", csv_sep, counter->cgrp->name);
538 
539 			fputc('\n', stderr);
540 			continue;
541 		}
542 
543 		if (nsec_counter(counter))
544 			nsec_printout(cpu, counter, val);
545 		else
546 			abs_printout(cpu, counter, val);
547 
548 		if (!csv_output) {
549 			print_noise(counter, 1.0);
550 
551 			if (run != ena) {
552 				fprintf(stderr, "  (scaled from %.2f%%)",
553 					100.0 * run / ena);
554 			}
555 		}
556 		fputc('\n', stderr);
557 	}
558 }
559 
560 static void print_stat(int argc, const char **argv)
561 {
562 	struct perf_evsel *counter;
563 	int i;
564 
565 	fflush(stdout);
566 
567 	if (!csv_output) {
568 		fprintf(stderr, "\n");
569 		fprintf(stderr, " Performance counter stats for ");
570 		if(target_pid == -1 && target_tid == -1) {
571 			fprintf(stderr, "\'%s", argv[0]);
572 			for (i = 1; i < argc; i++)
573 				fprintf(stderr, " %s", argv[i]);
574 		} else if (target_pid != -1)
575 			fprintf(stderr, "process id \'%d", target_pid);
576 		else
577 			fprintf(stderr, "thread id \'%d", target_tid);
578 
579 		fprintf(stderr, "\'");
580 		if (run_count > 1)
581 			fprintf(stderr, " (%d runs)", run_count);
582 		fprintf(stderr, ":\n\n");
583 	}
584 
585 	if (no_aggr) {
586 		list_for_each_entry(counter, &evsel_list->entries, node)
587 			print_counter(counter);
588 	} else {
589 		list_for_each_entry(counter, &evsel_list->entries, node)
590 			print_counter_aggr(counter);
591 	}
592 
593 	if (!csv_output) {
594 		fprintf(stderr, "\n");
595 		fprintf(stderr, " %18.9f  seconds time elapsed",
596 				avg_stats(&walltime_nsecs_stats)/1e9);
597 		if (run_count > 1) {
598 			fprintf(stderr, "   ( +- %7.3f%% )",
599 				100*stddev_stats(&walltime_nsecs_stats) /
600 				avg_stats(&walltime_nsecs_stats));
601 		}
602 		fprintf(stderr, "\n\n");
603 	}
604 }
605 
606 static volatile int signr = -1;
607 
608 static void skip_signal(int signo)
609 {
610 	if(child_pid == -1)
611 		done = 1;
612 
613 	signr = signo;
614 }
615 
616 static void sig_atexit(void)
617 {
618 	if (child_pid != -1)
619 		kill(child_pid, SIGTERM);
620 
621 	if (signr == -1)
622 		return;
623 
624 	signal(signr, SIG_DFL);
625 	kill(getpid(), signr);
626 }
627 
628 static const char * const stat_usage[] = {
629 	"perf stat [<options>] [<command>]",
630 	NULL
631 };
632 
633 static int stat__set_big_num(const struct option *opt __used,
634 			     const char *s __used, int unset)
635 {
636 	big_num_opt = unset ? 0 : 1;
637 	return 0;
638 }
639 
640 static const struct option options[] = {
641 	OPT_CALLBACK('e', "event", &evsel_list, "event",
642 		     "event selector. use 'perf list' to list available events",
643 		     parse_events),
644 	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
645 		     "event filter", parse_filter),
646 	OPT_BOOLEAN('i', "no-inherit", &no_inherit,
647 		    "child tasks do not inherit counters"),
648 	OPT_INTEGER('p', "pid", &target_pid,
649 		    "stat events on existing process id"),
650 	OPT_INTEGER('t', "tid", &target_tid,
651 		    "stat events on existing thread id"),
652 	OPT_BOOLEAN('a', "all-cpus", &system_wide,
653 		    "system-wide collection from all CPUs"),
654 	OPT_BOOLEAN('c', "scale", &scale,
655 		    "scale/normalize counters"),
656 	OPT_INCR('v', "verbose", &verbose,
657 		    "be more verbose (show counter open errors, etc)"),
658 	OPT_INTEGER('r', "repeat", &run_count,
659 		    "repeat command and print average + stddev (max: 100)"),
660 	OPT_BOOLEAN('n', "null", &null_run,
661 		    "null run - dont start any counters"),
662 	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
663 			   "print large numbers with thousands\' separators",
664 			   stat__set_big_num),
665 	OPT_STRING('C', "cpu", &cpu_list, "cpu",
666 		    "list of cpus to monitor in system-wide"),
667 	OPT_BOOLEAN('A', "no-aggr", &no_aggr,
668 		    "disable CPU count aggregation"),
669 	OPT_STRING('x', "field-separator", &csv_sep, "separator",
670 		   "print counts with custom separator"),
671 	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
672 		     "monitor event in cgroup name only",
673 		     parse_cgroups),
674 	OPT_END()
675 };
676 
677 int cmd_stat(int argc, const char **argv, const char *prefix __used)
678 {
679 	struct perf_evsel *pos;
680 	int status = -ENOMEM;
681 
682 	setlocale(LC_ALL, "");
683 
684 	evsel_list = perf_evlist__new(NULL, NULL);
685 	if (evsel_list == NULL)
686 		return -ENOMEM;
687 
688 	argc = parse_options(argc, argv, options, stat_usage,
689 		PARSE_OPT_STOP_AT_NON_OPTION);
690 
691 	if (csv_sep)
692 		csv_output = true;
693 	else
694 		csv_sep = DEFAULT_SEPARATOR;
695 
696 	/*
697 	 * let the spreadsheet do the pretty-printing
698 	 */
699 	if (csv_output) {
700 		/* User explicitely passed -B? */
701 		if (big_num_opt == 1) {
702 			fprintf(stderr, "-B option not supported with -x\n");
703 			usage_with_options(stat_usage, options);
704 		} else /* Nope, so disable big number formatting */
705 			big_num = false;
706 	} else if (big_num_opt == 0) /* User passed --no-big-num */
707 		big_num = false;
708 
709 	if (!argc && target_pid == -1 && target_tid == -1)
710 		usage_with_options(stat_usage, options);
711 	if (run_count <= 0)
712 		usage_with_options(stat_usage, options);
713 
714 	/* no_aggr, cgroup are for system-wide only */
715 	if ((no_aggr || nr_cgroups) && !system_wide) {
716 		fprintf(stderr, "both cgroup and no-aggregation "
717 			"modes only available in system-wide mode\n");
718 
719 		usage_with_options(stat_usage, options);
720 	}
721 
722 	/* Set attrs and nr_counters if no event is selected and !null_run */
723 	if (!null_run && !evsel_list->nr_entries) {
724 		size_t c;
725 
726 		for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) {
727 			pos = perf_evsel__new(&default_attrs[c], c);
728 			if (pos == NULL)
729 				goto out;
730 			perf_evlist__add(evsel_list, pos);
731 		}
732 	}
733 
734 	if (target_pid != -1)
735 		target_tid = target_pid;
736 
737 	evsel_list->threads = thread_map__new(target_pid, target_tid);
738 	if (evsel_list->threads == NULL) {
739 		pr_err("Problems finding threads of monitor\n");
740 		usage_with_options(stat_usage, options);
741 	}
742 
743 	if (system_wide)
744 		evsel_list->cpus = cpu_map__new(cpu_list);
745 	else
746 		evsel_list->cpus = cpu_map__dummy_new();
747 
748 	if (evsel_list->cpus == NULL) {
749 		perror("failed to parse CPUs map");
750 		usage_with_options(stat_usage, options);
751 		return -1;
752 	}
753 
754 	list_for_each_entry(pos, &evsel_list->entries, node) {
755 		if (perf_evsel__alloc_stat_priv(pos) < 0 ||
756 		    perf_evsel__alloc_counts(pos, evsel_list->cpus->nr) < 0 ||
757 		    perf_evsel__alloc_fd(pos, evsel_list->cpus->nr, evsel_list->threads->nr) < 0)
758 			goto out_free_fd;
759 	}
760 
761 	/*
762 	 * We dont want to block the signals - that would cause
763 	 * child tasks to inherit that and Ctrl-C would not work.
764 	 * What we want is for Ctrl-C to work in the exec()-ed
765 	 * task, but being ignored by perf stat itself:
766 	 */
767 	atexit(sig_atexit);
768 	signal(SIGINT,  skip_signal);
769 	signal(SIGALRM, skip_signal);
770 	signal(SIGABRT, skip_signal);
771 
772 	status = 0;
773 	for (run_idx = 0; run_idx < run_count; run_idx++) {
774 		if (run_count != 1 && verbose)
775 			fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1);
776 		status = run_perf_stat(argc, argv);
777 	}
778 
779 	if (status != -1)
780 		print_stat(argc, argv);
781 out_free_fd:
782 	list_for_each_entry(pos, &evsel_list->entries, node)
783 		perf_evsel__free_stat_priv(pos);
784 	perf_evlist__delete_maps(evsel_list);
785 out:
786 	perf_evlist__delete(evsel_list);
787 	return status;
788 }
789