xref: /openbmc/linux/tools/perf/builtin-stat.c (revision 3ba78bd0)
186470930SIngo Molnar /*
286470930SIngo Molnar  * builtin-stat.c
386470930SIngo Molnar  *
486470930SIngo Molnar  * Builtin stat command: Give a precise performance counters summary
586470930SIngo Molnar  * overview about any workload, CPU or specific PID.
686470930SIngo Molnar  *
786470930SIngo Molnar  * Sample output:
886470930SIngo Molnar 
92cba3ffbSIngo Molnar    $ perf stat ./hackbench 10
1086470930SIngo Molnar 
112cba3ffbSIngo Molnar   Time: 0.118
1286470930SIngo Molnar 
132cba3ffbSIngo Molnar   Performance counter stats for './hackbench 10':
1486470930SIngo Molnar 
152cba3ffbSIngo Molnar        1708.761321 task-clock                #   11.037 CPUs utilized
162cba3ffbSIngo Molnar             41,190 context-switches          #    0.024 M/sec
172cba3ffbSIngo Molnar              6,735 CPU-migrations            #    0.004 M/sec
182cba3ffbSIngo Molnar             17,318 page-faults               #    0.010 M/sec
192cba3ffbSIngo Molnar      5,205,202,243 cycles                    #    3.046 GHz
202cba3ffbSIngo Molnar      3,856,436,920 stalled-cycles-frontend   #   74.09% frontend cycles idle
212cba3ffbSIngo Molnar      1,600,790,871 stalled-cycles-backend    #   30.75% backend  cycles idle
222cba3ffbSIngo Molnar      2,603,501,247 instructions              #    0.50  insns per cycle
232cba3ffbSIngo Molnar                                              #    1.48  stalled cycles per insn
242cba3ffbSIngo Molnar        484,357,498 branches                  #  283.455 M/sec
252cba3ffbSIngo Molnar          6,388,934 branch-misses             #    1.32% of all branches
262cba3ffbSIngo Molnar 
272cba3ffbSIngo Molnar         0.154822978  seconds time elapsed
2886470930SIngo Molnar 
2986470930SIngo Molnar  *
302cba3ffbSIngo Molnar  * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
3186470930SIngo Molnar  *
3286470930SIngo Molnar  * Improvements and fixes by:
3386470930SIngo Molnar  *
3486470930SIngo Molnar  *   Arjan van de Ven <arjan@linux.intel.com>
3586470930SIngo Molnar  *   Yanmin Zhang <yanmin.zhang@intel.com>
3686470930SIngo Molnar  *   Wu Fengguang <fengguang.wu@intel.com>
3786470930SIngo Molnar  *   Mike Galbraith <efault@gmx.de>
3886470930SIngo Molnar  *   Paul Mackerras <paulus@samba.org>
396e750a8fSJaswinder Singh Rajput  *   Jaswinder Singh Rajput <jaswinder@kernel.org>
4086470930SIngo Molnar  *
4186470930SIngo Molnar  * Released under the GPL v2. (and only v2, not any later version)
4286470930SIngo Molnar  */
4386470930SIngo Molnar 
4486470930SIngo Molnar #include "perf.h"
4586470930SIngo Molnar #include "builtin.h"
46f14d5707SArnaldo Carvalho de Melo #include "util/cgroup.h"
4786470930SIngo Molnar #include "util/util.h"
484b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h>
4986470930SIngo Molnar #include "util/parse-events.h"
504cabc3d1SAndi Kleen #include "util/pmu.h"
518f28827aSFrederic Weisbecker #include "util/event.h"
52361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h"
5369aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h"
548f28827aSFrederic Weisbecker #include "util/debug.h"
55a5d243d0SIngo Molnar #include "util/color.h"
560007eceaSXiao Guangrong #include "util/stat.h"
5760666c63SLiming Wang #include "util/header.h"
58a12b51c4SPaul Mackerras #include "util/cpumap.h"
59d6d901c2SZhang, Yanmin #include "util/thread.h"
60fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h"
61d809560bSJiri Olsa #include "util/counts.h"
624979d0c7SJiri Olsa #include "util/session.h"
6386470930SIngo Molnar 
641f16c575SPeter Zijlstra #include <stdlib.h>
6586470930SIngo Molnar #include <sys/prctl.h>
665af52b51SStephane Eranian #include <locale.h>
6786470930SIngo Molnar 
68d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR	" "
692cee77c4SDavid Ahern #define CNTR_NOT_SUPPORTED	"<not supported>"
702cee77c4SDavid Ahern #define CNTR_NOT_COUNTED	"<not counted>"
71d7470b6aSStephane Eranian 
72d4f63a47SJiri Olsa static void print_counters(struct timespec *ts, int argc, const char **argv);
7313370a9bSStephane Eranian 
744cabc3d1SAndi Kleen /* Default events used for perf stat -T */
75a454742cSJiri Olsa static const char *transaction_attrs = {
76a454742cSJiri Olsa 	"task-clock,"
774cabc3d1SAndi Kleen 	"{"
784cabc3d1SAndi Kleen 	"instructions,"
794cabc3d1SAndi Kleen 	"cycles,"
804cabc3d1SAndi Kleen 	"cpu/cycles-t/,"
814cabc3d1SAndi Kleen 	"cpu/tx-start/,"
824cabc3d1SAndi Kleen 	"cpu/el-start/,"
834cabc3d1SAndi Kleen 	"cpu/cycles-ct/"
844cabc3d1SAndi Kleen 	"}"
854cabc3d1SAndi Kleen };
864cabc3d1SAndi Kleen 
874cabc3d1SAndi Kleen /* More limited version when the CPU does not have all events. */
88a454742cSJiri Olsa static const char * transaction_limited_attrs = {
89a454742cSJiri Olsa 	"task-clock,"
904cabc3d1SAndi Kleen 	"{"
914cabc3d1SAndi Kleen 	"instructions,"
924cabc3d1SAndi Kleen 	"cycles,"
934cabc3d1SAndi Kleen 	"cpu/cycles-t/,"
944cabc3d1SAndi Kleen 	"cpu/tx-start/"
954cabc3d1SAndi Kleen 	"}"
964cabc3d1SAndi Kleen };
974cabc3d1SAndi Kleen 
98666e6d48SRobert Richter static struct perf_evlist	*evsel_list;
99361c99a6SArnaldo Carvalho de Melo 
100602ad878SArnaldo Carvalho de Melo static struct target target = {
10177a6f014SNamhyung Kim 	.uid	= UINT_MAX,
10277a6f014SNamhyung Kim };
10342202dd5SIngo Molnar 
1041e5a2931SJiri Olsa typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);
1051e5a2931SJiri Olsa 
1063d632595SJaswinder Singh Rajput static int			run_count			=  1;
1072e6cdf99SStephane Eranian static bool			no_inherit			= false;
108d07f0b12SStephane Eranian static volatile pid_t		child_pid			= -1;
109c0555642SIan Munsie static bool			null_run			=  false;
1102cba3ffbSIngo Molnar static int			detailed_run			=  0;
1114cabc3d1SAndi Kleen static bool			transaction_run;
112201e0b06SArnaldo Carvalho de Melo static bool			big_num				=  true;
113d7470b6aSStephane Eranian static int			big_num_opt			=  -1;
114d7470b6aSStephane Eranian static const char		*csv_sep			= NULL;
115d7470b6aSStephane Eranian static bool			csv_output			= false;
11643bece79SLin Ming static bool			group				= false;
1171f16c575SPeter Zijlstra static const char		*pre_cmd			= NULL;
1181f16c575SPeter Zijlstra static const char		*post_cmd			= NULL;
1191f16c575SPeter Zijlstra static bool			sync_run			= false;
12041191688SAndi Kleen static unsigned int		initial_delay			= 0;
121410136f5SStephane Eranian static unsigned int		unit_width			= 4; /* strlen("unit") */
122a7e191c3SFrederik Deweerdt static bool			forever				= false;
12313370a9bSStephane Eranian static struct timespec		ref_time;
12486ee6e18SStephane Eranian static struct cpu_map		*aggr_map;
1251e5a2931SJiri Olsa static aggr_get_id_t		aggr_get_id;
126e0547311SJiri Olsa static bool			append_file;
127e0547311SJiri Olsa static const char		*output_name;
128e0547311SJiri Olsa static int			output_fd;
1295af52b51SStephane Eranian 
1304979d0c7SJiri Olsa struct perf_stat {
1314979d0c7SJiri Olsa 	bool			 record;
1324979d0c7SJiri Olsa 	struct perf_data_file	 file;
1334979d0c7SJiri Olsa 	struct perf_session	*session;
1344979d0c7SJiri Olsa 	u64			 bytes_written;
1354979d0c7SJiri Olsa };
1364979d0c7SJiri Olsa 
1374979d0c7SJiri Olsa static struct perf_stat		perf_stat;
1384979d0c7SJiri Olsa #define STAT_RECORD		perf_stat.record
1394979d0c7SJiri Olsa 
14060666c63SLiming Wang static volatile int done = 0;
14160666c63SLiming Wang 
142421a50f3SJiri Olsa static struct perf_stat_config stat_config = {
143421a50f3SJiri Olsa 	.aggr_mode	= AGGR_GLOBAL,
144711a572eSJiri Olsa 	.scale		= true,
145421a50f3SJiri Olsa };
146421a50f3SJiri Olsa 
14713370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a,
14813370a9bSStephane Eranian 				 struct timespec *b)
14913370a9bSStephane Eranian {
15013370a9bSStephane Eranian 	r->tv_sec = a->tv_sec - b->tv_sec;
15113370a9bSStephane Eranian 	if (a->tv_nsec < b->tv_nsec) {
15213370a9bSStephane Eranian 		r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec;
15313370a9bSStephane Eranian 		r->tv_sec--;
15413370a9bSStephane Eranian 	} else {
15513370a9bSStephane Eranian 		r->tv_nsec = a->tv_nsec - b->tv_nsec ;
15613370a9bSStephane Eranian 	}
15713370a9bSStephane Eranian }
15813370a9bSStephane Eranian 
159254ecbc7SJiri Olsa static void perf_stat__reset_stats(void)
160254ecbc7SJiri Olsa {
161254ecbc7SJiri Olsa 	perf_evlist__reset_stats(evsel_list);
162f87027b9SJiri Olsa 	perf_stat__reset_shadow_stats();
1631eda3b21SJiri Olsa }
1641eda3b21SJiri Olsa 
165cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel)
16686470930SIngo Molnar {
16769aad6f1SArnaldo Carvalho de Melo 	struct perf_event_attr *attr = &evsel->attr;
168727ab04eSArnaldo Carvalho de Melo 
169711a572eSJiri Olsa 	if (stat_config.scale)
17086470930SIngo Molnar 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
17186470930SIngo Molnar 				    PERF_FORMAT_TOTAL_TIME_RUNNING;
17286470930SIngo Molnar 
1732e6cdf99SStephane Eranian 	attr->inherit = !no_inherit;
1745d2cd909SArnaldo Carvalho de Melo 
1756acd8e92SJiri Olsa 	/*
1766acd8e92SJiri Olsa 	 * Some events get initialized with sample_(period/type) set,
1776acd8e92SJiri Olsa 	 * like tracepoints. Clear it up for counting.
1786acd8e92SJiri Olsa 	 */
1796acd8e92SJiri Olsa 	attr->sample_period = 0;
1804979d0c7SJiri Olsa 	/*
1814979d0c7SJiri Olsa 	 * But set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless
1824979d0c7SJiri Olsa 	 * while avoiding that older tools show confusing messages.
1834979d0c7SJiri Olsa 	 */
1844979d0c7SJiri Olsa 	attr->sample_type   = PERF_SAMPLE_IDENTIFIER;
1856acd8e92SJiri Olsa 
18667ccdecdSJiri Olsa 	/*
18767ccdecdSJiri Olsa 	 * Disabling all counters initially, they will be enabled
18867ccdecdSJiri Olsa 	 * either manually by us or by kernel via enable_on_exec
18967ccdecdSJiri Olsa 	 * set later.
19067ccdecdSJiri Olsa 	 */
191c8280cecSJiri Olsa 	if (perf_evsel__is_group_leader(evsel)) {
19267ccdecdSJiri Olsa 		attr->disabled = 1;
19367ccdecdSJiri Olsa 
194c8280cecSJiri Olsa 		/*
195c8280cecSJiri Olsa 		 * In case of initial_delay we enable tracee
196c8280cecSJiri Olsa 		 * events manually.
197c8280cecSJiri Olsa 		 */
198c8280cecSJiri Olsa 		if (target__none(&target) && !initial_delay)
199c8280cecSJiri Olsa 			attr->enable_on_exec = 1;
200c8280cecSJiri Olsa 	}
201c8280cecSJiri Olsa 
202602ad878SArnaldo Carvalho de Melo 	if (target__has_cpu(&target))
203594ac61aSArnaldo Carvalho de Melo 		return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
2045622c07bSStephane Eranian 
205594ac61aSArnaldo Carvalho de Melo 	return perf_evsel__open_per_thread(evsel, evsel_list->threads);
20686470930SIngo Molnar }
20786470930SIngo Molnar 
20886470930SIngo Molnar /*
20986470930SIngo Molnar  * Does the counter have nsecs as a unit?
21086470930SIngo Molnar  */
211daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel)
21286470930SIngo Molnar {
213daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
214daec78a0SArnaldo Carvalho de Melo 	    perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
21586470930SIngo Molnar 		return 1;
21686470930SIngo Molnar 
21786470930SIngo Molnar 	return 0;
21886470930SIngo Molnar }
21986470930SIngo Molnar 
2204979d0c7SJiri Olsa static int perf_stat__write(struct perf_stat *stat, void *bf, size_t size)
2214979d0c7SJiri Olsa {
2224979d0c7SJiri Olsa 	if (perf_data_file__write(stat->session->file, bf, size) < 0) {
2234979d0c7SJiri Olsa 		pr_err("failed to write perf data, error: %m\n");
2244979d0c7SJiri Olsa 		return -1;
2254979d0c7SJiri Olsa 	}
2264979d0c7SJiri Olsa 
2274979d0c7SJiri Olsa 	stat->bytes_written += size;
2284979d0c7SJiri Olsa 	return 0;
2294979d0c7SJiri Olsa }
2304979d0c7SJiri Olsa 
2314979d0c7SJiri Olsa static int process_synthesized_event(struct perf_tool *tool,
2324979d0c7SJiri Olsa 				     union perf_event *event,
2334979d0c7SJiri Olsa 				     struct perf_sample *sample __maybe_unused,
2344979d0c7SJiri Olsa 				     struct machine *machine __maybe_unused)
2354979d0c7SJiri Olsa {
2364979d0c7SJiri Olsa 	struct perf_stat *stat = (void *)tool;
2374979d0c7SJiri Olsa 	return perf_stat__write(stat, event, event->header.size);
2384979d0c7SJiri Olsa }
2394979d0c7SJiri Olsa 
240f5b4a9c3SStephane Eranian /*
241f5b4a9c3SStephane Eranian  * Read out the results of a single counter:
242f5b4a9c3SStephane Eranian  * do not aggregate counts across CPUs in system-wide mode
243f5b4a9c3SStephane Eranian  */
244c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter)
245f5b4a9c3SStephane Eranian {
2469bf1a529SJiri Olsa 	int nthreads = thread_map__nr(evsel_list->threads);
2479bf1a529SJiri Olsa 	int ncpus = perf_evsel__nr_cpus(counter);
2489bf1a529SJiri Olsa 	int cpu, thread;
249f5b4a9c3SStephane Eranian 
2503b4331d9SSuzuki K. Poulose 	if (!counter->supported)
2513b4331d9SSuzuki K. Poulose 		return -ENOENT;
2523b4331d9SSuzuki K. Poulose 
2539bf1a529SJiri Olsa 	if (counter->system_wide)
2549bf1a529SJiri Olsa 		nthreads = 1;
2559bf1a529SJiri Olsa 
2569bf1a529SJiri Olsa 	for (thread = 0; thread < nthreads; thread++) {
2579bf1a529SJiri Olsa 		for (cpu = 0; cpu < ncpus; cpu++) {
2583b3eb044SJiri Olsa 			struct perf_counts_values *count;
2593b3eb044SJiri Olsa 
2603b3eb044SJiri Olsa 			count = perf_counts(counter->counts, cpu, thread);
2613b3eb044SJiri Olsa 			if (perf_evsel__read(counter, cpu, thread, count))
262c52b12edSArnaldo Carvalho de Melo 				return -1;
263f5b4a9c3SStephane Eranian 		}
2649bf1a529SJiri Olsa 	}
265c52b12edSArnaldo Carvalho de Melo 
266c52b12edSArnaldo Carvalho de Melo 	return 0;
26786470930SIngo Molnar }
26886470930SIngo Molnar 
2695fc472a6SJiri Olsa static void read_counters(bool close_counters)
270106a94a0SJiri Olsa {
271106a94a0SJiri Olsa 	struct perf_evsel *counter;
272106a94a0SJiri Olsa 
273106a94a0SJiri Olsa 	evlist__for_each(evsel_list, counter) {
2743b3eb044SJiri Olsa 		if (read_counter(counter))
275245bad8eSAndi Kleen 			pr_debug("failed to read counter %s\n", counter->name);
2763b3eb044SJiri Olsa 
277f80010ebSJiri Olsa 		if (perf_stat_process_counter(&stat_config, counter))
2783b3eb044SJiri Olsa 			pr_warning("failed to process counter %s\n", counter->name);
279106a94a0SJiri Olsa 
2805fc472a6SJiri Olsa 		if (close_counters) {
281106a94a0SJiri Olsa 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
282106a94a0SJiri Olsa 					     thread_map__nr(evsel_list->threads));
283106a94a0SJiri Olsa 		}
284106a94a0SJiri Olsa 	}
285106a94a0SJiri Olsa }
286106a94a0SJiri Olsa 
287ba411a95SJiri Olsa static void process_interval(void)
28813370a9bSStephane Eranian {
28913370a9bSStephane Eranian 	struct timespec ts, rs;
29013370a9bSStephane Eranian 
291106a94a0SJiri Olsa 	read_counters(false);
29286ee6e18SStephane Eranian 
29313370a9bSStephane Eranian 	clock_gettime(CLOCK_MONOTONIC, &ts);
29413370a9bSStephane Eranian 	diff_timespec(&rs, &ts, &ref_time);
29513370a9bSStephane Eranian 
296d4f63a47SJiri Olsa 	print_counters(&rs, 0, NULL);
29713370a9bSStephane Eranian }
29813370a9bSStephane Eranian 
29967ccdecdSJiri Olsa static void enable_counters(void)
30041191688SAndi Kleen {
30167ccdecdSJiri Olsa 	if (initial_delay)
30241191688SAndi Kleen 		usleep(initial_delay * 1000);
30367ccdecdSJiri Olsa 
30467ccdecdSJiri Olsa 	/*
30567ccdecdSJiri Olsa 	 * We need to enable counters only if:
30667ccdecdSJiri Olsa 	 * - we don't have tracee (attaching to task or cpu)
30767ccdecdSJiri Olsa 	 * - we have initial delay configured
30867ccdecdSJiri Olsa 	 */
30967ccdecdSJiri Olsa 	if (!target__none(&target) || initial_delay)
310ab46db0aSJiri Olsa 		perf_evlist__enable(evsel_list);
31141191688SAndi Kleen }
31241191688SAndi Kleen 
313f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno;
3146af206fdSArnaldo Carvalho de Melo 
3156af206fdSArnaldo Carvalho de Melo /*
3166af206fdSArnaldo Carvalho de Melo  * perf_evlist__prepare_workload will send a SIGUSR1
3176af206fdSArnaldo Carvalho de Melo  * if the fork fails, since we asked by setting its
3186af206fdSArnaldo Carvalho de Melo  * want_signal to true.
3196af206fdSArnaldo Carvalho de Melo  */
320f33cbe72SArnaldo Carvalho de Melo static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
321f33cbe72SArnaldo Carvalho de Melo 					void *ucontext __maybe_unused)
3226af206fdSArnaldo Carvalho de Melo {
323f33cbe72SArnaldo Carvalho de Melo 	workload_exec_errno = info->si_value.sival_int;
3246af206fdSArnaldo Carvalho de Melo }
3256af206fdSArnaldo Carvalho de Melo 
326acf28922SNamhyung Kim static int __run_perf_stat(int argc, const char **argv)
32786470930SIngo Molnar {
328ec0d3d1fSJiri Olsa 	int interval = stat_config.interval;
32956e52e85SArnaldo Carvalho de Melo 	char msg[512];
33086470930SIngo Molnar 	unsigned long long t0, t1;
331cac21425SJiri Olsa 	struct perf_evsel *counter;
33213370a9bSStephane Eranian 	struct timespec ts;
333410136f5SStephane Eranian 	size_t l;
33442202dd5SIngo Molnar 	int status = 0;
3356be2850eSZhang, Yanmin 	const bool forks = (argc > 0);
33686470930SIngo Molnar 
33713370a9bSStephane Eranian 	if (interval) {
33813370a9bSStephane Eranian 		ts.tv_sec  = interval / 1000;
33913370a9bSStephane Eranian 		ts.tv_nsec = (interval % 1000) * 1000000;
34013370a9bSStephane Eranian 	} else {
34113370a9bSStephane Eranian 		ts.tv_sec  = 1;
34213370a9bSStephane Eranian 		ts.tv_nsec = 0;
34313370a9bSStephane Eranian 	}
34413370a9bSStephane Eranian 
345acf28922SNamhyung Kim 	if (forks) {
346735f7e0bSArnaldo Carvalho de Melo 		if (perf_evlist__prepare_workload(evsel_list, &target, argv, false,
347735f7e0bSArnaldo Carvalho de Melo 						  workload_exec_failed_signal) < 0) {
348acf28922SNamhyung Kim 			perror("failed to prepare workload");
349fceda7feSDavid Ahern 			return -1;
350051ae7f7SPaul Mackerras 		}
351d20a47e7SNamhyung Kim 		child_pid = evsel_list->workload.pid;
35260666c63SLiming Wang 	}
353051ae7f7SPaul Mackerras 
3546a4bb04cSJiri Olsa 	if (group)
35563dab225SArnaldo Carvalho de Melo 		perf_evlist__set_leader(evsel_list);
3566a4bb04cSJiri Olsa 
3570050f7aaSArnaldo Carvalho de Melo 	evlist__for_each(evsel_list, counter) {
358cac21425SJiri Olsa 		if (create_perf_stat_counter(counter) < 0) {
359979987a5SDavid Ahern 			/*
360979987a5SDavid Ahern 			 * PPC returns ENXIO for HW counters until 2.6.37
361979987a5SDavid Ahern 			 * (behavior changed with commit b0a873e).
362979987a5SDavid Ahern 			 */
36338f6ae1eSAnton Blanchard 			if (errno == EINVAL || errno == ENOSYS ||
364979987a5SDavid Ahern 			    errno == ENOENT || errno == EOPNOTSUPP ||
365979987a5SDavid Ahern 			    errno == ENXIO) {
366c63ca0c0SDavid Ahern 				if (verbose)
367c63ca0c0SDavid Ahern 					ui__warning("%s event is not supported by the kernel.\n",
3687289f83cSArnaldo Carvalho de Melo 						    perf_evsel__name(counter));
3692cee77c4SDavid Ahern 				counter->supported = false;
370cb5ef600SKan Liang 
371cb5ef600SKan Liang 				if ((counter->leader != counter) ||
372cb5ef600SKan Liang 				    !(counter->leader->nr_members > 1))
373ede70290SIngo Molnar 					continue;
374c63ca0c0SDavid Ahern 			}
375ede70290SIngo Molnar 
37656e52e85SArnaldo Carvalho de Melo 			perf_evsel__open_strerror(counter, &target,
37756e52e85SArnaldo Carvalho de Melo 						  errno, msg, sizeof(msg));
37856e52e85SArnaldo Carvalho de Melo 			ui__error("%s\n", msg);
37956e52e85SArnaldo Carvalho de Melo 
380084ab9f8SArnaldo Carvalho de Melo 			if (child_pid != -1)
381084ab9f8SArnaldo Carvalho de Melo 				kill(child_pid, SIGTERM);
382fceda7feSDavid Ahern 
383084ab9f8SArnaldo Carvalho de Melo 			return -1;
384084ab9f8SArnaldo Carvalho de Melo 		}
3852cee77c4SDavid Ahern 		counter->supported = true;
386410136f5SStephane Eranian 
387410136f5SStephane Eranian 		l = strlen(counter->unit);
388410136f5SStephane Eranian 		if (l > unit_width)
389410136f5SStephane Eranian 			unit_width = l;
39048290609SArnaldo Carvalho de Melo 	}
39186470930SIngo Molnar 
39223d4aad4SArnaldo Carvalho de Melo 	if (perf_evlist__apply_filters(evsel_list, &counter)) {
39323d4aad4SArnaldo Carvalho de Melo 		error("failed to set filter \"%s\" on event %s with %d (%s)\n",
39423d4aad4SArnaldo Carvalho de Melo 			counter->filter, perf_evsel__name(counter), errno,
395759e612bSMasami Hiramatsu 			strerror_r(errno, msg, sizeof(msg)));
396cfd748aeSFrederic Weisbecker 		return -1;
397cfd748aeSFrederic Weisbecker 	}
398cfd748aeSFrederic Weisbecker 
3994979d0c7SJiri Olsa 	if (STAT_RECORD) {
4004979d0c7SJiri Olsa 		int err, fd = perf_data_file__fd(&perf_stat.file);
4014979d0c7SJiri Olsa 
4024979d0c7SJiri Olsa 		err = perf_session__write_header(perf_stat.session, evsel_list,
4034979d0c7SJiri Olsa 						 fd, false);
4044979d0c7SJiri Olsa 		if (err < 0)
4054979d0c7SJiri Olsa 			return err;
4064979d0c7SJiri Olsa 	}
4074979d0c7SJiri Olsa 
40886470930SIngo Molnar 	/*
40986470930SIngo Molnar 	 * Enable counters and exec the command:
41086470930SIngo Molnar 	 */
41186470930SIngo Molnar 	t0 = rdclock();
41213370a9bSStephane Eranian 	clock_gettime(CLOCK_MONOTONIC, &ref_time);
41386470930SIngo Molnar 
41460666c63SLiming Wang 	if (forks) {
415acf28922SNamhyung Kim 		perf_evlist__start_workload(evsel_list);
41667ccdecdSJiri Olsa 		enable_counters();
417acf28922SNamhyung Kim 
41813370a9bSStephane Eranian 		if (interval) {
41913370a9bSStephane Eranian 			while (!waitpid(child_pid, &status, WNOHANG)) {
42013370a9bSStephane Eranian 				nanosleep(&ts, NULL);
421ba411a95SJiri Olsa 				process_interval();
42213370a9bSStephane Eranian 			}
42313370a9bSStephane Eranian 		}
42442202dd5SIngo Molnar 		wait(&status);
4256af206fdSArnaldo Carvalho de Melo 
426f33cbe72SArnaldo Carvalho de Melo 		if (workload_exec_errno) {
427f33cbe72SArnaldo Carvalho de Melo 			const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
428f33cbe72SArnaldo Carvalho de Melo 			pr_err("Workload failed: %s\n", emsg);
4296af206fdSArnaldo Carvalho de Melo 			return -1;
430f33cbe72SArnaldo Carvalho de Melo 		}
4316af206fdSArnaldo Carvalho de Melo 
43233e49ea7SAndi Kleen 		if (WIFSIGNALED(status))
43333e49ea7SAndi Kleen 			psignal(WTERMSIG(status), argv[0]);
43460666c63SLiming Wang 	} else {
43567ccdecdSJiri Olsa 		enable_counters();
43613370a9bSStephane Eranian 		while (!done) {
43713370a9bSStephane Eranian 			nanosleep(&ts, NULL);
43813370a9bSStephane Eranian 			if (interval)
439ba411a95SJiri Olsa 				process_interval();
44013370a9bSStephane Eranian 		}
44160666c63SLiming Wang 	}
44286470930SIngo Molnar 
44386470930SIngo Molnar 	t1 = rdclock();
44486470930SIngo Molnar 
4459e9772c4SPeter Zijlstra 	update_stats(&walltime_nsecs_stats, t1 - t0);
44642202dd5SIngo Molnar 
447106a94a0SJiri Olsa 	read_counters(true);
448c52b12edSArnaldo Carvalho de Melo 
44942202dd5SIngo Molnar 	return WEXITSTATUS(status);
45042202dd5SIngo Molnar }
45142202dd5SIngo Molnar 
45241cde476SArnaldo Carvalho de Melo static int run_perf_stat(int argc, const char **argv)
4531f16c575SPeter Zijlstra {
4541f16c575SPeter Zijlstra 	int ret;
4551f16c575SPeter Zijlstra 
4561f16c575SPeter Zijlstra 	if (pre_cmd) {
4571f16c575SPeter Zijlstra 		ret = system(pre_cmd);
4581f16c575SPeter Zijlstra 		if (ret)
4591f16c575SPeter Zijlstra 			return ret;
4601f16c575SPeter Zijlstra 	}
4611f16c575SPeter Zijlstra 
4621f16c575SPeter Zijlstra 	if (sync_run)
4631f16c575SPeter Zijlstra 		sync();
4641f16c575SPeter Zijlstra 
4651f16c575SPeter Zijlstra 	ret = __run_perf_stat(argc, argv);
4661f16c575SPeter Zijlstra 	if (ret)
4671f16c575SPeter Zijlstra 		return ret;
4681f16c575SPeter Zijlstra 
4691f16c575SPeter Zijlstra 	if (post_cmd) {
4701f16c575SPeter Zijlstra 		ret = system(post_cmd);
4711f16c575SPeter Zijlstra 		if (ret)
4721f16c575SPeter Zijlstra 			return ret;
4731f16c575SPeter Zijlstra 	}
4741f16c575SPeter Zijlstra 
4751f16c575SPeter Zijlstra 	return ret;
4761f16c575SPeter Zijlstra }
4771f16c575SPeter Zijlstra 
478d73515c0SAndi Kleen static void print_running(u64 run, u64 ena)
479d73515c0SAndi Kleen {
480d73515c0SAndi Kleen 	if (csv_output) {
4815821522eSJiri Olsa 		fprintf(stat_config.output, "%s%" PRIu64 "%s%.2f",
482d73515c0SAndi Kleen 					csv_sep,
483d73515c0SAndi Kleen 					run,
484d73515c0SAndi Kleen 					csv_sep,
485d73515c0SAndi Kleen 					ena ? 100.0 * run / ena : 100.0);
486d73515c0SAndi Kleen 	} else if (run != ena) {
4875821522eSJiri Olsa 		fprintf(stat_config.output, "  (%.2f%%)", 100.0 * run / ena);
488d73515c0SAndi Kleen 	}
489d73515c0SAndi Kleen }
490d73515c0SAndi Kleen 
491f99844cbSIngo Molnar static void print_noise_pct(double total, double avg)
492f99844cbSIngo Molnar {
4930007eceaSXiao Guangrong 	double pct = rel_stddev_stats(total, avg);
494f99844cbSIngo Molnar 
4953ae9a34dSZhengyu He 	if (csv_output)
4965821522eSJiri Olsa 		fprintf(stat_config.output, "%s%.2f%%", csv_sep, pct);
497a1bca6ccSJim Cromie 	else if (pct)
4985821522eSJiri Olsa 		fprintf(stat_config.output, "  ( +-%6.2f%% )", pct);
499f99844cbSIngo Molnar }
500f99844cbSIngo Molnar 
50169aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg)
50242202dd5SIngo Molnar {
503581cc8a2SJiri Olsa 	struct perf_stat_evsel *ps;
50469aad6f1SArnaldo Carvalho de Melo 
505849abde9SPeter Zijlstra 	if (run_count == 1)
506849abde9SPeter Zijlstra 		return;
507849abde9SPeter Zijlstra 
50869aad6f1SArnaldo Carvalho de Melo 	ps = evsel->priv;
509f99844cbSIngo Molnar 	print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
51042202dd5SIngo Molnar }
51142202dd5SIngo Molnar 
51212c08a9fSStephane Eranian static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
51342202dd5SIngo Molnar {
514421a50f3SJiri Olsa 	switch (stat_config.aggr_mode) {
51512c08a9fSStephane Eranian 	case AGGR_CORE:
5165821522eSJiri Olsa 		fprintf(stat_config.output, "S%d-C%*d%s%*d%s",
51712c08a9fSStephane Eranian 			cpu_map__id_to_socket(id),
51812c08a9fSStephane Eranian 			csv_output ? 0 : -8,
51912c08a9fSStephane Eranian 			cpu_map__id_to_cpu(id),
52012c08a9fSStephane Eranian 			csv_sep,
52112c08a9fSStephane Eranian 			csv_output ? 0 : 4,
52212c08a9fSStephane Eranian 			nr,
52312c08a9fSStephane Eranian 			csv_sep);
52412c08a9fSStephane Eranian 		break;
52586ee6e18SStephane Eranian 	case AGGR_SOCKET:
5265821522eSJiri Olsa 		fprintf(stat_config.output, "S%*d%s%*d%s",
527d7e7a451SStephane Eranian 			csv_output ? 0 : -5,
52812c08a9fSStephane Eranian 			id,
529d7e7a451SStephane Eranian 			csv_sep,
530d7e7a451SStephane Eranian 			csv_output ? 0 : 4,
531d7e7a451SStephane Eranian 			nr,
532d7e7a451SStephane Eranian 			csv_sep);
53386ee6e18SStephane Eranian 			break;
53486ee6e18SStephane Eranian 	case AGGR_NONE:
5355821522eSJiri Olsa 		fprintf(stat_config.output, "CPU%*d%s",
536d7470b6aSStephane Eranian 			csv_output ? 0 : -4,
53712c08a9fSStephane Eranian 			perf_evsel__cpus(evsel)->map[id], csv_sep);
53886ee6e18SStephane Eranian 		break;
53932b8af82SJiri Olsa 	case AGGR_THREAD:
5405821522eSJiri Olsa 		fprintf(stat_config.output, "%*s-%*d%s",
54132b8af82SJiri Olsa 			csv_output ? 0 : 16,
54232b8af82SJiri Olsa 			thread_map__comm(evsel->threads, id),
54332b8af82SJiri Olsa 			csv_output ? 0 : -8,
54432b8af82SJiri Olsa 			thread_map__pid(evsel->threads, id),
54532b8af82SJiri Olsa 			csv_sep);
54632b8af82SJiri Olsa 		break;
54786ee6e18SStephane Eranian 	case AGGR_GLOBAL:
548208df99eSJiri Olsa 	case AGGR_UNSET:
54986ee6e18SStephane Eranian 	default:
55086ee6e18SStephane Eranian 		break;
55186ee6e18SStephane Eranian 	}
55286ee6e18SStephane Eranian }
553d7470b6aSStephane Eranian 
554da88c7f7SAndi Kleen static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
55586ee6e18SStephane Eranian {
5565821522eSJiri Olsa 	FILE *output = stat_config.output;
55786ee6e18SStephane Eranian 	double msecs = avg / 1e6;
558410136f5SStephane Eranian 	const char *fmt_v, *fmt_n;
5594bbe5a61SDavid Ahern 	char name[25];
56086ee6e18SStephane Eranian 
561410136f5SStephane Eranian 	fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
562410136f5SStephane Eranian 	fmt_n = csv_output ? "%s" : "%-25s";
563410136f5SStephane Eranian 
564da88c7f7SAndi Kleen 	aggr_printout(evsel, id, nr);
56586ee6e18SStephane Eranian 
5664bbe5a61SDavid Ahern 	scnprintf(name, sizeof(name), "%s%s",
5674bbe5a61SDavid Ahern 		  perf_evsel__name(evsel), csv_output ? "" : " (msec)");
568410136f5SStephane Eranian 
569410136f5SStephane Eranian 	fprintf(output, fmt_v, msecs, csv_sep);
570410136f5SStephane Eranian 
571410136f5SStephane Eranian 	if (csv_output)
572410136f5SStephane Eranian 		fprintf(output, "%s%s", evsel->unit, csv_sep);
573410136f5SStephane Eranian 	else
574410136f5SStephane Eranian 		fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
575410136f5SStephane Eranian 
576410136f5SStephane Eranian 	fprintf(output, fmt_n, name);
577d7470b6aSStephane Eranian 
578023695d9SStephane Eranian 	if (evsel->cgrp)
5794aa9015fSStephane Eranian 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
58042202dd5SIngo Molnar }
58142202dd5SIngo Molnar 
582556b1fb7SJiri Olsa static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
583556b1fb7SJiri Olsa {
5845821522eSJiri Olsa 	FILE *output = stat_config.output;
585556b1fb7SJiri Olsa 	double sc =  evsel->scale;
586556b1fb7SJiri Olsa 	const char *fmt;
587556b1fb7SJiri Olsa 
588556b1fb7SJiri Olsa 	if (csv_output) {
589556b1fb7SJiri Olsa 		fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
590556b1fb7SJiri Olsa 	} else {
591556b1fb7SJiri Olsa 		if (big_num)
592556b1fb7SJiri Olsa 			fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
593556b1fb7SJiri Olsa 		else
594556b1fb7SJiri Olsa 			fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
595556b1fb7SJiri Olsa 	}
596556b1fb7SJiri Olsa 
597556b1fb7SJiri Olsa 	aggr_printout(evsel, id, nr);
598556b1fb7SJiri Olsa 
599556b1fb7SJiri Olsa 	fprintf(output, fmt, avg, csv_sep);
600556b1fb7SJiri Olsa 
601556b1fb7SJiri Olsa 	if (evsel->unit)
602556b1fb7SJiri Olsa 		fprintf(output, "%-*s%s",
603556b1fb7SJiri Olsa 			csv_output ? 0 : unit_width,
604556b1fb7SJiri Olsa 			evsel->unit, csv_sep);
605556b1fb7SJiri Olsa 
606556b1fb7SJiri Olsa 	fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
607556b1fb7SJiri Olsa 
608556b1fb7SJiri Olsa 	if (evsel->cgrp)
609556b1fb7SJiri Olsa 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
610eedfcb4bSAndi Kleen }
611556b1fb7SJiri Olsa 
612eedfcb4bSAndi Kleen static void printout(int id, int nr, struct perf_evsel *counter, double uval)
613eedfcb4bSAndi Kleen {
614eedfcb4bSAndi Kleen 	int cpu = cpu_map__id_to_cpu(id);
615556b1fb7SJiri Olsa 
616eedfcb4bSAndi Kleen 	if (stat_config.aggr_mode == AGGR_GLOBAL)
617eedfcb4bSAndi Kleen 		cpu = 0;
618eedfcb4bSAndi Kleen 
619eedfcb4bSAndi Kleen 	if (nsec_counter(counter))
620eedfcb4bSAndi Kleen 		nsec_printout(id, nr, counter, uval);
621eedfcb4bSAndi Kleen 	else
622eedfcb4bSAndi Kleen 		abs_printout(id, nr, counter, uval);
623eedfcb4bSAndi Kleen 
624eedfcb4bSAndi Kleen 	if (!csv_output && !stat_config.interval)
625eedfcb4bSAndi Kleen 		perf_stat__print_shadow_stats(stat_config.output, counter,
626eedfcb4bSAndi Kleen 					      uval, cpu,
627421a50f3SJiri Olsa 					      stat_config.aggr_mode);
628556b1fb7SJiri Olsa }
629556b1fb7SJiri Olsa 
63086ee6e18SStephane Eranian static void print_aggr(char *prefix)
631d7e7a451SStephane Eranian {
6325821522eSJiri Olsa 	FILE *output = stat_config.output;
633d7e7a451SStephane Eranian 	struct perf_evsel *counter;
634601083cfSKan Liang 	int cpu, s, s2, id, nr;
635410136f5SStephane Eranian 	double uval;
636d7e7a451SStephane Eranian 	u64 ena, run, val;
637d7e7a451SStephane Eranian 
63886ee6e18SStephane Eranian 	if (!(aggr_map || aggr_get_id))
639d7e7a451SStephane Eranian 		return;
640d7e7a451SStephane Eranian 
64186ee6e18SStephane Eranian 	for (s = 0; s < aggr_map->nr; s++) {
64286ee6e18SStephane Eranian 		id = aggr_map->map[s];
6430050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
644d7e7a451SStephane Eranian 			val = ena = run = 0;
645d7e7a451SStephane Eranian 			nr = 0;
646d7e7a451SStephane Eranian 			for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
647601083cfSKan Liang 				s2 = aggr_get_id(perf_evsel__cpus(counter), cpu);
64886ee6e18SStephane Eranian 				if (s2 != id)
649d7e7a451SStephane Eranian 					continue;
650a6fa0038SJiri Olsa 				val += perf_counts(counter->counts, cpu, 0)->val;
651a6fa0038SJiri Olsa 				ena += perf_counts(counter->counts, cpu, 0)->ena;
652a6fa0038SJiri Olsa 				run += perf_counts(counter->counts, cpu, 0)->run;
653d7e7a451SStephane Eranian 				nr++;
654d7e7a451SStephane Eranian 			}
655d7e7a451SStephane Eranian 			if (prefix)
656d7e7a451SStephane Eranian 				fprintf(output, "%s", prefix);
657d7e7a451SStephane Eranian 
658d7e7a451SStephane Eranian 			if (run == 0 || ena == 0) {
659582ec082SStephane Eranian 				aggr_printout(counter, id, nr);
66086ee6e18SStephane Eranian 
661410136f5SStephane Eranian 				fprintf(output, "%*s%s",
662d7e7a451SStephane Eranian 					csv_output ? 0 : 18,
663d7e7a451SStephane Eranian 					counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
664410136f5SStephane Eranian 					csv_sep);
665410136f5SStephane Eranian 
666410136f5SStephane Eranian 				fprintf(output, "%-*s%s",
667410136f5SStephane Eranian 					csv_output ? 0 : unit_width,
668410136f5SStephane Eranian 					counter->unit, csv_sep);
669410136f5SStephane Eranian 
670410136f5SStephane Eranian 				fprintf(output, "%*s",
671410136f5SStephane Eranian 					csv_output ? 0 : -25,
672d7e7a451SStephane Eranian 					perf_evsel__name(counter));
67386ee6e18SStephane Eranian 
674d7e7a451SStephane Eranian 				if (counter->cgrp)
675d7e7a451SStephane Eranian 					fprintf(output, "%s%s",
676d7e7a451SStephane Eranian 						csv_sep, counter->cgrp->name);
677d7e7a451SStephane Eranian 
678d73515c0SAndi Kleen 				print_running(run, ena);
679d7e7a451SStephane Eranian 				fputc('\n', output);
680d7e7a451SStephane Eranian 				continue;
681d7e7a451SStephane Eranian 			}
682410136f5SStephane Eranian 			uval = val * counter->scale;
683eedfcb4bSAndi Kleen 			printout(id, nr, counter, uval);
684d73515c0SAndi Kleen 			if (!csv_output)
685d7e7a451SStephane Eranian 				print_noise(counter, 1.0);
686d7e7a451SStephane Eranian 
687d73515c0SAndi Kleen 			print_running(run, ena);
688d7e7a451SStephane Eranian 			fputc('\n', output);
689d7e7a451SStephane Eranian 		}
690d7e7a451SStephane Eranian 	}
691d7e7a451SStephane Eranian }
692d7e7a451SStephane Eranian 
69332b8af82SJiri Olsa static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
69432b8af82SJiri Olsa {
6955821522eSJiri Olsa 	FILE *output = stat_config.output;
69632b8af82SJiri Olsa 	int nthreads = thread_map__nr(counter->threads);
69732b8af82SJiri Olsa 	int ncpus = cpu_map__nr(counter->cpus);
69832b8af82SJiri Olsa 	int cpu, thread;
69932b8af82SJiri Olsa 	double uval;
70032b8af82SJiri Olsa 
70132b8af82SJiri Olsa 	for (thread = 0; thread < nthreads; thread++) {
70232b8af82SJiri Olsa 		u64 ena = 0, run = 0, val = 0;
70332b8af82SJiri Olsa 
70432b8af82SJiri Olsa 		for (cpu = 0; cpu < ncpus; cpu++) {
70532b8af82SJiri Olsa 			val += perf_counts(counter->counts, cpu, thread)->val;
70632b8af82SJiri Olsa 			ena += perf_counts(counter->counts, cpu, thread)->ena;
70732b8af82SJiri Olsa 			run += perf_counts(counter->counts, cpu, thread)->run;
70832b8af82SJiri Olsa 		}
70932b8af82SJiri Olsa 
71032b8af82SJiri Olsa 		if (prefix)
71132b8af82SJiri Olsa 			fprintf(output, "%s", prefix);
71232b8af82SJiri Olsa 
71332b8af82SJiri Olsa 		uval = val * counter->scale;
714eedfcb4bSAndi Kleen 		printout(thread, 0, counter, uval);
71532b8af82SJiri Olsa 
71632b8af82SJiri Olsa 		if (!csv_output)
71732b8af82SJiri Olsa 			print_noise(counter, 1.0);
71832b8af82SJiri Olsa 
71932b8af82SJiri Olsa 		print_running(run, ena);
72032b8af82SJiri Olsa 		fputc('\n', output);
72132b8af82SJiri Olsa 	}
72232b8af82SJiri Olsa }
72332b8af82SJiri Olsa 
72442202dd5SIngo Molnar /*
72542202dd5SIngo Molnar  * Print out the results of a single counter:
726f5b4a9c3SStephane Eranian  * aggregated counts in system-wide mode
72742202dd5SIngo Molnar  */
72813370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
72942202dd5SIngo Molnar {
7305821522eSJiri Olsa 	FILE *output = stat_config.output;
731581cc8a2SJiri Olsa 	struct perf_stat_evsel *ps = counter->priv;
73269aad6f1SArnaldo Carvalho de Melo 	double avg = avg_stats(&ps->res_stats[0]);
733c52b12edSArnaldo Carvalho de Melo 	int scaled = counter->counts->scaled;
734410136f5SStephane Eranian 	double uval;
735d73515c0SAndi Kleen 	double avg_enabled, avg_running;
736d73515c0SAndi Kleen 
737d73515c0SAndi Kleen 	avg_enabled = avg_stats(&ps->res_stats[1]);
738d73515c0SAndi Kleen 	avg_running = avg_stats(&ps->res_stats[2]);
73942202dd5SIngo Molnar 
74013370a9bSStephane Eranian 	if (prefix)
74113370a9bSStephane Eranian 		fprintf(output, "%s", prefix);
74213370a9bSStephane Eranian 
7433b4331d9SSuzuki K. Poulose 	if (scaled == -1 || !counter->supported) {
744410136f5SStephane Eranian 		fprintf(output, "%*s%s",
745d7470b6aSStephane Eranian 			csv_output ? 0 : 18,
7462cee77c4SDavid Ahern 			counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
747410136f5SStephane Eranian 			csv_sep);
748410136f5SStephane Eranian 		fprintf(output, "%-*s%s",
749410136f5SStephane Eranian 			csv_output ? 0 : unit_width,
750410136f5SStephane Eranian 			counter->unit, csv_sep);
751410136f5SStephane Eranian 		fprintf(output, "%*s",
752410136f5SStephane Eranian 			csv_output ? 0 : -25,
7537289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter));
754023695d9SStephane Eranian 
755023695d9SStephane Eranian 		if (counter->cgrp)
7564aa9015fSStephane Eranian 			fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
757023695d9SStephane Eranian 
758d73515c0SAndi Kleen 		print_running(avg_running, avg_enabled);
7594aa9015fSStephane Eranian 		fputc('\n', output);
76042202dd5SIngo Molnar 		return;
76142202dd5SIngo Molnar 	}
76242202dd5SIngo Molnar 
763410136f5SStephane Eranian 	uval = avg * counter->scale;
764eedfcb4bSAndi Kleen 	printout(-1, 0, counter, uval);
765849abde9SPeter Zijlstra 
7663ae9a34dSZhengyu He 	print_noise(counter, avg);
7673ae9a34dSZhengyu He 
768d73515c0SAndi Kleen 	print_running(avg_running, avg_enabled);
7694aa9015fSStephane Eranian 	fprintf(output, "\n");
77042202dd5SIngo Molnar }
77142202dd5SIngo Molnar 
772f5b4a9c3SStephane Eranian /*
773f5b4a9c3SStephane Eranian  * Print out the results of a single counter:
774f5b4a9c3SStephane Eranian  * does not use aggregated count in system-wide
775f5b4a9c3SStephane Eranian  */
77613370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix)
777f5b4a9c3SStephane Eranian {
7785821522eSJiri Olsa 	FILE *output = stat_config.output;
779f5b4a9c3SStephane Eranian 	u64 ena, run, val;
780410136f5SStephane Eranian 	double uval;
781f5b4a9c3SStephane Eranian 	int cpu;
782f5b4a9c3SStephane Eranian 
7837ae92e74SYan, Zheng 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
784a6fa0038SJiri Olsa 		val = perf_counts(counter->counts, cpu, 0)->val;
785a6fa0038SJiri Olsa 		ena = perf_counts(counter->counts, cpu, 0)->ena;
786a6fa0038SJiri Olsa 		run = perf_counts(counter->counts, cpu, 0)->run;
78713370a9bSStephane Eranian 
78813370a9bSStephane Eranian 		if (prefix)
78913370a9bSStephane Eranian 			fprintf(output, "%s", prefix);
79013370a9bSStephane Eranian 
791f5b4a9c3SStephane Eranian 		if (run == 0 || ena == 0) {
792410136f5SStephane Eranian 			fprintf(output, "CPU%*d%s%*s%s",
793d7470b6aSStephane Eranian 				csv_output ? 0 : -4,
7947ae92e74SYan, Zheng 				perf_evsel__cpus(counter)->map[cpu], csv_sep,
795d7470b6aSStephane Eranian 				csv_output ? 0 : 18,
7962cee77c4SDavid Ahern 				counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
797410136f5SStephane Eranian 				csv_sep);
798410136f5SStephane Eranian 
799410136f5SStephane Eranian 				fprintf(output, "%-*s%s",
800410136f5SStephane Eranian 					csv_output ? 0 : unit_width,
801410136f5SStephane Eranian 					counter->unit, csv_sep);
802410136f5SStephane Eranian 
803410136f5SStephane Eranian 				fprintf(output, "%*s",
804410136f5SStephane Eranian 					csv_output ? 0 : -25,
8057289f83cSArnaldo Carvalho de Melo 					perf_evsel__name(counter));
806f5b4a9c3SStephane Eranian 
807023695d9SStephane Eranian 			if (counter->cgrp)
8084aa9015fSStephane Eranian 				fprintf(output, "%s%s",
8094aa9015fSStephane Eranian 					csv_sep, counter->cgrp->name);
810023695d9SStephane Eranian 
811d73515c0SAndi Kleen 			print_running(run, ena);
8124aa9015fSStephane Eranian 			fputc('\n', output);
813f5b4a9c3SStephane Eranian 			continue;
814f5b4a9c3SStephane Eranian 		}
815f5b4a9c3SStephane Eranian 
816410136f5SStephane Eranian 		uval = val * counter->scale;
817eedfcb4bSAndi Kleen 		printout(cpu, 0, counter, uval);
818d73515c0SAndi Kleen 		if (!csv_output)
819f5b4a9c3SStephane Eranian 			print_noise(counter, 1.0);
820d73515c0SAndi Kleen 		print_running(run, ena);
821f5b4a9c3SStephane Eranian 
8224aa9015fSStephane Eranian 		fputc('\n', output);
823f5b4a9c3SStephane Eranian 	}
824f5b4a9c3SStephane Eranian }
825f5b4a9c3SStephane Eranian 
826d4f63a47SJiri Olsa static void print_interval(char *prefix, struct timespec *ts)
82742202dd5SIngo Molnar {
8285821522eSJiri Olsa 	FILE *output = stat_config.output;
829d4f63a47SJiri Olsa 	static int num_print_interval;
830d4f63a47SJiri Olsa 
831d4f63a47SJiri Olsa 	sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
832d4f63a47SJiri Olsa 
833d4f63a47SJiri Olsa 	if (num_print_interval == 0 && !csv_output) {
834421a50f3SJiri Olsa 		switch (stat_config.aggr_mode) {
835d4f63a47SJiri Olsa 		case AGGR_SOCKET:
836d4f63a47SJiri Olsa 			fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
837d4f63a47SJiri Olsa 			break;
838d4f63a47SJiri Olsa 		case AGGR_CORE:
839d4f63a47SJiri Olsa 			fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
840d4f63a47SJiri Olsa 			break;
841d4f63a47SJiri Olsa 		case AGGR_NONE:
842d4f63a47SJiri Olsa 			fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
843d4f63a47SJiri Olsa 			break;
84432b8af82SJiri Olsa 		case AGGR_THREAD:
84532b8af82SJiri Olsa 			fprintf(output, "#           time             comm-pid                  counts %*s events\n", unit_width, "unit");
84632b8af82SJiri Olsa 			break;
847d4f63a47SJiri Olsa 		case AGGR_GLOBAL:
848d4f63a47SJiri Olsa 		default:
849d4f63a47SJiri Olsa 			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
850208df99eSJiri Olsa 		case AGGR_UNSET:
851208df99eSJiri Olsa 			break;
852d4f63a47SJiri Olsa 		}
853d4f63a47SJiri Olsa 	}
854d4f63a47SJiri Olsa 
855d4f63a47SJiri Olsa 	if (++num_print_interval == 25)
856d4f63a47SJiri Olsa 		num_print_interval = 0;
857d4f63a47SJiri Olsa }
858d4f63a47SJiri Olsa 
859d4f63a47SJiri Olsa static void print_header(int argc, const char **argv)
860d4f63a47SJiri Olsa {
8615821522eSJiri Olsa 	FILE *output = stat_config.output;
86269aad6f1SArnaldo Carvalho de Melo 	int i;
86342202dd5SIngo Molnar 
86486470930SIngo Molnar 	fflush(stdout);
86586470930SIngo Molnar 
866d7470b6aSStephane Eranian 	if (!csv_output) {
8674aa9015fSStephane Eranian 		fprintf(output, "\n");
8684aa9015fSStephane Eranian 		fprintf(output, " Performance counter stats for ");
86962d3b617SDavid Ahern 		if (target.system_wide)
87062d3b617SDavid Ahern 			fprintf(output, "\'system wide");
87162d3b617SDavid Ahern 		else if (target.cpu_list)
87262d3b617SDavid Ahern 			fprintf(output, "\'CPU(s) %s", target.cpu_list);
873602ad878SArnaldo Carvalho de Melo 		else if (!target__has_task(&target)) {
8744aa9015fSStephane Eranian 			fprintf(output, "\'%s", argv[0]);
87586470930SIngo Molnar 			for (i = 1; i < argc; i++)
8764aa9015fSStephane Eranian 				fprintf(output, " %s", argv[i]);
87720f946b4SNamhyung Kim 		} else if (target.pid)
87820f946b4SNamhyung Kim 			fprintf(output, "process id \'%s", target.pid);
879d6d901c2SZhang, Yanmin 		else
88020f946b4SNamhyung Kim 			fprintf(output, "thread id \'%s", target.tid);
88186470930SIngo Molnar 
8824aa9015fSStephane Eranian 		fprintf(output, "\'");
88342202dd5SIngo Molnar 		if (run_count > 1)
8844aa9015fSStephane Eranian 			fprintf(output, " (%d runs)", run_count);
8854aa9015fSStephane Eranian 		fprintf(output, ":\n\n");
886d7470b6aSStephane Eranian 	}
887f5b4a9c3SStephane Eranian }
88886470930SIngo Molnar 
889d4f63a47SJiri Olsa static void print_footer(void)
890d4f63a47SJiri Olsa {
8915821522eSJiri Olsa 	FILE *output = stat_config.output;
8925821522eSJiri Olsa 
893c3305257SIngo Molnar 	if (!null_run)
8944aa9015fSStephane Eranian 		fprintf(output, "\n");
8954aa9015fSStephane Eranian 	fprintf(output, " %17.9f seconds time elapsed",
896506d4bc8SPeter Zijlstra 			avg_stats(&walltime_nsecs_stats)/1e9);
897566747e6SIngo Molnar 	if (run_count > 1) {
8984aa9015fSStephane Eranian 		fprintf(output, "                                        ");
899f99844cbSIngo Molnar 		print_noise_pct(stddev_stats(&walltime_nsecs_stats),
900506d4bc8SPeter Zijlstra 				avg_stats(&walltime_nsecs_stats));
901566747e6SIngo Molnar 	}
9024aa9015fSStephane Eranian 	fprintf(output, "\n\n");
90386470930SIngo Molnar }
904d4f63a47SJiri Olsa 
905d4f63a47SJiri Olsa static void print_counters(struct timespec *ts, int argc, const char **argv)
906d4f63a47SJiri Olsa {
907ec0d3d1fSJiri Olsa 	int interval = stat_config.interval;
908d4f63a47SJiri Olsa 	struct perf_evsel *counter;
909d4f63a47SJiri Olsa 	char buf[64], *prefix = NULL;
910d4f63a47SJiri Olsa 
911d4f63a47SJiri Olsa 	if (interval)
912d4f63a47SJiri Olsa 		print_interval(prefix = buf, ts);
913d4f63a47SJiri Olsa 	else
914d4f63a47SJiri Olsa 		print_header(argc, argv);
915d4f63a47SJiri Olsa 
916421a50f3SJiri Olsa 	switch (stat_config.aggr_mode) {
917d4f63a47SJiri Olsa 	case AGGR_CORE:
918d4f63a47SJiri Olsa 	case AGGR_SOCKET:
919d4f63a47SJiri Olsa 		print_aggr(prefix);
920d4f63a47SJiri Olsa 		break;
92132b8af82SJiri Olsa 	case AGGR_THREAD:
92232b8af82SJiri Olsa 		evlist__for_each(evsel_list, counter)
92332b8af82SJiri Olsa 			print_aggr_thread(counter, prefix);
92432b8af82SJiri Olsa 		break;
925d4f63a47SJiri Olsa 	case AGGR_GLOBAL:
926d4f63a47SJiri Olsa 		evlist__for_each(evsel_list, counter)
927d4f63a47SJiri Olsa 			print_counter_aggr(counter, prefix);
928d4f63a47SJiri Olsa 		break;
929d4f63a47SJiri Olsa 	case AGGR_NONE:
930d4f63a47SJiri Olsa 		evlist__for_each(evsel_list, counter)
931d4f63a47SJiri Olsa 			print_counter(counter, prefix);
932d4f63a47SJiri Olsa 		break;
933208df99eSJiri Olsa 	case AGGR_UNSET:
934d4f63a47SJiri Olsa 	default:
935d4f63a47SJiri Olsa 		break;
936d4f63a47SJiri Olsa 	}
937d4f63a47SJiri Olsa 
938d4f63a47SJiri Olsa 	if (!interval && !csv_output)
939d4f63a47SJiri Olsa 		print_footer();
940d4f63a47SJiri Olsa 
9415821522eSJiri Olsa 	fflush(stat_config.output);
942d7470b6aSStephane Eranian }
94386470930SIngo Molnar 
944f7b7c26eSPeter Zijlstra static volatile int signr = -1;
945f7b7c26eSPeter Zijlstra 
94686470930SIngo Molnar static void skip_signal(int signo)
94786470930SIngo Molnar {
948ec0d3d1fSJiri Olsa 	if ((child_pid == -1) || stat_config.interval)
94960666c63SLiming Wang 		done = 1;
95060666c63SLiming Wang 
951f7b7c26eSPeter Zijlstra 	signr = signo;
952d07f0b12SStephane Eranian 	/*
953d07f0b12SStephane Eranian 	 * render child_pid harmless
954d07f0b12SStephane Eranian 	 * won't send SIGTERM to a random
955d07f0b12SStephane Eranian 	 * process in case of race condition
956d07f0b12SStephane Eranian 	 * and fast PID recycling
957d07f0b12SStephane Eranian 	 */
958d07f0b12SStephane Eranian 	child_pid = -1;
959f7b7c26eSPeter Zijlstra }
960f7b7c26eSPeter Zijlstra 
961f7b7c26eSPeter Zijlstra static void sig_atexit(void)
962f7b7c26eSPeter Zijlstra {
963d07f0b12SStephane Eranian 	sigset_t set, oset;
964d07f0b12SStephane Eranian 
965d07f0b12SStephane Eranian 	/*
966d07f0b12SStephane Eranian 	 * avoid race condition with SIGCHLD handler
967d07f0b12SStephane Eranian 	 * in skip_signal() which is modifying child_pid
968d07f0b12SStephane Eranian 	 * goal is to avoid send SIGTERM to a random
969d07f0b12SStephane Eranian 	 * process
970d07f0b12SStephane Eranian 	 */
971d07f0b12SStephane Eranian 	sigemptyset(&set);
972d07f0b12SStephane Eranian 	sigaddset(&set, SIGCHLD);
973d07f0b12SStephane Eranian 	sigprocmask(SIG_BLOCK, &set, &oset);
974d07f0b12SStephane Eranian 
975933da83aSChris Wilson 	if (child_pid != -1)
976933da83aSChris Wilson 		kill(child_pid, SIGTERM);
977933da83aSChris Wilson 
978d07f0b12SStephane Eranian 	sigprocmask(SIG_SETMASK, &oset, NULL);
979d07f0b12SStephane Eranian 
980f7b7c26eSPeter Zijlstra 	if (signr == -1)
981f7b7c26eSPeter Zijlstra 		return;
982f7b7c26eSPeter Zijlstra 
983f7b7c26eSPeter Zijlstra 	signal(signr, SIG_DFL);
984f7b7c26eSPeter Zijlstra 	kill(getpid(), signr);
98586470930SIngo Molnar }
98686470930SIngo Molnar 
9871d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused,
9881d037ca1SIrina Tirdea 			     const char *s __maybe_unused, int unset)
989d7470b6aSStephane Eranian {
990d7470b6aSStephane Eranian 	big_num_opt = unset ? 0 : 1;
991d7470b6aSStephane Eranian 	return 0;
992d7470b6aSStephane Eranian }
993d7470b6aSStephane Eranian 
994e0547311SJiri Olsa static const struct option stat_options[] = {
995e0547311SJiri Olsa 	OPT_BOOLEAN('T', "transaction", &transaction_run,
996e0547311SJiri Olsa 		    "hardware transaction statistics"),
997e0547311SJiri Olsa 	OPT_CALLBACK('e', "event", &evsel_list, "event",
998e0547311SJiri Olsa 		     "event selector. use 'perf list' to list available events",
999e0547311SJiri Olsa 		     parse_events_option),
1000e0547311SJiri Olsa 	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1001e0547311SJiri Olsa 		     "event filter", parse_filter),
1002e0547311SJiri Olsa 	OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1003e0547311SJiri Olsa 		    "child tasks do not inherit counters"),
1004e0547311SJiri Olsa 	OPT_STRING('p', "pid", &target.pid, "pid",
1005e0547311SJiri Olsa 		   "stat events on existing process id"),
1006e0547311SJiri Olsa 	OPT_STRING('t', "tid", &target.tid, "tid",
1007e0547311SJiri Olsa 		   "stat events on existing thread id"),
1008e0547311SJiri Olsa 	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1009e0547311SJiri Olsa 		    "system-wide collection from all CPUs"),
1010e0547311SJiri Olsa 	OPT_BOOLEAN('g', "group", &group,
1011e0547311SJiri Olsa 		    "put the counters into a counter group"),
1012e0547311SJiri Olsa 	OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
1013e0547311SJiri Olsa 	OPT_INCR('v', "verbose", &verbose,
1014e0547311SJiri Olsa 		    "be more verbose (show counter open errors, etc)"),
1015e0547311SJiri Olsa 	OPT_INTEGER('r', "repeat", &run_count,
1016e0547311SJiri Olsa 		    "repeat command and print average + stddev (max: 100, forever: 0)"),
1017e0547311SJiri Olsa 	OPT_BOOLEAN('n', "null", &null_run,
1018e0547311SJiri Olsa 		    "null run - dont start any counters"),
1019e0547311SJiri Olsa 	OPT_INCR('d', "detailed", &detailed_run,
1020e0547311SJiri Olsa 		    "detailed run - start a lot of events"),
1021e0547311SJiri Olsa 	OPT_BOOLEAN('S', "sync", &sync_run,
1022e0547311SJiri Olsa 		    "call sync() before starting a run"),
1023e0547311SJiri Olsa 	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1024e0547311SJiri Olsa 			   "print large numbers with thousands\' separators",
1025e0547311SJiri Olsa 			   stat__set_big_num),
1026e0547311SJiri Olsa 	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1027e0547311SJiri Olsa 		    "list of cpus to monitor in system-wide"),
1028e0547311SJiri Olsa 	OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
1029e0547311SJiri Olsa 		    "disable CPU count aggregation", AGGR_NONE),
1030e0547311SJiri Olsa 	OPT_STRING('x', "field-separator", &csv_sep, "separator",
1031e0547311SJiri Olsa 		   "print counts with custom separator"),
1032e0547311SJiri Olsa 	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1033e0547311SJiri Olsa 		     "monitor event in cgroup name only", parse_cgroups),
1034e0547311SJiri Olsa 	OPT_STRING('o', "output", &output_name, "file", "output file name"),
1035e0547311SJiri Olsa 	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1036e0547311SJiri Olsa 	OPT_INTEGER(0, "log-fd", &output_fd,
1037e0547311SJiri Olsa 		    "log output to fd, instead of stderr"),
1038e0547311SJiri Olsa 	OPT_STRING(0, "pre", &pre_cmd, "command",
1039e0547311SJiri Olsa 			"command to run prior to the measured command"),
1040e0547311SJiri Olsa 	OPT_STRING(0, "post", &post_cmd, "command",
1041e0547311SJiri Olsa 			"command to run after to the measured command"),
1042e0547311SJiri Olsa 	OPT_UINTEGER('I', "interval-print", &stat_config.interval,
1043e0547311SJiri Olsa 		    "print counts at regular interval in ms (>= 10)"),
1044e0547311SJiri Olsa 	OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
1045e0547311SJiri Olsa 		     "aggregate counts per processor socket", AGGR_SOCKET),
1046e0547311SJiri Olsa 	OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
1047e0547311SJiri Olsa 		     "aggregate counts per physical processor core", AGGR_CORE),
1048e0547311SJiri Olsa 	OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
1049e0547311SJiri Olsa 		     "aggregate counts per thread", AGGR_THREAD),
1050e0547311SJiri Olsa 	OPT_UINTEGER('D', "delay", &initial_delay,
1051e0547311SJiri Olsa 		     "ms to wait before starting measurement after program start"),
1052e0547311SJiri Olsa 	OPT_END()
1053e0547311SJiri Olsa };
1054e0547311SJiri Olsa 
10551fe7a300SJiri Olsa static int perf_stat__get_socket(struct cpu_map *map, int cpu)
10561fe7a300SJiri Olsa {
10571fe7a300SJiri Olsa 	return cpu_map__get_socket(map, cpu, NULL);
10581fe7a300SJiri Olsa }
10591fe7a300SJiri Olsa 
10601fe7a300SJiri Olsa static int perf_stat__get_core(struct cpu_map *map, int cpu)
10611fe7a300SJiri Olsa {
10621fe7a300SJiri Olsa 	return cpu_map__get_core(map, cpu, NULL);
10631fe7a300SJiri Olsa }
10641fe7a300SJiri Olsa 
10651e5a2931SJiri Olsa static int cpu_map__get_max(struct cpu_map *map)
10661e5a2931SJiri Olsa {
10671e5a2931SJiri Olsa 	int i, max = -1;
10681e5a2931SJiri Olsa 
10691e5a2931SJiri Olsa 	for (i = 0; i < map->nr; i++) {
10701e5a2931SJiri Olsa 		if (map->map[i] > max)
10711e5a2931SJiri Olsa 			max = map->map[i];
10721e5a2931SJiri Olsa 	}
10731e5a2931SJiri Olsa 
10741e5a2931SJiri Olsa 	return max;
10751e5a2931SJiri Olsa }
10761e5a2931SJiri Olsa 
10771e5a2931SJiri Olsa static struct cpu_map *cpus_aggr_map;
10781e5a2931SJiri Olsa 
10791e5a2931SJiri Olsa static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int idx)
10801e5a2931SJiri Olsa {
10811e5a2931SJiri Olsa 	int cpu;
10821e5a2931SJiri Olsa 
10831e5a2931SJiri Olsa 	if (idx >= map->nr)
10841e5a2931SJiri Olsa 		return -1;
10851e5a2931SJiri Olsa 
10861e5a2931SJiri Olsa 	cpu = map->map[idx];
10871e5a2931SJiri Olsa 
10881e5a2931SJiri Olsa 	if (cpus_aggr_map->map[cpu] == -1)
10891e5a2931SJiri Olsa 		cpus_aggr_map->map[cpu] = get_id(map, idx);
10901e5a2931SJiri Olsa 
10911e5a2931SJiri Olsa 	return cpus_aggr_map->map[cpu];
10921e5a2931SJiri Olsa }
10931e5a2931SJiri Olsa 
10941e5a2931SJiri Olsa static int perf_stat__get_socket_cached(struct cpu_map *map, int idx)
10951e5a2931SJiri Olsa {
10961e5a2931SJiri Olsa 	return perf_stat__get_aggr(perf_stat__get_socket, map, idx);
10971e5a2931SJiri Olsa }
10981e5a2931SJiri Olsa 
10991e5a2931SJiri Olsa static int perf_stat__get_core_cached(struct cpu_map *map, int idx)
11001e5a2931SJiri Olsa {
11011e5a2931SJiri Olsa 	return perf_stat__get_aggr(perf_stat__get_core, map, idx);
11021e5a2931SJiri Olsa }
11031e5a2931SJiri Olsa 
110486ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void)
110586ee6e18SStephane Eranian {
11061e5a2931SJiri Olsa 	int nr;
11071e5a2931SJiri Olsa 
1108421a50f3SJiri Olsa 	switch (stat_config.aggr_mode) {
110986ee6e18SStephane Eranian 	case AGGR_SOCKET:
111086ee6e18SStephane Eranian 		if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
111186ee6e18SStephane Eranian 			perror("cannot build socket map");
111286ee6e18SStephane Eranian 			return -1;
111386ee6e18SStephane Eranian 		}
11141e5a2931SJiri Olsa 		aggr_get_id = perf_stat__get_socket_cached;
111586ee6e18SStephane Eranian 		break;
111612c08a9fSStephane Eranian 	case AGGR_CORE:
111712c08a9fSStephane Eranian 		if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
111812c08a9fSStephane Eranian 			perror("cannot build core map");
111912c08a9fSStephane Eranian 			return -1;
112012c08a9fSStephane Eranian 		}
11211e5a2931SJiri Olsa 		aggr_get_id = perf_stat__get_core_cached;
112212c08a9fSStephane Eranian 		break;
112386ee6e18SStephane Eranian 	case AGGR_NONE:
112486ee6e18SStephane Eranian 	case AGGR_GLOBAL:
112532b8af82SJiri Olsa 	case AGGR_THREAD:
1126208df99eSJiri Olsa 	case AGGR_UNSET:
112786ee6e18SStephane Eranian 	default:
112886ee6e18SStephane Eranian 		break;
112986ee6e18SStephane Eranian 	}
11301e5a2931SJiri Olsa 
11311e5a2931SJiri Olsa 	/*
11321e5a2931SJiri Olsa 	 * The evsel_list->cpus is the base we operate on,
11331e5a2931SJiri Olsa 	 * taking the highest cpu number to be the size of
11341e5a2931SJiri Olsa 	 * the aggregation translate cpumap.
11351e5a2931SJiri Olsa 	 */
11361e5a2931SJiri Olsa 	nr = cpu_map__get_max(evsel_list->cpus);
11371e5a2931SJiri Olsa 	cpus_aggr_map = cpu_map__empty_new(nr + 1);
11381e5a2931SJiri Olsa 	return cpus_aggr_map ? 0 : -ENOMEM;
113986ee6e18SStephane Eranian }
114086ee6e18SStephane Eranian 
1141544c2ae7SMasami Hiramatsu static void perf_stat__exit_aggr_mode(void)
1142544c2ae7SMasami Hiramatsu {
1143544c2ae7SMasami Hiramatsu 	cpu_map__put(aggr_map);
1144544c2ae7SMasami Hiramatsu 	cpu_map__put(cpus_aggr_map);
1145544c2ae7SMasami Hiramatsu 	aggr_map = NULL;
1146544c2ae7SMasami Hiramatsu 	cpus_aggr_map = NULL;
1147544c2ae7SMasami Hiramatsu }
1148544c2ae7SMasami Hiramatsu 
11492cba3ffbSIngo Molnar /*
11502cba3ffbSIngo Molnar  * Add default attributes, if there were no attributes specified or
11512cba3ffbSIngo Molnar  * if -d/--detailed, -d -d or -d -d -d is used:
11522cba3ffbSIngo Molnar  */
11532cba3ffbSIngo Molnar static int add_default_attributes(void)
11542cba3ffbSIngo Molnar {
1155b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr default_attrs[] = {
1156b070a547SArnaldo Carvalho de Melo 
1157b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
1158b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
1159b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
1160b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
1161b070a547SArnaldo Carvalho de Melo 
1162b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
1163b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
1164b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
1165b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
1166b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
1167b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
1168b070a547SArnaldo Carvalho de Melo 
1169b070a547SArnaldo Carvalho de Melo };
1170b070a547SArnaldo Carvalho de Melo 
1171b070a547SArnaldo Carvalho de Melo /*
1172b070a547SArnaldo Carvalho de Melo  * Detailed stats (-d), covering the L1 and last level data caches:
1173b070a547SArnaldo Carvalho de Melo  */
1174b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr detailed_attrs[] = {
1175b070a547SArnaldo Carvalho de Melo 
1176b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1177b070a547SArnaldo Carvalho de Melo     .config =
1178b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1179b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1180b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1181b070a547SArnaldo Carvalho de Melo 
1182b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1183b070a547SArnaldo Carvalho de Melo     .config =
1184b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1185b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1186b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1187b070a547SArnaldo Carvalho de Melo 
1188b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1189b070a547SArnaldo Carvalho de Melo     .config =
1190b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1191b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1192b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1193b070a547SArnaldo Carvalho de Melo 
1194b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1195b070a547SArnaldo Carvalho de Melo     .config =
1196b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1197b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1198b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1199b070a547SArnaldo Carvalho de Melo };
1200b070a547SArnaldo Carvalho de Melo 
1201b070a547SArnaldo Carvalho de Melo /*
1202b070a547SArnaldo Carvalho de Melo  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1203b070a547SArnaldo Carvalho de Melo  */
1204b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_detailed_attrs[] = {
1205b070a547SArnaldo Carvalho de Melo 
1206b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1207b070a547SArnaldo Carvalho de Melo     .config =
1208b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1209b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1210b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1211b070a547SArnaldo Carvalho de Melo 
1212b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1213b070a547SArnaldo Carvalho de Melo     .config =
1214b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1215b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1216b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1217b070a547SArnaldo Carvalho de Melo 
1218b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1219b070a547SArnaldo Carvalho de Melo     .config =
1220b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1221b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1222b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1223b070a547SArnaldo Carvalho de Melo 
1224b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1225b070a547SArnaldo Carvalho de Melo     .config =
1226b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1227b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1228b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1229b070a547SArnaldo Carvalho de Melo 
1230b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1231b070a547SArnaldo Carvalho de Melo     .config =
1232b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1233b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1234b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1235b070a547SArnaldo Carvalho de Melo 
1236b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1237b070a547SArnaldo Carvalho de Melo     .config =
1238b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1239b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1240b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1241b070a547SArnaldo Carvalho de Melo 
1242b070a547SArnaldo Carvalho de Melo };
1243b070a547SArnaldo Carvalho de Melo 
1244b070a547SArnaldo Carvalho de Melo /*
1245b070a547SArnaldo Carvalho de Melo  * Very, very detailed stats (-d -d -d), adding prefetch events:
1246b070a547SArnaldo Carvalho de Melo  */
1247b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_very_detailed_attrs[] = {
1248b070a547SArnaldo Carvalho de Melo 
1249b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1250b070a547SArnaldo Carvalho de Melo     .config =
1251b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1252b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1253b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1254b070a547SArnaldo Carvalho de Melo 
1255b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1256b070a547SArnaldo Carvalho de Melo     .config =
1257b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1258b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1259b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1260b070a547SArnaldo Carvalho de Melo };
1261b070a547SArnaldo Carvalho de Melo 
12622cba3ffbSIngo Molnar 	/* Set attrs if no event is selected and !null_run: */
12632cba3ffbSIngo Molnar 	if (null_run)
12642cba3ffbSIngo Molnar 		return 0;
12652cba3ffbSIngo Molnar 
12664cabc3d1SAndi Kleen 	if (transaction_run) {
12674cabc3d1SAndi Kleen 		int err;
12684cabc3d1SAndi Kleen 		if (pmu_have_event("cpu", "cycles-ct") &&
12694cabc3d1SAndi Kleen 		    pmu_have_event("cpu", "el-start"))
1270a454742cSJiri Olsa 			err = parse_events(evsel_list, transaction_attrs, NULL);
12714cabc3d1SAndi Kleen 		else
1272a454742cSJiri Olsa 			err = parse_events(evsel_list, transaction_limited_attrs, NULL);
1273a454742cSJiri Olsa 		if (err) {
12744cabc3d1SAndi Kleen 			fprintf(stderr, "Cannot set up transaction events\n");
12754cabc3d1SAndi Kleen 			return -1;
12764cabc3d1SAndi Kleen 		}
12774cabc3d1SAndi Kleen 		return 0;
12784cabc3d1SAndi Kleen 	}
12794cabc3d1SAndi Kleen 
12802cba3ffbSIngo Molnar 	if (!evsel_list->nr_entries) {
128179695e1bSArnaldo Carvalho de Melo 		if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
12822cba3ffbSIngo Molnar 			return -1;
12832cba3ffbSIngo Molnar 	}
12842cba3ffbSIngo Molnar 
12852cba3ffbSIngo Molnar 	/* Detailed events get appended to the event list: */
12862cba3ffbSIngo Molnar 
12872cba3ffbSIngo Molnar 	if (detailed_run <  1)
12882cba3ffbSIngo Molnar 		return 0;
12892cba3ffbSIngo Molnar 
12902cba3ffbSIngo Molnar 	/* Append detailed run extra attributes: */
129179695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
12922cba3ffbSIngo Molnar 		return -1;
12932cba3ffbSIngo Molnar 
12942cba3ffbSIngo Molnar 	if (detailed_run < 2)
12952cba3ffbSIngo Molnar 		return 0;
12962cba3ffbSIngo Molnar 
12972cba3ffbSIngo Molnar 	/* Append very detailed run extra attributes: */
129879695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
12992cba3ffbSIngo Molnar 		return -1;
13002cba3ffbSIngo Molnar 
13012cba3ffbSIngo Molnar 	if (detailed_run < 3)
13022cba3ffbSIngo Molnar 		return 0;
13032cba3ffbSIngo Molnar 
13042cba3ffbSIngo Molnar 	/* Append very, very detailed run extra attributes: */
130579695e1bSArnaldo Carvalho de Melo 	return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
13062cba3ffbSIngo Molnar }
13072cba3ffbSIngo Molnar 
13084979d0c7SJiri Olsa static const char * const recort_usage[] = {
13094979d0c7SJiri Olsa 	"perf stat record [<options>]",
13104979d0c7SJiri Olsa 	NULL,
13114979d0c7SJiri Olsa };
13124979d0c7SJiri Olsa 
13133ba78bd0SJiri Olsa static void init_features(struct perf_session *session)
13143ba78bd0SJiri Olsa {
13153ba78bd0SJiri Olsa 	int feat;
13163ba78bd0SJiri Olsa 
13173ba78bd0SJiri Olsa 	for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
13183ba78bd0SJiri Olsa 		perf_header__set_feat(&session->header, feat);
13193ba78bd0SJiri Olsa 
13203ba78bd0SJiri Olsa 	perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
13213ba78bd0SJiri Olsa 	perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
13223ba78bd0SJiri Olsa 	perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
13233ba78bd0SJiri Olsa 	perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
13243ba78bd0SJiri Olsa }
13253ba78bd0SJiri Olsa 
13264979d0c7SJiri Olsa static int __cmd_record(int argc, const char **argv)
13274979d0c7SJiri Olsa {
13284979d0c7SJiri Olsa 	struct perf_session *session;
13294979d0c7SJiri Olsa 	struct perf_data_file *file = &perf_stat.file;
13304979d0c7SJiri Olsa 
13314979d0c7SJiri Olsa 	argc = parse_options(argc, argv, stat_options, record_usage,
13324979d0c7SJiri Olsa 			     PARSE_OPT_STOP_AT_NON_OPTION);
13334979d0c7SJiri Olsa 
13344979d0c7SJiri Olsa 	if (output_name)
13354979d0c7SJiri Olsa 		file->path = output_name;
13364979d0c7SJiri Olsa 
13374979d0c7SJiri Olsa 	session = perf_session__new(file, false, NULL);
13384979d0c7SJiri Olsa 	if (session == NULL) {
13394979d0c7SJiri Olsa 		pr_err("Perf session creation failed.\n");
13404979d0c7SJiri Olsa 		return -1;
13414979d0c7SJiri Olsa 	}
13424979d0c7SJiri Olsa 
13434979d0c7SJiri Olsa 	/* No pipe support ATM */
13444979d0c7SJiri Olsa 	if (perf_stat.file.is_pipe)
13454979d0c7SJiri Olsa 		return -EINVAL;
13464979d0c7SJiri Olsa 
13473ba78bd0SJiri Olsa 	init_features(session);
13483ba78bd0SJiri Olsa 
13494979d0c7SJiri Olsa 	session->evlist   = evsel_list;
13504979d0c7SJiri Olsa 	perf_stat.session = session;
13514979d0c7SJiri Olsa 	perf_stat.record  = true;
13524979d0c7SJiri Olsa 	return argc;
13534979d0c7SJiri Olsa }
13544979d0c7SJiri Olsa 
13551d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
135686470930SIngo Molnar {
1357b070a547SArnaldo Carvalho de Melo 	const char * const stat_usage[] = {
1358b070a547SArnaldo Carvalho de Melo 		"perf stat [<options>] [<command>]",
1359b070a547SArnaldo Carvalho de Melo 		NULL
1360b070a547SArnaldo Carvalho de Melo 	};
1361cc03c542SNamhyung Kim 	int status = -EINVAL, run_idx;
13624aa9015fSStephane Eranian 	const char *mode;
13635821522eSJiri Olsa 	FILE *output = stderr;
1364ec0d3d1fSJiri Olsa 	unsigned int interval;
13654979d0c7SJiri Olsa 	const char * const stat_subcommands[] = { "record" };
136642202dd5SIngo Molnar 
13675af52b51SStephane Eranian 	setlocale(LC_ALL, "");
13685af52b51SStephane Eranian 
1369334fe7a3SNamhyung Kim 	evsel_list = perf_evlist__new();
1370361c99a6SArnaldo Carvalho de Melo 	if (evsel_list == NULL)
1371361c99a6SArnaldo Carvalho de Melo 		return -ENOMEM;
1372361c99a6SArnaldo Carvalho de Melo 
13734979d0c7SJiri Olsa 	argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
13744979d0c7SJiri Olsa 					(const char **) stat_usage,
1375a0541234SAnton Blanchard 					PARSE_OPT_STOP_AT_NON_OPTION);
1376d7470b6aSStephane Eranian 
13774979d0c7SJiri Olsa 	if (argc && !strncmp(argv[0], "rec", 3)) {
13784979d0c7SJiri Olsa 		argc = __cmd_record(argc, argv);
13794979d0c7SJiri Olsa 		if (argc < 0)
13804979d0c7SJiri Olsa 			return -1;
13814979d0c7SJiri Olsa 	}
13824979d0c7SJiri Olsa 
1383ec0d3d1fSJiri Olsa 	interval = stat_config.interval;
1384ec0d3d1fSJiri Olsa 
13854979d0c7SJiri Olsa 	/*
13864979d0c7SJiri Olsa 	 * For record command the -o is already taken care of.
13874979d0c7SJiri Olsa 	 */
13884979d0c7SJiri Olsa 	if (!STAT_RECORD && output_name && strcmp(output_name, "-"))
13894aa9015fSStephane Eranian 		output = NULL;
13904aa9015fSStephane Eranian 
139156f3bae7SJim Cromie 	if (output_name && output_fd) {
139256f3bae7SJim Cromie 		fprintf(stderr, "cannot use both --output and --log-fd\n");
1393e0547311SJiri Olsa 		parse_options_usage(stat_usage, stat_options, "o", 1);
1394e0547311SJiri Olsa 		parse_options_usage(NULL, stat_options, "log-fd", 0);
1395cc03c542SNamhyung Kim 		goto out;
139656f3bae7SJim Cromie 	}
1397fc3e4d07SStephane Eranian 
1398fc3e4d07SStephane Eranian 	if (output_fd < 0) {
1399fc3e4d07SStephane Eranian 		fprintf(stderr, "argument to --log-fd must be a > 0\n");
1400e0547311SJiri Olsa 		parse_options_usage(stat_usage, stat_options, "log-fd", 0);
1401cc03c542SNamhyung Kim 		goto out;
1402fc3e4d07SStephane Eranian 	}
1403fc3e4d07SStephane Eranian 
14044aa9015fSStephane Eranian 	if (!output) {
14054aa9015fSStephane Eranian 		struct timespec tm;
14064aa9015fSStephane Eranian 		mode = append_file ? "a" : "w";
14074aa9015fSStephane Eranian 
14084aa9015fSStephane Eranian 		output = fopen(output_name, mode);
14094aa9015fSStephane Eranian 		if (!output) {
14104aa9015fSStephane Eranian 			perror("failed to create output file");
1411fceda7feSDavid Ahern 			return -1;
14124aa9015fSStephane Eranian 		}
14134aa9015fSStephane Eranian 		clock_gettime(CLOCK_REALTIME, &tm);
14144aa9015fSStephane Eranian 		fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1415fc3e4d07SStephane Eranian 	} else if (output_fd > 0) {
141656f3bae7SJim Cromie 		mode = append_file ? "a" : "w";
141756f3bae7SJim Cromie 		output = fdopen(output_fd, mode);
141856f3bae7SJim Cromie 		if (!output) {
141956f3bae7SJim Cromie 			perror("Failed opening logfd");
142056f3bae7SJim Cromie 			return -errno;
142156f3bae7SJim Cromie 		}
14224aa9015fSStephane Eranian 	}
14234aa9015fSStephane Eranian 
14245821522eSJiri Olsa 	stat_config.output = output;
14255821522eSJiri Olsa 
1426d4ffd04dSJim Cromie 	if (csv_sep) {
1427d7470b6aSStephane Eranian 		csv_output = true;
1428d4ffd04dSJim Cromie 		if (!strcmp(csv_sep, "\\t"))
1429d4ffd04dSJim Cromie 			csv_sep = "\t";
1430d4ffd04dSJim Cromie 	} else
1431d7470b6aSStephane Eranian 		csv_sep = DEFAULT_SEPARATOR;
1432d7470b6aSStephane Eranian 
1433d7470b6aSStephane Eranian 	/*
1434d7470b6aSStephane Eranian 	 * let the spreadsheet do the pretty-printing
1435d7470b6aSStephane Eranian 	 */
1436d7470b6aSStephane Eranian 	if (csv_output) {
143761a9f324SJim Cromie 		/* User explicitly passed -B? */
1438d7470b6aSStephane Eranian 		if (big_num_opt == 1) {
1439d7470b6aSStephane Eranian 			fprintf(stderr, "-B option not supported with -x\n");
1440e0547311SJiri Olsa 			parse_options_usage(stat_usage, stat_options, "B", 1);
1441e0547311SJiri Olsa 			parse_options_usage(NULL, stat_options, "x", 1);
1442cc03c542SNamhyung Kim 			goto out;
1443d7470b6aSStephane Eranian 		} else /* Nope, so disable big number formatting */
1444d7470b6aSStephane Eranian 			big_num = false;
1445d7470b6aSStephane Eranian 	} else if (big_num_opt == 0) /* User passed --no-big-num */
1446d7470b6aSStephane Eranian 		big_num = false;
1447d7470b6aSStephane Eranian 
1448602ad878SArnaldo Carvalho de Melo 	if (!argc && target__none(&target))
1449e0547311SJiri Olsa 		usage_with_options(stat_usage, stat_options);
1450ac3063bdSDavid Ahern 
1451a7e191c3SFrederik Deweerdt 	if (run_count < 0) {
1452cc03c542SNamhyung Kim 		pr_err("Run count must be a positive number\n");
1453e0547311SJiri Olsa 		parse_options_usage(stat_usage, stat_options, "r", 1);
1454cc03c542SNamhyung Kim 		goto out;
1455a7e191c3SFrederik Deweerdt 	} else if (run_count == 0) {
1456a7e191c3SFrederik Deweerdt 		forever = true;
1457a7e191c3SFrederik Deweerdt 		run_count = 1;
1458a7e191c3SFrederik Deweerdt 	}
145986470930SIngo Molnar 
1460421a50f3SJiri Olsa 	if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) {
146132b8af82SJiri Olsa 		fprintf(stderr, "The --per-thread option is only available "
146232b8af82SJiri Olsa 			"when monitoring via -p -t options.\n");
1463e0547311SJiri Olsa 		parse_options_usage(NULL, stat_options, "p", 1);
1464e0547311SJiri Olsa 		parse_options_usage(NULL, stat_options, "t", 1);
146532b8af82SJiri Olsa 		goto out;
146632b8af82SJiri Olsa 	}
146732b8af82SJiri Olsa 
146832b8af82SJiri Olsa 	/*
146932b8af82SJiri Olsa 	 * no_aggr, cgroup are for system-wide only
147032b8af82SJiri Olsa 	 * --per-thread is aggregated per thread, we dont mix it with cpu mode
147132b8af82SJiri Olsa 	 */
1472421a50f3SJiri Olsa 	if (((stat_config.aggr_mode != AGGR_GLOBAL &&
1473421a50f3SJiri Olsa 	      stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
1474602ad878SArnaldo Carvalho de Melo 	    !target__has_cpu(&target)) {
1475023695d9SStephane Eranian 		fprintf(stderr, "both cgroup and no-aggregation "
1476023695d9SStephane Eranian 			"modes only available in system-wide mode\n");
1477023695d9SStephane Eranian 
1478e0547311SJiri Olsa 		parse_options_usage(stat_usage, stat_options, "G", 1);
1479e0547311SJiri Olsa 		parse_options_usage(NULL, stat_options, "A", 1);
1480e0547311SJiri Olsa 		parse_options_usage(NULL, stat_options, "a", 1);
1481cc03c542SNamhyung Kim 		goto out;
1482d7e7a451SStephane Eranian 	}
1483d7e7a451SStephane Eranian 
14842cba3ffbSIngo Molnar 	if (add_default_attributes())
1485c6264defSIngo Molnar 		goto out;
148686470930SIngo Molnar 
1487602ad878SArnaldo Carvalho de Melo 	target__validate(&target);
14885c98d466SArnaldo Carvalho de Melo 
148977a6f014SNamhyung Kim 	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1490602ad878SArnaldo Carvalho de Melo 		if (target__has_task(&target)) {
14915c98d466SArnaldo Carvalho de Melo 			pr_err("Problems finding threads of monitor\n");
1492e0547311SJiri Olsa 			parse_options_usage(stat_usage, stat_options, "p", 1);
1493e0547311SJiri Olsa 			parse_options_usage(NULL, stat_options, "t", 1);
1494602ad878SArnaldo Carvalho de Melo 		} else if (target__has_cpu(&target)) {
149560d567e2SArnaldo Carvalho de Melo 			perror("failed to parse CPUs map");
1496e0547311SJiri Olsa 			parse_options_usage(stat_usage, stat_options, "C", 1);
1497e0547311SJiri Olsa 			parse_options_usage(NULL, stat_options, "a", 1);
1498cc03c542SNamhyung Kim 		}
1499cc03c542SNamhyung Kim 		goto out;
150060d567e2SArnaldo Carvalho de Melo 	}
150132b8af82SJiri Olsa 
150232b8af82SJiri Olsa 	/*
150332b8af82SJiri Olsa 	 * Initialize thread_map with comm names,
150432b8af82SJiri Olsa 	 * so we could print it out on output.
150532b8af82SJiri Olsa 	 */
1506421a50f3SJiri Olsa 	if (stat_config.aggr_mode == AGGR_THREAD)
150732b8af82SJiri Olsa 		thread_map__read_comms(evsel_list->threads);
150832b8af82SJiri Olsa 
150913370a9bSStephane Eranian 	if (interval && interval < 100) {
151019afd104SKan Liang 		if (interval < 10) {
151119afd104SKan Liang 			pr_err("print interval must be >= 10ms\n");
1512e0547311SJiri Olsa 			parse_options_usage(stat_usage, stat_options, "I", 1);
151303ad9747SArnaldo Carvalho de Melo 			goto out;
151419afd104SKan Liang 		} else
151519afd104SKan Liang 			pr_warning("print interval < 100ms. "
151619afd104SKan Liang 				   "The overhead percentage could be high in some cases. "
151719afd104SKan Liang 				   "Please proceed with caution.\n");
151813370a9bSStephane Eranian 	}
1519c45c6ea2SStephane Eranian 
1520d134ffb9SArnaldo Carvalho de Melo 	if (perf_evlist__alloc_stats(evsel_list, interval))
152103ad9747SArnaldo Carvalho de Melo 		goto out;
1522d6d901c2SZhang, Yanmin 
152386ee6e18SStephane Eranian 	if (perf_stat_init_aggr_mode())
152403ad9747SArnaldo Carvalho de Melo 		goto out;
152586ee6e18SStephane Eranian 
152686470930SIngo Molnar 	/*
152786470930SIngo Molnar 	 * We dont want to block the signals - that would cause
152886470930SIngo Molnar 	 * child tasks to inherit that and Ctrl-C would not work.
152986470930SIngo Molnar 	 * What we want is for Ctrl-C to work in the exec()-ed
153086470930SIngo Molnar 	 * task, but being ignored by perf stat itself:
153186470930SIngo Molnar 	 */
1532f7b7c26eSPeter Zijlstra 	atexit(sig_atexit);
1533a7e191c3SFrederik Deweerdt 	if (!forever)
153486470930SIngo Molnar 		signal(SIGINT,  skip_signal);
153513370a9bSStephane Eranian 	signal(SIGCHLD, skip_signal);
153686470930SIngo Molnar 	signal(SIGALRM, skip_signal);
153786470930SIngo Molnar 	signal(SIGABRT, skip_signal);
153886470930SIngo Molnar 
153942202dd5SIngo Molnar 	status = 0;
1540a7e191c3SFrederik Deweerdt 	for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
154142202dd5SIngo Molnar 		if (run_count != 1 && verbose)
15424aa9015fSStephane Eranian 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
15434aa9015fSStephane Eranian 				run_idx + 1);
1544f9cef0a9SIngo Molnar 
154542202dd5SIngo Molnar 		status = run_perf_stat(argc, argv);
1546a7e191c3SFrederik Deweerdt 		if (forever && status != -1) {
1547d4f63a47SJiri Olsa 			print_counters(NULL, argc, argv);
1548254ecbc7SJiri Olsa 			perf_stat__reset_stats();
1549a7e191c3SFrederik Deweerdt 		}
155042202dd5SIngo Molnar 	}
155142202dd5SIngo Molnar 
1552a7e191c3SFrederik Deweerdt 	if (!forever && status != -1 && !interval)
1553d4f63a47SJiri Olsa 		print_counters(NULL, argc, argv);
1554d134ffb9SArnaldo Carvalho de Melo 
15554979d0c7SJiri Olsa 	if (STAT_RECORD) {
15564979d0c7SJiri Olsa 		/*
15574979d0c7SJiri Olsa 		 * We synthesize the kernel mmap record just so that older tools
15584979d0c7SJiri Olsa 		 * don't emit warnings about not being able to resolve symbols
15594979d0c7SJiri Olsa 		 * due to /proc/sys/kernel/kptr_restrict settings and instear provide
15604979d0c7SJiri Olsa 		 * a saner message about no samples being in the perf.data file.
15614979d0c7SJiri Olsa 		 *
15624979d0c7SJiri Olsa 		 * This also serves to suppress a warning about f_header.data.size == 0
15634979d0c7SJiri Olsa 		 * in header.c.  -acme
15644979d0c7SJiri Olsa 		 */
15654979d0c7SJiri Olsa 		int fd = perf_data_file__fd(&perf_stat.file);
15664979d0c7SJiri Olsa 		int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat,
15674979d0c7SJiri Olsa 							     process_synthesized_event,
15684979d0c7SJiri Olsa 							     &perf_stat.session->machines.host);
15694979d0c7SJiri Olsa 		if (err) {
15704979d0c7SJiri Olsa 			pr_warning("Couldn't synthesize the kernel mmap record, harmless, "
15714979d0c7SJiri Olsa 				   "older tools may produce warnings about this file\n.");
15724979d0c7SJiri Olsa 		}
15734979d0c7SJiri Olsa 
15744979d0c7SJiri Olsa 		perf_stat.session->header.data_size += perf_stat.bytes_written;
15754979d0c7SJiri Olsa 		perf_session__write_header(perf_stat.session, evsel_list, fd, true);
15764979d0c7SJiri Olsa 
15774979d0c7SJiri Olsa 		perf_session__delete(perf_stat.session);
15784979d0c7SJiri Olsa 	}
15794979d0c7SJiri Olsa 
1580544c2ae7SMasami Hiramatsu 	perf_stat__exit_aggr_mode();
1581d134ffb9SArnaldo Carvalho de Melo 	perf_evlist__free_stats(evsel_list);
15820015e2e1SArnaldo Carvalho de Melo out:
15830015e2e1SArnaldo Carvalho de Melo 	perf_evlist__delete(evsel_list);
158442202dd5SIngo Molnar 	return status;
158586470930SIngo Molnar }
1586