xref: /openbmc/linux/tools/perf/builtin-stat.c (revision ecd25094)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * builtin-stat.c
4  *
5  * Builtin stat command: Give a precise performance counters summary
6  * overview about any workload, CPU or specific PID.
7  *
8  * Sample output:
9 
10    $ perf stat ./hackbench 10
11 
12   Time: 0.118
13 
14   Performance counter stats for './hackbench 10':
15 
16        1708.761321 task-clock                #   11.037 CPUs utilized
17             41,190 context-switches          #    0.024 M/sec
18              6,735 CPU-migrations            #    0.004 M/sec
19             17,318 page-faults               #    0.010 M/sec
20      5,205,202,243 cycles                    #    3.046 GHz
21      3,856,436,920 stalled-cycles-frontend   #   74.09% frontend cycles idle
22      1,600,790,871 stalled-cycles-backend    #   30.75% backend  cycles idle
23      2,603,501,247 instructions              #    0.50  insns per cycle
24                                              #    1.48  stalled cycles per insn
25        484,357,498 branches                  #  283.455 M/sec
26          6,388,934 branch-misses             #    1.32% of all branches
27 
28         0.154822978  seconds time elapsed
29 
30  *
31  * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
32  *
33  * Improvements and fixes by:
34  *
35  *   Arjan van de Ven <arjan@linux.intel.com>
36  *   Yanmin Zhang <yanmin.zhang@intel.com>
37  *   Wu Fengguang <fengguang.wu@intel.com>
38  *   Mike Galbraith <efault@gmx.de>
39  *   Paul Mackerras <paulus@samba.org>
40  *   Jaswinder Singh Rajput <jaswinder@kernel.org>
41  */
42 
43 #include "builtin.h"
44 #include "perf.h"
45 #include "util/cgroup.h"
46 #include <subcmd/parse-options.h>
47 #include "util/parse-events.h"
48 #include "util/pmu.h"
49 #include "util/event.h"
50 #include "util/evlist.h"
51 #include "util/evsel.h"
52 #include "util/debug.h"
53 #include "util/color.h"
54 #include "util/stat.h"
55 #include "util/header.h"
56 #include "util/cpumap.h"
57 #include "util/thread_map.h"
58 #include "util/counts.h"
59 #include "util/group.h"
60 #include "util/session.h"
61 #include "util/tool.h"
62 #include "util/string2.h"
63 #include "util/metricgroup.h"
64 #include "util/target.h"
65 #include "util/time-utils.h"
66 #include "util/top.h"
67 #include "asm/bug.h"
68 
69 #include <linux/time64.h>
70 #include <linux/zalloc.h>
71 #include <api/fs/fs.h>
72 #include <errno.h>
73 #include <signal.h>
74 #include <stdlib.h>
75 #include <sys/prctl.h>
76 #include <inttypes.h>
77 #include <locale.h>
78 #include <math.h>
79 #include <sys/types.h>
80 #include <sys/stat.h>
81 #include <sys/wait.h>
82 #include <unistd.h>
83 #include <sys/time.h>
84 #include <sys/resource.h>
85 
86 #include <linux/ctype.h>
87 #include <perf/evlist.h>
88 
89 #define DEFAULT_SEPARATOR	" "
90 #define FREEZE_ON_SMI_PATH	"devices/cpu/freeze_on_smi"
91 
92 static void print_counters(struct timespec *ts, int argc, const char **argv);
93 
94 /* Default events used for perf stat -T */
95 static const char *transaction_attrs = {
96 	"task-clock,"
97 	"{"
98 	"instructions,"
99 	"cycles,"
100 	"cpu/cycles-t/,"
101 	"cpu/tx-start/,"
102 	"cpu/el-start/,"
103 	"cpu/cycles-ct/"
104 	"}"
105 };
106 
107 /* More limited version when the CPU does not have all events. */
108 static const char * transaction_limited_attrs = {
109 	"task-clock,"
110 	"{"
111 	"instructions,"
112 	"cycles,"
113 	"cpu/cycles-t/,"
114 	"cpu/tx-start/"
115 	"}"
116 };
117 
118 static const char * topdown_attrs[] = {
119 	"topdown-total-slots",
120 	"topdown-slots-retired",
121 	"topdown-recovery-bubbles",
122 	"topdown-fetch-bubbles",
123 	"topdown-slots-issued",
124 	NULL,
125 };
126 
127 static const char *smi_cost_attrs = {
128 	"{"
129 	"msr/aperf/,"
130 	"msr/smi/,"
131 	"cycles"
132 	"}"
133 };
134 
135 static struct evlist	*evsel_list;
136 
137 static struct target target = {
138 	.uid	= UINT_MAX,
139 };
140 
141 #define METRIC_ONLY_LEN 20
142 
143 static volatile pid_t		child_pid			= -1;
144 static int			detailed_run			=  0;
145 static bool			transaction_run;
146 static bool			topdown_run			= false;
147 static bool			smi_cost			= false;
148 static bool			smi_reset			= false;
149 static int			big_num_opt			=  -1;
150 static bool			group				= false;
151 static const char		*pre_cmd			= NULL;
152 static const char		*post_cmd			= NULL;
153 static bool			sync_run			= false;
154 static bool			forever				= false;
155 static bool			force_metric_only		= false;
156 static struct timespec		ref_time;
157 static bool			append_file;
158 static bool			interval_count;
159 static const char		*output_name;
160 static int			output_fd;
161 
162 struct perf_stat {
163 	bool			 record;
164 	struct perf_data	 data;
165 	struct perf_session	*session;
166 	u64			 bytes_written;
167 	struct perf_tool	 tool;
168 	bool			 maps_allocated;
169 	struct perf_cpu_map	*cpus;
170 	struct perf_thread_map *threads;
171 	enum aggr_mode		 aggr_mode;
172 };
173 
174 static struct perf_stat		perf_stat;
175 #define STAT_RECORD		perf_stat.record
176 
177 static volatile int done = 0;
178 
179 static struct perf_stat_config stat_config = {
180 	.aggr_mode		= AGGR_GLOBAL,
181 	.scale			= true,
182 	.unit_width		= 4, /* strlen("unit") */
183 	.run_count		= 1,
184 	.metric_only_len	= METRIC_ONLY_LEN,
185 	.walltime_nsecs_stats	= &walltime_nsecs_stats,
186 	.big_num		= true,
187 };
188 
189 static inline void diff_timespec(struct timespec *r, struct timespec *a,
190 				 struct timespec *b)
191 {
192 	r->tv_sec = a->tv_sec - b->tv_sec;
193 	if (a->tv_nsec < b->tv_nsec) {
194 		r->tv_nsec = a->tv_nsec + NSEC_PER_SEC - b->tv_nsec;
195 		r->tv_sec--;
196 	} else {
197 		r->tv_nsec = a->tv_nsec - b->tv_nsec ;
198 	}
199 }
200 
201 static void perf_stat__reset_stats(void)
202 {
203 	int i;
204 
205 	perf_evlist__reset_stats(evsel_list);
206 	perf_stat__reset_shadow_stats();
207 
208 	for (i = 0; i < stat_config.stats_num; i++)
209 		perf_stat__reset_shadow_per_stat(&stat_config.stats[i]);
210 }
211 
212 static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
213 				     union perf_event *event,
214 				     struct perf_sample *sample __maybe_unused,
215 				     struct machine *machine __maybe_unused)
216 {
217 	if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) {
218 		pr_err("failed to write perf data, error: %m\n");
219 		return -1;
220 	}
221 
222 	perf_stat.bytes_written += event->header.size;
223 	return 0;
224 }
225 
226 static int write_stat_round_event(u64 tm, u64 type)
227 {
228 	return perf_event__synthesize_stat_round(NULL, tm, type,
229 						 process_synthesized_event,
230 						 NULL);
231 }
232 
233 #define WRITE_STAT_ROUND_EVENT(time, interval) \
234 	write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
235 
236 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
237 
238 static int
239 perf_evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread,
240 			     struct perf_counts_values *count)
241 {
242 	struct perf_sample_id *sid = SID(counter, cpu, thread);
243 
244 	return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
245 					   process_synthesized_event, NULL);
246 }
247 
248 static int read_single_counter(struct evsel *counter, int cpu,
249 			       int thread, struct timespec *rs)
250 {
251 	if (counter->tool_event == PERF_TOOL_DURATION_TIME) {
252 		u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL;
253 		struct perf_counts_values *count =
254 			perf_counts(counter->counts, cpu, thread);
255 		count->ena = count->run = val;
256 		count->val = val;
257 		return 0;
258 	}
259 	return perf_evsel__read_counter(counter, cpu, thread);
260 }
261 
262 /*
263  * Read out the results of a single counter:
264  * do not aggregate counts across CPUs in system-wide mode
265  */
266 static int read_counter(struct evsel *counter, struct timespec *rs)
267 {
268 	int nthreads = perf_thread_map__nr(evsel_list->core.threads);
269 	int ncpus, cpu, thread;
270 
271 	if (target__has_cpu(&target) && !target__has_per_thread(&target))
272 		ncpus = perf_evsel__nr_cpus(counter);
273 	else
274 		ncpus = 1;
275 
276 	if (!counter->supported)
277 		return -ENOENT;
278 
279 	if (counter->system_wide)
280 		nthreads = 1;
281 
282 	for (thread = 0; thread < nthreads; thread++) {
283 		for (cpu = 0; cpu < ncpus; cpu++) {
284 			struct perf_counts_values *count;
285 
286 			count = perf_counts(counter->counts, cpu, thread);
287 
288 			/*
289 			 * The leader's group read loads data into its group members
290 			 * (via perf_evsel__read_counter) and sets threir count->loaded.
291 			 */
292 			if (!perf_counts__is_loaded(counter->counts, cpu, thread) &&
293 			    read_single_counter(counter, cpu, thread, rs)) {
294 				counter->counts->scaled = -1;
295 				perf_counts(counter->counts, cpu, thread)->ena = 0;
296 				perf_counts(counter->counts, cpu, thread)->run = 0;
297 				return -1;
298 			}
299 
300 			perf_counts__set_loaded(counter->counts, cpu, thread, false);
301 
302 			if (STAT_RECORD) {
303 				if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
304 					pr_err("failed to write stat event\n");
305 					return -1;
306 				}
307 			}
308 
309 			if (verbose > 1) {
310 				fprintf(stat_config.output,
311 					"%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
312 						perf_evsel__name(counter),
313 						cpu,
314 						count->val, count->ena, count->run);
315 			}
316 		}
317 	}
318 
319 	return 0;
320 }
321 
322 static void read_counters(struct timespec *rs)
323 {
324 	struct evsel *counter;
325 	int ret;
326 
327 	evlist__for_each_entry(evsel_list, counter) {
328 		ret = read_counter(counter, rs);
329 		if (ret)
330 			pr_debug("failed to read counter %s\n", counter->name);
331 
332 		if (ret == 0 && perf_stat_process_counter(&stat_config, counter))
333 			pr_warning("failed to process counter %s\n", counter->name);
334 	}
335 }
336 
337 static void process_interval(void)
338 {
339 	struct timespec ts, rs;
340 
341 	clock_gettime(CLOCK_MONOTONIC, &ts);
342 	diff_timespec(&rs, &ts, &ref_time);
343 
344 	read_counters(&rs);
345 
346 	if (STAT_RECORD) {
347 		if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL))
348 			pr_err("failed to write stat round event\n");
349 	}
350 
351 	init_stats(&walltime_nsecs_stats);
352 	update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000);
353 	print_counters(&rs, 0, NULL);
354 }
355 
356 static void enable_counters(void)
357 {
358 	if (stat_config.initial_delay)
359 		usleep(stat_config.initial_delay * USEC_PER_MSEC);
360 
361 	/*
362 	 * We need to enable counters only if:
363 	 * - we don't have tracee (attaching to task or cpu)
364 	 * - we have initial delay configured
365 	 */
366 	if (!target__none(&target) || stat_config.initial_delay)
367 		evlist__enable(evsel_list);
368 }
369 
370 static void disable_counters(void)
371 {
372 	/*
373 	 * If we don't have tracee (attaching to task or cpu), counters may
374 	 * still be running. To get accurate group ratios, we must stop groups
375 	 * from counting before reading their constituent counters.
376 	 */
377 	if (!target__none(&target))
378 		evlist__disable(evsel_list);
379 }
380 
381 static volatile int workload_exec_errno;
382 
383 /*
384  * perf_evlist__prepare_workload will send a SIGUSR1
385  * if the fork fails, since we asked by setting its
386  * want_signal to true.
387  */
388 static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
389 					void *ucontext __maybe_unused)
390 {
391 	workload_exec_errno = info->si_value.sival_int;
392 }
393 
394 static bool perf_evsel__should_store_id(struct evsel *counter)
395 {
396 	return STAT_RECORD || counter->core.attr.read_format & PERF_FORMAT_ID;
397 }
398 
399 static bool is_target_alive(struct target *_target,
400 			    struct perf_thread_map *threads)
401 {
402 	struct stat st;
403 	int i;
404 
405 	if (!target__has_task(_target))
406 		return true;
407 
408 	for (i = 0; i < threads->nr; i++) {
409 		char path[PATH_MAX];
410 
411 		scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(),
412 			  threads->map[i].pid);
413 
414 		if (!stat(path, &st))
415 			return true;
416 	}
417 
418 	return false;
419 }
420 
421 static int __run_perf_stat(int argc, const char **argv, int run_idx)
422 {
423 	int interval = stat_config.interval;
424 	int times = stat_config.times;
425 	int timeout = stat_config.timeout;
426 	char msg[BUFSIZ];
427 	unsigned long long t0, t1;
428 	struct evsel *counter;
429 	struct timespec ts;
430 	size_t l;
431 	int status = 0;
432 	const bool forks = (argc > 0);
433 	bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false;
434 
435 	if (interval) {
436 		ts.tv_sec  = interval / USEC_PER_MSEC;
437 		ts.tv_nsec = (interval % USEC_PER_MSEC) * NSEC_PER_MSEC;
438 	} else if (timeout) {
439 		ts.tv_sec  = timeout / USEC_PER_MSEC;
440 		ts.tv_nsec = (timeout % USEC_PER_MSEC) * NSEC_PER_MSEC;
441 	} else {
442 		ts.tv_sec  = 1;
443 		ts.tv_nsec = 0;
444 	}
445 
446 	if (forks) {
447 		if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe,
448 						  workload_exec_failed_signal) < 0) {
449 			perror("failed to prepare workload");
450 			return -1;
451 		}
452 		child_pid = evsel_list->workload.pid;
453 	}
454 
455 	if (group)
456 		perf_evlist__set_leader(evsel_list);
457 
458 	evlist__for_each_entry(evsel_list, counter) {
459 try_again:
460 		if (create_perf_stat_counter(counter, &stat_config, &target) < 0) {
461 
462 			/* Weak group failed. Reset the group. */
463 			if ((errno == EINVAL || errno == EBADF) &&
464 			    counter->leader != counter &&
465 			    counter->weak_group) {
466 				counter = perf_evlist__reset_weak_group(evsel_list, counter);
467 				goto try_again;
468 			}
469 
470 			/*
471 			 * PPC returns ENXIO for HW counters until 2.6.37
472 			 * (behavior changed with commit b0a873e).
473 			 */
474 			if (errno == EINVAL || errno == ENOSYS ||
475 			    errno == ENOENT || errno == EOPNOTSUPP ||
476 			    errno == ENXIO) {
477 				if (verbose > 0)
478 					ui__warning("%s event is not supported by the kernel.\n",
479 						    perf_evsel__name(counter));
480 				counter->supported = false;
481 
482 				if ((counter->leader != counter) ||
483 				    !(counter->leader->core.nr_members > 1))
484 					continue;
485 			} else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
486                                 if (verbose > 0)
487                                         ui__warning("%s\n", msg);
488                                 goto try_again;
489 			} else if (target__has_per_thread(&target) &&
490 				   evsel_list->core.threads &&
491 				   evsel_list->core.threads->err_thread != -1) {
492 				/*
493 				 * For global --per-thread case, skip current
494 				 * error thread.
495 				 */
496 				if (!thread_map__remove(evsel_list->core.threads,
497 							evsel_list->core.threads->err_thread)) {
498 					evsel_list->core.threads->err_thread = -1;
499 					goto try_again;
500 				}
501 			}
502 
503 			perf_evsel__open_strerror(counter, &target,
504 						  errno, msg, sizeof(msg));
505 			ui__error("%s\n", msg);
506 
507 			if (child_pid != -1)
508 				kill(child_pid, SIGTERM);
509 
510 			return -1;
511 		}
512 		counter->supported = true;
513 
514 		l = strlen(counter->unit);
515 		if (l > stat_config.unit_width)
516 			stat_config.unit_width = l;
517 
518 		if (perf_evsel__should_store_id(counter) &&
519 		    perf_evsel__store_ids(counter, evsel_list))
520 			return -1;
521 	}
522 
523 	if (perf_evlist__apply_filters(evsel_list, &counter)) {
524 		pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
525 			counter->filter, perf_evsel__name(counter), errno,
526 			str_error_r(errno, msg, sizeof(msg)));
527 		return -1;
528 	}
529 
530 	if (STAT_RECORD) {
531 		int err, fd = perf_data__fd(&perf_stat.data);
532 
533 		if (is_pipe) {
534 			err = perf_header__write_pipe(perf_data__fd(&perf_stat.data));
535 		} else {
536 			err = perf_session__write_header(perf_stat.session, evsel_list,
537 							 fd, false);
538 		}
539 
540 		if (err < 0)
541 			return err;
542 
543 		err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list,
544 						  process_synthesized_event, is_pipe);
545 		if (err < 0)
546 			return err;
547 	}
548 
549 	/*
550 	 * Enable counters and exec the command:
551 	 */
552 	t0 = rdclock();
553 	clock_gettime(CLOCK_MONOTONIC, &ref_time);
554 
555 	if (forks) {
556 		perf_evlist__start_workload(evsel_list);
557 		enable_counters();
558 
559 		if (interval || timeout) {
560 			while (!waitpid(child_pid, &status, WNOHANG)) {
561 				nanosleep(&ts, NULL);
562 				if (timeout)
563 					break;
564 				process_interval();
565 				if (interval_count && !(--times))
566 					break;
567 			}
568 		}
569 		if (child_pid != -1)
570 			wait4(child_pid, &status, 0, &stat_config.ru_data);
571 
572 		if (workload_exec_errno) {
573 			const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
574 			pr_err("Workload failed: %s\n", emsg);
575 			return -1;
576 		}
577 
578 		if (WIFSIGNALED(status))
579 			psignal(WTERMSIG(status), argv[0]);
580 	} else {
581 		enable_counters();
582 		while (!done) {
583 			nanosleep(&ts, NULL);
584 			if (!is_target_alive(&target, evsel_list->core.threads))
585 				break;
586 			if (timeout)
587 				break;
588 			if (interval) {
589 				process_interval();
590 				if (interval_count && !(--times))
591 					break;
592 			}
593 		}
594 	}
595 
596 	disable_counters();
597 
598 	t1 = rdclock();
599 
600 	if (stat_config.walltime_run_table)
601 		stat_config.walltime_run[run_idx] = t1 - t0;
602 
603 	update_stats(&walltime_nsecs_stats, t1 - t0);
604 
605 	/*
606 	 * Closing a group leader splits the group, and as we only disable
607 	 * group leaders, results in remaining events becoming enabled. To
608 	 * avoid arbitrary skew, we must read all counters before closing any
609 	 * group leaders.
610 	 */
611 	read_counters(&(struct timespec) { .tv_nsec = t1-t0 });
612 
613 	/*
614 	 * We need to keep evsel_list alive, because it's processed
615 	 * later the evsel_list will be closed after.
616 	 */
617 	if (!STAT_RECORD)
618 		evlist__close(evsel_list);
619 
620 	return WEXITSTATUS(status);
621 }
622 
623 static int run_perf_stat(int argc, const char **argv, int run_idx)
624 {
625 	int ret;
626 
627 	if (pre_cmd) {
628 		ret = system(pre_cmd);
629 		if (ret)
630 			return ret;
631 	}
632 
633 	if (sync_run)
634 		sync();
635 
636 	ret = __run_perf_stat(argc, argv, run_idx);
637 	if (ret)
638 		return ret;
639 
640 	if (post_cmd) {
641 		ret = system(post_cmd);
642 		if (ret)
643 			return ret;
644 	}
645 
646 	return ret;
647 }
648 
649 static void print_counters(struct timespec *ts, int argc, const char **argv)
650 {
651 	/* Do not print anything if we record to the pipe. */
652 	if (STAT_RECORD && perf_stat.data.is_pipe)
653 		return;
654 
655 	perf_evlist__print_counters(evsel_list, &stat_config, &target,
656 				    ts, argc, argv);
657 }
658 
659 static volatile int signr = -1;
660 
661 static void skip_signal(int signo)
662 {
663 	if ((child_pid == -1) || stat_config.interval)
664 		done = 1;
665 
666 	signr = signo;
667 	/*
668 	 * render child_pid harmless
669 	 * won't send SIGTERM to a random
670 	 * process in case of race condition
671 	 * and fast PID recycling
672 	 */
673 	child_pid = -1;
674 }
675 
676 static void sig_atexit(void)
677 {
678 	sigset_t set, oset;
679 
680 	/*
681 	 * avoid race condition with SIGCHLD handler
682 	 * in skip_signal() which is modifying child_pid
683 	 * goal is to avoid send SIGTERM to a random
684 	 * process
685 	 */
686 	sigemptyset(&set);
687 	sigaddset(&set, SIGCHLD);
688 	sigprocmask(SIG_BLOCK, &set, &oset);
689 
690 	if (child_pid != -1)
691 		kill(child_pid, SIGTERM);
692 
693 	sigprocmask(SIG_SETMASK, &oset, NULL);
694 
695 	if (signr == -1)
696 		return;
697 
698 	signal(signr, SIG_DFL);
699 	kill(getpid(), signr);
700 }
701 
702 static int stat__set_big_num(const struct option *opt __maybe_unused,
703 			     const char *s __maybe_unused, int unset)
704 {
705 	big_num_opt = unset ? 0 : 1;
706 	return 0;
707 }
708 
709 static int enable_metric_only(const struct option *opt __maybe_unused,
710 			      const char *s __maybe_unused, int unset)
711 {
712 	force_metric_only = true;
713 	stat_config.metric_only = !unset;
714 	return 0;
715 }
716 
717 static int parse_metric_groups(const struct option *opt,
718 			       const char *str,
719 			       int unset __maybe_unused)
720 {
721 	return metricgroup__parse_groups(opt, str, &stat_config.metric_events);
722 }
723 
724 static struct option stat_options[] = {
725 	OPT_BOOLEAN('T', "transaction", &transaction_run,
726 		    "hardware transaction statistics"),
727 	OPT_CALLBACK('e', "event", &evsel_list, "event",
728 		     "event selector. use 'perf list' to list available events",
729 		     parse_events_option),
730 	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
731 		     "event filter", parse_filter),
732 	OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit,
733 		    "child tasks do not inherit counters"),
734 	OPT_STRING('p', "pid", &target.pid, "pid",
735 		   "stat events on existing process id"),
736 	OPT_STRING('t', "tid", &target.tid, "tid",
737 		   "stat events on existing thread id"),
738 	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
739 		    "system-wide collection from all CPUs"),
740 	OPT_BOOLEAN('g', "group", &group,
741 		    "put the counters into a counter group"),
742 	OPT_BOOLEAN(0, "scale", &stat_config.scale,
743 		    "Use --no-scale to disable counter scaling for multiplexing"),
744 	OPT_INCR('v', "verbose", &verbose,
745 		    "be more verbose (show counter open errors, etc)"),
746 	OPT_INTEGER('r', "repeat", &stat_config.run_count,
747 		    "repeat command and print average + stddev (max: 100, forever: 0)"),
748 	OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table,
749 		    "display details about each run (only with -r option)"),
750 	OPT_BOOLEAN('n', "null", &stat_config.null_run,
751 		    "null run - dont start any counters"),
752 	OPT_INCR('d', "detailed", &detailed_run,
753 		    "detailed run - start a lot of events"),
754 	OPT_BOOLEAN('S', "sync", &sync_run,
755 		    "call sync() before starting a run"),
756 	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
757 			   "print large numbers with thousands\' separators",
758 			   stat__set_big_num),
759 	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
760 		    "list of cpus to monitor in system-wide"),
761 	OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
762 		    "disable CPU count aggregation", AGGR_NONE),
763 	OPT_BOOLEAN(0, "no-merge", &stat_config.no_merge, "Do not merge identical named events"),
764 	OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator",
765 		   "print counts with custom separator"),
766 	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
767 		     "monitor event in cgroup name only", parse_cgroups),
768 	OPT_STRING('o', "output", &output_name, "file", "output file name"),
769 	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
770 	OPT_INTEGER(0, "log-fd", &output_fd,
771 		    "log output to fd, instead of stderr"),
772 	OPT_STRING(0, "pre", &pre_cmd, "command",
773 			"command to run prior to the measured command"),
774 	OPT_STRING(0, "post", &post_cmd, "command",
775 			"command to run after to the measured command"),
776 	OPT_UINTEGER('I', "interval-print", &stat_config.interval,
777 		    "print counts at regular interval in ms "
778 		    "(overhead is possible for values <= 100ms)"),
779 	OPT_INTEGER(0, "interval-count", &stat_config.times,
780 		    "print counts for fixed number of times"),
781 	OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear,
782 		    "clear screen in between new interval"),
783 	OPT_UINTEGER(0, "timeout", &stat_config.timeout,
784 		    "stop workload and print counts after a timeout period in ms (>= 10ms)"),
785 	OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
786 		     "aggregate counts per processor socket", AGGR_SOCKET),
787 	OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
788 		     "aggregate counts per processor die", AGGR_DIE),
789 	OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
790 		     "aggregate counts per physical processor core", AGGR_CORE),
791 	OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
792 		     "aggregate counts per thread", AGGR_THREAD),
793 	OPT_UINTEGER('D', "delay", &stat_config.initial_delay,
794 		     "ms to wait before starting measurement after program start"),
795 	OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
796 			"Only print computed metrics. No raw values", enable_metric_only),
797 	OPT_BOOLEAN(0, "topdown", &topdown_run,
798 			"measure topdown level 1 statistics"),
799 	OPT_BOOLEAN(0, "smi-cost", &smi_cost,
800 			"measure SMI cost"),
801 	OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list",
802 		     "monitor specified metrics or metric groups (separated by ,)",
803 		     parse_metric_groups),
804 	OPT_END()
805 };
806 
807 static int perf_stat__get_socket(struct perf_stat_config *config __maybe_unused,
808 				 struct perf_cpu_map *map, int cpu)
809 {
810 	return cpu_map__get_socket(map, cpu, NULL);
811 }
812 
813 static int perf_stat__get_die(struct perf_stat_config *config __maybe_unused,
814 			      struct perf_cpu_map *map, int cpu)
815 {
816 	return cpu_map__get_die(map, cpu, NULL);
817 }
818 
819 static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
820 			       struct perf_cpu_map *map, int cpu)
821 {
822 	return cpu_map__get_core(map, cpu, NULL);
823 }
824 
825 static int cpu_map__get_max(struct perf_cpu_map *map)
826 {
827 	int i, max = -1;
828 
829 	for (i = 0; i < map->nr; i++) {
830 		if (map->map[i] > max)
831 			max = map->map[i];
832 	}
833 
834 	return max;
835 }
836 
837 static int perf_stat__get_aggr(struct perf_stat_config *config,
838 			       aggr_get_id_t get_id, struct perf_cpu_map *map, int idx)
839 {
840 	int cpu;
841 
842 	if (idx >= map->nr)
843 		return -1;
844 
845 	cpu = map->map[idx];
846 
847 	if (config->cpus_aggr_map->map[cpu] == -1)
848 		config->cpus_aggr_map->map[cpu] = get_id(config, map, idx);
849 
850 	return config->cpus_aggr_map->map[cpu];
851 }
852 
853 static int perf_stat__get_socket_cached(struct perf_stat_config *config,
854 					struct perf_cpu_map *map, int idx)
855 {
856 	return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx);
857 }
858 
859 static int perf_stat__get_die_cached(struct perf_stat_config *config,
860 					struct perf_cpu_map *map, int idx)
861 {
862 	return perf_stat__get_aggr(config, perf_stat__get_die, map, idx);
863 }
864 
865 static int perf_stat__get_core_cached(struct perf_stat_config *config,
866 				      struct perf_cpu_map *map, int idx)
867 {
868 	return perf_stat__get_aggr(config, perf_stat__get_core, map, idx);
869 }
870 
871 static bool term_percore_set(void)
872 {
873 	struct evsel *counter;
874 
875 	evlist__for_each_entry(evsel_list, counter) {
876 		if (counter->percore)
877 			return true;
878 	}
879 
880 	return false;
881 }
882 
883 static int perf_stat_init_aggr_mode(void)
884 {
885 	int nr;
886 
887 	switch (stat_config.aggr_mode) {
888 	case AGGR_SOCKET:
889 		if (cpu_map__build_socket_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
890 			perror("cannot build socket map");
891 			return -1;
892 		}
893 		stat_config.aggr_get_id = perf_stat__get_socket_cached;
894 		break;
895 	case AGGR_DIE:
896 		if (cpu_map__build_die_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
897 			perror("cannot build die map");
898 			return -1;
899 		}
900 		stat_config.aggr_get_id = perf_stat__get_die_cached;
901 		break;
902 	case AGGR_CORE:
903 		if (cpu_map__build_core_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
904 			perror("cannot build core map");
905 			return -1;
906 		}
907 		stat_config.aggr_get_id = perf_stat__get_core_cached;
908 		break;
909 	case AGGR_NONE:
910 		if (term_percore_set()) {
911 			if (cpu_map__build_core_map(evsel_list->core.cpus,
912 						    &stat_config.aggr_map)) {
913 				perror("cannot build core map");
914 				return -1;
915 			}
916 			stat_config.aggr_get_id = perf_stat__get_core_cached;
917 		}
918 		break;
919 	case AGGR_GLOBAL:
920 	case AGGR_THREAD:
921 	case AGGR_UNSET:
922 	default:
923 		break;
924 	}
925 
926 	/*
927 	 * The evsel_list->cpus is the base we operate on,
928 	 * taking the highest cpu number to be the size of
929 	 * the aggregation translate cpumap.
930 	 */
931 	nr = cpu_map__get_max(evsel_list->core.cpus);
932 	stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1);
933 	return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
934 }
935 
936 static void perf_stat__exit_aggr_mode(void)
937 {
938 	perf_cpu_map__put(stat_config.aggr_map);
939 	perf_cpu_map__put(stat_config.cpus_aggr_map);
940 	stat_config.aggr_map = NULL;
941 	stat_config.cpus_aggr_map = NULL;
942 }
943 
944 static inline int perf_env__get_cpu(struct perf_env *env, struct perf_cpu_map *map, int idx)
945 {
946 	int cpu;
947 
948 	if (idx > map->nr)
949 		return -1;
950 
951 	cpu = map->map[idx];
952 
953 	if (cpu >= env->nr_cpus_avail)
954 		return -1;
955 
956 	return cpu;
957 }
958 
959 static int perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data)
960 {
961 	struct perf_env *env = data;
962 	int cpu = perf_env__get_cpu(env, map, idx);
963 
964 	return cpu == -1 ? -1 : env->cpu[cpu].socket_id;
965 }
966 
967 static int perf_env__get_die(struct perf_cpu_map *map, int idx, void *data)
968 {
969 	struct perf_env *env = data;
970 	int die_id = -1, cpu = perf_env__get_cpu(env, map, idx);
971 
972 	if (cpu != -1) {
973 		/*
974 		 * Encode socket in bit range 15:8
975 		 * die_id is relative to socket,
976 		 * we need a global id. So we combine
977 		 * socket + die id
978 		 */
979 		if (WARN_ONCE(env->cpu[cpu].socket_id >> 8, "The socket id number is too big.\n"))
980 			return -1;
981 
982 		if (WARN_ONCE(env->cpu[cpu].die_id >> 8, "The die id number is too big.\n"))
983 			return -1;
984 
985 		die_id = (env->cpu[cpu].socket_id << 8) | (env->cpu[cpu].die_id & 0xff);
986 	}
987 
988 	return die_id;
989 }
990 
991 static int perf_env__get_core(struct perf_cpu_map *map, int idx, void *data)
992 {
993 	struct perf_env *env = data;
994 	int core = -1, cpu = perf_env__get_cpu(env, map, idx);
995 
996 	if (cpu != -1) {
997 		/*
998 		 * Encode socket in bit range 31:24
999 		 * encode die id in bit range 23:16
1000 		 * core_id is relative to socket and die,
1001 		 * we need a global id. So we combine
1002 		 * socket + die id + core id
1003 		 */
1004 		if (WARN_ONCE(env->cpu[cpu].socket_id >> 8, "The socket id number is too big.\n"))
1005 			return -1;
1006 
1007 		if (WARN_ONCE(env->cpu[cpu].die_id >> 8, "The die id number is too big.\n"))
1008 			return -1;
1009 
1010 		if (WARN_ONCE(env->cpu[cpu].core_id >> 16, "The core id number is too big.\n"))
1011 			return -1;
1012 
1013 		core = (env->cpu[cpu].socket_id << 24) |
1014 		       (env->cpu[cpu].die_id << 16) |
1015 		       (env->cpu[cpu].core_id & 0xffff);
1016 	}
1017 
1018 	return core;
1019 }
1020 
1021 static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
1022 				      struct perf_cpu_map **sockp)
1023 {
1024 	return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
1025 }
1026 
1027 static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus,
1028 				   struct perf_cpu_map **diep)
1029 {
1030 	return cpu_map__build_map(cpus, diep, perf_env__get_die, env);
1031 }
1032 
1033 static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus,
1034 				    struct perf_cpu_map **corep)
1035 {
1036 	return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
1037 }
1038 
1039 static int perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
1040 				      struct perf_cpu_map *map, int idx)
1041 {
1042 	return perf_env__get_socket(map, idx, &perf_stat.session->header.env);
1043 }
1044 static int perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused,
1045 				   struct perf_cpu_map *map, int idx)
1046 {
1047 	return perf_env__get_die(map, idx, &perf_stat.session->header.env);
1048 }
1049 
1050 static int perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused,
1051 				    struct perf_cpu_map *map, int idx)
1052 {
1053 	return perf_env__get_core(map, idx, &perf_stat.session->header.env);
1054 }
1055 
1056 static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
1057 {
1058 	struct perf_env *env = &st->session->header.env;
1059 
1060 	switch (stat_config.aggr_mode) {
1061 	case AGGR_SOCKET:
1062 		if (perf_env__build_socket_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
1063 			perror("cannot build socket map");
1064 			return -1;
1065 		}
1066 		stat_config.aggr_get_id = perf_stat__get_socket_file;
1067 		break;
1068 	case AGGR_DIE:
1069 		if (perf_env__build_die_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
1070 			perror("cannot build die map");
1071 			return -1;
1072 		}
1073 		stat_config.aggr_get_id = perf_stat__get_die_file;
1074 		break;
1075 	case AGGR_CORE:
1076 		if (perf_env__build_core_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
1077 			perror("cannot build core map");
1078 			return -1;
1079 		}
1080 		stat_config.aggr_get_id = perf_stat__get_core_file;
1081 		break;
1082 	case AGGR_NONE:
1083 	case AGGR_GLOBAL:
1084 	case AGGR_THREAD:
1085 	case AGGR_UNSET:
1086 	default:
1087 		break;
1088 	}
1089 
1090 	return 0;
1091 }
1092 
1093 static int topdown_filter_events(const char **attr, char **str, bool use_group)
1094 {
1095 	int off = 0;
1096 	int i;
1097 	int len = 0;
1098 	char *s;
1099 
1100 	for (i = 0; attr[i]; i++) {
1101 		if (pmu_have_event("cpu", attr[i])) {
1102 			len += strlen(attr[i]) + 1;
1103 			attr[i - off] = attr[i];
1104 		} else
1105 			off++;
1106 	}
1107 	attr[i - off] = NULL;
1108 
1109 	*str = malloc(len + 1 + 2);
1110 	if (!*str)
1111 		return -1;
1112 	s = *str;
1113 	if (i - off == 0) {
1114 		*s = 0;
1115 		return 0;
1116 	}
1117 	if (use_group)
1118 		*s++ = '{';
1119 	for (i = 0; attr[i]; i++) {
1120 		strcpy(s, attr[i]);
1121 		s += strlen(s);
1122 		*s++ = ',';
1123 	}
1124 	if (use_group) {
1125 		s[-1] = '}';
1126 		*s = 0;
1127 	} else
1128 		s[-1] = 0;
1129 	return 0;
1130 }
1131 
1132 __weak bool arch_topdown_check_group(bool *warn)
1133 {
1134 	*warn = false;
1135 	return false;
1136 }
1137 
1138 __weak void arch_topdown_group_warn(void)
1139 {
1140 }
1141 
1142 /*
1143  * Add default attributes, if there were no attributes specified or
1144  * if -d/--detailed, -d -d or -d -d -d is used:
1145  */
1146 static int add_default_attributes(void)
1147 {
1148 	int err;
1149 	struct perf_event_attr default_attrs0[] = {
1150 
1151   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
1152   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
1153   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
1154   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
1155 
1156   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
1157 };
1158 	struct perf_event_attr frontend_attrs[] = {
1159   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
1160 };
1161 	struct perf_event_attr backend_attrs[] = {
1162   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
1163 };
1164 	struct perf_event_attr default_attrs1[] = {
1165   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
1166   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
1167   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
1168 
1169 };
1170 
1171 /*
1172  * Detailed stats (-d), covering the L1 and last level data caches:
1173  */
1174 	struct perf_event_attr detailed_attrs[] = {
1175 
1176   { .type = PERF_TYPE_HW_CACHE,
1177     .config =
1178 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1179 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1180 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1181 
1182   { .type = PERF_TYPE_HW_CACHE,
1183     .config =
1184 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1185 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1186 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1187 
1188   { .type = PERF_TYPE_HW_CACHE,
1189     .config =
1190 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1191 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1192 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1193 
1194   { .type = PERF_TYPE_HW_CACHE,
1195     .config =
1196 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1197 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1198 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1199 };
1200 
1201 /*
1202  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1203  */
1204 	struct perf_event_attr very_detailed_attrs[] = {
1205 
1206   { .type = PERF_TYPE_HW_CACHE,
1207     .config =
1208 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1209 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1210 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1211 
1212   { .type = PERF_TYPE_HW_CACHE,
1213     .config =
1214 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1215 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1216 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1217 
1218   { .type = PERF_TYPE_HW_CACHE,
1219     .config =
1220 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1221 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1222 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1223 
1224   { .type = PERF_TYPE_HW_CACHE,
1225     .config =
1226 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1227 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1228 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1229 
1230   { .type = PERF_TYPE_HW_CACHE,
1231     .config =
1232 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1233 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1234 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1235 
1236   { .type = PERF_TYPE_HW_CACHE,
1237     .config =
1238 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1239 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1240 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1241 
1242 };
1243 
1244 /*
1245  * Very, very detailed stats (-d -d -d), adding prefetch events:
1246  */
1247 	struct perf_event_attr very_very_detailed_attrs[] = {
1248 
1249   { .type = PERF_TYPE_HW_CACHE,
1250     .config =
1251 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1252 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1253 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1254 
1255   { .type = PERF_TYPE_HW_CACHE,
1256     .config =
1257 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1258 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1259 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1260 };
1261 	struct parse_events_error errinfo;
1262 
1263 	/* Set attrs if no event is selected and !null_run: */
1264 	if (stat_config.null_run)
1265 		return 0;
1266 
1267 	if (transaction_run) {
1268 		/* Handle -T as -M transaction. Once platform specific metrics
1269 		 * support has been added to the json files, all archictures
1270 		 * will use this approach. To determine transaction support
1271 		 * on an architecture test for such a metric name.
1272 		 */
1273 		if (metricgroup__has_metric("transaction")) {
1274 			struct option opt = { .value = &evsel_list };
1275 
1276 			return metricgroup__parse_groups(&opt, "transaction",
1277 							 &stat_config.metric_events);
1278 		}
1279 
1280 		if (pmu_have_event("cpu", "cycles-ct") &&
1281 		    pmu_have_event("cpu", "el-start"))
1282 			err = parse_events(evsel_list, transaction_attrs,
1283 					   &errinfo);
1284 		else
1285 			err = parse_events(evsel_list,
1286 					   transaction_limited_attrs,
1287 					   &errinfo);
1288 		if (err) {
1289 			fprintf(stderr, "Cannot set up transaction events\n");
1290 			parse_events_print_error(&errinfo, transaction_attrs);
1291 			return -1;
1292 		}
1293 		return 0;
1294 	}
1295 
1296 	if (smi_cost) {
1297 		int smi;
1298 
1299 		if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) {
1300 			fprintf(stderr, "freeze_on_smi is not supported.\n");
1301 			return -1;
1302 		}
1303 
1304 		if (!smi) {
1305 			if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) {
1306 				fprintf(stderr, "Failed to set freeze_on_smi.\n");
1307 				return -1;
1308 			}
1309 			smi_reset = true;
1310 		}
1311 
1312 		if (pmu_have_event("msr", "aperf") &&
1313 		    pmu_have_event("msr", "smi")) {
1314 			if (!force_metric_only)
1315 				stat_config.metric_only = true;
1316 			err = parse_events(evsel_list, smi_cost_attrs, &errinfo);
1317 		} else {
1318 			fprintf(stderr, "To measure SMI cost, it needs "
1319 				"msr/aperf/, msr/smi/ and cpu/cycles/ support\n");
1320 			parse_events_print_error(&errinfo, smi_cost_attrs);
1321 			return -1;
1322 		}
1323 		if (err) {
1324 			fprintf(stderr, "Cannot set up SMI cost events\n");
1325 			return -1;
1326 		}
1327 		return 0;
1328 	}
1329 
1330 	if (topdown_run) {
1331 		char *str = NULL;
1332 		bool warn = false;
1333 
1334 		if (stat_config.aggr_mode != AGGR_GLOBAL &&
1335 		    stat_config.aggr_mode != AGGR_CORE) {
1336 			pr_err("top down event configuration requires --per-core mode\n");
1337 			return -1;
1338 		}
1339 		stat_config.aggr_mode = AGGR_CORE;
1340 		if (nr_cgroups || !target__has_cpu(&target)) {
1341 			pr_err("top down event configuration requires system-wide mode (-a)\n");
1342 			return -1;
1343 		}
1344 
1345 		if (!force_metric_only)
1346 			stat_config.metric_only = true;
1347 		if (topdown_filter_events(topdown_attrs, &str,
1348 				arch_topdown_check_group(&warn)) < 0) {
1349 			pr_err("Out of memory\n");
1350 			return -1;
1351 		}
1352 		if (topdown_attrs[0] && str) {
1353 			if (warn)
1354 				arch_topdown_group_warn();
1355 			err = parse_events(evsel_list, str, &errinfo);
1356 			if (err) {
1357 				fprintf(stderr,
1358 					"Cannot set up top down events %s: %d\n",
1359 					str, err);
1360 				parse_events_print_error(&errinfo, str);
1361 				free(str);
1362 				return -1;
1363 			}
1364 		} else {
1365 			fprintf(stderr, "System does not support topdown\n");
1366 			return -1;
1367 		}
1368 		free(str);
1369 	}
1370 
1371 	if (!evsel_list->core.nr_entries) {
1372 		if (target__has_cpu(&target))
1373 			default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
1374 
1375 		if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
1376 			return -1;
1377 		if (pmu_have_event("cpu", "stalled-cycles-frontend")) {
1378 			if (perf_evlist__add_default_attrs(evsel_list,
1379 						frontend_attrs) < 0)
1380 				return -1;
1381 		}
1382 		if (pmu_have_event("cpu", "stalled-cycles-backend")) {
1383 			if (perf_evlist__add_default_attrs(evsel_list,
1384 						backend_attrs) < 0)
1385 				return -1;
1386 		}
1387 		if (perf_evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
1388 			return -1;
1389 	}
1390 
1391 	/* Detailed events get appended to the event list: */
1392 
1393 	if (detailed_run <  1)
1394 		return 0;
1395 
1396 	/* Append detailed run extra attributes: */
1397 	if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
1398 		return -1;
1399 
1400 	if (detailed_run < 2)
1401 		return 0;
1402 
1403 	/* Append very detailed run extra attributes: */
1404 	if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
1405 		return -1;
1406 
1407 	if (detailed_run < 3)
1408 		return 0;
1409 
1410 	/* Append very, very detailed run extra attributes: */
1411 	return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
1412 }
1413 
1414 static const char * const stat_record_usage[] = {
1415 	"perf stat record [<options>]",
1416 	NULL,
1417 };
1418 
1419 static void init_features(struct perf_session *session)
1420 {
1421 	int feat;
1422 
1423 	for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
1424 		perf_header__set_feat(&session->header, feat);
1425 
1426 	perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
1427 	perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
1428 	perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
1429 	perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
1430 	perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
1431 }
1432 
1433 static int __cmd_record(int argc, const char **argv)
1434 {
1435 	struct perf_session *session;
1436 	struct perf_data *data = &perf_stat.data;
1437 
1438 	argc = parse_options(argc, argv, stat_options, stat_record_usage,
1439 			     PARSE_OPT_STOP_AT_NON_OPTION);
1440 
1441 	if (output_name)
1442 		data->path = output_name;
1443 
1444 	if (stat_config.run_count != 1 || forever) {
1445 		pr_err("Cannot use -r option with perf stat record.\n");
1446 		return -1;
1447 	}
1448 
1449 	session = perf_session__new(data, false, NULL);
1450 	if (session == NULL) {
1451 		pr_err("Perf session creation failed.\n");
1452 		return -1;
1453 	}
1454 
1455 	init_features(session);
1456 
1457 	session->evlist   = evsel_list;
1458 	perf_stat.session = session;
1459 	perf_stat.record  = true;
1460 	return argc;
1461 }
1462 
1463 static int process_stat_round_event(struct perf_session *session,
1464 				    union perf_event *event)
1465 {
1466 	struct perf_record_stat_round *stat_round = &event->stat_round;
1467 	struct evsel *counter;
1468 	struct timespec tsh, *ts = NULL;
1469 	const char **argv = session->header.env.cmdline_argv;
1470 	int argc = session->header.env.nr_cmdline;
1471 
1472 	evlist__for_each_entry(evsel_list, counter)
1473 		perf_stat_process_counter(&stat_config, counter);
1474 
1475 	if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
1476 		update_stats(&walltime_nsecs_stats, stat_round->time);
1477 
1478 	if (stat_config.interval && stat_round->time) {
1479 		tsh.tv_sec  = stat_round->time / NSEC_PER_SEC;
1480 		tsh.tv_nsec = stat_round->time % NSEC_PER_SEC;
1481 		ts = &tsh;
1482 	}
1483 
1484 	print_counters(ts, argc, argv);
1485 	return 0;
1486 }
1487 
1488 static
1489 int process_stat_config_event(struct perf_session *session,
1490 			      union perf_event *event)
1491 {
1492 	struct perf_tool *tool = session->tool;
1493 	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
1494 
1495 	perf_event__read_stat_config(&stat_config, &event->stat_config);
1496 
1497 	if (perf_cpu_map__empty(st->cpus)) {
1498 		if (st->aggr_mode != AGGR_UNSET)
1499 			pr_warning("warning: processing task data, aggregation mode not set\n");
1500 		return 0;
1501 	}
1502 
1503 	if (st->aggr_mode != AGGR_UNSET)
1504 		stat_config.aggr_mode = st->aggr_mode;
1505 
1506 	if (perf_stat.data.is_pipe)
1507 		perf_stat_init_aggr_mode();
1508 	else
1509 		perf_stat_init_aggr_mode_file(st);
1510 
1511 	return 0;
1512 }
1513 
1514 static int set_maps(struct perf_stat *st)
1515 {
1516 	if (!st->cpus || !st->threads)
1517 		return 0;
1518 
1519 	if (WARN_ONCE(st->maps_allocated, "stats double allocation\n"))
1520 		return -EINVAL;
1521 
1522 	perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads);
1523 
1524 	if (perf_evlist__alloc_stats(evsel_list, true))
1525 		return -ENOMEM;
1526 
1527 	st->maps_allocated = true;
1528 	return 0;
1529 }
1530 
1531 static
1532 int process_thread_map_event(struct perf_session *session,
1533 			     union perf_event *event)
1534 {
1535 	struct perf_tool *tool = session->tool;
1536 	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
1537 
1538 	if (st->threads) {
1539 		pr_warning("Extra thread map event, ignoring.\n");
1540 		return 0;
1541 	}
1542 
1543 	st->threads = thread_map__new_event(&event->thread_map);
1544 	if (!st->threads)
1545 		return -ENOMEM;
1546 
1547 	return set_maps(st);
1548 }
1549 
1550 static
1551 int process_cpu_map_event(struct perf_session *session,
1552 			  union perf_event *event)
1553 {
1554 	struct perf_tool *tool = session->tool;
1555 	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
1556 	struct perf_cpu_map *cpus;
1557 
1558 	if (st->cpus) {
1559 		pr_warning("Extra cpu map event, ignoring.\n");
1560 		return 0;
1561 	}
1562 
1563 	cpus = cpu_map__new_data(&event->cpu_map.data);
1564 	if (!cpus)
1565 		return -ENOMEM;
1566 
1567 	st->cpus = cpus;
1568 	return set_maps(st);
1569 }
1570 
1571 static int runtime_stat_new(struct perf_stat_config *config, int nthreads)
1572 {
1573 	int i;
1574 
1575 	config->stats = calloc(nthreads, sizeof(struct runtime_stat));
1576 	if (!config->stats)
1577 		return -1;
1578 
1579 	config->stats_num = nthreads;
1580 
1581 	for (i = 0; i < nthreads; i++)
1582 		runtime_stat__init(&config->stats[i]);
1583 
1584 	return 0;
1585 }
1586 
1587 static void runtime_stat_delete(struct perf_stat_config *config)
1588 {
1589 	int i;
1590 
1591 	if (!config->stats)
1592 		return;
1593 
1594 	for (i = 0; i < config->stats_num; i++)
1595 		runtime_stat__exit(&config->stats[i]);
1596 
1597 	zfree(&config->stats);
1598 }
1599 
1600 static const char * const stat_report_usage[] = {
1601 	"perf stat report [<options>]",
1602 	NULL,
1603 };
1604 
1605 static struct perf_stat perf_stat = {
1606 	.tool = {
1607 		.attr		= perf_event__process_attr,
1608 		.event_update	= perf_event__process_event_update,
1609 		.thread_map	= process_thread_map_event,
1610 		.cpu_map	= process_cpu_map_event,
1611 		.stat_config	= process_stat_config_event,
1612 		.stat		= perf_event__process_stat_event,
1613 		.stat_round	= process_stat_round_event,
1614 	},
1615 	.aggr_mode = AGGR_UNSET,
1616 };
1617 
1618 static int __cmd_report(int argc, const char **argv)
1619 {
1620 	struct perf_session *session;
1621 	const struct option options[] = {
1622 	OPT_STRING('i', "input", &input_name, "file", "input file name"),
1623 	OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode,
1624 		     "aggregate counts per processor socket", AGGR_SOCKET),
1625 	OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode,
1626 		     "aggregate counts per processor die", AGGR_DIE),
1627 	OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode,
1628 		     "aggregate counts per physical processor core", AGGR_CORE),
1629 	OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode,
1630 		     "disable CPU count aggregation", AGGR_NONE),
1631 	OPT_END()
1632 	};
1633 	struct stat st;
1634 	int ret;
1635 
1636 	argc = parse_options(argc, argv, options, stat_report_usage, 0);
1637 
1638 	if (!input_name || !strlen(input_name)) {
1639 		if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
1640 			input_name = "-";
1641 		else
1642 			input_name = "perf.data";
1643 	}
1644 
1645 	perf_stat.data.path = input_name;
1646 	perf_stat.data.mode = PERF_DATA_MODE_READ;
1647 
1648 	session = perf_session__new(&perf_stat.data, false, &perf_stat.tool);
1649 	if (session == NULL)
1650 		return -1;
1651 
1652 	perf_stat.session  = session;
1653 	stat_config.output = stderr;
1654 	evsel_list         = session->evlist;
1655 
1656 	ret = perf_session__process_events(session);
1657 	if (ret)
1658 		return ret;
1659 
1660 	perf_session__delete(session);
1661 	return 0;
1662 }
1663 
1664 static void setup_system_wide(int forks)
1665 {
1666 	/*
1667 	 * Make system wide (-a) the default target if
1668 	 * no target was specified and one of following
1669 	 * conditions is met:
1670 	 *
1671 	 *   - there's no workload specified
1672 	 *   - there is workload specified but all requested
1673 	 *     events are system wide events
1674 	 */
1675 	if (!target__none(&target))
1676 		return;
1677 
1678 	if (!forks)
1679 		target.system_wide = true;
1680 	else {
1681 		struct evsel *counter;
1682 
1683 		evlist__for_each_entry(evsel_list, counter) {
1684 			if (!counter->system_wide)
1685 				return;
1686 		}
1687 
1688 		if (evsel_list->core.nr_entries)
1689 			target.system_wide = true;
1690 	}
1691 }
1692 
1693 int cmd_stat(int argc, const char **argv)
1694 {
1695 	const char * const stat_usage[] = {
1696 		"perf stat [<options>] [<command>]",
1697 		NULL
1698 	};
1699 	int status = -EINVAL, run_idx;
1700 	const char *mode;
1701 	FILE *output = stderr;
1702 	unsigned int interval, timeout;
1703 	const char * const stat_subcommands[] = { "record", "report" };
1704 
1705 	setlocale(LC_ALL, "");
1706 
1707 	evsel_list = evlist__new();
1708 	if (evsel_list == NULL)
1709 		return -ENOMEM;
1710 
1711 	parse_events__shrink_config_terms();
1712 
1713 	/* String-parsing callback-based options would segfault when negated */
1714 	set_option_flag(stat_options, 'e', "event", PARSE_OPT_NONEG);
1715 	set_option_flag(stat_options, 'M', "metrics", PARSE_OPT_NONEG);
1716 	set_option_flag(stat_options, 'G', "cgroup", PARSE_OPT_NONEG);
1717 
1718 	argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
1719 					(const char **) stat_usage,
1720 					PARSE_OPT_STOP_AT_NON_OPTION);
1721 	perf_stat__collect_metric_expr(evsel_list);
1722 	perf_stat__init_shadow_stats();
1723 
1724 	if (stat_config.csv_sep) {
1725 		stat_config.csv_output = true;
1726 		if (!strcmp(stat_config.csv_sep, "\\t"))
1727 			stat_config.csv_sep = "\t";
1728 	} else
1729 		stat_config.csv_sep = DEFAULT_SEPARATOR;
1730 
1731 	if (argc && !strncmp(argv[0], "rec", 3)) {
1732 		argc = __cmd_record(argc, argv);
1733 		if (argc < 0)
1734 			return -1;
1735 	} else if (argc && !strncmp(argv[0], "rep", 3))
1736 		return __cmd_report(argc, argv);
1737 
1738 	interval = stat_config.interval;
1739 	timeout = stat_config.timeout;
1740 
1741 	/*
1742 	 * For record command the -o is already taken care of.
1743 	 */
1744 	if (!STAT_RECORD && output_name && strcmp(output_name, "-"))
1745 		output = NULL;
1746 
1747 	if (output_name && output_fd) {
1748 		fprintf(stderr, "cannot use both --output and --log-fd\n");
1749 		parse_options_usage(stat_usage, stat_options, "o", 1);
1750 		parse_options_usage(NULL, stat_options, "log-fd", 0);
1751 		goto out;
1752 	}
1753 
1754 	if (stat_config.metric_only && stat_config.aggr_mode == AGGR_THREAD) {
1755 		fprintf(stderr, "--metric-only is not supported with --per-thread\n");
1756 		goto out;
1757 	}
1758 
1759 	if (stat_config.metric_only && stat_config.run_count > 1) {
1760 		fprintf(stderr, "--metric-only is not supported with -r\n");
1761 		goto out;
1762 	}
1763 
1764 	if (stat_config.walltime_run_table && stat_config.run_count <= 1) {
1765 		fprintf(stderr, "--table is only supported with -r\n");
1766 		parse_options_usage(stat_usage, stat_options, "r", 1);
1767 		parse_options_usage(NULL, stat_options, "table", 0);
1768 		goto out;
1769 	}
1770 
1771 	if (output_fd < 0) {
1772 		fprintf(stderr, "argument to --log-fd must be a > 0\n");
1773 		parse_options_usage(stat_usage, stat_options, "log-fd", 0);
1774 		goto out;
1775 	}
1776 
1777 	if (!output) {
1778 		struct timespec tm;
1779 		mode = append_file ? "a" : "w";
1780 
1781 		output = fopen(output_name, mode);
1782 		if (!output) {
1783 			perror("failed to create output file");
1784 			return -1;
1785 		}
1786 		clock_gettime(CLOCK_REALTIME, &tm);
1787 		fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1788 	} else if (output_fd > 0) {
1789 		mode = append_file ? "a" : "w";
1790 		output = fdopen(output_fd, mode);
1791 		if (!output) {
1792 			perror("Failed opening logfd");
1793 			return -errno;
1794 		}
1795 	}
1796 
1797 	stat_config.output = output;
1798 
1799 	/*
1800 	 * let the spreadsheet do the pretty-printing
1801 	 */
1802 	if (stat_config.csv_output) {
1803 		/* User explicitly passed -B? */
1804 		if (big_num_opt == 1) {
1805 			fprintf(stderr, "-B option not supported with -x\n");
1806 			parse_options_usage(stat_usage, stat_options, "B", 1);
1807 			parse_options_usage(NULL, stat_options, "x", 1);
1808 			goto out;
1809 		} else /* Nope, so disable big number formatting */
1810 			stat_config.big_num = false;
1811 	} else if (big_num_opt == 0) /* User passed --no-big-num */
1812 		stat_config.big_num = false;
1813 
1814 	setup_system_wide(argc);
1815 
1816 	/*
1817 	 * Display user/system times only for single
1818 	 * run and when there's specified tracee.
1819 	 */
1820 	if ((stat_config.run_count == 1) && target__none(&target))
1821 		stat_config.ru_display = true;
1822 
1823 	if (stat_config.run_count < 0) {
1824 		pr_err("Run count must be a positive number\n");
1825 		parse_options_usage(stat_usage, stat_options, "r", 1);
1826 		goto out;
1827 	} else if (stat_config.run_count == 0) {
1828 		forever = true;
1829 		stat_config.run_count = 1;
1830 	}
1831 
1832 	if (stat_config.walltime_run_table) {
1833 		stat_config.walltime_run = zalloc(stat_config.run_count * sizeof(stat_config.walltime_run[0]));
1834 		if (!stat_config.walltime_run) {
1835 			pr_err("failed to setup -r option");
1836 			goto out;
1837 		}
1838 	}
1839 
1840 	if ((stat_config.aggr_mode == AGGR_THREAD) &&
1841 		!target__has_task(&target)) {
1842 		if (!target.system_wide || target.cpu_list) {
1843 			fprintf(stderr, "The --per-thread option is only "
1844 				"available when monitoring via -p -t -a "
1845 				"options or only --per-thread.\n");
1846 			parse_options_usage(NULL, stat_options, "p", 1);
1847 			parse_options_usage(NULL, stat_options, "t", 1);
1848 			goto out;
1849 		}
1850 	}
1851 
1852 	/*
1853 	 * no_aggr, cgroup are for system-wide only
1854 	 * --per-thread is aggregated per thread, we dont mix it with cpu mode
1855 	 */
1856 	if (((stat_config.aggr_mode != AGGR_GLOBAL &&
1857 	      stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
1858 	    !target__has_cpu(&target)) {
1859 		fprintf(stderr, "both cgroup and no-aggregation "
1860 			"modes only available in system-wide mode\n");
1861 
1862 		parse_options_usage(stat_usage, stat_options, "G", 1);
1863 		parse_options_usage(NULL, stat_options, "A", 1);
1864 		parse_options_usage(NULL, stat_options, "a", 1);
1865 		goto out;
1866 	}
1867 
1868 	if (add_default_attributes())
1869 		goto out;
1870 
1871 	target__validate(&target);
1872 
1873 	if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide))
1874 		target.per_thread = true;
1875 
1876 	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1877 		if (target__has_task(&target)) {
1878 			pr_err("Problems finding threads of monitor\n");
1879 			parse_options_usage(stat_usage, stat_options, "p", 1);
1880 			parse_options_usage(NULL, stat_options, "t", 1);
1881 		} else if (target__has_cpu(&target)) {
1882 			perror("failed to parse CPUs map");
1883 			parse_options_usage(stat_usage, stat_options, "C", 1);
1884 			parse_options_usage(NULL, stat_options, "a", 1);
1885 		}
1886 		goto out;
1887 	}
1888 
1889 	/*
1890 	 * Initialize thread_map with comm names,
1891 	 * so we could print it out on output.
1892 	 */
1893 	if (stat_config.aggr_mode == AGGR_THREAD) {
1894 		thread_map__read_comms(evsel_list->core.threads);
1895 		if (target.system_wide) {
1896 			if (runtime_stat_new(&stat_config,
1897 				perf_thread_map__nr(evsel_list->core.threads))) {
1898 				goto out;
1899 			}
1900 		}
1901 	}
1902 
1903 	if (stat_config.times && interval)
1904 		interval_count = true;
1905 	else if (stat_config.times && !interval) {
1906 		pr_err("interval-count option should be used together with "
1907 				"interval-print.\n");
1908 		parse_options_usage(stat_usage, stat_options, "interval-count", 0);
1909 		parse_options_usage(stat_usage, stat_options, "I", 1);
1910 		goto out;
1911 	}
1912 
1913 	if (timeout && timeout < 100) {
1914 		if (timeout < 10) {
1915 			pr_err("timeout must be >= 10ms.\n");
1916 			parse_options_usage(stat_usage, stat_options, "timeout", 0);
1917 			goto out;
1918 		} else
1919 			pr_warning("timeout < 100ms. "
1920 				   "The overhead percentage could be high in some cases. "
1921 				   "Please proceed with caution.\n");
1922 	}
1923 	if (timeout && interval) {
1924 		pr_err("timeout option is not supported with interval-print.\n");
1925 		parse_options_usage(stat_usage, stat_options, "timeout", 0);
1926 		parse_options_usage(stat_usage, stat_options, "I", 1);
1927 		goto out;
1928 	}
1929 
1930 	if (perf_evlist__alloc_stats(evsel_list, interval))
1931 		goto out;
1932 
1933 	if (perf_stat_init_aggr_mode())
1934 		goto out;
1935 
1936 	/*
1937 	 * Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless
1938 	 * while avoiding that older tools show confusing messages.
1939 	 *
1940 	 * However for pipe sessions we need to keep it zero,
1941 	 * because script's perf_evsel__check_attr is triggered
1942 	 * by attr->sample_type != 0, and we can't run it on
1943 	 * stat sessions.
1944 	 */
1945 	stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe);
1946 
1947 	/*
1948 	 * We dont want to block the signals - that would cause
1949 	 * child tasks to inherit that and Ctrl-C would not work.
1950 	 * What we want is for Ctrl-C to work in the exec()-ed
1951 	 * task, but being ignored by perf stat itself:
1952 	 */
1953 	atexit(sig_atexit);
1954 	if (!forever)
1955 		signal(SIGINT,  skip_signal);
1956 	signal(SIGCHLD, skip_signal);
1957 	signal(SIGALRM, skip_signal);
1958 	signal(SIGABRT, skip_signal);
1959 
1960 	status = 0;
1961 	for (run_idx = 0; forever || run_idx < stat_config.run_count; run_idx++) {
1962 		if (stat_config.run_count != 1 && verbose > 0)
1963 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
1964 				run_idx + 1);
1965 
1966 		status = run_perf_stat(argc, argv, run_idx);
1967 		if (forever && status != -1) {
1968 			print_counters(NULL, argc, argv);
1969 			perf_stat__reset_stats();
1970 		}
1971 	}
1972 
1973 	if (!forever && status != -1 && !interval)
1974 		print_counters(NULL, argc, argv);
1975 
1976 	if (STAT_RECORD) {
1977 		/*
1978 		 * We synthesize the kernel mmap record just so that older tools
1979 		 * don't emit warnings about not being able to resolve symbols
1980 		 * due to /proc/sys/kernel/kptr_restrict settings and instear provide
1981 		 * a saner message about no samples being in the perf.data file.
1982 		 *
1983 		 * This also serves to suppress a warning about f_header.data.size == 0
1984 		 * in header.c at the moment 'perf stat record' gets introduced, which
1985 		 * is not really needed once we start adding the stat specific PERF_RECORD_
1986 		 * records, but the need to suppress the kptr_restrict messages in older
1987 		 * tools remain  -acme
1988 		 */
1989 		int fd = perf_data__fd(&perf_stat.data);
1990 		int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat,
1991 							     process_synthesized_event,
1992 							     &perf_stat.session->machines.host);
1993 		if (err) {
1994 			pr_warning("Couldn't synthesize the kernel mmap record, harmless, "
1995 				   "older tools may produce warnings about this file\n.");
1996 		}
1997 
1998 		if (!interval) {
1999 			if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL))
2000 				pr_err("failed to write stat round event\n");
2001 		}
2002 
2003 		if (!perf_stat.data.is_pipe) {
2004 			perf_stat.session->header.data_size += perf_stat.bytes_written;
2005 			perf_session__write_header(perf_stat.session, evsel_list, fd, true);
2006 		}
2007 
2008 		evlist__close(evsel_list);
2009 		perf_session__delete(perf_stat.session);
2010 	}
2011 
2012 	perf_stat__exit_aggr_mode();
2013 	perf_evlist__free_stats(evsel_list);
2014 out:
2015 	zfree(&stat_config.walltime_run);
2016 
2017 	if (smi_cost && smi_reset)
2018 		sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
2019 
2020 	evlist__delete(evsel_list);
2021 
2022 	runtime_stat_delete(&stat_config);
2023 
2024 	return status;
2025 }
2026