xref: /openbmc/linux/tools/perf/builtin-stat.c (revision 602ad878)
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"
4686470930SIngo Molnar #include "util/util.h"
4786470930SIngo Molnar #include "util/parse-options.h"
4886470930SIngo Molnar #include "util/parse-events.h"
494cabc3d1SAndi Kleen #include "util/pmu.h"
508f28827aSFrederic Weisbecker #include "util/event.h"
51361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h"
5269aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h"
538f28827aSFrederic Weisbecker #include "util/debug.h"
54a5d243d0SIngo Molnar #include "util/color.h"
550007eceaSXiao Guangrong #include "util/stat.h"
5660666c63SLiming Wang #include "util/header.h"
57a12b51c4SPaul Mackerras #include "util/cpumap.h"
58d6d901c2SZhang, Yanmin #include "util/thread.h"
59fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h"
6086470930SIngo Molnar 
611f16c575SPeter Zijlstra #include <stdlib.h>
6286470930SIngo Molnar #include <sys/prctl.h>
635af52b51SStephane Eranian #include <locale.h>
6486470930SIngo Molnar 
65d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR	" "
662cee77c4SDavid Ahern #define CNTR_NOT_SUPPORTED	"<not supported>"
672cee77c4SDavid Ahern #define CNTR_NOT_COUNTED	"<not counted>"
68d7470b6aSStephane Eranian 
6913370a9bSStephane Eranian static void print_stat(int argc, const char **argv);
7013370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix);
7113370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix);
7286ee6e18SStephane Eranian static void print_aggr(char *prefix);
7313370a9bSStephane Eranian 
744cabc3d1SAndi Kleen /* Default events used for perf stat -T */
754cabc3d1SAndi Kleen static const char * const transaction_attrs[] = {
764cabc3d1SAndi Kleen 	"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. */
884cabc3d1SAndi Kleen static const char * const transaction_limited_attrs[] = {
894cabc3d1SAndi Kleen 	"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 
984cabc3d1SAndi Kleen /* must match transaction_attrs and the beginning limited_attrs */
994cabc3d1SAndi Kleen enum {
1004cabc3d1SAndi Kleen 	T_TASK_CLOCK,
1014cabc3d1SAndi Kleen 	T_INSTRUCTIONS,
1024cabc3d1SAndi Kleen 	T_CYCLES,
1034cabc3d1SAndi Kleen 	T_CYCLES_IN_TX,
1044cabc3d1SAndi Kleen 	T_TRANSACTION_START,
1054cabc3d1SAndi Kleen 	T_ELISION_START,
1064cabc3d1SAndi Kleen 	T_CYCLES_IN_TX_CP,
1074cabc3d1SAndi Kleen };
1084cabc3d1SAndi Kleen 
109666e6d48SRobert Richter static struct perf_evlist	*evsel_list;
110361c99a6SArnaldo Carvalho de Melo 
111602ad878SArnaldo Carvalho de Melo static struct target target = {
11277a6f014SNamhyung Kim 	.uid	= UINT_MAX,
11377a6f014SNamhyung Kim };
11442202dd5SIngo Molnar 
11586ee6e18SStephane Eranian enum aggr_mode {
11686ee6e18SStephane Eranian 	AGGR_NONE,
11786ee6e18SStephane Eranian 	AGGR_GLOBAL,
11886ee6e18SStephane Eranian 	AGGR_SOCKET,
11912c08a9fSStephane Eranian 	AGGR_CORE,
12086ee6e18SStephane Eranian };
12186ee6e18SStephane Eranian 
1223d632595SJaswinder Singh Rajput static int			run_count			=  1;
1232e6cdf99SStephane Eranian static bool			no_inherit			= false;
124c0555642SIan Munsie static bool			scale				=  true;
12586ee6e18SStephane Eranian static enum aggr_mode		aggr_mode			= AGGR_GLOBAL;
126d07f0b12SStephane Eranian static volatile pid_t		child_pid			= -1;
127c0555642SIan Munsie static bool			null_run			=  false;
1282cba3ffbSIngo Molnar static int			detailed_run			=  0;
1294cabc3d1SAndi Kleen static bool			transaction_run;
130201e0b06SArnaldo Carvalho de Melo static bool			big_num				=  true;
131d7470b6aSStephane Eranian static int			big_num_opt			=  -1;
132d7470b6aSStephane Eranian static const char		*csv_sep			= NULL;
133d7470b6aSStephane Eranian static bool			csv_output			= false;
13443bece79SLin Ming static bool			group				= false;
1354aa9015fSStephane Eranian static FILE			*output				= NULL;
1361f16c575SPeter Zijlstra static const char		*pre_cmd			= NULL;
1371f16c575SPeter Zijlstra static const char		*post_cmd			= NULL;
1381f16c575SPeter Zijlstra static bool			sync_run			= false;
13913370a9bSStephane Eranian static unsigned int		interval			= 0;
14041191688SAndi Kleen static unsigned int		initial_delay			= 0;
141a7e191c3SFrederik Deweerdt static bool			forever				= false;
14213370a9bSStephane Eranian static struct timespec		ref_time;
14386ee6e18SStephane Eranian static struct cpu_map		*aggr_map;
14486ee6e18SStephane Eranian static int			(*aggr_get_id)(struct cpu_map *m, int cpu);
1455af52b51SStephane Eranian 
14660666c63SLiming Wang static volatile int done = 0;
14760666c63SLiming Wang 
14869aad6f1SArnaldo Carvalho de Melo struct perf_stat {
14969aad6f1SArnaldo Carvalho de Melo 	struct stats	  res_stats[3];
15069aad6f1SArnaldo Carvalho de Melo };
15169aad6f1SArnaldo Carvalho de Melo 
15213370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a,
15313370a9bSStephane Eranian 				 struct timespec *b)
15413370a9bSStephane Eranian {
15513370a9bSStephane Eranian 	r->tv_sec = a->tv_sec - b->tv_sec;
15613370a9bSStephane Eranian 	if (a->tv_nsec < b->tv_nsec) {
15713370a9bSStephane Eranian 		r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec;
15813370a9bSStephane Eranian 		r->tv_sec--;
15913370a9bSStephane Eranian 	} else {
16013370a9bSStephane Eranian 		r->tv_nsec = a->tv_nsec - b->tv_nsec ;
16113370a9bSStephane Eranian 	}
16213370a9bSStephane Eranian }
16313370a9bSStephane Eranian 
16413370a9bSStephane Eranian static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
16513370a9bSStephane Eranian {
16613370a9bSStephane Eranian 	return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus;
16713370a9bSStephane Eranian }
16813370a9bSStephane Eranian 
16913370a9bSStephane Eranian static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
17013370a9bSStephane Eranian {
17113370a9bSStephane Eranian 	return perf_evsel__cpus(evsel)->nr;
17213370a9bSStephane Eranian }
17313370a9bSStephane Eranian 
174a7e191c3SFrederik Deweerdt static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
175a7e191c3SFrederik Deweerdt {
176a7e191c3SFrederik Deweerdt 	memset(evsel->priv, 0, sizeof(struct perf_stat));
177a7e191c3SFrederik Deweerdt }
178a7e191c3SFrederik Deweerdt 
179c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
18069aad6f1SArnaldo Carvalho de Melo {
181c52b12edSArnaldo Carvalho de Melo 	evsel->priv = zalloc(sizeof(struct perf_stat));
18269aad6f1SArnaldo Carvalho de Melo 	return evsel->priv == NULL ? -ENOMEM : 0;
18369aad6f1SArnaldo Carvalho de Melo }
18469aad6f1SArnaldo Carvalho de Melo 
18569aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
18669aad6f1SArnaldo Carvalho de Melo {
18769aad6f1SArnaldo Carvalho de Melo 	free(evsel->priv);
18869aad6f1SArnaldo Carvalho de Melo 	evsel->priv = NULL;
18969aad6f1SArnaldo Carvalho de Melo }
19069aad6f1SArnaldo Carvalho de Melo 
19113370a9bSStephane Eranian static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
1927ae92e74SYan, Zheng {
19313370a9bSStephane Eranian 	void *addr;
19413370a9bSStephane Eranian 	size_t sz;
19513370a9bSStephane Eranian 
19613370a9bSStephane Eranian 	sz = sizeof(*evsel->counts) +
19713370a9bSStephane Eranian 	     (perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values));
19813370a9bSStephane Eranian 
19913370a9bSStephane Eranian 	addr = zalloc(sz);
20013370a9bSStephane Eranian 	if (!addr)
20113370a9bSStephane Eranian 		return -ENOMEM;
20213370a9bSStephane Eranian 
20313370a9bSStephane Eranian 	evsel->prev_raw_counts =  addr;
20413370a9bSStephane Eranian 
20513370a9bSStephane Eranian 	return 0;
2067ae92e74SYan, Zheng }
2077ae92e74SYan, Zheng 
20813370a9bSStephane Eranian static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
2097ae92e74SYan, Zheng {
21013370a9bSStephane Eranian 	free(evsel->prev_raw_counts);
21113370a9bSStephane Eranian 	evsel->prev_raw_counts = NULL;
2127ae92e74SYan, Zheng }
2137ae92e74SYan, Zheng 
214d134ffb9SArnaldo Carvalho de Melo static void perf_evlist__free_stats(struct perf_evlist *evlist)
215d134ffb9SArnaldo Carvalho de Melo {
216d134ffb9SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
217d134ffb9SArnaldo Carvalho de Melo 
218d134ffb9SArnaldo Carvalho de Melo 	list_for_each_entry(evsel, &evlist->entries, node) {
219d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_stat_priv(evsel);
220d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_counts(evsel);
221d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_prev_raw_counts(evsel);
222d134ffb9SArnaldo Carvalho de Melo 	}
223d134ffb9SArnaldo Carvalho de Melo }
224d134ffb9SArnaldo Carvalho de Melo 
225d134ffb9SArnaldo Carvalho de Melo static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
226d134ffb9SArnaldo Carvalho de Melo {
227d134ffb9SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
228d134ffb9SArnaldo Carvalho de Melo 
229d134ffb9SArnaldo Carvalho de Melo 	list_for_each_entry(evsel, &evlist->entries, node) {
230d134ffb9SArnaldo Carvalho de Melo 		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
231d134ffb9SArnaldo Carvalho de Melo 		    perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
232d134ffb9SArnaldo Carvalho de Melo 		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
233d134ffb9SArnaldo Carvalho de Melo 			goto out_free;
234d134ffb9SArnaldo Carvalho de Melo 	}
235d134ffb9SArnaldo Carvalho de Melo 
236d134ffb9SArnaldo Carvalho de Melo 	return 0;
237d134ffb9SArnaldo Carvalho de Melo 
238d134ffb9SArnaldo Carvalho de Melo out_free:
239d134ffb9SArnaldo Carvalho de Melo 	perf_evlist__free_stats(evlist);
240d134ffb9SArnaldo Carvalho de Melo 	return -1;
241d134ffb9SArnaldo Carvalho de Melo }
242d134ffb9SArnaldo Carvalho de Melo 
243666e6d48SRobert Richter static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
244666e6d48SRobert Richter static struct stats runtime_cycles_stats[MAX_NR_CPUS];
245666e6d48SRobert Richter static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
246666e6d48SRobert Richter static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS];
247666e6d48SRobert Richter static struct stats runtime_branches_stats[MAX_NR_CPUS];
248666e6d48SRobert Richter static struct stats runtime_cacherefs_stats[MAX_NR_CPUS];
249666e6d48SRobert Richter static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS];
250666e6d48SRobert Richter static struct stats runtime_l1_icache_stats[MAX_NR_CPUS];
251666e6d48SRobert Richter static struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
252666e6d48SRobert Richter static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
253666e6d48SRobert Richter static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
2544cabc3d1SAndi Kleen static struct stats runtime_cycles_in_tx_stats[MAX_NR_CPUS];
255666e6d48SRobert Richter static struct stats walltime_nsecs_stats;
2564cabc3d1SAndi Kleen static struct stats runtime_transaction_stats[MAX_NR_CPUS];
2574cabc3d1SAndi Kleen static struct stats runtime_elision_stats[MAX_NR_CPUS];
25886470930SIngo Molnar 
259d134ffb9SArnaldo Carvalho de Melo static void perf_stat__reset_stats(struct perf_evlist *evlist)
260a7e191c3SFrederik Deweerdt {
261d134ffb9SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
262d134ffb9SArnaldo Carvalho de Melo 
263d134ffb9SArnaldo Carvalho de Melo 	list_for_each_entry(evsel, &evlist->entries, node) {
264d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__reset_stat_priv(evsel);
265d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
266d134ffb9SArnaldo Carvalho de Melo 	}
267d134ffb9SArnaldo Carvalho de Melo 
268a7e191c3SFrederik Deweerdt 	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
269a7e191c3SFrederik Deweerdt 	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
270a7e191c3SFrederik Deweerdt 	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
271a7e191c3SFrederik Deweerdt 	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
272a7e191c3SFrederik Deweerdt 	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
273a7e191c3SFrederik Deweerdt 	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
274a7e191c3SFrederik Deweerdt 	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
275a7e191c3SFrederik Deweerdt 	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
276a7e191c3SFrederik Deweerdt 	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
277a7e191c3SFrederik Deweerdt 	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
278a7e191c3SFrederik Deweerdt 	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
2794cabc3d1SAndi Kleen 	memset(runtime_cycles_in_tx_stats, 0,
2804cabc3d1SAndi Kleen 			sizeof(runtime_cycles_in_tx_stats));
2814cabc3d1SAndi Kleen 	memset(runtime_transaction_stats, 0,
2824cabc3d1SAndi Kleen 		sizeof(runtime_transaction_stats));
2834cabc3d1SAndi Kleen 	memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
284a7e191c3SFrederik Deweerdt 	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
285a7e191c3SFrederik Deweerdt }
286a7e191c3SFrederik Deweerdt 
287cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel)
28886470930SIngo Molnar {
28969aad6f1SArnaldo Carvalho de Melo 	struct perf_event_attr *attr = &evsel->attr;
290727ab04eSArnaldo Carvalho de Melo 
29186470930SIngo Molnar 	if (scale)
29286470930SIngo Molnar 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
29386470930SIngo Molnar 				    PERF_FORMAT_TOTAL_TIME_RUNNING;
29486470930SIngo Molnar 
2952e6cdf99SStephane Eranian 	attr->inherit = !no_inherit;
2965d2cd909SArnaldo Carvalho de Melo 
297602ad878SArnaldo Carvalho de Melo 	if (target__has_cpu(&target))
298594ac61aSArnaldo Carvalho de Melo 		return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
2995622c07bSStephane Eranian 
300602ad878SArnaldo Carvalho de Melo 	if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) {
30186470930SIngo Molnar 		attr->disabled = 1;
30241191688SAndi Kleen 		if (!initial_delay)
30357e7986eSPaul Mackerras 			attr->enable_on_exec = 1;
3046be2850eSZhang, Yanmin 	}
305084ab9f8SArnaldo Carvalho de Melo 
306594ac61aSArnaldo Carvalho de Melo 	return perf_evsel__open_per_thread(evsel, evsel_list->threads);
30786470930SIngo Molnar }
30886470930SIngo Molnar 
30986470930SIngo Molnar /*
31086470930SIngo Molnar  * Does the counter have nsecs as a unit?
31186470930SIngo Molnar  */
312daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel)
31386470930SIngo Molnar {
314daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
315daec78a0SArnaldo Carvalho de Melo 	    perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
31686470930SIngo Molnar 		return 1;
31786470930SIngo Molnar 
31886470930SIngo Molnar 	return 0;
31986470930SIngo Molnar }
32086470930SIngo Molnar 
3214cabc3d1SAndi Kleen static struct perf_evsel *nth_evsel(int n)
3224cabc3d1SAndi Kleen {
3234cabc3d1SAndi Kleen 	static struct perf_evsel **array;
3244cabc3d1SAndi Kleen 	static int array_len;
3254cabc3d1SAndi Kleen 	struct perf_evsel *ev;
3264cabc3d1SAndi Kleen 	int j;
3274cabc3d1SAndi Kleen 
3284cabc3d1SAndi Kleen 	/* Assumes this only called when evsel_list does not change anymore. */
3294cabc3d1SAndi Kleen 	if (!array) {
3304cabc3d1SAndi Kleen 		list_for_each_entry(ev, &evsel_list->entries, node)
3314cabc3d1SAndi Kleen 			array_len++;
3324cabc3d1SAndi Kleen 		array = malloc(array_len * sizeof(void *));
3334cabc3d1SAndi Kleen 		if (!array)
3344cabc3d1SAndi Kleen 			exit(ENOMEM);
3354cabc3d1SAndi Kleen 		j = 0;
3364cabc3d1SAndi Kleen 		list_for_each_entry(ev, &evsel_list->entries, node)
3374cabc3d1SAndi Kleen 			array[j++] = ev;
3384cabc3d1SAndi Kleen 	}
3394cabc3d1SAndi Kleen 	if (n < array_len)
3404cabc3d1SAndi Kleen 		return array[n];
3414cabc3d1SAndi Kleen 	return NULL;
3424cabc3d1SAndi Kleen }
3434cabc3d1SAndi Kleen 
34486470930SIngo Molnar /*
345dcd9936aSIngo Molnar  * Update various tracking values we maintain to print
346dcd9936aSIngo Molnar  * more semantic information such as miss/hit ratios,
347dcd9936aSIngo Molnar  * instruction rates, etc:
348dcd9936aSIngo Molnar  */
349dcd9936aSIngo Molnar static void update_shadow_stats(struct perf_evsel *counter, u64 *count)
350dcd9936aSIngo Molnar {
351dcd9936aSIngo Molnar 	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
352dcd9936aSIngo Molnar 		update_stats(&runtime_nsecs_stats[0], count[0]);
353dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
354dcd9936aSIngo Molnar 		update_stats(&runtime_cycles_stats[0], count[0]);
3554cabc3d1SAndi Kleen 	else if (transaction_run &&
3564cabc3d1SAndi Kleen 		 perf_evsel__cmp(counter, nth_evsel(T_CYCLES_IN_TX)))
3574cabc3d1SAndi Kleen 		update_stats(&runtime_cycles_in_tx_stats[0], count[0]);
3584cabc3d1SAndi Kleen 	else if (transaction_run &&
3594cabc3d1SAndi Kleen 		 perf_evsel__cmp(counter, nth_evsel(T_TRANSACTION_START)))
3604cabc3d1SAndi Kleen 		update_stats(&runtime_transaction_stats[0], count[0]);
3614cabc3d1SAndi Kleen 	else if (transaction_run &&
3624cabc3d1SAndi Kleen 		 perf_evsel__cmp(counter, nth_evsel(T_ELISION_START)))
3634cabc3d1SAndi Kleen 		update_stats(&runtime_elision_stats[0], count[0]);
364d3d1e86dSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
365d3d1e86dSIngo Molnar 		update_stats(&runtime_stalled_cycles_front_stats[0], count[0]);
366129c04cbSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
367d3d1e86dSIngo Molnar 		update_stats(&runtime_stalled_cycles_back_stats[0], count[0]);
368dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
369dcd9936aSIngo Molnar 		update_stats(&runtime_branches_stats[0], count[0]);
370dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
371dcd9936aSIngo Molnar 		update_stats(&runtime_cacherefs_stats[0], count[0]);
3728bb6c79fSIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
3738bb6c79fSIngo Molnar 		update_stats(&runtime_l1_dcache_stats[0], count[0]);
374c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
375c3305257SIngo Molnar 		update_stats(&runtime_l1_icache_stats[0], count[0]);
376c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
377c3305257SIngo Molnar 		update_stats(&runtime_ll_cache_stats[0], count[0]);
378c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
379c3305257SIngo Molnar 		update_stats(&runtime_dtlb_cache_stats[0], count[0]);
380c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
381c3305257SIngo Molnar 		update_stats(&runtime_itlb_cache_stats[0], count[0]);
382dcd9936aSIngo Molnar }
383dcd9936aSIngo Molnar 
384dcd9936aSIngo Molnar /*
38586470930SIngo Molnar  * Read out the results of a single counter:
386f5b4a9c3SStephane Eranian  * aggregate counts across CPUs in system-wide mode
38786470930SIngo Molnar  */
388c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter)
38986470930SIngo Molnar {
39069aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps = counter->priv;
391c52b12edSArnaldo Carvalho de Melo 	u64 *count = counter->counts->aggr.values;
392c52b12edSArnaldo Carvalho de Melo 	int i;
39386470930SIngo Molnar 
3947ae92e74SYan, Zheng 	if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter),
395b3a319d5SNamhyung Kim 			       thread_map__nr(evsel_list->threads), scale) < 0)
396c52b12edSArnaldo Carvalho de Melo 		return -1;
3979e9772c4SPeter Zijlstra 
3989e9772c4SPeter Zijlstra 	for (i = 0; i < 3; i++)
39969aad6f1SArnaldo Carvalho de Melo 		update_stats(&ps->res_stats[i], count[i]);
4009e9772c4SPeter Zijlstra 
4019e9772c4SPeter Zijlstra 	if (verbose) {
4024aa9015fSStephane Eranian 		fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
4037289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter), count[0], count[1], count[2]);
4049e9772c4SPeter Zijlstra 	}
4059e9772c4SPeter Zijlstra 
40686470930SIngo Molnar 	/*
40786470930SIngo Molnar 	 * Save the full runtime - to allow normalization during printout:
40886470930SIngo Molnar 	 */
409dcd9936aSIngo Molnar 	update_shadow_stats(counter, count);
410c52b12edSArnaldo Carvalho de Melo 
411c52b12edSArnaldo Carvalho de Melo 	return 0;
412f5b4a9c3SStephane Eranian }
413f5b4a9c3SStephane Eranian 
414f5b4a9c3SStephane Eranian /*
415f5b4a9c3SStephane Eranian  * Read out the results of a single counter:
416f5b4a9c3SStephane Eranian  * do not aggregate counts across CPUs in system-wide mode
417f5b4a9c3SStephane Eranian  */
418c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter)
419f5b4a9c3SStephane Eranian {
420c52b12edSArnaldo Carvalho de Melo 	u64 *count;
421f5b4a9c3SStephane Eranian 	int cpu;
422f5b4a9c3SStephane Eranian 
4237ae92e74SYan, Zheng 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
424c52b12edSArnaldo Carvalho de Melo 		if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0)
425c52b12edSArnaldo Carvalho de Melo 			return -1;
426f5b4a9c3SStephane Eranian 
427c52b12edSArnaldo Carvalho de Melo 		count = counter->counts->cpu[cpu].values;
428f5b4a9c3SStephane Eranian 
429dcd9936aSIngo Molnar 		update_shadow_stats(counter, count);
430f5b4a9c3SStephane Eranian 	}
431c52b12edSArnaldo Carvalho de Melo 
432c52b12edSArnaldo Carvalho de Melo 	return 0;
43386470930SIngo Molnar }
43486470930SIngo Molnar 
43513370a9bSStephane Eranian static void print_interval(void)
43613370a9bSStephane Eranian {
43713370a9bSStephane Eranian 	static int num_print_interval;
43813370a9bSStephane Eranian 	struct perf_evsel *counter;
43913370a9bSStephane Eranian 	struct perf_stat *ps;
44013370a9bSStephane Eranian 	struct timespec ts, rs;
44113370a9bSStephane Eranian 	char prefix[64];
44213370a9bSStephane Eranian 
44386ee6e18SStephane Eranian 	if (aggr_mode == AGGR_GLOBAL) {
44413370a9bSStephane Eranian 		list_for_each_entry(counter, &evsel_list->entries, node) {
44513370a9bSStephane Eranian 			ps = counter->priv;
44613370a9bSStephane Eranian 			memset(ps->res_stats, 0, sizeof(ps->res_stats));
44713370a9bSStephane Eranian 			read_counter_aggr(counter);
44813370a9bSStephane Eranian 		}
44986ee6e18SStephane Eranian 	} else	{
45086ee6e18SStephane Eranian 		list_for_each_entry(counter, &evsel_list->entries, node) {
45186ee6e18SStephane Eranian 			ps = counter->priv;
45286ee6e18SStephane Eranian 			memset(ps->res_stats, 0, sizeof(ps->res_stats));
45386ee6e18SStephane Eranian 			read_counter(counter);
45413370a9bSStephane Eranian 		}
45586ee6e18SStephane Eranian 	}
45686ee6e18SStephane Eranian 
45713370a9bSStephane Eranian 	clock_gettime(CLOCK_MONOTONIC, &ts);
45813370a9bSStephane Eranian 	diff_timespec(&rs, &ts, &ref_time);
45913370a9bSStephane Eranian 	sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep);
46013370a9bSStephane Eranian 
46113370a9bSStephane Eranian 	if (num_print_interval == 0 && !csv_output) {
46286ee6e18SStephane Eranian 		switch (aggr_mode) {
46386ee6e18SStephane Eranian 		case AGGR_SOCKET:
464d7e7a451SStephane Eranian 			fprintf(output, "#           time socket cpus             counts events\n");
46586ee6e18SStephane Eranian 			break;
46612c08a9fSStephane Eranian 		case AGGR_CORE:
46712c08a9fSStephane Eranian 			fprintf(output, "#           time core         cpus             counts events\n");
46812c08a9fSStephane Eranian 			break;
46986ee6e18SStephane Eranian 		case AGGR_NONE:
47013370a9bSStephane Eranian 			fprintf(output, "#           time CPU                 counts events\n");
47186ee6e18SStephane Eranian 			break;
47286ee6e18SStephane Eranian 		case AGGR_GLOBAL:
47386ee6e18SStephane Eranian 		default:
47413370a9bSStephane Eranian 			fprintf(output, "#           time             counts events\n");
47513370a9bSStephane Eranian 		}
47686ee6e18SStephane Eranian 	}
47713370a9bSStephane Eranian 
47813370a9bSStephane Eranian 	if (++num_print_interval == 25)
47913370a9bSStephane Eranian 		num_print_interval = 0;
48013370a9bSStephane Eranian 
48186ee6e18SStephane Eranian 	switch (aggr_mode) {
48212c08a9fSStephane Eranian 	case AGGR_CORE:
48386ee6e18SStephane Eranian 	case AGGR_SOCKET:
48486ee6e18SStephane Eranian 		print_aggr(prefix);
48586ee6e18SStephane Eranian 		break;
48686ee6e18SStephane Eranian 	case AGGR_NONE:
48713370a9bSStephane Eranian 		list_for_each_entry(counter, &evsel_list->entries, node)
48813370a9bSStephane Eranian 			print_counter(counter, prefix);
48986ee6e18SStephane Eranian 		break;
49086ee6e18SStephane Eranian 	case AGGR_GLOBAL:
49186ee6e18SStephane Eranian 	default:
49213370a9bSStephane Eranian 		list_for_each_entry(counter, &evsel_list->entries, node)
49313370a9bSStephane Eranian 			print_counter_aggr(counter, prefix);
49413370a9bSStephane Eranian 	}
4952bbf03f1SAndi Kleen 
4962bbf03f1SAndi Kleen 	fflush(output);
49713370a9bSStephane Eranian }
49813370a9bSStephane Eranian 
49941191688SAndi Kleen static void handle_initial_delay(void)
50041191688SAndi Kleen {
50141191688SAndi Kleen 	struct perf_evsel *counter;
50241191688SAndi Kleen 
50341191688SAndi Kleen 	if (initial_delay) {
50441191688SAndi Kleen 		const int ncpus = cpu_map__nr(evsel_list->cpus),
50541191688SAndi Kleen 			nthreads = thread_map__nr(evsel_list->threads);
50641191688SAndi Kleen 
50741191688SAndi Kleen 		usleep(initial_delay * 1000);
50841191688SAndi Kleen 		list_for_each_entry(counter, &evsel_list->entries, node)
50941191688SAndi Kleen 			perf_evsel__enable(counter, ncpus, nthreads);
51041191688SAndi Kleen 	}
51141191688SAndi Kleen }
51241191688SAndi Kleen 
513acf28922SNamhyung Kim static int __run_perf_stat(int argc, const char **argv)
51486470930SIngo Molnar {
51556e52e85SArnaldo Carvalho de Melo 	char msg[512];
51686470930SIngo Molnar 	unsigned long long t0, t1;
517cac21425SJiri Olsa 	struct perf_evsel *counter;
51813370a9bSStephane Eranian 	struct timespec ts;
51942202dd5SIngo Molnar 	int status = 0;
5206be2850eSZhang, Yanmin 	const bool forks = (argc > 0);
52186470930SIngo Molnar 
52213370a9bSStephane Eranian 	if (interval) {
52313370a9bSStephane Eranian 		ts.tv_sec  = interval / 1000;
52413370a9bSStephane Eranian 		ts.tv_nsec = (interval % 1000) * 1000000;
52513370a9bSStephane Eranian 	} else {
52613370a9bSStephane Eranian 		ts.tv_sec  = 1;
52713370a9bSStephane Eranian 		ts.tv_nsec = 0;
52813370a9bSStephane Eranian 	}
52913370a9bSStephane Eranian 
530acf28922SNamhyung Kim 	if (forks) {
531acf28922SNamhyung Kim 		if (perf_evlist__prepare_workload(evsel_list, &target, argv,
532acf28922SNamhyung Kim 						  false, false) < 0) {
533acf28922SNamhyung Kim 			perror("failed to prepare workload");
534fceda7feSDavid Ahern 			return -1;
535051ae7f7SPaul Mackerras 		}
536d20a47e7SNamhyung Kim 		child_pid = evsel_list->workload.pid;
53760666c63SLiming Wang 	}
538051ae7f7SPaul Mackerras 
5396a4bb04cSJiri Olsa 	if (group)
54063dab225SArnaldo Carvalho de Melo 		perf_evlist__set_leader(evsel_list);
5416a4bb04cSJiri Olsa 
542361c99a6SArnaldo Carvalho de Melo 	list_for_each_entry(counter, &evsel_list->entries, node) {
543cac21425SJiri Olsa 		if (create_perf_stat_counter(counter) < 0) {
544979987a5SDavid Ahern 			/*
545979987a5SDavid Ahern 			 * PPC returns ENXIO for HW counters until 2.6.37
546979987a5SDavid Ahern 			 * (behavior changed with commit b0a873e).
547979987a5SDavid Ahern 			 */
54838f6ae1eSAnton Blanchard 			if (errno == EINVAL || errno == ENOSYS ||
549979987a5SDavid Ahern 			    errno == ENOENT || errno == EOPNOTSUPP ||
550979987a5SDavid Ahern 			    errno == ENXIO) {
551c63ca0c0SDavid Ahern 				if (verbose)
552c63ca0c0SDavid Ahern 					ui__warning("%s event is not supported by the kernel.\n",
5537289f83cSArnaldo Carvalho de Melo 						    perf_evsel__name(counter));
5542cee77c4SDavid Ahern 				counter->supported = false;
555ede70290SIngo Molnar 				continue;
556c63ca0c0SDavid Ahern 			}
557ede70290SIngo Molnar 
55856e52e85SArnaldo Carvalho de Melo 			perf_evsel__open_strerror(counter, &target,
55956e52e85SArnaldo Carvalho de Melo 						  errno, msg, sizeof(msg));
56056e52e85SArnaldo Carvalho de Melo 			ui__error("%s\n", msg);
56156e52e85SArnaldo Carvalho de Melo 
562084ab9f8SArnaldo Carvalho de Melo 			if (child_pid != -1)
563084ab9f8SArnaldo Carvalho de Melo 				kill(child_pid, SIGTERM);
564fceda7feSDavid Ahern 
565084ab9f8SArnaldo Carvalho de Melo 			return -1;
566084ab9f8SArnaldo Carvalho de Melo 		}
5672cee77c4SDavid Ahern 		counter->supported = true;
56848290609SArnaldo Carvalho de Melo 	}
56986470930SIngo Molnar 
5701491a632SArnaldo Carvalho de Melo 	if (perf_evlist__apply_filters(evsel_list)) {
571cfd748aeSFrederic Weisbecker 		error("failed to set filter with %d (%s)\n", errno,
572cfd748aeSFrederic Weisbecker 			strerror(errno));
573cfd748aeSFrederic Weisbecker 		return -1;
574cfd748aeSFrederic Weisbecker 	}
575cfd748aeSFrederic Weisbecker 
57686470930SIngo Molnar 	/*
57786470930SIngo Molnar 	 * Enable counters and exec the command:
57886470930SIngo Molnar 	 */
57986470930SIngo Molnar 	t0 = rdclock();
58013370a9bSStephane Eranian 	clock_gettime(CLOCK_MONOTONIC, &ref_time);
58186470930SIngo Molnar 
58260666c63SLiming Wang 	if (forks) {
583acf28922SNamhyung Kim 		perf_evlist__start_workload(evsel_list);
58441191688SAndi Kleen 		handle_initial_delay();
585acf28922SNamhyung Kim 
58613370a9bSStephane Eranian 		if (interval) {
58713370a9bSStephane Eranian 			while (!waitpid(child_pid, &status, WNOHANG)) {
58813370a9bSStephane Eranian 				nanosleep(&ts, NULL);
58913370a9bSStephane Eranian 				print_interval();
59013370a9bSStephane Eranian 			}
59113370a9bSStephane Eranian 		}
59242202dd5SIngo Molnar 		wait(&status);
59333e49ea7SAndi Kleen 		if (WIFSIGNALED(status))
59433e49ea7SAndi Kleen 			psignal(WTERMSIG(status), argv[0]);
59560666c63SLiming Wang 	} else {
59641191688SAndi Kleen 		handle_initial_delay();
59713370a9bSStephane Eranian 		while (!done) {
59813370a9bSStephane Eranian 			nanosleep(&ts, NULL);
59913370a9bSStephane Eranian 			if (interval)
60013370a9bSStephane Eranian 				print_interval();
60113370a9bSStephane Eranian 		}
60260666c63SLiming Wang 	}
60386470930SIngo Molnar 
60486470930SIngo Molnar 	t1 = rdclock();
60586470930SIngo Molnar 
6069e9772c4SPeter Zijlstra 	update_stats(&walltime_nsecs_stats, t1 - t0);
60742202dd5SIngo Molnar 
60886ee6e18SStephane Eranian 	if (aggr_mode == AGGR_GLOBAL) {
609361c99a6SArnaldo Carvalho de Melo 		list_for_each_entry(counter, &evsel_list->entries, node) {
610c52b12edSArnaldo Carvalho de Melo 			read_counter_aggr(counter);
6117ae92e74SYan, Zheng 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
612b3a319d5SNamhyung Kim 					     thread_map__nr(evsel_list->threads));
613c52b12edSArnaldo Carvalho de Melo 		}
61486ee6e18SStephane Eranian 	} else {
61586ee6e18SStephane Eranian 		list_for_each_entry(counter, &evsel_list->entries, node) {
61686ee6e18SStephane Eranian 			read_counter(counter);
61786ee6e18SStephane Eranian 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
61886ee6e18SStephane Eranian 		}
619c52b12edSArnaldo Carvalho de Melo 	}
620c52b12edSArnaldo Carvalho de Melo 
62142202dd5SIngo Molnar 	return WEXITSTATUS(status);
62242202dd5SIngo Molnar }
62342202dd5SIngo Molnar 
6241f16c575SPeter Zijlstra static int run_perf_stat(int argc __maybe_unused, const char **argv)
6251f16c575SPeter Zijlstra {
6261f16c575SPeter Zijlstra 	int ret;
6271f16c575SPeter Zijlstra 
6281f16c575SPeter Zijlstra 	if (pre_cmd) {
6291f16c575SPeter Zijlstra 		ret = system(pre_cmd);
6301f16c575SPeter Zijlstra 		if (ret)
6311f16c575SPeter Zijlstra 			return ret;
6321f16c575SPeter Zijlstra 	}
6331f16c575SPeter Zijlstra 
6341f16c575SPeter Zijlstra 	if (sync_run)
6351f16c575SPeter Zijlstra 		sync();
6361f16c575SPeter Zijlstra 
6371f16c575SPeter Zijlstra 	ret = __run_perf_stat(argc, argv);
6381f16c575SPeter Zijlstra 	if (ret)
6391f16c575SPeter Zijlstra 		return ret;
6401f16c575SPeter Zijlstra 
6411f16c575SPeter Zijlstra 	if (post_cmd) {
6421f16c575SPeter Zijlstra 		ret = system(post_cmd);
6431f16c575SPeter Zijlstra 		if (ret)
6441f16c575SPeter Zijlstra 			return ret;
6451f16c575SPeter Zijlstra 	}
6461f16c575SPeter Zijlstra 
6471f16c575SPeter Zijlstra 	return ret;
6481f16c575SPeter Zijlstra }
6491f16c575SPeter Zijlstra 
650f99844cbSIngo Molnar static void print_noise_pct(double total, double avg)
651f99844cbSIngo Molnar {
6520007eceaSXiao Guangrong 	double pct = rel_stddev_stats(total, avg);
653f99844cbSIngo Molnar 
6543ae9a34dSZhengyu He 	if (csv_output)
6554aa9015fSStephane Eranian 		fprintf(output, "%s%.2f%%", csv_sep, pct);
656a1bca6ccSJim Cromie 	else if (pct)
6574aa9015fSStephane Eranian 		fprintf(output, "  ( +-%6.2f%% )", pct);
658f99844cbSIngo Molnar }
659f99844cbSIngo Molnar 
66069aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg)
66142202dd5SIngo Molnar {
66269aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps;
66369aad6f1SArnaldo Carvalho de Melo 
664849abde9SPeter Zijlstra 	if (run_count == 1)
665849abde9SPeter Zijlstra 		return;
666849abde9SPeter Zijlstra 
66769aad6f1SArnaldo Carvalho de Melo 	ps = evsel->priv;
668f99844cbSIngo Molnar 	print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
66942202dd5SIngo Molnar }
67042202dd5SIngo Molnar 
67112c08a9fSStephane Eranian static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
67242202dd5SIngo Molnar {
67386ee6e18SStephane Eranian 	switch (aggr_mode) {
67412c08a9fSStephane Eranian 	case AGGR_CORE:
67512c08a9fSStephane Eranian 		fprintf(output, "S%d-C%*d%s%*d%s",
67612c08a9fSStephane Eranian 			cpu_map__id_to_socket(id),
67712c08a9fSStephane Eranian 			csv_output ? 0 : -8,
67812c08a9fSStephane Eranian 			cpu_map__id_to_cpu(id),
67912c08a9fSStephane Eranian 			csv_sep,
68012c08a9fSStephane Eranian 			csv_output ? 0 : 4,
68112c08a9fSStephane Eranian 			nr,
68212c08a9fSStephane Eranian 			csv_sep);
68312c08a9fSStephane Eranian 		break;
68486ee6e18SStephane Eranian 	case AGGR_SOCKET:
68586ee6e18SStephane Eranian 		fprintf(output, "S%*d%s%*d%s",
686d7e7a451SStephane Eranian 			csv_output ? 0 : -5,
68712c08a9fSStephane Eranian 			id,
688d7e7a451SStephane Eranian 			csv_sep,
689d7e7a451SStephane Eranian 			csv_output ? 0 : 4,
690d7e7a451SStephane Eranian 			nr,
691d7e7a451SStephane Eranian 			csv_sep);
69286ee6e18SStephane Eranian 			break;
69386ee6e18SStephane Eranian 	case AGGR_NONE:
69486ee6e18SStephane Eranian 		fprintf(output, "CPU%*d%s",
695d7470b6aSStephane Eranian 			csv_output ? 0 : -4,
69612c08a9fSStephane Eranian 			perf_evsel__cpus(evsel)->map[id], csv_sep);
69786ee6e18SStephane Eranian 		break;
69886ee6e18SStephane Eranian 	case AGGR_GLOBAL:
69986ee6e18SStephane Eranian 	default:
70086ee6e18SStephane Eranian 		break;
70186ee6e18SStephane Eranian 	}
70286ee6e18SStephane Eranian }
703d7470b6aSStephane Eranian 
70486ee6e18SStephane Eranian static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
70586ee6e18SStephane Eranian {
70686ee6e18SStephane Eranian 	double msecs = avg / 1e6;
70786ee6e18SStephane Eranian 	const char *fmt = csv_output ? "%.6f%s%s" : "%18.6f%s%-25s";
7084bbe5a61SDavid Ahern 	char name[25];
70986ee6e18SStephane Eranian 
71086ee6e18SStephane Eranian 	aggr_printout(evsel, cpu, nr);
71186ee6e18SStephane Eranian 
7124bbe5a61SDavid Ahern 	scnprintf(name, sizeof(name), "%s%s",
7134bbe5a61SDavid Ahern 		  perf_evsel__name(evsel), csv_output ? "" : " (msec)");
7144bbe5a61SDavid Ahern 	fprintf(output, fmt, msecs, csv_sep, name);
715d7470b6aSStephane Eranian 
716023695d9SStephane Eranian 	if (evsel->cgrp)
7174aa9015fSStephane Eranian 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
718023695d9SStephane Eranian 
71913370a9bSStephane Eranian 	if (csv_output || interval)
720d7470b6aSStephane Eranian 		return;
72142202dd5SIngo Molnar 
722daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
7234aa9015fSStephane Eranian 		fprintf(output, " # %8.3f CPUs utilized          ",
7244aa9015fSStephane Eranian 			avg / avg_stats(&walltime_nsecs_stats));
7259dac6a29SNamhyung Kim 	else
7269dac6a29SNamhyung Kim 		fprintf(output, "                                   ");
72742202dd5SIngo Molnar }
72842202dd5SIngo Molnar 
72915e6392fSNamhyung Kim /* used for get_ratio_color() */
73015e6392fSNamhyung Kim enum grc_type {
73115e6392fSNamhyung Kim 	GRC_STALLED_CYCLES_FE,
73215e6392fSNamhyung Kim 	GRC_STALLED_CYCLES_BE,
73315e6392fSNamhyung Kim 	GRC_CACHE_MISSES,
73415e6392fSNamhyung Kim 	GRC_MAX_NR
73515e6392fSNamhyung Kim };
73615e6392fSNamhyung Kim 
73715e6392fSNamhyung Kim static const char *get_ratio_color(enum grc_type type, double ratio)
73815e6392fSNamhyung Kim {
73915e6392fSNamhyung Kim 	static const double grc_table[GRC_MAX_NR][3] = {
74015e6392fSNamhyung Kim 		[GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 },
74115e6392fSNamhyung Kim 		[GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 },
74215e6392fSNamhyung Kim 		[GRC_CACHE_MISSES] 	= { 20.0, 10.0, 5.0 },
74315e6392fSNamhyung Kim 	};
74415e6392fSNamhyung Kim 	const char *color = PERF_COLOR_NORMAL;
74515e6392fSNamhyung Kim 
74615e6392fSNamhyung Kim 	if (ratio > grc_table[type][0])
74715e6392fSNamhyung Kim 		color = PERF_COLOR_RED;
74815e6392fSNamhyung Kim 	else if (ratio > grc_table[type][1])
74915e6392fSNamhyung Kim 		color = PERF_COLOR_MAGENTA;
75015e6392fSNamhyung Kim 	else if (ratio > grc_table[type][2])
75115e6392fSNamhyung Kim 		color = PERF_COLOR_YELLOW;
75215e6392fSNamhyung Kim 
75315e6392fSNamhyung Kim 	return color;
75415e6392fSNamhyung Kim }
75515e6392fSNamhyung Kim 
7561d037ca1SIrina Tirdea static void print_stalled_cycles_frontend(int cpu,
7571d037ca1SIrina Tirdea 					  struct perf_evsel *evsel
7581d037ca1SIrina Tirdea 					  __maybe_unused, double avg)
759d3d1e86dSIngo Molnar {
760d3d1e86dSIngo Molnar 	double total, ratio = 0.0;
761d3d1e86dSIngo Molnar 	const char *color;
762d3d1e86dSIngo Molnar 
763d3d1e86dSIngo Molnar 	total = avg_stats(&runtime_cycles_stats[cpu]);
764d3d1e86dSIngo Molnar 
765d3d1e86dSIngo Molnar 	if (total)
766d3d1e86dSIngo Molnar 		ratio = avg / total * 100.0;
767d3d1e86dSIngo Molnar 
76815e6392fSNamhyung Kim 	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
769d3d1e86dSIngo Molnar 
7704aa9015fSStephane Eranian 	fprintf(output, " #  ");
7714aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
7724aa9015fSStephane Eranian 	fprintf(output, " frontend cycles idle   ");
773d3d1e86dSIngo Molnar }
774d3d1e86dSIngo Molnar 
7751d037ca1SIrina Tirdea static void print_stalled_cycles_backend(int cpu,
7761d037ca1SIrina Tirdea 					 struct perf_evsel *evsel
7771d037ca1SIrina Tirdea 					 __maybe_unused, double avg)
778a5d243d0SIngo Molnar {
779a5d243d0SIngo Molnar 	double total, ratio = 0.0;
780a5d243d0SIngo Molnar 	const char *color;
781a5d243d0SIngo Molnar 
782a5d243d0SIngo Molnar 	total = avg_stats(&runtime_cycles_stats[cpu]);
783a5d243d0SIngo Molnar 
784a5d243d0SIngo Molnar 	if (total)
785a5d243d0SIngo Molnar 		ratio = avg / total * 100.0;
786a5d243d0SIngo Molnar 
78715e6392fSNamhyung Kim 	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
788a5d243d0SIngo Molnar 
7894aa9015fSStephane Eranian 	fprintf(output, " #  ");
7904aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
7914aa9015fSStephane Eranian 	fprintf(output, " backend  cycles idle   ");
792a5d243d0SIngo Molnar }
793a5d243d0SIngo Molnar 
7941d037ca1SIrina Tirdea static void print_branch_misses(int cpu,
7951d037ca1SIrina Tirdea 				struct perf_evsel *evsel __maybe_unused,
7961d037ca1SIrina Tirdea 				double avg)
797c78df6c1SIngo Molnar {
798c78df6c1SIngo Molnar 	double total, ratio = 0.0;
799c78df6c1SIngo Molnar 	const char *color;
800c78df6c1SIngo Molnar 
801c78df6c1SIngo Molnar 	total = avg_stats(&runtime_branches_stats[cpu]);
802c78df6c1SIngo Molnar 
803c78df6c1SIngo Molnar 	if (total)
804c78df6c1SIngo Molnar 		ratio = avg / total * 100.0;
805c78df6c1SIngo Molnar 
80615e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
807c78df6c1SIngo Molnar 
8084aa9015fSStephane Eranian 	fprintf(output, " #  ");
8094aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
8104aa9015fSStephane Eranian 	fprintf(output, " of all branches        ");
811c78df6c1SIngo Molnar }
812c78df6c1SIngo Molnar 
8131d037ca1SIrina Tirdea static void print_l1_dcache_misses(int cpu,
8141d037ca1SIrina Tirdea 				   struct perf_evsel *evsel __maybe_unused,
8151d037ca1SIrina Tirdea 				   double avg)
8168bb6c79fSIngo Molnar {
8178bb6c79fSIngo Molnar 	double total, ratio = 0.0;
8188bb6c79fSIngo Molnar 	const char *color;
8198bb6c79fSIngo Molnar 
8208bb6c79fSIngo Molnar 	total = avg_stats(&runtime_l1_dcache_stats[cpu]);
8218bb6c79fSIngo Molnar 
8228bb6c79fSIngo Molnar 	if (total)
8238bb6c79fSIngo Molnar 		ratio = avg / total * 100.0;
8248bb6c79fSIngo Molnar 
82515e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
8268bb6c79fSIngo Molnar 
8274aa9015fSStephane Eranian 	fprintf(output, " #  ");
8284aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
8294aa9015fSStephane Eranian 	fprintf(output, " of all L1-dcache hits  ");
8308bb6c79fSIngo Molnar }
8318bb6c79fSIngo Molnar 
8321d037ca1SIrina Tirdea static void print_l1_icache_misses(int cpu,
8331d037ca1SIrina Tirdea 				   struct perf_evsel *evsel __maybe_unused,
8341d037ca1SIrina Tirdea 				   double avg)
835c3305257SIngo Molnar {
836c3305257SIngo Molnar 	double total, ratio = 0.0;
837c3305257SIngo Molnar 	const char *color;
838c3305257SIngo Molnar 
839c3305257SIngo Molnar 	total = avg_stats(&runtime_l1_icache_stats[cpu]);
840c3305257SIngo Molnar 
841c3305257SIngo Molnar 	if (total)
842c3305257SIngo Molnar 		ratio = avg / total * 100.0;
843c3305257SIngo Molnar 
84415e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
845c3305257SIngo Molnar 
8464aa9015fSStephane Eranian 	fprintf(output, " #  ");
8474aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
8484aa9015fSStephane Eranian 	fprintf(output, " of all L1-icache hits  ");
849c3305257SIngo Molnar }
850c3305257SIngo Molnar 
8511d037ca1SIrina Tirdea static void print_dtlb_cache_misses(int cpu,
8521d037ca1SIrina Tirdea 				    struct perf_evsel *evsel __maybe_unused,
8531d037ca1SIrina Tirdea 				    double avg)
854c3305257SIngo Molnar {
855c3305257SIngo Molnar 	double total, ratio = 0.0;
856c3305257SIngo Molnar 	const char *color;
857c3305257SIngo Molnar 
858c3305257SIngo Molnar 	total = avg_stats(&runtime_dtlb_cache_stats[cpu]);
859c3305257SIngo Molnar 
860c3305257SIngo Molnar 	if (total)
861c3305257SIngo Molnar 		ratio = avg / total * 100.0;
862c3305257SIngo Molnar 
86315e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
864c3305257SIngo Molnar 
8654aa9015fSStephane Eranian 	fprintf(output, " #  ");
8664aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
8674aa9015fSStephane Eranian 	fprintf(output, " of all dTLB cache hits ");
868c3305257SIngo Molnar }
869c3305257SIngo Molnar 
8701d037ca1SIrina Tirdea static void print_itlb_cache_misses(int cpu,
8711d037ca1SIrina Tirdea 				    struct perf_evsel *evsel __maybe_unused,
8721d037ca1SIrina Tirdea 				    double avg)
873c3305257SIngo Molnar {
874c3305257SIngo Molnar 	double total, ratio = 0.0;
875c3305257SIngo Molnar 	const char *color;
876c3305257SIngo Molnar 
877c3305257SIngo Molnar 	total = avg_stats(&runtime_itlb_cache_stats[cpu]);
878c3305257SIngo Molnar 
879c3305257SIngo Molnar 	if (total)
880c3305257SIngo Molnar 		ratio = avg / total * 100.0;
881c3305257SIngo Molnar 
88215e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
883c3305257SIngo Molnar 
8844aa9015fSStephane Eranian 	fprintf(output, " #  ");
8854aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
8864aa9015fSStephane Eranian 	fprintf(output, " of all iTLB cache hits ");
887c3305257SIngo Molnar }
888c3305257SIngo Molnar 
8891d037ca1SIrina Tirdea static void print_ll_cache_misses(int cpu,
8901d037ca1SIrina Tirdea 				  struct perf_evsel *evsel __maybe_unused,
8911d037ca1SIrina Tirdea 				  double avg)
892c3305257SIngo Molnar {
893c3305257SIngo Molnar 	double total, ratio = 0.0;
894c3305257SIngo Molnar 	const char *color;
895c3305257SIngo Molnar 
896c3305257SIngo Molnar 	total = avg_stats(&runtime_ll_cache_stats[cpu]);
897c3305257SIngo Molnar 
898c3305257SIngo Molnar 	if (total)
899c3305257SIngo Molnar 		ratio = avg / total * 100.0;
900c3305257SIngo Molnar 
90115e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
902c3305257SIngo Molnar 
9034aa9015fSStephane Eranian 	fprintf(output, " #  ");
9044aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
9054aa9015fSStephane Eranian 	fprintf(output, " of all LL-cache hits   ");
906c3305257SIngo Molnar }
907c3305257SIngo Molnar 
908d7e7a451SStephane Eranian static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
90942202dd5SIngo Molnar {
9104cabc3d1SAndi Kleen 	double total, ratio = 0.0, total2;
911d7470b6aSStephane Eranian 	const char *fmt;
912d7470b6aSStephane Eranian 
913d7470b6aSStephane Eranian 	if (csv_output)
91486ee6e18SStephane Eranian 		fmt = "%.0f%s%s";
915d7470b6aSStephane Eranian 	else if (big_num)
91686ee6e18SStephane Eranian 		fmt = "%'18.0f%s%-25s";
917d7470b6aSStephane Eranian 	else
91886ee6e18SStephane Eranian 		fmt = "%18.0f%s%-25s";
919f5b4a9c3SStephane Eranian 
92086ee6e18SStephane Eranian 	aggr_printout(evsel, cpu, nr);
92186ee6e18SStephane Eranian 
92286ee6e18SStephane Eranian 	if (aggr_mode == AGGR_GLOBAL)
923f5b4a9c3SStephane Eranian 		cpu = 0;
924c7f7fea3SIngo Molnar 
92586ee6e18SStephane Eranian 	fprintf(output, fmt, avg, csv_sep, perf_evsel__name(evsel));
926d7470b6aSStephane Eranian 
927023695d9SStephane Eranian 	if (evsel->cgrp)
9284aa9015fSStephane Eranian 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
929023695d9SStephane Eranian 
93013370a9bSStephane Eranian 	if (csv_output || interval)
931d7470b6aSStephane Eranian 		return;
93242202dd5SIngo Molnar 
933daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
934f5b4a9c3SStephane Eranian 		total = avg_stats(&runtime_cycles_stats[cpu]);
9353e7a0817SRamkumar Ramachandra 		if (total) {
936c7f7fea3SIngo Molnar 			ratio = avg / total;
9374aa9015fSStephane Eranian 			fprintf(output, " #   %5.2f  insns per cycle        ", ratio);
9383e7a0817SRamkumar Ramachandra 		}
939d3d1e86dSIngo Molnar 		total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
940d3d1e86dSIngo Molnar 		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
941481f988aSIngo Molnar 
942481f988aSIngo Molnar 		if (total && avg) {
943481f988aSIngo Molnar 			ratio = total / avg;
9444aa9015fSStephane Eranian 			fprintf(output, "\n                                             #   %5.2f  stalled cycles per insn", ratio);
945481f988aSIngo Molnar 		}
946481f988aSIngo Molnar 
947daec78a0SArnaldo Carvalho de Melo 	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
948f5b4a9c3SStephane Eranian 			runtime_branches_stats[cpu].n != 0) {
949c78df6c1SIngo Molnar 		print_branch_misses(cpu, evsel, avg);
9508bb6c79fSIngo Molnar 	} else if (
9518bb6c79fSIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
9528bb6c79fSIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
9538bb6c79fSIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
9548bb6c79fSIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
955c6264defSIngo Molnar 			runtime_l1_dcache_stats[cpu].n != 0) {
9568bb6c79fSIngo Molnar 		print_l1_dcache_misses(cpu, evsel, avg);
957c3305257SIngo Molnar 	} else if (
958c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
959c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
960c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
961c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
962c3305257SIngo Molnar 			runtime_l1_icache_stats[cpu].n != 0) {
963c3305257SIngo Molnar 		print_l1_icache_misses(cpu, evsel, avg);
964c3305257SIngo Molnar 	} else if (
965c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
966c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
967c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
968c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
969c3305257SIngo Molnar 			runtime_dtlb_cache_stats[cpu].n != 0) {
970c3305257SIngo Molnar 		print_dtlb_cache_misses(cpu, evsel, avg);
971c3305257SIngo Molnar 	} else if (
972c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
973c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
974c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
975c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
976c3305257SIngo Molnar 			runtime_itlb_cache_stats[cpu].n != 0) {
977c3305257SIngo Molnar 		print_itlb_cache_misses(cpu, evsel, avg);
978c3305257SIngo Molnar 	} else if (
979c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
980c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
981c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
982c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
983c3305257SIngo Molnar 			runtime_ll_cache_stats[cpu].n != 0) {
984c3305257SIngo Molnar 		print_ll_cache_misses(cpu, evsel, avg);
985d58f4c82SIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
986d58f4c82SIngo Molnar 			runtime_cacherefs_stats[cpu].n != 0) {
987d58f4c82SIngo Molnar 		total = avg_stats(&runtime_cacherefs_stats[cpu]);
988d58f4c82SIngo Molnar 
989d58f4c82SIngo Molnar 		if (total)
990d58f4c82SIngo Molnar 			ratio = avg * 100 / total;
991d58f4c82SIngo Molnar 
9924aa9015fSStephane Eranian 		fprintf(output, " # %8.3f %% of all cache refs    ", ratio);
993d58f4c82SIngo Molnar 
994d3d1e86dSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
995d3d1e86dSIngo Molnar 		print_stalled_cycles_frontend(cpu, evsel, avg);
996129c04cbSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
997d3d1e86dSIngo Molnar 		print_stalled_cycles_backend(cpu, evsel, avg);
998481f988aSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
999481f988aSIngo Molnar 		total = avg_stats(&runtime_nsecs_stats[cpu]);
1000481f988aSIngo Molnar 
1001c458fe62SRamkumar Ramachandra 		if (total) {
1002c458fe62SRamkumar Ramachandra 			ratio = avg / total;
10034aa9015fSStephane Eranian 			fprintf(output, " # %8.3f GHz                    ", ratio);
1004c458fe62SRamkumar Ramachandra 		}
10054cabc3d1SAndi Kleen 	} else if (transaction_run &&
10064cabc3d1SAndi Kleen 		   perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) {
10074cabc3d1SAndi Kleen 		total = avg_stats(&runtime_cycles_stats[cpu]);
10084cabc3d1SAndi Kleen 		if (total)
10094cabc3d1SAndi Kleen 			fprintf(output,
10104cabc3d1SAndi Kleen 				" #   %5.2f%% transactional cycles   ",
10114cabc3d1SAndi Kleen 				100.0 * (avg / total));
10124cabc3d1SAndi Kleen 	} else if (transaction_run &&
10134cabc3d1SAndi Kleen 		   perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX_CP))) {
10144cabc3d1SAndi Kleen 		total = avg_stats(&runtime_cycles_stats[cpu]);
10154cabc3d1SAndi Kleen 		total2 = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
10164cabc3d1SAndi Kleen 		if (total2 < avg)
10174cabc3d1SAndi Kleen 			total2 = avg;
10184cabc3d1SAndi Kleen 		if (total)
10194cabc3d1SAndi Kleen 			fprintf(output,
10204cabc3d1SAndi Kleen 				" #   %5.2f%% aborted cycles         ",
10214cabc3d1SAndi Kleen 				100.0 * ((total2-avg) / total));
10224cabc3d1SAndi Kleen 	} else if (transaction_run &&
10234cabc3d1SAndi Kleen 		   perf_evsel__cmp(evsel, nth_evsel(T_TRANSACTION_START)) &&
10244cabc3d1SAndi Kleen 		   avg > 0 &&
10254cabc3d1SAndi Kleen 		   runtime_cycles_in_tx_stats[cpu].n != 0) {
10264cabc3d1SAndi Kleen 		total = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
10274cabc3d1SAndi Kleen 
10284cabc3d1SAndi Kleen 		if (total)
10294cabc3d1SAndi Kleen 			ratio = total / avg;
10304cabc3d1SAndi Kleen 
10314cabc3d1SAndi Kleen 		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
10324cabc3d1SAndi Kleen 	} else if (transaction_run &&
10334cabc3d1SAndi Kleen 		   perf_evsel__cmp(evsel, nth_evsel(T_ELISION_START)) &&
10344cabc3d1SAndi Kleen 		   avg > 0 &&
10354cabc3d1SAndi Kleen 		   runtime_cycles_in_tx_stats[cpu].n != 0) {
10364cabc3d1SAndi Kleen 		total = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
10374cabc3d1SAndi Kleen 
10384cabc3d1SAndi Kleen 		if (total)
10394cabc3d1SAndi Kleen 			ratio = total / avg;
10404cabc3d1SAndi Kleen 
10414cabc3d1SAndi Kleen 		fprintf(output, " # %8.0f cycles / elision       ", ratio);
1042481f988aSIngo Molnar 	} else if (runtime_nsecs_stats[cpu].n != 0) {
10435fde2523SNamhyung Kim 		char unit = 'M';
10445fde2523SNamhyung Kim 
1045481f988aSIngo Molnar 		total = avg_stats(&runtime_nsecs_stats[cpu]);
1046481f988aSIngo Molnar 
1047481f988aSIngo Molnar 		if (total)
1048481f988aSIngo Molnar 			ratio = 1000.0 * avg / total;
10495fde2523SNamhyung Kim 		if (ratio < 0.001) {
10505fde2523SNamhyung Kim 			ratio *= 1000;
10515fde2523SNamhyung Kim 			unit = 'K';
10525fde2523SNamhyung Kim 		}
1053481f988aSIngo Molnar 
10545fde2523SNamhyung Kim 		fprintf(output, " # %8.3f %c/sec                  ", ratio, unit);
1055a5d243d0SIngo Molnar 	} else {
10564aa9015fSStephane Eranian 		fprintf(output, "                                   ");
105742202dd5SIngo Molnar 	}
105842202dd5SIngo Molnar }
105942202dd5SIngo Molnar 
106086ee6e18SStephane Eranian static void print_aggr(char *prefix)
1061d7e7a451SStephane Eranian {
1062d7e7a451SStephane Eranian 	struct perf_evsel *counter;
1063582ec082SStephane Eranian 	int cpu, cpu2, s, s2, id, nr;
1064d7e7a451SStephane Eranian 	u64 ena, run, val;
1065d7e7a451SStephane Eranian 
106686ee6e18SStephane Eranian 	if (!(aggr_map || aggr_get_id))
1067d7e7a451SStephane Eranian 		return;
1068d7e7a451SStephane Eranian 
106986ee6e18SStephane Eranian 	for (s = 0; s < aggr_map->nr; s++) {
107086ee6e18SStephane Eranian 		id = aggr_map->map[s];
1071d7e7a451SStephane Eranian 		list_for_each_entry(counter, &evsel_list->entries, node) {
1072d7e7a451SStephane Eranian 			val = ena = run = 0;
1073d7e7a451SStephane Eranian 			nr = 0;
1074d7e7a451SStephane Eranian 			for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1075582ec082SStephane Eranian 				cpu2 = perf_evsel__cpus(counter)->map[cpu];
1076582ec082SStephane Eranian 				s2 = aggr_get_id(evsel_list->cpus, cpu2);
107786ee6e18SStephane Eranian 				if (s2 != id)
1078d7e7a451SStephane Eranian 					continue;
1079d7e7a451SStephane Eranian 				val += counter->counts->cpu[cpu].val;
1080d7e7a451SStephane Eranian 				ena += counter->counts->cpu[cpu].ena;
1081d7e7a451SStephane Eranian 				run += counter->counts->cpu[cpu].run;
1082d7e7a451SStephane Eranian 				nr++;
1083d7e7a451SStephane Eranian 			}
1084d7e7a451SStephane Eranian 			if (prefix)
1085d7e7a451SStephane Eranian 				fprintf(output, "%s", prefix);
1086d7e7a451SStephane Eranian 
1087d7e7a451SStephane Eranian 			if (run == 0 || ena == 0) {
1088582ec082SStephane Eranian 				aggr_printout(counter, id, nr);
108986ee6e18SStephane Eranian 
109086ee6e18SStephane Eranian 				fprintf(output, "%*s%s%*s",
1091d7e7a451SStephane Eranian 					csv_output ? 0 : 18,
1092d7e7a451SStephane Eranian 					counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
1093d7e7a451SStephane Eranian 					csv_sep,
1094d7e7a451SStephane Eranian 					csv_output ? 0 : -24,
1095d7e7a451SStephane Eranian 					perf_evsel__name(counter));
109686ee6e18SStephane Eranian 
1097d7e7a451SStephane Eranian 				if (counter->cgrp)
1098d7e7a451SStephane Eranian 					fprintf(output, "%s%s",
1099d7e7a451SStephane Eranian 						csv_sep, counter->cgrp->name);
1100d7e7a451SStephane Eranian 
1101d7e7a451SStephane Eranian 				fputc('\n', output);
1102d7e7a451SStephane Eranian 				continue;
1103d7e7a451SStephane Eranian 			}
1104d7e7a451SStephane Eranian 
1105d7e7a451SStephane Eranian 			if (nsec_counter(counter))
110686ee6e18SStephane Eranian 				nsec_printout(id, nr, counter, val);
1107d7e7a451SStephane Eranian 			else
110886ee6e18SStephane Eranian 				abs_printout(id, nr, counter, val);
1109d7e7a451SStephane Eranian 
1110d7e7a451SStephane Eranian 			if (!csv_output) {
1111d7e7a451SStephane Eranian 				print_noise(counter, 1.0);
1112d7e7a451SStephane Eranian 
1113d7e7a451SStephane Eranian 				if (run != ena)
1114d7e7a451SStephane Eranian 					fprintf(output, "  (%.2f%%)",
1115d7e7a451SStephane Eranian 						100.0 * run / ena);
1116d7e7a451SStephane Eranian 			}
1117d7e7a451SStephane Eranian 			fputc('\n', output);
1118d7e7a451SStephane Eranian 		}
1119d7e7a451SStephane Eranian 	}
1120d7e7a451SStephane Eranian }
1121d7e7a451SStephane Eranian 
112242202dd5SIngo Molnar /*
112342202dd5SIngo Molnar  * Print out the results of a single counter:
1124f5b4a9c3SStephane Eranian  * aggregated counts in system-wide mode
112542202dd5SIngo Molnar  */
112613370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
112742202dd5SIngo Molnar {
112869aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps = counter->priv;
112969aad6f1SArnaldo Carvalho de Melo 	double avg = avg_stats(&ps->res_stats[0]);
1130c52b12edSArnaldo Carvalho de Melo 	int scaled = counter->counts->scaled;
113142202dd5SIngo Molnar 
113213370a9bSStephane Eranian 	if (prefix)
113313370a9bSStephane Eranian 		fprintf(output, "%s", prefix);
113413370a9bSStephane Eranian 
113542202dd5SIngo Molnar 	if (scaled == -1) {
11364aa9015fSStephane Eranian 		fprintf(output, "%*s%s%*s",
1137d7470b6aSStephane Eranian 			csv_output ? 0 : 18,
11382cee77c4SDavid Ahern 			counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
1139023695d9SStephane Eranian 			csv_sep,
1140023695d9SStephane Eranian 			csv_output ? 0 : -24,
11417289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter));
1142023695d9SStephane Eranian 
1143023695d9SStephane Eranian 		if (counter->cgrp)
11444aa9015fSStephane Eranian 			fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
1145023695d9SStephane Eranian 
11464aa9015fSStephane Eranian 		fputc('\n', output);
114742202dd5SIngo Molnar 		return;
114842202dd5SIngo Molnar 	}
114942202dd5SIngo Molnar 
115042202dd5SIngo Molnar 	if (nsec_counter(counter))
1151d7e7a451SStephane Eranian 		nsec_printout(-1, 0, counter, avg);
115242202dd5SIngo Molnar 	else
1153d7e7a451SStephane Eranian 		abs_printout(-1, 0, counter, avg);
1154849abde9SPeter Zijlstra 
11553ae9a34dSZhengyu He 	print_noise(counter, avg);
11563ae9a34dSZhengyu He 
1157d7470b6aSStephane Eranian 	if (csv_output) {
11584aa9015fSStephane Eranian 		fputc('\n', output);
1159d7470b6aSStephane Eranian 		return;
1160d7470b6aSStephane Eranian 	}
1161d7470b6aSStephane Eranian 
1162506d4bc8SPeter Zijlstra 	if (scaled) {
1163506d4bc8SPeter Zijlstra 		double avg_enabled, avg_running;
1164506d4bc8SPeter Zijlstra 
116569aad6f1SArnaldo Carvalho de Melo 		avg_enabled = avg_stats(&ps->res_stats[1]);
116669aad6f1SArnaldo Carvalho de Melo 		avg_running = avg_stats(&ps->res_stats[2]);
1167506d4bc8SPeter Zijlstra 
11684aa9015fSStephane Eranian 		fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled);
1169506d4bc8SPeter Zijlstra 	}
11704aa9015fSStephane Eranian 	fprintf(output, "\n");
117142202dd5SIngo Molnar }
117242202dd5SIngo Molnar 
1173f5b4a9c3SStephane Eranian /*
1174f5b4a9c3SStephane Eranian  * Print out the results of a single counter:
1175f5b4a9c3SStephane Eranian  * does not use aggregated count in system-wide
1176f5b4a9c3SStephane Eranian  */
117713370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix)
1178f5b4a9c3SStephane Eranian {
1179f5b4a9c3SStephane Eranian 	u64 ena, run, val;
1180f5b4a9c3SStephane Eranian 	int cpu;
1181f5b4a9c3SStephane Eranian 
11827ae92e74SYan, Zheng 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1183c52b12edSArnaldo Carvalho de Melo 		val = counter->counts->cpu[cpu].val;
1184c52b12edSArnaldo Carvalho de Melo 		ena = counter->counts->cpu[cpu].ena;
1185c52b12edSArnaldo Carvalho de Melo 		run = counter->counts->cpu[cpu].run;
118613370a9bSStephane Eranian 
118713370a9bSStephane Eranian 		if (prefix)
118813370a9bSStephane Eranian 			fprintf(output, "%s", prefix);
118913370a9bSStephane Eranian 
1190f5b4a9c3SStephane Eranian 		if (run == 0 || ena == 0) {
11914aa9015fSStephane Eranian 			fprintf(output, "CPU%*d%s%*s%s%*s",
1192d7470b6aSStephane Eranian 				csv_output ? 0 : -4,
11937ae92e74SYan, Zheng 				perf_evsel__cpus(counter)->map[cpu], csv_sep,
1194d7470b6aSStephane Eranian 				csv_output ? 0 : 18,
11952cee77c4SDavid Ahern 				counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
11962cee77c4SDavid Ahern 				csv_sep,
1197023695d9SStephane Eranian 				csv_output ? 0 : -24,
11987289f83cSArnaldo Carvalho de Melo 				perf_evsel__name(counter));
1199f5b4a9c3SStephane Eranian 
1200023695d9SStephane Eranian 			if (counter->cgrp)
12014aa9015fSStephane Eranian 				fprintf(output, "%s%s",
12024aa9015fSStephane Eranian 					csv_sep, counter->cgrp->name);
1203023695d9SStephane Eranian 
12044aa9015fSStephane Eranian 			fputc('\n', output);
1205f5b4a9c3SStephane Eranian 			continue;
1206f5b4a9c3SStephane Eranian 		}
1207f5b4a9c3SStephane Eranian 
1208f5b4a9c3SStephane Eranian 		if (nsec_counter(counter))
1209d7e7a451SStephane Eranian 			nsec_printout(cpu, 0, counter, val);
1210f5b4a9c3SStephane Eranian 		else
1211d7e7a451SStephane Eranian 			abs_printout(cpu, 0, counter, val);
1212f5b4a9c3SStephane Eranian 
1213d7470b6aSStephane Eranian 		if (!csv_output) {
1214f5b4a9c3SStephane Eranian 			print_noise(counter, 1.0);
1215f5b4a9c3SStephane Eranian 
1216c6264defSIngo Molnar 			if (run != ena)
12174aa9015fSStephane Eranian 				fprintf(output, "  (%.2f%%)",
12184aa9015fSStephane Eranian 					100.0 * run / ena);
1219d7470b6aSStephane Eranian 		}
12204aa9015fSStephane Eranian 		fputc('\n', output);
1221f5b4a9c3SStephane Eranian 	}
1222f5b4a9c3SStephane Eranian }
1223f5b4a9c3SStephane Eranian 
122442202dd5SIngo Molnar static void print_stat(int argc, const char **argv)
122542202dd5SIngo Molnar {
122669aad6f1SArnaldo Carvalho de Melo 	struct perf_evsel *counter;
122769aad6f1SArnaldo Carvalho de Melo 	int i;
122842202dd5SIngo Molnar 
122986470930SIngo Molnar 	fflush(stdout);
123086470930SIngo Molnar 
1231d7470b6aSStephane Eranian 	if (!csv_output) {
12324aa9015fSStephane Eranian 		fprintf(output, "\n");
12334aa9015fSStephane Eranian 		fprintf(output, " Performance counter stats for ");
123462d3b617SDavid Ahern 		if (target.system_wide)
123562d3b617SDavid Ahern 			fprintf(output, "\'system wide");
123662d3b617SDavid Ahern 		else if (target.cpu_list)
123762d3b617SDavid Ahern 			fprintf(output, "\'CPU(s) %s", target.cpu_list);
1238602ad878SArnaldo Carvalho de Melo 		else if (!target__has_task(&target)) {
12394aa9015fSStephane Eranian 			fprintf(output, "\'%s", argv[0]);
124086470930SIngo Molnar 			for (i = 1; i < argc; i++)
12414aa9015fSStephane Eranian 				fprintf(output, " %s", argv[i]);
124220f946b4SNamhyung Kim 		} else if (target.pid)
124320f946b4SNamhyung Kim 			fprintf(output, "process id \'%s", target.pid);
1244d6d901c2SZhang, Yanmin 		else
124520f946b4SNamhyung Kim 			fprintf(output, "thread id \'%s", target.tid);
124686470930SIngo Molnar 
12474aa9015fSStephane Eranian 		fprintf(output, "\'");
124842202dd5SIngo Molnar 		if (run_count > 1)
12494aa9015fSStephane Eranian 			fprintf(output, " (%d runs)", run_count);
12504aa9015fSStephane Eranian 		fprintf(output, ":\n\n");
1251d7470b6aSStephane Eranian 	}
125286470930SIngo Molnar 
125386ee6e18SStephane Eranian 	switch (aggr_mode) {
125412c08a9fSStephane Eranian 	case AGGR_CORE:
125586ee6e18SStephane Eranian 	case AGGR_SOCKET:
125686ee6e18SStephane Eranian 		print_aggr(NULL);
125786ee6e18SStephane Eranian 		break;
125886ee6e18SStephane Eranian 	case AGGR_GLOBAL:
1259361c99a6SArnaldo Carvalho de Melo 		list_for_each_entry(counter, &evsel_list->entries, node)
126013370a9bSStephane Eranian 			print_counter_aggr(counter, NULL);
126186ee6e18SStephane Eranian 		break;
126286ee6e18SStephane Eranian 	case AGGR_NONE:
126386ee6e18SStephane Eranian 		list_for_each_entry(counter, &evsel_list->entries, node)
126486ee6e18SStephane Eranian 			print_counter(counter, NULL);
126586ee6e18SStephane Eranian 		break;
126686ee6e18SStephane Eranian 	default:
126786ee6e18SStephane Eranian 		break;
1268f5b4a9c3SStephane Eranian 	}
126986470930SIngo Molnar 
1270d7470b6aSStephane Eranian 	if (!csv_output) {
1271c3305257SIngo Molnar 		if (!null_run)
12724aa9015fSStephane Eranian 			fprintf(output, "\n");
12734aa9015fSStephane Eranian 		fprintf(output, " %17.9f seconds time elapsed",
1274506d4bc8SPeter Zijlstra 				avg_stats(&walltime_nsecs_stats)/1e9);
1275566747e6SIngo Molnar 		if (run_count > 1) {
12764aa9015fSStephane Eranian 			fprintf(output, "                                        ");
1277f99844cbSIngo Molnar 			print_noise_pct(stddev_stats(&walltime_nsecs_stats),
1278506d4bc8SPeter Zijlstra 					avg_stats(&walltime_nsecs_stats));
1279566747e6SIngo Molnar 		}
12804aa9015fSStephane Eranian 		fprintf(output, "\n\n");
128186470930SIngo Molnar 	}
1282d7470b6aSStephane Eranian }
128386470930SIngo Molnar 
1284f7b7c26eSPeter Zijlstra static volatile int signr = -1;
1285f7b7c26eSPeter Zijlstra 
128686470930SIngo Molnar static void skip_signal(int signo)
128786470930SIngo Molnar {
128813370a9bSStephane Eranian 	if ((child_pid == -1) || interval)
128960666c63SLiming Wang 		done = 1;
129060666c63SLiming Wang 
1291f7b7c26eSPeter Zijlstra 	signr = signo;
1292d07f0b12SStephane Eranian 	/*
1293d07f0b12SStephane Eranian 	 * render child_pid harmless
1294d07f0b12SStephane Eranian 	 * won't send SIGTERM to a random
1295d07f0b12SStephane Eranian 	 * process in case of race condition
1296d07f0b12SStephane Eranian 	 * and fast PID recycling
1297d07f0b12SStephane Eranian 	 */
1298d07f0b12SStephane Eranian 	child_pid = -1;
1299f7b7c26eSPeter Zijlstra }
1300f7b7c26eSPeter Zijlstra 
1301f7b7c26eSPeter Zijlstra static void sig_atexit(void)
1302f7b7c26eSPeter Zijlstra {
1303d07f0b12SStephane Eranian 	sigset_t set, oset;
1304d07f0b12SStephane Eranian 
1305d07f0b12SStephane Eranian 	/*
1306d07f0b12SStephane Eranian 	 * avoid race condition with SIGCHLD handler
1307d07f0b12SStephane Eranian 	 * in skip_signal() which is modifying child_pid
1308d07f0b12SStephane Eranian 	 * goal is to avoid send SIGTERM to a random
1309d07f0b12SStephane Eranian 	 * process
1310d07f0b12SStephane Eranian 	 */
1311d07f0b12SStephane Eranian 	sigemptyset(&set);
1312d07f0b12SStephane Eranian 	sigaddset(&set, SIGCHLD);
1313d07f0b12SStephane Eranian 	sigprocmask(SIG_BLOCK, &set, &oset);
1314d07f0b12SStephane Eranian 
1315933da83aSChris Wilson 	if (child_pid != -1)
1316933da83aSChris Wilson 		kill(child_pid, SIGTERM);
1317933da83aSChris Wilson 
1318d07f0b12SStephane Eranian 	sigprocmask(SIG_SETMASK, &oset, NULL);
1319d07f0b12SStephane Eranian 
1320f7b7c26eSPeter Zijlstra 	if (signr == -1)
1321f7b7c26eSPeter Zijlstra 		return;
1322f7b7c26eSPeter Zijlstra 
1323f7b7c26eSPeter Zijlstra 	signal(signr, SIG_DFL);
1324f7b7c26eSPeter Zijlstra 	kill(getpid(), signr);
132586470930SIngo Molnar }
132686470930SIngo Molnar 
13271d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused,
13281d037ca1SIrina Tirdea 			     const char *s __maybe_unused, int unset)
1329d7470b6aSStephane Eranian {
1330d7470b6aSStephane Eranian 	big_num_opt = unset ? 0 : 1;
1331d7470b6aSStephane Eranian 	return 0;
1332d7470b6aSStephane Eranian }
1333d7470b6aSStephane Eranian 
133486ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void)
133586ee6e18SStephane Eranian {
133686ee6e18SStephane Eranian 	switch (aggr_mode) {
133786ee6e18SStephane Eranian 	case AGGR_SOCKET:
133886ee6e18SStephane Eranian 		if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
133986ee6e18SStephane Eranian 			perror("cannot build socket map");
134086ee6e18SStephane Eranian 			return -1;
134186ee6e18SStephane Eranian 		}
134286ee6e18SStephane Eranian 		aggr_get_id = cpu_map__get_socket;
134386ee6e18SStephane Eranian 		break;
134412c08a9fSStephane Eranian 	case AGGR_CORE:
134512c08a9fSStephane Eranian 		if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
134612c08a9fSStephane Eranian 			perror("cannot build core map");
134712c08a9fSStephane Eranian 			return -1;
134812c08a9fSStephane Eranian 		}
134912c08a9fSStephane Eranian 		aggr_get_id = cpu_map__get_core;
135012c08a9fSStephane Eranian 		break;
135186ee6e18SStephane Eranian 	case AGGR_NONE:
135286ee6e18SStephane Eranian 	case AGGR_GLOBAL:
135386ee6e18SStephane Eranian 	default:
135486ee6e18SStephane Eranian 		break;
135586ee6e18SStephane Eranian 	}
135686ee6e18SStephane Eranian 	return 0;
135786ee6e18SStephane Eranian }
135886ee6e18SStephane Eranian 
13594cabc3d1SAndi Kleen static int setup_events(const char * const *attrs, unsigned len)
13604cabc3d1SAndi Kleen {
13614cabc3d1SAndi Kleen 	unsigned i;
13624cabc3d1SAndi Kleen 
13634cabc3d1SAndi Kleen 	for (i = 0; i < len; i++) {
13644cabc3d1SAndi Kleen 		if (parse_events(evsel_list, attrs[i]))
13654cabc3d1SAndi Kleen 			return -1;
13664cabc3d1SAndi Kleen 	}
13674cabc3d1SAndi Kleen 	return 0;
13684cabc3d1SAndi Kleen }
136986ee6e18SStephane Eranian 
13702cba3ffbSIngo Molnar /*
13712cba3ffbSIngo Molnar  * Add default attributes, if there were no attributes specified or
13722cba3ffbSIngo Molnar  * if -d/--detailed, -d -d or -d -d -d is used:
13732cba3ffbSIngo Molnar  */
13742cba3ffbSIngo Molnar static int add_default_attributes(void)
13752cba3ffbSIngo Molnar {
1376b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr default_attrs[] = {
1377b070a547SArnaldo Carvalho de Melo 
1378b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
1379b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
1380b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
1381b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
1382b070a547SArnaldo Carvalho de Melo 
1383b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
1384b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
1385b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
1386b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
1387b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
1388b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
1389b070a547SArnaldo Carvalho de Melo 
1390b070a547SArnaldo Carvalho de Melo };
1391b070a547SArnaldo Carvalho de Melo 
1392b070a547SArnaldo Carvalho de Melo /*
1393b070a547SArnaldo Carvalho de Melo  * Detailed stats (-d), covering the L1 and last level data caches:
1394b070a547SArnaldo Carvalho de Melo  */
1395b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr detailed_attrs[] = {
1396b070a547SArnaldo Carvalho de Melo 
1397b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1398b070a547SArnaldo Carvalho de Melo     .config =
1399b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1400b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1401b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1402b070a547SArnaldo Carvalho de Melo 
1403b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1404b070a547SArnaldo Carvalho de Melo     .config =
1405b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1406b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1407b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1408b070a547SArnaldo Carvalho de Melo 
1409b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1410b070a547SArnaldo Carvalho de Melo     .config =
1411b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1412b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1413b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1414b070a547SArnaldo Carvalho de Melo 
1415b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1416b070a547SArnaldo Carvalho de Melo     .config =
1417b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1418b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1419b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1420b070a547SArnaldo Carvalho de Melo };
1421b070a547SArnaldo Carvalho de Melo 
1422b070a547SArnaldo Carvalho de Melo /*
1423b070a547SArnaldo Carvalho de Melo  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1424b070a547SArnaldo Carvalho de Melo  */
1425b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_detailed_attrs[] = {
1426b070a547SArnaldo Carvalho de Melo 
1427b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1428b070a547SArnaldo Carvalho de Melo     .config =
1429b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1430b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1431b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1432b070a547SArnaldo Carvalho de Melo 
1433b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1434b070a547SArnaldo Carvalho de Melo     .config =
1435b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1436b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1437b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1438b070a547SArnaldo Carvalho de Melo 
1439b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1440b070a547SArnaldo Carvalho de Melo     .config =
1441b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1442b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1443b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1444b070a547SArnaldo Carvalho de Melo 
1445b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1446b070a547SArnaldo Carvalho de Melo     .config =
1447b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1448b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1449b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1450b070a547SArnaldo Carvalho de Melo 
1451b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1452b070a547SArnaldo Carvalho de Melo     .config =
1453b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1454b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1455b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1456b070a547SArnaldo Carvalho de Melo 
1457b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1458b070a547SArnaldo Carvalho de Melo     .config =
1459b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1460b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1461b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1462b070a547SArnaldo Carvalho de Melo 
1463b070a547SArnaldo Carvalho de Melo };
1464b070a547SArnaldo Carvalho de Melo 
1465b070a547SArnaldo Carvalho de Melo /*
1466b070a547SArnaldo Carvalho de Melo  * Very, very detailed stats (-d -d -d), adding prefetch events:
1467b070a547SArnaldo Carvalho de Melo  */
1468b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_very_detailed_attrs[] = {
1469b070a547SArnaldo Carvalho de Melo 
1470b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1471b070a547SArnaldo Carvalho de Melo     .config =
1472b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1473b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1474b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1475b070a547SArnaldo Carvalho de Melo 
1476b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1477b070a547SArnaldo Carvalho de Melo     .config =
1478b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1479b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1480b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1481b070a547SArnaldo Carvalho de Melo };
1482b070a547SArnaldo Carvalho de Melo 
14832cba3ffbSIngo Molnar 	/* Set attrs if no event is selected and !null_run: */
14842cba3ffbSIngo Molnar 	if (null_run)
14852cba3ffbSIngo Molnar 		return 0;
14862cba3ffbSIngo Molnar 
14874cabc3d1SAndi Kleen 	if (transaction_run) {
14884cabc3d1SAndi Kleen 		int err;
14894cabc3d1SAndi Kleen 		if (pmu_have_event("cpu", "cycles-ct") &&
14904cabc3d1SAndi Kleen 		    pmu_have_event("cpu", "el-start"))
14914cabc3d1SAndi Kleen 			err = setup_events(transaction_attrs,
14924cabc3d1SAndi Kleen 					ARRAY_SIZE(transaction_attrs));
14934cabc3d1SAndi Kleen 		else
14944cabc3d1SAndi Kleen 			err = setup_events(transaction_limited_attrs,
14954cabc3d1SAndi Kleen 				 ARRAY_SIZE(transaction_limited_attrs));
14964cabc3d1SAndi Kleen 		if (err < 0) {
14974cabc3d1SAndi Kleen 			fprintf(stderr, "Cannot set up transaction events\n");
14984cabc3d1SAndi Kleen 			return -1;
14994cabc3d1SAndi Kleen 		}
15004cabc3d1SAndi Kleen 		return 0;
15014cabc3d1SAndi Kleen 	}
15024cabc3d1SAndi Kleen 
15032cba3ffbSIngo Molnar 	if (!evsel_list->nr_entries) {
150479695e1bSArnaldo Carvalho de Melo 		if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
15052cba3ffbSIngo Molnar 			return -1;
15062cba3ffbSIngo Molnar 	}
15072cba3ffbSIngo Molnar 
15082cba3ffbSIngo Molnar 	/* Detailed events get appended to the event list: */
15092cba3ffbSIngo Molnar 
15102cba3ffbSIngo Molnar 	if (detailed_run <  1)
15112cba3ffbSIngo Molnar 		return 0;
15122cba3ffbSIngo Molnar 
15132cba3ffbSIngo Molnar 	/* Append detailed run extra attributes: */
151479695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
15152cba3ffbSIngo Molnar 		return -1;
15162cba3ffbSIngo Molnar 
15172cba3ffbSIngo Molnar 	if (detailed_run < 2)
15182cba3ffbSIngo Molnar 		return 0;
15192cba3ffbSIngo Molnar 
15202cba3ffbSIngo Molnar 	/* Append very detailed run extra attributes: */
152179695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
15222cba3ffbSIngo Molnar 		return -1;
15232cba3ffbSIngo Molnar 
15242cba3ffbSIngo Molnar 	if (detailed_run < 3)
15252cba3ffbSIngo Molnar 		return 0;
15262cba3ffbSIngo Molnar 
15272cba3ffbSIngo Molnar 	/* Append very, very detailed run extra attributes: */
152879695e1bSArnaldo Carvalho de Melo 	return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
15292cba3ffbSIngo Molnar }
15302cba3ffbSIngo Molnar 
15311d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
153286470930SIngo Molnar {
15331f16c575SPeter Zijlstra 	bool append_file = false;
1534b070a547SArnaldo Carvalho de Melo 	int output_fd = 0;
1535b070a547SArnaldo Carvalho de Melo 	const char *output_name	= NULL;
1536b070a547SArnaldo Carvalho de Melo 	const struct option options[] = {
15374cabc3d1SAndi Kleen 	OPT_BOOLEAN('T', "transaction", &transaction_run,
15384cabc3d1SAndi Kleen 		    "hardware transaction statistics"),
1539b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK('e', "event", &evsel_list, "event",
1540b070a547SArnaldo Carvalho de Melo 		     "event selector. use 'perf list' to list available events",
1541b070a547SArnaldo Carvalho de Melo 		     parse_events_option),
1542b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1543b070a547SArnaldo Carvalho de Melo 		     "event filter", parse_filter),
1544b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1545b070a547SArnaldo Carvalho de Melo 		    "child tasks do not inherit counters"),
1546b070a547SArnaldo Carvalho de Melo 	OPT_STRING('p', "pid", &target.pid, "pid",
1547b070a547SArnaldo Carvalho de Melo 		   "stat events on existing process id"),
1548b070a547SArnaldo Carvalho de Melo 	OPT_STRING('t', "tid", &target.tid, "tid",
1549b070a547SArnaldo Carvalho de Melo 		   "stat events on existing thread id"),
1550b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1551b070a547SArnaldo Carvalho de Melo 		    "system-wide collection from all CPUs"),
1552b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('g', "group", &group,
1553b070a547SArnaldo Carvalho de Melo 		    "put the counters into a counter group"),
1554b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"),
1555b070a547SArnaldo Carvalho de Melo 	OPT_INCR('v', "verbose", &verbose,
1556b070a547SArnaldo Carvalho de Melo 		    "be more verbose (show counter open errors, etc)"),
1557b070a547SArnaldo Carvalho de Melo 	OPT_INTEGER('r', "repeat", &run_count,
1558a7e191c3SFrederik Deweerdt 		    "repeat command and print average + stddev (max: 100, forever: 0)"),
1559b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('n', "null", &null_run,
1560b070a547SArnaldo Carvalho de Melo 		    "null run - dont start any counters"),
1561b070a547SArnaldo Carvalho de Melo 	OPT_INCR('d', "detailed", &detailed_run,
1562b070a547SArnaldo Carvalho de Melo 		    "detailed run - start a lot of events"),
1563b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('S', "sync", &sync_run,
1564b070a547SArnaldo Carvalho de Melo 		    "call sync() before starting a run"),
1565b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1566b070a547SArnaldo Carvalho de Melo 			   "print large numbers with thousands\' separators",
1567b070a547SArnaldo Carvalho de Melo 			   stat__set_big_num),
1568b070a547SArnaldo Carvalho de Melo 	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1569b070a547SArnaldo Carvalho de Melo 		    "list of cpus to monitor in system-wide"),
157086ee6e18SStephane Eranian 	OPT_SET_UINT('A', "no-aggr", &aggr_mode,
157186ee6e18SStephane Eranian 		    "disable CPU count aggregation", AGGR_NONE),
1572b070a547SArnaldo Carvalho de Melo 	OPT_STRING('x', "field-separator", &csv_sep, "separator",
1573b070a547SArnaldo Carvalho de Melo 		   "print counts with custom separator"),
1574b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1575b070a547SArnaldo Carvalho de Melo 		     "monitor event in cgroup name only", parse_cgroups),
1576b070a547SArnaldo Carvalho de Melo 	OPT_STRING('o', "output", &output_name, "file", "output file name"),
1577b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1578b070a547SArnaldo Carvalho de Melo 	OPT_INTEGER(0, "log-fd", &output_fd,
1579b070a547SArnaldo Carvalho de Melo 		    "log output to fd, instead of stderr"),
15801f16c575SPeter Zijlstra 	OPT_STRING(0, "pre", &pre_cmd, "command",
15811f16c575SPeter Zijlstra 			"command to run prior to the measured command"),
15821f16c575SPeter Zijlstra 	OPT_STRING(0, "post", &post_cmd, "command",
15831f16c575SPeter Zijlstra 			"command to run after to the measured command"),
158413370a9bSStephane Eranian 	OPT_UINTEGER('I', "interval-print", &interval,
158513370a9bSStephane Eranian 		    "print counts at regular interval in ms (>= 100)"),
1586d4304958SStephane Eranian 	OPT_SET_UINT(0, "per-socket", &aggr_mode,
158786ee6e18SStephane Eranian 		     "aggregate counts per processor socket", AGGR_SOCKET),
158812c08a9fSStephane Eranian 	OPT_SET_UINT(0, "per-core", &aggr_mode,
158912c08a9fSStephane Eranian 		     "aggregate counts per physical processor core", AGGR_CORE),
159041191688SAndi Kleen 	OPT_UINTEGER('D', "delay", &initial_delay,
159141191688SAndi Kleen 		     "ms to wait before starting measurement after program start"),
1592b070a547SArnaldo Carvalho de Melo 	OPT_END()
1593b070a547SArnaldo Carvalho de Melo 	};
1594b070a547SArnaldo Carvalho de Melo 	const char * const stat_usage[] = {
1595b070a547SArnaldo Carvalho de Melo 		"perf stat [<options>] [<command>]",
1596b070a547SArnaldo Carvalho de Melo 		NULL
1597b070a547SArnaldo Carvalho de Melo 	};
1598cc03c542SNamhyung Kim 	int status = -EINVAL, run_idx;
15994aa9015fSStephane Eranian 	const char *mode;
160042202dd5SIngo Molnar 
16015af52b51SStephane Eranian 	setlocale(LC_ALL, "");
16025af52b51SStephane Eranian 
1603334fe7a3SNamhyung Kim 	evsel_list = perf_evlist__new();
1604361c99a6SArnaldo Carvalho de Melo 	if (evsel_list == NULL)
1605361c99a6SArnaldo Carvalho de Melo 		return -ENOMEM;
1606361c99a6SArnaldo Carvalho de Melo 
1607a0541234SAnton Blanchard 	argc = parse_options(argc, argv, options, stat_usage,
1608a0541234SAnton Blanchard 		PARSE_OPT_STOP_AT_NON_OPTION);
1609d7470b6aSStephane Eranian 
16104aa9015fSStephane Eranian 	output = stderr;
16114aa9015fSStephane Eranian 	if (output_name && strcmp(output_name, "-"))
16124aa9015fSStephane Eranian 		output = NULL;
16134aa9015fSStephane Eranian 
161456f3bae7SJim Cromie 	if (output_name && output_fd) {
161556f3bae7SJim Cromie 		fprintf(stderr, "cannot use both --output and --log-fd\n");
1616cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "o", 1);
1617cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "log-fd", 0);
1618cc03c542SNamhyung Kim 		goto out;
161956f3bae7SJim Cromie 	}
1620fc3e4d07SStephane Eranian 
1621fc3e4d07SStephane Eranian 	if (output_fd < 0) {
1622fc3e4d07SStephane Eranian 		fprintf(stderr, "argument to --log-fd must be a > 0\n");
1623cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "log-fd", 0);
1624cc03c542SNamhyung Kim 		goto out;
1625fc3e4d07SStephane Eranian 	}
1626fc3e4d07SStephane Eranian 
16274aa9015fSStephane Eranian 	if (!output) {
16284aa9015fSStephane Eranian 		struct timespec tm;
16294aa9015fSStephane Eranian 		mode = append_file ? "a" : "w";
16304aa9015fSStephane Eranian 
16314aa9015fSStephane Eranian 		output = fopen(output_name, mode);
16324aa9015fSStephane Eranian 		if (!output) {
16334aa9015fSStephane Eranian 			perror("failed to create output file");
1634fceda7feSDavid Ahern 			return -1;
16354aa9015fSStephane Eranian 		}
16364aa9015fSStephane Eranian 		clock_gettime(CLOCK_REALTIME, &tm);
16374aa9015fSStephane Eranian 		fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1638fc3e4d07SStephane Eranian 	} else if (output_fd > 0) {
163956f3bae7SJim Cromie 		mode = append_file ? "a" : "w";
164056f3bae7SJim Cromie 		output = fdopen(output_fd, mode);
164156f3bae7SJim Cromie 		if (!output) {
164256f3bae7SJim Cromie 			perror("Failed opening logfd");
164356f3bae7SJim Cromie 			return -errno;
164456f3bae7SJim Cromie 		}
16454aa9015fSStephane Eranian 	}
16464aa9015fSStephane Eranian 
1647d4ffd04dSJim Cromie 	if (csv_sep) {
1648d7470b6aSStephane Eranian 		csv_output = true;
1649d4ffd04dSJim Cromie 		if (!strcmp(csv_sep, "\\t"))
1650d4ffd04dSJim Cromie 			csv_sep = "\t";
1651d4ffd04dSJim Cromie 	} else
1652d7470b6aSStephane Eranian 		csv_sep = DEFAULT_SEPARATOR;
1653d7470b6aSStephane Eranian 
1654d7470b6aSStephane Eranian 	/*
1655d7470b6aSStephane Eranian 	 * let the spreadsheet do the pretty-printing
1656d7470b6aSStephane Eranian 	 */
1657d7470b6aSStephane Eranian 	if (csv_output) {
165861a9f324SJim Cromie 		/* User explicitly passed -B? */
1659d7470b6aSStephane Eranian 		if (big_num_opt == 1) {
1660d7470b6aSStephane Eranian 			fprintf(stderr, "-B option not supported with -x\n");
1661cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "B", 1);
1662cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "x", 1);
1663cc03c542SNamhyung Kim 			goto out;
1664d7470b6aSStephane Eranian 		} else /* Nope, so disable big number formatting */
1665d7470b6aSStephane Eranian 			big_num = false;
1666d7470b6aSStephane Eranian 	} else if (big_num_opt == 0) /* User passed --no-big-num */
1667d7470b6aSStephane Eranian 		big_num = false;
1668d7470b6aSStephane Eranian 
1669602ad878SArnaldo Carvalho de Melo 	if (!argc && target__none(&target))
167086470930SIngo Molnar 		usage_with_options(stat_usage, options);
1671ac3063bdSDavid Ahern 
1672a7e191c3SFrederik Deweerdt 	if (run_count < 0) {
1673cc03c542SNamhyung Kim 		pr_err("Run count must be a positive number\n");
1674cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "r", 1);
1675cc03c542SNamhyung Kim 		goto out;
1676a7e191c3SFrederik Deweerdt 	} else if (run_count == 0) {
1677a7e191c3SFrederik Deweerdt 		forever = true;
1678a7e191c3SFrederik Deweerdt 		run_count = 1;
1679a7e191c3SFrederik Deweerdt 	}
168086470930SIngo Molnar 
1681023695d9SStephane Eranian 	/* no_aggr, cgroup are for system-wide only */
1682602ad878SArnaldo Carvalho de Melo 	if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) &&
1683602ad878SArnaldo Carvalho de Melo 	    !target__has_cpu(&target)) {
1684023695d9SStephane Eranian 		fprintf(stderr, "both cgroup and no-aggregation "
1685023695d9SStephane Eranian 			"modes only available in system-wide mode\n");
1686023695d9SStephane Eranian 
1687cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "G", 1);
1688cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "A", 1);
1689cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "a", 1);
1690cc03c542SNamhyung Kim 		goto out;
1691d7e7a451SStephane Eranian 	}
1692d7e7a451SStephane Eranian 
16932cba3ffbSIngo Molnar 	if (add_default_attributes())
1694c6264defSIngo Molnar 		goto out;
169586470930SIngo Molnar 
1696602ad878SArnaldo Carvalho de Melo 	target__validate(&target);
16975c98d466SArnaldo Carvalho de Melo 
169877a6f014SNamhyung Kim 	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1699602ad878SArnaldo Carvalho de Melo 		if (target__has_task(&target)) {
17005c98d466SArnaldo Carvalho de Melo 			pr_err("Problems finding threads of monitor\n");
1701cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "p", 1);
1702cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "t", 1);
1703602ad878SArnaldo Carvalho de Melo 		} else if (target__has_cpu(&target)) {
170460d567e2SArnaldo Carvalho de Melo 			perror("failed to parse CPUs map");
1705cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "C", 1);
1706cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "a", 1);
1707cc03c542SNamhyung Kim 		}
1708cc03c542SNamhyung Kim 		goto out;
170960d567e2SArnaldo Carvalho de Melo 	}
171013370a9bSStephane Eranian 	if (interval && interval < 100) {
171113370a9bSStephane Eranian 		pr_err("print interval must be >= 100ms\n");
1712cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "I", 1);
1713cc03c542SNamhyung Kim 		goto out_free_maps;
171413370a9bSStephane Eranian 	}
1715c45c6ea2SStephane Eranian 
1716d134ffb9SArnaldo Carvalho de Melo 	if (perf_evlist__alloc_stats(evsel_list, interval))
1717d134ffb9SArnaldo Carvalho de Melo 		goto out_free_maps;
1718d6d901c2SZhang, Yanmin 
171986ee6e18SStephane Eranian 	if (perf_stat_init_aggr_mode())
1720cc03c542SNamhyung Kim 		goto out_free_maps;
172186ee6e18SStephane Eranian 
172286470930SIngo Molnar 	/*
172386470930SIngo Molnar 	 * We dont want to block the signals - that would cause
172486470930SIngo Molnar 	 * child tasks to inherit that and Ctrl-C would not work.
172586470930SIngo Molnar 	 * What we want is for Ctrl-C to work in the exec()-ed
172686470930SIngo Molnar 	 * task, but being ignored by perf stat itself:
172786470930SIngo Molnar 	 */
1728f7b7c26eSPeter Zijlstra 	atexit(sig_atexit);
1729a7e191c3SFrederik Deweerdt 	if (!forever)
173086470930SIngo Molnar 		signal(SIGINT,  skip_signal);
173113370a9bSStephane Eranian 	signal(SIGCHLD, skip_signal);
173286470930SIngo Molnar 	signal(SIGALRM, skip_signal);
173386470930SIngo Molnar 	signal(SIGABRT, skip_signal);
173486470930SIngo Molnar 
173542202dd5SIngo Molnar 	status = 0;
1736a7e191c3SFrederik Deweerdt 	for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
173742202dd5SIngo Molnar 		if (run_count != 1 && verbose)
17384aa9015fSStephane Eranian 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
17394aa9015fSStephane Eranian 				run_idx + 1);
1740f9cef0a9SIngo Molnar 
174142202dd5SIngo Molnar 		status = run_perf_stat(argc, argv);
1742a7e191c3SFrederik Deweerdt 		if (forever && status != -1) {
1743a7e191c3SFrederik Deweerdt 			print_stat(argc, argv);
1744d134ffb9SArnaldo Carvalho de Melo 			perf_stat__reset_stats(evsel_list);
1745a7e191c3SFrederik Deweerdt 		}
174642202dd5SIngo Molnar 	}
174742202dd5SIngo Molnar 
1748a7e191c3SFrederik Deweerdt 	if (!forever && status != -1 && !interval)
174942202dd5SIngo Molnar 		print_stat(argc, argv);
1750d134ffb9SArnaldo Carvalho de Melo 
1751d134ffb9SArnaldo Carvalho de Melo 	perf_evlist__free_stats(evsel_list);
1752d134ffb9SArnaldo Carvalho de Melo out_free_maps:
17537e2ed097SArnaldo Carvalho de Melo 	perf_evlist__delete_maps(evsel_list);
17540015e2e1SArnaldo Carvalho de Melo out:
17550015e2e1SArnaldo Carvalho de Melo 	perf_evlist__delete(evsel_list);
175642202dd5SIngo Molnar 	return status;
175786470930SIngo Molnar }
1758