xref: /openbmc/linux/tools/perf/builtin-stat.c (revision 3b4331d9)
186470930SIngo Molnar /*
286470930SIngo Molnar  * builtin-stat.c
386470930SIngo Molnar  *
486470930SIngo Molnar  * Builtin stat command: Give a precise performance counters summary
586470930SIngo Molnar  * overview about any workload, CPU or specific PID.
686470930SIngo Molnar  *
786470930SIngo Molnar  * Sample output:
886470930SIngo Molnar 
92cba3ffbSIngo Molnar    $ perf stat ./hackbench 10
1086470930SIngo Molnar 
112cba3ffbSIngo Molnar   Time: 0.118
1286470930SIngo Molnar 
132cba3ffbSIngo Molnar   Performance counter stats for './hackbench 10':
1486470930SIngo Molnar 
152cba3ffbSIngo Molnar        1708.761321 task-clock                #   11.037 CPUs utilized
162cba3ffbSIngo Molnar             41,190 context-switches          #    0.024 M/sec
172cba3ffbSIngo Molnar              6,735 CPU-migrations            #    0.004 M/sec
182cba3ffbSIngo Molnar             17,318 page-faults               #    0.010 M/sec
192cba3ffbSIngo Molnar      5,205,202,243 cycles                    #    3.046 GHz
202cba3ffbSIngo Molnar      3,856,436,920 stalled-cycles-frontend   #   74.09% frontend cycles idle
212cba3ffbSIngo Molnar      1,600,790,871 stalled-cycles-backend    #   30.75% backend  cycles idle
222cba3ffbSIngo Molnar      2,603,501,247 instructions              #    0.50  insns per cycle
232cba3ffbSIngo Molnar                                              #    1.48  stalled cycles per insn
242cba3ffbSIngo Molnar        484,357,498 branches                  #  283.455 M/sec
252cba3ffbSIngo Molnar          6,388,934 branch-misses             #    1.32% of all branches
262cba3ffbSIngo Molnar 
272cba3ffbSIngo Molnar         0.154822978  seconds time elapsed
2886470930SIngo Molnar 
2986470930SIngo Molnar  *
302cba3ffbSIngo Molnar  * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
3186470930SIngo Molnar  *
3286470930SIngo Molnar  * Improvements and fixes by:
3386470930SIngo Molnar  *
3486470930SIngo Molnar  *   Arjan van de Ven <arjan@linux.intel.com>
3586470930SIngo Molnar  *   Yanmin Zhang <yanmin.zhang@intel.com>
3686470930SIngo Molnar  *   Wu Fengguang <fengguang.wu@intel.com>
3786470930SIngo Molnar  *   Mike Galbraith <efault@gmx.de>
3886470930SIngo Molnar  *   Paul Mackerras <paulus@samba.org>
396e750a8fSJaswinder Singh Rajput  *   Jaswinder Singh Rajput <jaswinder@kernel.org>
4086470930SIngo Molnar  *
4186470930SIngo Molnar  * Released under the GPL v2. (and only v2, not any later version)
4286470930SIngo Molnar  */
4386470930SIngo Molnar 
4486470930SIngo Molnar #include "perf.h"
4586470930SIngo Molnar #include "builtin.h"
46f14d5707SArnaldo Carvalho de Melo #include "util/cgroup.h"
4786470930SIngo Molnar #include "util/util.h"
4886470930SIngo Molnar #include "util/parse-options.h"
4986470930SIngo Molnar #include "util/parse-events.h"
504cabc3d1SAndi Kleen #include "util/pmu.h"
518f28827aSFrederic Weisbecker #include "util/event.h"
52361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h"
5369aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h"
548f28827aSFrederic Weisbecker #include "util/debug.h"
55a5d243d0SIngo Molnar #include "util/color.h"
560007eceaSXiao Guangrong #include "util/stat.h"
5760666c63SLiming Wang #include "util/header.h"
58a12b51c4SPaul Mackerras #include "util/cpumap.h"
59d6d901c2SZhang, Yanmin #include "util/thread.h"
60fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h"
6186470930SIngo Molnar 
621f16c575SPeter Zijlstra #include <stdlib.h>
6386470930SIngo Molnar #include <sys/prctl.h>
645af52b51SStephane Eranian #include <locale.h>
6586470930SIngo Molnar 
66d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR	" "
672cee77c4SDavid Ahern #define CNTR_NOT_SUPPORTED	"<not supported>"
682cee77c4SDavid Ahern #define CNTR_NOT_COUNTED	"<not counted>"
69d7470b6aSStephane Eranian 
7013370a9bSStephane Eranian static void print_stat(int argc, const char **argv);
7113370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix);
7213370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix);
7386ee6e18SStephane Eranian static void print_aggr(char *prefix);
7413370a9bSStephane Eranian 
754cabc3d1SAndi Kleen /* Default events used for perf stat -T */
764cabc3d1SAndi Kleen static const char * const transaction_attrs[] = {
774cabc3d1SAndi Kleen 	"task-clock",
784cabc3d1SAndi Kleen 	"{"
794cabc3d1SAndi Kleen 	"instructions,"
804cabc3d1SAndi Kleen 	"cycles,"
814cabc3d1SAndi Kleen 	"cpu/cycles-t/,"
824cabc3d1SAndi Kleen 	"cpu/tx-start/,"
834cabc3d1SAndi Kleen 	"cpu/el-start/,"
844cabc3d1SAndi Kleen 	"cpu/cycles-ct/"
854cabc3d1SAndi Kleen 	"}"
864cabc3d1SAndi Kleen };
874cabc3d1SAndi Kleen 
884cabc3d1SAndi Kleen /* More limited version when the CPU does not have all events. */
894cabc3d1SAndi Kleen static const char * const transaction_limited_attrs[] = {
904cabc3d1SAndi Kleen 	"task-clock",
914cabc3d1SAndi Kleen 	"{"
924cabc3d1SAndi Kleen 	"instructions,"
934cabc3d1SAndi Kleen 	"cycles,"
944cabc3d1SAndi Kleen 	"cpu/cycles-t/,"
954cabc3d1SAndi Kleen 	"cpu/tx-start/"
964cabc3d1SAndi Kleen 	"}"
974cabc3d1SAndi Kleen };
984cabc3d1SAndi Kleen 
994cabc3d1SAndi Kleen /* must match transaction_attrs and the beginning limited_attrs */
1004cabc3d1SAndi Kleen enum {
1014cabc3d1SAndi Kleen 	T_TASK_CLOCK,
1024cabc3d1SAndi Kleen 	T_INSTRUCTIONS,
1034cabc3d1SAndi Kleen 	T_CYCLES,
1044cabc3d1SAndi Kleen 	T_CYCLES_IN_TX,
1054cabc3d1SAndi Kleen 	T_TRANSACTION_START,
1064cabc3d1SAndi Kleen 	T_ELISION_START,
1074cabc3d1SAndi Kleen 	T_CYCLES_IN_TX_CP,
1084cabc3d1SAndi Kleen };
1094cabc3d1SAndi Kleen 
110666e6d48SRobert Richter static struct perf_evlist	*evsel_list;
111361c99a6SArnaldo Carvalho de Melo 
112602ad878SArnaldo Carvalho de Melo static struct target target = {
11377a6f014SNamhyung Kim 	.uid	= UINT_MAX,
11477a6f014SNamhyung Kim };
11542202dd5SIngo Molnar 
11686ee6e18SStephane Eranian enum aggr_mode {
11786ee6e18SStephane Eranian 	AGGR_NONE,
11886ee6e18SStephane Eranian 	AGGR_GLOBAL,
11986ee6e18SStephane Eranian 	AGGR_SOCKET,
12012c08a9fSStephane Eranian 	AGGR_CORE,
12186ee6e18SStephane Eranian };
12286ee6e18SStephane Eranian 
1233d632595SJaswinder Singh Rajput static int			run_count			=  1;
1242e6cdf99SStephane Eranian static bool			no_inherit			= false;
125c0555642SIan Munsie static bool			scale				=  true;
12686ee6e18SStephane Eranian static enum aggr_mode		aggr_mode			= AGGR_GLOBAL;
127d07f0b12SStephane Eranian static volatile pid_t		child_pid			= -1;
128c0555642SIan Munsie static bool			null_run			=  false;
1292cba3ffbSIngo Molnar static int			detailed_run			=  0;
1304cabc3d1SAndi Kleen static bool			transaction_run;
131201e0b06SArnaldo Carvalho de Melo static bool			big_num				=  true;
132d7470b6aSStephane Eranian static int			big_num_opt			=  -1;
133d7470b6aSStephane Eranian static const char		*csv_sep			= NULL;
134d7470b6aSStephane Eranian static bool			csv_output			= false;
13543bece79SLin Ming static bool			group				= false;
1364aa9015fSStephane Eranian static FILE			*output				= NULL;
1371f16c575SPeter Zijlstra static const char		*pre_cmd			= NULL;
1381f16c575SPeter Zijlstra static const char		*post_cmd			= NULL;
1391f16c575SPeter Zijlstra static bool			sync_run			= false;
14013370a9bSStephane Eranian static unsigned int		interval			= 0;
14141191688SAndi Kleen static unsigned int		initial_delay			= 0;
142410136f5SStephane Eranian static unsigned int		unit_width			= 4; /* strlen("unit") */
143a7e191c3SFrederik Deweerdt static bool			forever				= false;
14413370a9bSStephane Eranian static struct timespec		ref_time;
14586ee6e18SStephane Eranian static struct cpu_map		*aggr_map;
14686ee6e18SStephane Eranian static int			(*aggr_get_id)(struct cpu_map *m, int cpu);
1475af52b51SStephane Eranian 
14860666c63SLiming Wang static volatile int done = 0;
14960666c63SLiming Wang 
15069aad6f1SArnaldo Carvalho de Melo struct perf_stat {
15169aad6f1SArnaldo Carvalho de Melo 	struct stats	  res_stats[3];
15269aad6f1SArnaldo Carvalho de Melo };
15369aad6f1SArnaldo Carvalho de Melo 
15413370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a,
15513370a9bSStephane Eranian 				 struct timespec *b)
15613370a9bSStephane Eranian {
15713370a9bSStephane Eranian 	r->tv_sec = a->tv_sec - b->tv_sec;
15813370a9bSStephane Eranian 	if (a->tv_nsec < b->tv_nsec) {
15913370a9bSStephane Eranian 		r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec;
16013370a9bSStephane Eranian 		r->tv_sec--;
16113370a9bSStephane Eranian 	} else {
16213370a9bSStephane Eranian 		r->tv_nsec = a->tv_nsec - b->tv_nsec ;
16313370a9bSStephane Eranian 	}
16413370a9bSStephane Eranian }
16513370a9bSStephane Eranian 
16613370a9bSStephane Eranian static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
16713370a9bSStephane Eranian {
16813370a9bSStephane Eranian 	return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus;
16913370a9bSStephane Eranian }
17013370a9bSStephane Eranian 
17113370a9bSStephane Eranian static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
17213370a9bSStephane Eranian {
17313370a9bSStephane Eranian 	return perf_evsel__cpus(evsel)->nr;
17413370a9bSStephane Eranian }
17513370a9bSStephane Eranian 
176a7e191c3SFrederik Deweerdt static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
177a7e191c3SFrederik Deweerdt {
17890f6bb6cSAndi Kleen 	int i;
17990f6bb6cSAndi Kleen 	struct perf_stat *ps = evsel->priv;
18090f6bb6cSAndi Kleen 
18190f6bb6cSAndi Kleen 	for (i = 0; i < 3; i++)
18290f6bb6cSAndi Kleen 		init_stats(&ps->res_stats[i]);
183a7e191c3SFrederik Deweerdt }
184a7e191c3SFrederik Deweerdt 
185c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
18669aad6f1SArnaldo Carvalho de Melo {
187c52b12edSArnaldo Carvalho de Melo 	evsel->priv = zalloc(sizeof(struct perf_stat));
188d180ac14SJiri Olsa 	if (evsel->priv == NULL)
18990f6bb6cSAndi Kleen 		return -ENOMEM;
19090f6bb6cSAndi Kleen 	perf_evsel__reset_stat_priv(evsel);
19190f6bb6cSAndi Kleen 	return 0;
19269aad6f1SArnaldo Carvalho de Melo }
19369aad6f1SArnaldo Carvalho de Melo 
19469aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
19569aad6f1SArnaldo Carvalho de Melo {
19604662523SArnaldo Carvalho de Melo 	zfree(&evsel->priv);
19769aad6f1SArnaldo Carvalho de Melo }
19869aad6f1SArnaldo Carvalho de Melo 
19913370a9bSStephane Eranian static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
2007ae92e74SYan, Zheng {
20113370a9bSStephane Eranian 	void *addr;
20213370a9bSStephane Eranian 	size_t sz;
20313370a9bSStephane Eranian 
20413370a9bSStephane Eranian 	sz = sizeof(*evsel->counts) +
20513370a9bSStephane Eranian 	     (perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values));
20613370a9bSStephane Eranian 
20713370a9bSStephane Eranian 	addr = zalloc(sz);
20813370a9bSStephane Eranian 	if (!addr)
20913370a9bSStephane Eranian 		return -ENOMEM;
21013370a9bSStephane Eranian 
21113370a9bSStephane Eranian 	evsel->prev_raw_counts =  addr;
21213370a9bSStephane Eranian 
21313370a9bSStephane Eranian 	return 0;
2147ae92e74SYan, Zheng }
2157ae92e74SYan, Zheng 
21613370a9bSStephane Eranian static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
2177ae92e74SYan, Zheng {
21804662523SArnaldo Carvalho de Melo 	zfree(&evsel->prev_raw_counts);
2197ae92e74SYan, Zheng }
2207ae92e74SYan, Zheng 
221d134ffb9SArnaldo Carvalho de Melo static void perf_evlist__free_stats(struct perf_evlist *evlist)
222d134ffb9SArnaldo Carvalho de Melo {
223d134ffb9SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
224d134ffb9SArnaldo Carvalho de Melo 
2250050f7aaSArnaldo Carvalho de Melo 	evlist__for_each(evlist, evsel) {
226d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_stat_priv(evsel);
227d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_counts(evsel);
228d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_prev_raw_counts(evsel);
229d134ffb9SArnaldo Carvalho de Melo 	}
230d134ffb9SArnaldo Carvalho de Melo }
231d134ffb9SArnaldo Carvalho de Melo 
232d134ffb9SArnaldo Carvalho de Melo static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
233d134ffb9SArnaldo Carvalho de Melo {
234d134ffb9SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
235d134ffb9SArnaldo Carvalho de Melo 
2360050f7aaSArnaldo Carvalho de Melo 	evlist__for_each(evlist, evsel) {
237d134ffb9SArnaldo Carvalho de Melo 		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
238d134ffb9SArnaldo Carvalho de Melo 		    perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
239d134ffb9SArnaldo Carvalho de Melo 		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
240d134ffb9SArnaldo Carvalho de Melo 			goto out_free;
241d134ffb9SArnaldo Carvalho de Melo 	}
242d134ffb9SArnaldo Carvalho de Melo 
243d134ffb9SArnaldo Carvalho de Melo 	return 0;
244d134ffb9SArnaldo Carvalho de Melo 
245d134ffb9SArnaldo Carvalho de Melo out_free:
246d134ffb9SArnaldo Carvalho de Melo 	perf_evlist__free_stats(evlist);
247d134ffb9SArnaldo Carvalho de Melo 	return -1;
248d134ffb9SArnaldo Carvalho de Melo }
249d134ffb9SArnaldo Carvalho de Melo 
250666e6d48SRobert Richter static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
251666e6d48SRobert Richter static struct stats runtime_cycles_stats[MAX_NR_CPUS];
252666e6d48SRobert Richter static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
253666e6d48SRobert Richter static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS];
254666e6d48SRobert Richter static struct stats runtime_branches_stats[MAX_NR_CPUS];
255666e6d48SRobert Richter static struct stats runtime_cacherefs_stats[MAX_NR_CPUS];
256666e6d48SRobert Richter static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS];
257666e6d48SRobert Richter static struct stats runtime_l1_icache_stats[MAX_NR_CPUS];
258666e6d48SRobert Richter static struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
259666e6d48SRobert Richter static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
260666e6d48SRobert Richter static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
2614cabc3d1SAndi Kleen static struct stats runtime_cycles_in_tx_stats[MAX_NR_CPUS];
262666e6d48SRobert Richter static struct stats walltime_nsecs_stats;
2634cabc3d1SAndi Kleen static struct stats runtime_transaction_stats[MAX_NR_CPUS];
2644cabc3d1SAndi Kleen static struct stats runtime_elision_stats[MAX_NR_CPUS];
26586470930SIngo Molnar 
266d134ffb9SArnaldo Carvalho de Melo static void perf_stat__reset_stats(struct perf_evlist *evlist)
267a7e191c3SFrederik Deweerdt {
268d134ffb9SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
269d134ffb9SArnaldo Carvalho de Melo 
2700050f7aaSArnaldo Carvalho de Melo 	evlist__for_each(evlist, evsel) {
271d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__reset_stat_priv(evsel);
272d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
273d134ffb9SArnaldo Carvalho de Melo 	}
274d134ffb9SArnaldo Carvalho de Melo 
275a7e191c3SFrederik Deweerdt 	memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
276a7e191c3SFrederik Deweerdt 	memset(runtime_cycles_stats, 0, sizeof(runtime_cycles_stats));
277a7e191c3SFrederik Deweerdt 	memset(runtime_stalled_cycles_front_stats, 0, sizeof(runtime_stalled_cycles_front_stats));
278a7e191c3SFrederik Deweerdt 	memset(runtime_stalled_cycles_back_stats, 0, sizeof(runtime_stalled_cycles_back_stats));
279a7e191c3SFrederik Deweerdt 	memset(runtime_branches_stats, 0, sizeof(runtime_branches_stats));
280a7e191c3SFrederik Deweerdt 	memset(runtime_cacherefs_stats, 0, sizeof(runtime_cacherefs_stats));
281a7e191c3SFrederik Deweerdt 	memset(runtime_l1_dcache_stats, 0, sizeof(runtime_l1_dcache_stats));
282a7e191c3SFrederik Deweerdt 	memset(runtime_l1_icache_stats, 0, sizeof(runtime_l1_icache_stats));
283a7e191c3SFrederik Deweerdt 	memset(runtime_ll_cache_stats, 0, sizeof(runtime_ll_cache_stats));
284a7e191c3SFrederik Deweerdt 	memset(runtime_itlb_cache_stats, 0, sizeof(runtime_itlb_cache_stats));
285a7e191c3SFrederik Deweerdt 	memset(runtime_dtlb_cache_stats, 0, sizeof(runtime_dtlb_cache_stats));
2864cabc3d1SAndi Kleen 	memset(runtime_cycles_in_tx_stats, 0,
2874cabc3d1SAndi Kleen 			sizeof(runtime_cycles_in_tx_stats));
2884cabc3d1SAndi Kleen 	memset(runtime_transaction_stats, 0,
2894cabc3d1SAndi Kleen 		sizeof(runtime_transaction_stats));
2904cabc3d1SAndi Kleen 	memset(runtime_elision_stats, 0, sizeof(runtime_elision_stats));
291a7e191c3SFrederik Deweerdt 	memset(&walltime_nsecs_stats, 0, sizeof(walltime_nsecs_stats));
292a7e191c3SFrederik Deweerdt }
293a7e191c3SFrederik Deweerdt 
294cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel)
29586470930SIngo Molnar {
29669aad6f1SArnaldo Carvalho de Melo 	struct perf_event_attr *attr = &evsel->attr;
297727ab04eSArnaldo Carvalho de Melo 
29886470930SIngo Molnar 	if (scale)
29986470930SIngo Molnar 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
30086470930SIngo Molnar 				    PERF_FORMAT_TOTAL_TIME_RUNNING;
30186470930SIngo Molnar 
3022e6cdf99SStephane Eranian 	attr->inherit = !no_inherit;
3035d2cd909SArnaldo Carvalho de Melo 
304602ad878SArnaldo Carvalho de Melo 	if (target__has_cpu(&target))
305594ac61aSArnaldo Carvalho de Melo 		return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
3065622c07bSStephane Eranian 
307602ad878SArnaldo Carvalho de Melo 	if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) {
30886470930SIngo Molnar 		attr->disabled = 1;
30941191688SAndi Kleen 		if (!initial_delay)
31057e7986eSPaul Mackerras 			attr->enable_on_exec = 1;
3116be2850eSZhang, Yanmin 	}
312084ab9f8SArnaldo Carvalho de Melo 
313594ac61aSArnaldo Carvalho de Melo 	return perf_evsel__open_per_thread(evsel, evsel_list->threads);
31486470930SIngo Molnar }
31586470930SIngo Molnar 
31686470930SIngo Molnar /*
31786470930SIngo Molnar  * Does the counter have nsecs as a unit?
31886470930SIngo Molnar  */
319daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel)
32086470930SIngo Molnar {
321daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
322daec78a0SArnaldo Carvalho de Melo 	    perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
32386470930SIngo Molnar 		return 1;
32486470930SIngo Molnar 
32586470930SIngo Molnar 	return 0;
32686470930SIngo Molnar }
32786470930SIngo Molnar 
3284cabc3d1SAndi Kleen static struct perf_evsel *nth_evsel(int n)
3294cabc3d1SAndi Kleen {
3304cabc3d1SAndi Kleen 	static struct perf_evsel **array;
3314cabc3d1SAndi Kleen 	static int array_len;
3324cabc3d1SAndi Kleen 	struct perf_evsel *ev;
3334cabc3d1SAndi Kleen 	int j;
3344cabc3d1SAndi Kleen 
3354cabc3d1SAndi Kleen 	/* Assumes this only called when evsel_list does not change anymore. */
3364cabc3d1SAndi Kleen 	if (!array) {
3370050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, ev)
3384cabc3d1SAndi Kleen 			array_len++;
3394cabc3d1SAndi Kleen 		array = malloc(array_len * sizeof(void *));
3404cabc3d1SAndi Kleen 		if (!array)
3414cabc3d1SAndi Kleen 			exit(ENOMEM);
3424cabc3d1SAndi Kleen 		j = 0;
3430050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, ev)
3444cabc3d1SAndi Kleen 			array[j++] = ev;
3454cabc3d1SAndi Kleen 	}
3464cabc3d1SAndi Kleen 	if (n < array_len)
3474cabc3d1SAndi Kleen 		return array[n];
3484cabc3d1SAndi Kleen 	return NULL;
3494cabc3d1SAndi Kleen }
3504cabc3d1SAndi Kleen 
35186470930SIngo Molnar /*
352dcd9936aSIngo Molnar  * Update various tracking values we maintain to print
353dcd9936aSIngo Molnar  * more semantic information such as miss/hit ratios,
354dcd9936aSIngo Molnar  * instruction rates, etc:
355dcd9936aSIngo Molnar  */
356dcd9936aSIngo Molnar static void update_shadow_stats(struct perf_evsel *counter, u64 *count)
357dcd9936aSIngo Molnar {
358dcd9936aSIngo Molnar 	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
359dcd9936aSIngo Molnar 		update_stats(&runtime_nsecs_stats[0], count[0]);
360dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
361dcd9936aSIngo Molnar 		update_stats(&runtime_cycles_stats[0], count[0]);
3624cabc3d1SAndi Kleen 	else if (transaction_run &&
3634cabc3d1SAndi Kleen 		 perf_evsel__cmp(counter, nth_evsel(T_CYCLES_IN_TX)))
3644cabc3d1SAndi Kleen 		update_stats(&runtime_cycles_in_tx_stats[0], count[0]);
3654cabc3d1SAndi Kleen 	else if (transaction_run &&
3664cabc3d1SAndi Kleen 		 perf_evsel__cmp(counter, nth_evsel(T_TRANSACTION_START)))
3674cabc3d1SAndi Kleen 		update_stats(&runtime_transaction_stats[0], count[0]);
3684cabc3d1SAndi Kleen 	else if (transaction_run &&
3694cabc3d1SAndi Kleen 		 perf_evsel__cmp(counter, nth_evsel(T_ELISION_START)))
3704cabc3d1SAndi Kleen 		update_stats(&runtime_elision_stats[0], count[0]);
371d3d1e86dSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
372d3d1e86dSIngo Molnar 		update_stats(&runtime_stalled_cycles_front_stats[0], count[0]);
373129c04cbSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
374d3d1e86dSIngo Molnar 		update_stats(&runtime_stalled_cycles_back_stats[0], count[0]);
375dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
376dcd9936aSIngo Molnar 		update_stats(&runtime_branches_stats[0], count[0]);
377dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
378dcd9936aSIngo Molnar 		update_stats(&runtime_cacherefs_stats[0], count[0]);
3798bb6c79fSIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
3808bb6c79fSIngo Molnar 		update_stats(&runtime_l1_dcache_stats[0], count[0]);
381c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
382c3305257SIngo Molnar 		update_stats(&runtime_l1_icache_stats[0], count[0]);
383c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
384c3305257SIngo Molnar 		update_stats(&runtime_ll_cache_stats[0], count[0]);
385c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
386c3305257SIngo Molnar 		update_stats(&runtime_dtlb_cache_stats[0], count[0]);
387c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
388c3305257SIngo Molnar 		update_stats(&runtime_itlb_cache_stats[0], count[0]);
389dcd9936aSIngo Molnar }
390dcd9936aSIngo Molnar 
391779d0b99SJiri Olsa static void zero_per_pkg(struct perf_evsel *counter)
392779d0b99SJiri Olsa {
393779d0b99SJiri Olsa 	if (counter->per_pkg_mask)
394779d0b99SJiri Olsa 		memset(counter->per_pkg_mask, 0, MAX_NR_CPUS);
395779d0b99SJiri Olsa }
396779d0b99SJiri Olsa 
397779d0b99SJiri Olsa static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
398779d0b99SJiri Olsa {
399779d0b99SJiri Olsa 	unsigned long *mask = counter->per_pkg_mask;
400779d0b99SJiri Olsa 	struct cpu_map *cpus = perf_evsel__cpus(counter);
401779d0b99SJiri Olsa 	int s;
402779d0b99SJiri Olsa 
403779d0b99SJiri Olsa 	*skip = false;
404779d0b99SJiri Olsa 
405779d0b99SJiri Olsa 	if (!counter->per_pkg)
406779d0b99SJiri Olsa 		return 0;
407779d0b99SJiri Olsa 
408779d0b99SJiri Olsa 	if (cpu_map__empty(cpus))
409779d0b99SJiri Olsa 		return 0;
410779d0b99SJiri Olsa 
411779d0b99SJiri Olsa 	if (!mask) {
412779d0b99SJiri Olsa 		mask = zalloc(MAX_NR_CPUS);
413779d0b99SJiri Olsa 		if (!mask)
414779d0b99SJiri Olsa 			return -ENOMEM;
415779d0b99SJiri Olsa 
416779d0b99SJiri Olsa 		counter->per_pkg_mask = mask;
417779d0b99SJiri Olsa 	}
418779d0b99SJiri Olsa 
419779d0b99SJiri Olsa 	s = cpu_map__get_socket(cpus, cpu);
420779d0b99SJiri Olsa 	if (s < 0)
421779d0b99SJiri Olsa 		return -1;
422779d0b99SJiri Olsa 
423779d0b99SJiri Olsa 	*skip = test_and_set_bit(s, mask) == 1;
424779d0b99SJiri Olsa 	return 0;
425779d0b99SJiri Olsa }
426779d0b99SJiri Olsa 
427060c4f9cSJiri Olsa static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
428060c4f9cSJiri Olsa 		   struct perf_counts_values *count)
429060c4f9cSJiri Olsa {
4301971f59fSJiri Olsa 	struct perf_counts_values *aggr = &evsel->counts->aggr;
431779d0b99SJiri Olsa 	static struct perf_counts_values zero;
432779d0b99SJiri Olsa 	bool skip = false;
433779d0b99SJiri Olsa 
434779d0b99SJiri Olsa 	if (check_per_pkg(evsel, cpu, &skip)) {
435779d0b99SJiri Olsa 		pr_err("failed to read per-pkg counter\n");
436779d0b99SJiri Olsa 		return -1;
437779d0b99SJiri Olsa 	}
438779d0b99SJiri Olsa 
439779d0b99SJiri Olsa 	if (skip)
440779d0b99SJiri Olsa 		count = &zero;
4411971f59fSJiri Olsa 
442060c4f9cSJiri Olsa 	switch (aggr_mode) {
443060c4f9cSJiri Olsa 	case AGGR_CORE:
444060c4f9cSJiri Olsa 	case AGGR_SOCKET:
445060c4f9cSJiri Olsa 	case AGGR_NONE:
4466c0345b7SJiri Olsa 		if (!evsel->snapshot)
447060c4f9cSJiri Olsa 			perf_evsel__compute_deltas(evsel, cpu, count);
448060c4f9cSJiri Olsa 		perf_counts_values__scale(count, scale, NULL);
449060c4f9cSJiri Olsa 		evsel->counts->cpu[cpu] = *count;
450060c4f9cSJiri Olsa 		update_shadow_stats(evsel, count->values);
451060c4f9cSJiri Olsa 		break;
452060c4f9cSJiri Olsa 	case AGGR_GLOBAL:
4531971f59fSJiri Olsa 		aggr->val += count->val;
4541971f59fSJiri Olsa 		if (scale) {
4551971f59fSJiri Olsa 			aggr->ena += count->ena;
4561971f59fSJiri Olsa 			aggr->run += count->run;
4571971f59fSJiri Olsa 		}
458060c4f9cSJiri Olsa 	default:
459060c4f9cSJiri Olsa 		break;
460060c4f9cSJiri Olsa 	}
461060c4f9cSJiri Olsa 
462060c4f9cSJiri Olsa 	return 0;
463060c4f9cSJiri Olsa }
464060c4f9cSJiri Olsa 
4651971f59fSJiri Olsa static int read_counter(struct perf_evsel *counter);
4661971f59fSJiri Olsa 
467dcd9936aSIngo Molnar /*
46886470930SIngo Molnar  * Read out the results of a single counter:
469f5b4a9c3SStephane Eranian  * aggregate counts across CPUs in system-wide mode
47086470930SIngo Molnar  */
471c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter)
47286470930SIngo Molnar {
4731971f59fSJiri Olsa 	struct perf_counts_values *aggr = &counter->counts->aggr;
47469aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps = counter->priv;
475c52b12edSArnaldo Carvalho de Melo 	u64 *count = counter->counts->aggr.values;
476c52b12edSArnaldo Carvalho de Melo 	int i;
47786470930SIngo Molnar 
4781971f59fSJiri Olsa 	aggr->val = aggr->ena = aggr->run = 0;
4791971f59fSJiri Olsa 
4801971f59fSJiri Olsa 	if (read_counter(counter))
481c52b12edSArnaldo Carvalho de Melo 		return -1;
4829e9772c4SPeter Zijlstra 
4836c0345b7SJiri Olsa 	if (!counter->snapshot)
4841971f59fSJiri Olsa 		perf_evsel__compute_deltas(counter, -1, aggr);
4851971f59fSJiri Olsa 	perf_counts_values__scale(aggr, scale, &counter->counts->scaled);
4861971f59fSJiri Olsa 
4879e9772c4SPeter Zijlstra 	for (i = 0; i < 3; i++)
48869aad6f1SArnaldo Carvalho de Melo 		update_stats(&ps->res_stats[i], count[i]);
4899e9772c4SPeter Zijlstra 
4909e9772c4SPeter Zijlstra 	if (verbose) {
4914aa9015fSStephane Eranian 		fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
4927289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter), count[0], count[1], count[2]);
4939e9772c4SPeter Zijlstra 	}
4949e9772c4SPeter Zijlstra 
49586470930SIngo Molnar 	/*
49686470930SIngo Molnar 	 * Save the full runtime - to allow normalization during printout:
49786470930SIngo Molnar 	 */
498dcd9936aSIngo Molnar 	update_shadow_stats(counter, count);
499c52b12edSArnaldo Carvalho de Melo 
500c52b12edSArnaldo Carvalho de Melo 	return 0;
501f5b4a9c3SStephane Eranian }
502f5b4a9c3SStephane Eranian 
503f5b4a9c3SStephane Eranian /*
504f5b4a9c3SStephane Eranian  * Read out the results of a single counter:
505f5b4a9c3SStephane Eranian  * do not aggregate counts across CPUs in system-wide mode
506f5b4a9c3SStephane Eranian  */
507c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter)
508f5b4a9c3SStephane Eranian {
5099bf1a529SJiri Olsa 	int nthreads = thread_map__nr(evsel_list->threads);
5109bf1a529SJiri Olsa 	int ncpus = perf_evsel__nr_cpus(counter);
5119bf1a529SJiri Olsa 	int cpu, thread;
512f5b4a9c3SStephane Eranian 
5133b4331d9SSuzuki K. Poulose 	if (!counter->supported)
5143b4331d9SSuzuki K. Poulose 		return -ENOENT;
5153b4331d9SSuzuki K. Poulose 
5169bf1a529SJiri Olsa 	if (counter->system_wide)
5179bf1a529SJiri Olsa 		nthreads = 1;
5189bf1a529SJiri Olsa 
519779d0b99SJiri Olsa 	if (counter->per_pkg)
520779d0b99SJiri Olsa 		zero_per_pkg(counter);
521779d0b99SJiri Olsa 
5229bf1a529SJiri Olsa 	for (thread = 0; thread < nthreads; thread++) {
5239bf1a529SJiri Olsa 		for (cpu = 0; cpu < ncpus; cpu++) {
5249bf1a529SJiri Olsa 			if (perf_evsel__read_cb(counter, cpu, thread, read_cb))
525c52b12edSArnaldo Carvalho de Melo 				return -1;
526f5b4a9c3SStephane Eranian 		}
5279bf1a529SJiri Olsa 	}
528c52b12edSArnaldo Carvalho de Melo 
529c52b12edSArnaldo Carvalho de Melo 	return 0;
53086470930SIngo Molnar }
53186470930SIngo Molnar 
53213370a9bSStephane Eranian static void print_interval(void)
53313370a9bSStephane Eranian {
53413370a9bSStephane Eranian 	static int num_print_interval;
53513370a9bSStephane Eranian 	struct perf_evsel *counter;
53613370a9bSStephane Eranian 	struct perf_stat *ps;
53713370a9bSStephane Eranian 	struct timespec ts, rs;
53813370a9bSStephane Eranian 	char prefix[64];
53913370a9bSStephane Eranian 
54086ee6e18SStephane Eranian 	if (aggr_mode == AGGR_GLOBAL) {
5410050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
54213370a9bSStephane Eranian 			ps = counter->priv;
54313370a9bSStephane Eranian 			memset(ps->res_stats, 0, sizeof(ps->res_stats));
54413370a9bSStephane Eranian 			read_counter_aggr(counter);
54513370a9bSStephane Eranian 		}
54686ee6e18SStephane Eranian 	} else	{
5470050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
54886ee6e18SStephane Eranian 			ps = counter->priv;
54986ee6e18SStephane Eranian 			memset(ps->res_stats, 0, sizeof(ps->res_stats));
55086ee6e18SStephane Eranian 			read_counter(counter);
55113370a9bSStephane Eranian 		}
55286ee6e18SStephane Eranian 	}
55386ee6e18SStephane Eranian 
55413370a9bSStephane Eranian 	clock_gettime(CLOCK_MONOTONIC, &ts);
55513370a9bSStephane Eranian 	diff_timespec(&rs, &ts, &ref_time);
55613370a9bSStephane Eranian 	sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep);
55713370a9bSStephane Eranian 
55813370a9bSStephane Eranian 	if (num_print_interval == 0 && !csv_output) {
55986ee6e18SStephane Eranian 		switch (aggr_mode) {
56086ee6e18SStephane Eranian 		case AGGR_SOCKET:
561410136f5SStephane Eranian 			fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
56286ee6e18SStephane Eranian 			break;
56312c08a9fSStephane Eranian 		case AGGR_CORE:
564410136f5SStephane Eranian 			fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
56512c08a9fSStephane Eranian 			break;
56686ee6e18SStephane Eranian 		case AGGR_NONE:
567410136f5SStephane Eranian 			fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
56886ee6e18SStephane Eranian 			break;
56986ee6e18SStephane Eranian 		case AGGR_GLOBAL:
57086ee6e18SStephane Eranian 		default:
571410136f5SStephane Eranian 			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
57213370a9bSStephane Eranian 		}
57386ee6e18SStephane Eranian 	}
57413370a9bSStephane Eranian 
57513370a9bSStephane Eranian 	if (++num_print_interval == 25)
57613370a9bSStephane Eranian 		num_print_interval = 0;
57713370a9bSStephane Eranian 
57886ee6e18SStephane Eranian 	switch (aggr_mode) {
57912c08a9fSStephane Eranian 	case AGGR_CORE:
58086ee6e18SStephane Eranian 	case AGGR_SOCKET:
58186ee6e18SStephane Eranian 		print_aggr(prefix);
58286ee6e18SStephane Eranian 		break;
58386ee6e18SStephane Eranian 	case AGGR_NONE:
5840050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
58513370a9bSStephane Eranian 			print_counter(counter, prefix);
58686ee6e18SStephane Eranian 		break;
58786ee6e18SStephane Eranian 	case AGGR_GLOBAL:
58886ee6e18SStephane Eranian 	default:
5890050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
59013370a9bSStephane Eranian 			print_counter_aggr(counter, prefix);
59113370a9bSStephane Eranian 	}
5922bbf03f1SAndi Kleen 
5932bbf03f1SAndi Kleen 	fflush(output);
59413370a9bSStephane Eranian }
59513370a9bSStephane Eranian 
59641191688SAndi Kleen static void handle_initial_delay(void)
59741191688SAndi Kleen {
59841191688SAndi Kleen 	struct perf_evsel *counter;
59941191688SAndi Kleen 
60041191688SAndi Kleen 	if (initial_delay) {
60141191688SAndi Kleen 		const int ncpus = cpu_map__nr(evsel_list->cpus),
60241191688SAndi Kleen 			nthreads = thread_map__nr(evsel_list->threads);
60341191688SAndi Kleen 
60441191688SAndi Kleen 		usleep(initial_delay * 1000);
6050050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
60641191688SAndi Kleen 			perf_evsel__enable(counter, ncpus, nthreads);
60741191688SAndi Kleen 	}
60841191688SAndi Kleen }
60941191688SAndi Kleen 
610f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno;
6116af206fdSArnaldo Carvalho de Melo 
6126af206fdSArnaldo Carvalho de Melo /*
6136af206fdSArnaldo Carvalho de Melo  * perf_evlist__prepare_workload will send a SIGUSR1
6146af206fdSArnaldo Carvalho de Melo  * if the fork fails, since we asked by setting its
6156af206fdSArnaldo Carvalho de Melo  * want_signal to true.
6166af206fdSArnaldo Carvalho de Melo  */
617f33cbe72SArnaldo Carvalho de Melo static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
618f33cbe72SArnaldo Carvalho de Melo 					void *ucontext __maybe_unused)
6196af206fdSArnaldo Carvalho de Melo {
620f33cbe72SArnaldo Carvalho de Melo 	workload_exec_errno = info->si_value.sival_int;
6216af206fdSArnaldo Carvalho de Melo }
6226af206fdSArnaldo Carvalho de Melo 
623acf28922SNamhyung Kim static int __run_perf_stat(int argc, const char **argv)
62486470930SIngo Molnar {
62556e52e85SArnaldo Carvalho de Melo 	char msg[512];
62686470930SIngo Molnar 	unsigned long long t0, t1;
627cac21425SJiri Olsa 	struct perf_evsel *counter;
62813370a9bSStephane Eranian 	struct timespec ts;
629410136f5SStephane Eranian 	size_t l;
63042202dd5SIngo Molnar 	int status = 0;
6316be2850eSZhang, Yanmin 	const bool forks = (argc > 0);
63286470930SIngo Molnar 
63313370a9bSStephane Eranian 	if (interval) {
63413370a9bSStephane Eranian 		ts.tv_sec  = interval / 1000;
63513370a9bSStephane Eranian 		ts.tv_nsec = (interval % 1000) * 1000000;
63613370a9bSStephane Eranian 	} else {
63713370a9bSStephane Eranian 		ts.tv_sec  = 1;
63813370a9bSStephane Eranian 		ts.tv_nsec = 0;
63913370a9bSStephane Eranian 	}
64013370a9bSStephane Eranian 
641acf28922SNamhyung Kim 	if (forks) {
642735f7e0bSArnaldo Carvalho de Melo 		if (perf_evlist__prepare_workload(evsel_list, &target, argv, false,
643735f7e0bSArnaldo Carvalho de Melo 						  workload_exec_failed_signal) < 0) {
644acf28922SNamhyung Kim 			perror("failed to prepare workload");
645fceda7feSDavid Ahern 			return -1;
646051ae7f7SPaul Mackerras 		}
647d20a47e7SNamhyung Kim 		child_pid = evsel_list->workload.pid;
64860666c63SLiming Wang 	}
649051ae7f7SPaul Mackerras 
6506a4bb04cSJiri Olsa 	if (group)
65163dab225SArnaldo Carvalho de Melo 		perf_evlist__set_leader(evsel_list);
6526a4bb04cSJiri Olsa 
6530050f7aaSArnaldo Carvalho de Melo 	evlist__for_each(evsel_list, counter) {
654cac21425SJiri Olsa 		if (create_perf_stat_counter(counter) < 0) {
655979987a5SDavid Ahern 			/*
656979987a5SDavid Ahern 			 * PPC returns ENXIO for HW counters until 2.6.37
657979987a5SDavid Ahern 			 * (behavior changed with commit b0a873e).
658979987a5SDavid Ahern 			 */
65938f6ae1eSAnton Blanchard 			if (errno == EINVAL || errno == ENOSYS ||
660979987a5SDavid Ahern 			    errno == ENOENT || errno == EOPNOTSUPP ||
661979987a5SDavid Ahern 			    errno == ENXIO) {
662c63ca0c0SDavid Ahern 				if (verbose)
663c63ca0c0SDavid Ahern 					ui__warning("%s event is not supported by the kernel.\n",
6647289f83cSArnaldo Carvalho de Melo 						    perf_evsel__name(counter));
6652cee77c4SDavid Ahern 				counter->supported = false;
666ede70290SIngo Molnar 				continue;
667c63ca0c0SDavid Ahern 			}
668ede70290SIngo Molnar 
66956e52e85SArnaldo Carvalho de Melo 			perf_evsel__open_strerror(counter, &target,
67056e52e85SArnaldo Carvalho de Melo 						  errno, msg, sizeof(msg));
67156e52e85SArnaldo Carvalho de Melo 			ui__error("%s\n", msg);
67256e52e85SArnaldo Carvalho de Melo 
673084ab9f8SArnaldo Carvalho de Melo 			if (child_pid != -1)
674084ab9f8SArnaldo Carvalho de Melo 				kill(child_pid, SIGTERM);
675fceda7feSDavid Ahern 
676084ab9f8SArnaldo Carvalho de Melo 			return -1;
677084ab9f8SArnaldo Carvalho de Melo 		}
6782cee77c4SDavid Ahern 		counter->supported = true;
679410136f5SStephane Eranian 
680410136f5SStephane Eranian 		l = strlen(counter->unit);
681410136f5SStephane Eranian 		if (l > unit_width)
682410136f5SStephane Eranian 			unit_width = l;
68348290609SArnaldo Carvalho de Melo 	}
68486470930SIngo Molnar 
6851491a632SArnaldo Carvalho de Melo 	if (perf_evlist__apply_filters(evsel_list)) {
686cfd748aeSFrederic Weisbecker 		error("failed to set filter with %d (%s)\n", errno,
687759e612bSMasami Hiramatsu 			strerror_r(errno, msg, sizeof(msg)));
688cfd748aeSFrederic Weisbecker 		return -1;
689cfd748aeSFrederic Weisbecker 	}
690cfd748aeSFrederic Weisbecker 
69186470930SIngo Molnar 	/*
69286470930SIngo Molnar 	 * Enable counters and exec the command:
69386470930SIngo Molnar 	 */
69486470930SIngo Molnar 	t0 = rdclock();
69513370a9bSStephane Eranian 	clock_gettime(CLOCK_MONOTONIC, &ref_time);
69686470930SIngo Molnar 
69760666c63SLiming Wang 	if (forks) {
698acf28922SNamhyung Kim 		perf_evlist__start_workload(evsel_list);
69941191688SAndi Kleen 		handle_initial_delay();
700acf28922SNamhyung Kim 
70113370a9bSStephane Eranian 		if (interval) {
70213370a9bSStephane Eranian 			while (!waitpid(child_pid, &status, WNOHANG)) {
70313370a9bSStephane Eranian 				nanosleep(&ts, NULL);
70413370a9bSStephane Eranian 				print_interval();
70513370a9bSStephane Eranian 			}
70613370a9bSStephane Eranian 		}
70742202dd5SIngo Molnar 		wait(&status);
7086af206fdSArnaldo Carvalho de Melo 
709f33cbe72SArnaldo Carvalho de Melo 		if (workload_exec_errno) {
710f33cbe72SArnaldo Carvalho de Melo 			const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
711f33cbe72SArnaldo Carvalho de Melo 			pr_err("Workload failed: %s\n", emsg);
7126af206fdSArnaldo Carvalho de Melo 			return -1;
713f33cbe72SArnaldo Carvalho de Melo 		}
7146af206fdSArnaldo Carvalho de Melo 
71533e49ea7SAndi Kleen 		if (WIFSIGNALED(status))
71633e49ea7SAndi Kleen 			psignal(WTERMSIG(status), argv[0]);
71760666c63SLiming Wang 	} else {
71841191688SAndi Kleen 		handle_initial_delay();
71913370a9bSStephane Eranian 		while (!done) {
72013370a9bSStephane Eranian 			nanosleep(&ts, NULL);
72113370a9bSStephane Eranian 			if (interval)
72213370a9bSStephane Eranian 				print_interval();
72313370a9bSStephane Eranian 		}
72460666c63SLiming Wang 	}
72586470930SIngo Molnar 
72686470930SIngo Molnar 	t1 = rdclock();
72786470930SIngo Molnar 
7289e9772c4SPeter Zijlstra 	update_stats(&walltime_nsecs_stats, t1 - t0);
72942202dd5SIngo Molnar 
73086ee6e18SStephane Eranian 	if (aggr_mode == AGGR_GLOBAL) {
7310050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
732c52b12edSArnaldo Carvalho de Melo 			read_counter_aggr(counter);
7337ae92e74SYan, Zheng 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
734b3a319d5SNamhyung Kim 					     thread_map__nr(evsel_list->threads));
735c52b12edSArnaldo Carvalho de Melo 		}
73686ee6e18SStephane Eranian 	} else {
7370050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
73886ee6e18SStephane Eranian 			read_counter(counter);
73986ee6e18SStephane Eranian 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
74086ee6e18SStephane Eranian 		}
741c52b12edSArnaldo Carvalho de Melo 	}
742c52b12edSArnaldo Carvalho de Melo 
74342202dd5SIngo Molnar 	return WEXITSTATUS(status);
74442202dd5SIngo Molnar }
74542202dd5SIngo Molnar 
74641cde476SArnaldo Carvalho de Melo static int run_perf_stat(int argc, const char **argv)
7471f16c575SPeter Zijlstra {
7481f16c575SPeter Zijlstra 	int ret;
7491f16c575SPeter Zijlstra 
7501f16c575SPeter Zijlstra 	if (pre_cmd) {
7511f16c575SPeter Zijlstra 		ret = system(pre_cmd);
7521f16c575SPeter Zijlstra 		if (ret)
7531f16c575SPeter Zijlstra 			return ret;
7541f16c575SPeter Zijlstra 	}
7551f16c575SPeter Zijlstra 
7561f16c575SPeter Zijlstra 	if (sync_run)
7571f16c575SPeter Zijlstra 		sync();
7581f16c575SPeter Zijlstra 
7591f16c575SPeter Zijlstra 	ret = __run_perf_stat(argc, argv);
7601f16c575SPeter Zijlstra 	if (ret)
7611f16c575SPeter Zijlstra 		return ret;
7621f16c575SPeter Zijlstra 
7631f16c575SPeter Zijlstra 	if (post_cmd) {
7641f16c575SPeter Zijlstra 		ret = system(post_cmd);
7651f16c575SPeter Zijlstra 		if (ret)
7661f16c575SPeter Zijlstra 			return ret;
7671f16c575SPeter Zijlstra 	}
7681f16c575SPeter Zijlstra 
7691f16c575SPeter Zijlstra 	return ret;
7701f16c575SPeter Zijlstra }
7711f16c575SPeter Zijlstra 
772f99844cbSIngo Molnar static void print_noise_pct(double total, double avg)
773f99844cbSIngo Molnar {
7740007eceaSXiao Guangrong 	double pct = rel_stddev_stats(total, avg);
775f99844cbSIngo Molnar 
7763ae9a34dSZhengyu He 	if (csv_output)
7774aa9015fSStephane Eranian 		fprintf(output, "%s%.2f%%", csv_sep, pct);
778a1bca6ccSJim Cromie 	else if (pct)
7794aa9015fSStephane Eranian 		fprintf(output, "  ( +-%6.2f%% )", pct);
780f99844cbSIngo Molnar }
781f99844cbSIngo Molnar 
78269aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg)
78342202dd5SIngo Molnar {
78469aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps;
78569aad6f1SArnaldo Carvalho de Melo 
786849abde9SPeter Zijlstra 	if (run_count == 1)
787849abde9SPeter Zijlstra 		return;
788849abde9SPeter Zijlstra 
78969aad6f1SArnaldo Carvalho de Melo 	ps = evsel->priv;
790f99844cbSIngo Molnar 	print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
79142202dd5SIngo Molnar }
79242202dd5SIngo Molnar 
79312c08a9fSStephane Eranian static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
79442202dd5SIngo Molnar {
79586ee6e18SStephane Eranian 	switch (aggr_mode) {
79612c08a9fSStephane Eranian 	case AGGR_CORE:
79712c08a9fSStephane Eranian 		fprintf(output, "S%d-C%*d%s%*d%s",
79812c08a9fSStephane Eranian 			cpu_map__id_to_socket(id),
79912c08a9fSStephane Eranian 			csv_output ? 0 : -8,
80012c08a9fSStephane Eranian 			cpu_map__id_to_cpu(id),
80112c08a9fSStephane Eranian 			csv_sep,
80212c08a9fSStephane Eranian 			csv_output ? 0 : 4,
80312c08a9fSStephane Eranian 			nr,
80412c08a9fSStephane Eranian 			csv_sep);
80512c08a9fSStephane Eranian 		break;
80686ee6e18SStephane Eranian 	case AGGR_SOCKET:
80786ee6e18SStephane Eranian 		fprintf(output, "S%*d%s%*d%s",
808d7e7a451SStephane Eranian 			csv_output ? 0 : -5,
80912c08a9fSStephane Eranian 			id,
810d7e7a451SStephane Eranian 			csv_sep,
811d7e7a451SStephane Eranian 			csv_output ? 0 : 4,
812d7e7a451SStephane Eranian 			nr,
813d7e7a451SStephane Eranian 			csv_sep);
81486ee6e18SStephane Eranian 			break;
81586ee6e18SStephane Eranian 	case AGGR_NONE:
81686ee6e18SStephane Eranian 		fprintf(output, "CPU%*d%s",
817d7470b6aSStephane Eranian 			csv_output ? 0 : -4,
81812c08a9fSStephane Eranian 			perf_evsel__cpus(evsel)->map[id], csv_sep);
81986ee6e18SStephane Eranian 		break;
82086ee6e18SStephane Eranian 	case AGGR_GLOBAL:
82186ee6e18SStephane Eranian 	default:
82286ee6e18SStephane Eranian 		break;
82386ee6e18SStephane Eranian 	}
82486ee6e18SStephane Eranian }
825d7470b6aSStephane Eranian 
826da88c7f7SAndi Kleen static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
82786ee6e18SStephane Eranian {
82886ee6e18SStephane Eranian 	double msecs = avg / 1e6;
829410136f5SStephane Eranian 	const char *fmt_v, *fmt_n;
8304bbe5a61SDavid Ahern 	char name[25];
83186ee6e18SStephane Eranian 
832410136f5SStephane Eranian 	fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
833410136f5SStephane Eranian 	fmt_n = csv_output ? "%s" : "%-25s";
834410136f5SStephane Eranian 
835da88c7f7SAndi Kleen 	aggr_printout(evsel, id, nr);
83686ee6e18SStephane Eranian 
8374bbe5a61SDavid Ahern 	scnprintf(name, sizeof(name), "%s%s",
8384bbe5a61SDavid Ahern 		  perf_evsel__name(evsel), csv_output ? "" : " (msec)");
839410136f5SStephane Eranian 
840410136f5SStephane Eranian 	fprintf(output, fmt_v, msecs, csv_sep);
841410136f5SStephane Eranian 
842410136f5SStephane Eranian 	if (csv_output)
843410136f5SStephane Eranian 		fprintf(output, "%s%s", evsel->unit, csv_sep);
844410136f5SStephane Eranian 	else
845410136f5SStephane Eranian 		fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
846410136f5SStephane Eranian 
847410136f5SStephane Eranian 	fprintf(output, fmt_n, name);
848d7470b6aSStephane Eranian 
849023695d9SStephane Eranian 	if (evsel->cgrp)
8504aa9015fSStephane Eranian 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
851023695d9SStephane Eranian 
85213370a9bSStephane Eranian 	if (csv_output || interval)
853d7470b6aSStephane Eranian 		return;
85442202dd5SIngo Molnar 
855daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
8564aa9015fSStephane Eranian 		fprintf(output, " # %8.3f CPUs utilized          ",
8574aa9015fSStephane Eranian 			avg / avg_stats(&walltime_nsecs_stats));
8589dac6a29SNamhyung Kim 	else
8599dac6a29SNamhyung Kim 		fprintf(output, "                                   ");
86042202dd5SIngo Molnar }
86142202dd5SIngo Molnar 
86215e6392fSNamhyung Kim /* used for get_ratio_color() */
86315e6392fSNamhyung Kim enum grc_type {
86415e6392fSNamhyung Kim 	GRC_STALLED_CYCLES_FE,
86515e6392fSNamhyung Kim 	GRC_STALLED_CYCLES_BE,
86615e6392fSNamhyung Kim 	GRC_CACHE_MISSES,
86715e6392fSNamhyung Kim 	GRC_MAX_NR
86815e6392fSNamhyung Kim };
86915e6392fSNamhyung Kim 
87015e6392fSNamhyung Kim static const char *get_ratio_color(enum grc_type type, double ratio)
87115e6392fSNamhyung Kim {
87215e6392fSNamhyung Kim 	static const double grc_table[GRC_MAX_NR][3] = {
87315e6392fSNamhyung Kim 		[GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 },
87415e6392fSNamhyung Kim 		[GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 },
87515e6392fSNamhyung Kim 		[GRC_CACHE_MISSES] 	= { 20.0, 10.0, 5.0 },
87615e6392fSNamhyung Kim 	};
87715e6392fSNamhyung Kim 	const char *color = PERF_COLOR_NORMAL;
87815e6392fSNamhyung Kim 
87915e6392fSNamhyung Kim 	if (ratio > grc_table[type][0])
88015e6392fSNamhyung Kim 		color = PERF_COLOR_RED;
88115e6392fSNamhyung Kim 	else if (ratio > grc_table[type][1])
88215e6392fSNamhyung Kim 		color = PERF_COLOR_MAGENTA;
88315e6392fSNamhyung Kim 	else if (ratio > grc_table[type][2])
88415e6392fSNamhyung Kim 		color = PERF_COLOR_YELLOW;
88515e6392fSNamhyung Kim 
88615e6392fSNamhyung Kim 	return color;
88715e6392fSNamhyung Kim }
88815e6392fSNamhyung Kim 
8891d037ca1SIrina Tirdea static void print_stalled_cycles_frontend(int cpu,
8901d037ca1SIrina Tirdea 					  struct perf_evsel *evsel
8911d037ca1SIrina Tirdea 					  __maybe_unused, double avg)
892d3d1e86dSIngo Molnar {
893d3d1e86dSIngo Molnar 	double total, ratio = 0.0;
894d3d1e86dSIngo Molnar 	const char *color;
895d3d1e86dSIngo Molnar 
896d3d1e86dSIngo Molnar 	total = avg_stats(&runtime_cycles_stats[cpu]);
897d3d1e86dSIngo Molnar 
898d3d1e86dSIngo Molnar 	if (total)
899d3d1e86dSIngo Molnar 		ratio = avg / total * 100.0;
900d3d1e86dSIngo Molnar 
90115e6392fSNamhyung Kim 	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
902d3d1e86dSIngo Molnar 
9034aa9015fSStephane Eranian 	fprintf(output, " #  ");
9044aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
9054aa9015fSStephane Eranian 	fprintf(output, " frontend cycles idle   ");
906d3d1e86dSIngo Molnar }
907d3d1e86dSIngo Molnar 
9081d037ca1SIrina Tirdea static void print_stalled_cycles_backend(int cpu,
9091d037ca1SIrina Tirdea 					 struct perf_evsel *evsel
9101d037ca1SIrina Tirdea 					 __maybe_unused, double avg)
911a5d243d0SIngo Molnar {
912a5d243d0SIngo Molnar 	double total, ratio = 0.0;
913a5d243d0SIngo Molnar 	const char *color;
914a5d243d0SIngo Molnar 
915a5d243d0SIngo Molnar 	total = avg_stats(&runtime_cycles_stats[cpu]);
916a5d243d0SIngo Molnar 
917a5d243d0SIngo Molnar 	if (total)
918a5d243d0SIngo Molnar 		ratio = avg / total * 100.0;
919a5d243d0SIngo Molnar 
92015e6392fSNamhyung Kim 	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
921a5d243d0SIngo Molnar 
9224aa9015fSStephane Eranian 	fprintf(output, " #  ");
9234aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
9244aa9015fSStephane Eranian 	fprintf(output, " backend  cycles idle   ");
925a5d243d0SIngo Molnar }
926a5d243d0SIngo Molnar 
9271d037ca1SIrina Tirdea static void print_branch_misses(int cpu,
9281d037ca1SIrina Tirdea 				struct perf_evsel *evsel __maybe_unused,
9291d037ca1SIrina Tirdea 				double avg)
930c78df6c1SIngo Molnar {
931c78df6c1SIngo Molnar 	double total, ratio = 0.0;
932c78df6c1SIngo Molnar 	const char *color;
933c78df6c1SIngo Molnar 
934c78df6c1SIngo Molnar 	total = avg_stats(&runtime_branches_stats[cpu]);
935c78df6c1SIngo Molnar 
936c78df6c1SIngo Molnar 	if (total)
937c78df6c1SIngo Molnar 		ratio = avg / total * 100.0;
938c78df6c1SIngo Molnar 
93915e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
940c78df6c1SIngo Molnar 
9414aa9015fSStephane Eranian 	fprintf(output, " #  ");
9424aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
9434aa9015fSStephane Eranian 	fprintf(output, " of all branches        ");
944c78df6c1SIngo Molnar }
945c78df6c1SIngo Molnar 
9461d037ca1SIrina Tirdea static void print_l1_dcache_misses(int cpu,
9471d037ca1SIrina Tirdea 				   struct perf_evsel *evsel __maybe_unused,
9481d037ca1SIrina Tirdea 				   double avg)
9498bb6c79fSIngo Molnar {
9508bb6c79fSIngo Molnar 	double total, ratio = 0.0;
9518bb6c79fSIngo Molnar 	const char *color;
9528bb6c79fSIngo Molnar 
9538bb6c79fSIngo Molnar 	total = avg_stats(&runtime_l1_dcache_stats[cpu]);
9548bb6c79fSIngo Molnar 
9558bb6c79fSIngo Molnar 	if (total)
9568bb6c79fSIngo Molnar 		ratio = avg / total * 100.0;
9578bb6c79fSIngo Molnar 
95815e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
9598bb6c79fSIngo Molnar 
9604aa9015fSStephane Eranian 	fprintf(output, " #  ");
9614aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
9624aa9015fSStephane Eranian 	fprintf(output, " of all L1-dcache hits  ");
9638bb6c79fSIngo Molnar }
9648bb6c79fSIngo Molnar 
9651d037ca1SIrina Tirdea static void print_l1_icache_misses(int cpu,
9661d037ca1SIrina Tirdea 				   struct perf_evsel *evsel __maybe_unused,
9671d037ca1SIrina Tirdea 				   double avg)
968c3305257SIngo Molnar {
969c3305257SIngo Molnar 	double total, ratio = 0.0;
970c3305257SIngo Molnar 	const char *color;
971c3305257SIngo Molnar 
972c3305257SIngo Molnar 	total = avg_stats(&runtime_l1_icache_stats[cpu]);
973c3305257SIngo Molnar 
974c3305257SIngo Molnar 	if (total)
975c3305257SIngo Molnar 		ratio = avg / total * 100.0;
976c3305257SIngo Molnar 
97715e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
978c3305257SIngo Molnar 
9794aa9015fSStephane Eranian 	fprintf(output, " #  ");
9804aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
9814aa9015fSStephane Eranian 	fprintf(output, " of all L1-icache hits  ");
982c3305257SIngo Molnar }
983c3305257SIngo Molnar 
9841d037ca1SIrina Tirdea static void print_dtlb_cache_misses(int cpu,
9851d037ca1SIrina Tirdea 				    struct perf_evsel *evsel __maybe_unused,
9861d037ca1SIrina Tirdea 				    double avg)
987c3305257SIngo Molnar {
988c3305257SIngo Molnar 	double total, ratio = 0.0;
989c3305257SIngo Molnar 	const char *color;
990c3305257SIngo Molnar 
991c3305257SIngo Molnar 	total = avg_stats(&runtime_dtlb_cache_stats[cpu]);
992c3305257SIngo Molnar 
993c3305257SIngo Molnar 	if (total)
994c3305257SIngo Molnar 		ratio = avg / total * 100.0;
995c3305257SIngo Molnar 
99615e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
997c3305257SIngo Molnar 
9984aa9015fSStephane Eranian 	fprintf(output, " #  ");
9994aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
10004aa9015fSStephane Eranian 	fprintf(output, " of all dTLB cache hits ");
1001c3305257SIngo Molnar }
1002c3305257SIngo Molnar 
10031d037ca1SIrina Tirdea static void print_itlb_cache_misses(int cpu,
10041d037ca1SIrina Tirdea 				    struct perf_evsel *evsel __maybe_unused,
10051d037ca1SIrina Tirdea 				    double avg)
1006c3305257SIngo Molnar {
1007c3305257SIngo Molnar 	double total, ratio = 0.0;
1008c3305257SIngo Molnar 	const char *color;
1009c3305257SIngo Molnar 
1010c3305257SIngo Molnar 	total = avg_stats(&runtime_itlb_cache_stats[cpu]);
1011c3305257SIngo Molnar 
1012c3305257SIngo Molnar 	if (total)
1013c3305257SIngo Molnar 		ratio = avg / total * 100.0;
1014c3305257SIngo Molnar 
101515e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
1016c3305257SIngo Molnar 
10174aa9015fSStephane Eranian 	fprintf(output, " #  ");
10184aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
10194aa9015fSStephane Eranian 	fprintf(output, " of all iTLB cache hits ");
1020c3305257SIngo Molnar }
1021c3305257SIngo Molnar 
10221d037ca1SIrina Tirdea static void print_ll_cache_misses(int cpu,
10231d037ca1SIrina Tirdea 				  struct perf_evsel *evsel __maybe_unused,
10241d037ca1SIrina Tirdea 				  double avg)
1025c3305257SIngo Molnar {
1026c3305257SIngo Molnar 	double total, ratio = 0.0;
1027c3305257SIngo Molnar 	const char *color;
1028c3305257SIngo Molnar 
1029c3305257SIngo Molnar 	total = avg_stats(&runtime_ll_cache_stats[cpu]);
1030c3305257SIngo Molnar 
1031c3305257SIngo Molnar 	if (total)
1032c3305257SIngo Molnar 		ratio = avg / total * 100.0;
1033c3305257SIngo Molnar 
103415e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
1035c3305257SIngo Molnar 
10364aa9015fSStephane Eranian 	fprintf(output, " #  ");
10374aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
10384aa9015fSStephane Eranian 	fprintf(output, " of all LL-cache hits   ");
1039c3305257SIngo Molnar }
1040c3305257SIngo Molnar 
1041da88c7f7SAndi Kleen static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
104242202dd5SIngo Molnar {
10434cabc3d1SAndi Kleen 	double total, ratio = 0.0, total2;
1044410136f5SStephane Eranian 	double sc =  evsel->scale;
1045d7470b6aSStephane Eranian 	const char *fmt;
1046da88c7f7SAndi Kleen 	int cpu = cpu_map__id_to_cpu(id);
1047d7470b6aSStephane Eranian 
1048410136f5SStephane Eranian 	if (csv_output) {
1049410136f5SStephane Eranian 		fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
1050410136f5SStephane Eranian 	} else {
1051410136f5SStephane Eranian 		if (big_num)
1052410136f5SStephane Eranian 			fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
1053d7470b6aSStephane Eranian 		else
1054410136f5SStephane Eranian 			fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
1055410136f5SStephane Eranian 	}
1056f5b4a9c3SStephane Eranian 
1057da88c7f7SAndi Kleen 	aggr_printout(evsel, id, nr);
105886ee6e18SStephane Eranian 
105986ee6e18SStephane Eranian 	if (aggr_mode == AGGR_GLOBAL)
1060f5b4a9c3SStephane Eranian 		cpu = 0;
1061c7f7fea3SIngo Molnar 
1062410136f5SStephane Eranian 	fprintf(output, fmt, avg, csv_sep);
1063410136f5SStephane Eranian 
1064410136f5SStephane Eranian 	if (evsel->unit)
1065410136f5SStephane Eranian 		fprintf(output, "%-*s%s",
1066410136f5SStephane Eranian 			csv_output ? 0 : unit_width,
1067410136f5SStephane Eranian 			evsel->unit, csv_sep);
1068410136f5SStephane Eranian 
1069410136f5SStephane Eranian 	fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
1070d7470b6aSStephane Eranian 
1071023695d9SStephane Eranian 	if (evsel->cgrp)
10724aa9015fSStephane Eranian 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
1073023695d9SStephane Eranian 
107413370a9bSStephane Eranian 	if (csv_output || interval)
1075d7470b6aSStephane Eranian 		return;
107642202dd5SIngo Molnar 
1077daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
1078f5b4a9c3SStephane Eranian 		total = avg_stats(&runtime_cycles_stats[cpu]);
10793e7a0817SRamkumar Ramachandra 		if (total) {
1080c7f7fea3SIngo Molnar 			ratio = avg / total;
10814aa9015fSStephane Eranian 			fprintf(output, " #   %5.2f  insns per cycle        ", ratio);
10823e7a0817SRamkumar Ramachandra 		}
1083d3d1e86dSIngo Molnar 		total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
1084d3d1e86dSIngo Molnar 		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
1085481f988aSIngo Molnar 
1086481f988aSIngo Molnar 		if (total && avg) {
1087481f988aSIngo Molnar 			ratio = total / avg;
1088410136f5SStephane Eranian 			fprintf(output, "\n");
1089410136f5SStephane Eranian 			if (aggr_mode == AGGR_NONE)
1090410136f5SStephane Eranian 				fprintf(output, "        ");
1091410136f5SStephane Eranian 			fprintf(output, "                                                  #   %5.2f  stalled cycles per insn", ratio);
1092481f988aSIngo Molnar 		}
1093481f988aSIngo Molnar 
1094daec78a0SArnaldo Carvalho de Melo 	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
1095f5b4a9c3SStephane Eranian 			runtime_branches_stats[cpu].n != 0) {
1096c78df6c1SIngo Molnar 		print_branch_misses(cpu, evsel, avg);
10978bb6c79fSIngo Molnar 	} else if (
10988bb6c79fSIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
10998bb6c79fSIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
11008bb6c79fSIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
11018bb6c79fSIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
1102c6264defSIngo Molnar 			runtime_l1_dcache_stats[cpu].n != 0) {
11038bb6c79fSIngo Molnar 		print_l1_dcache_misses(cpu, evsel, avg);
1104c3305257SIngo Molnar 	} else if (
1105c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
1106c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
1107c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
1108c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
1109c3305257SIngo Molnar 			runtime_l1_icache_stats[cpu].n != 0) {
1110c3305257SIngo Molnar 		print_l1_icache_misses(cpu, evsel, avg);
1111c3305257SIngo Molnar 	} else if (
1112c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
1113c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
1114c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
1115c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
1116c3305257SIngo Molnar 			runtime_dtlb_cache_stats[cpu].n != 0) {
1117c3305257SIngo Molnar 		print_dtlb_cache_misses(cpu, evsel, avg);
1118c3305257SIngo Molnar 	} else if (
1119c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
1120c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
1121c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
1122c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
1123c3305257SIngo Molnar 			runtime_itlb_cache_stats[cpu].n != 0) {
1124c3305257SIngo Molnar 		print_itlb_cache_misses(cpu, evsel, avg);
1125c3305257SIngo Molnar 	} else if (
1126c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
1127c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
1128c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
1129c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
1130c3305257SIngo Molnar 			runtime_ll_cache_stats[cpu].n != 0) {
1131c3305257SIngo Molnar 		print_ll_cache_misses(cpu, evsel, avg);
1132d58f4c82SIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
1133d58f4c82SIngo Molnar 			runtime_cacherefs_stats[cpu].n != 0) {
1134d58f4c82SIngo Molnar 		total = avg_stats(&runtime_cacherefs_stats[cpu]);
1135d58f4c82SIngo Molnar 
1136d58f4c82SIngo Molnar 		if (total)
1137d58f4c82SIngo Molnar 			ratio = avg * 100 / total;
1138d58f4c82SIngo Molnar 
11394aa9015fSStephane Eranian 		fprintf(output, " # %8.3f %% of all cache refs    ", ratio);
1140d58f4c82SIngo Molnar 
1141d3d1e86dSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
1142d3d1e86dSIngo Molnar 		print_stalled_cycles_frontend(cpu, evsel, avg);
1143129c04cbSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
1144d3d1e86dSIngo Molnar 		print_stalled_cycles_backend(cpu, evsel, avg);
1145481f988aSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
1146481f988aSIngo Molnar 		total = avg_stats(&runtime_nsecs_stats[cpu]);
1147481f988aSIngo Molnar 
1148c458fe62SRamkumar Ramachandra 		if (total) {
1149c458fe62SRamkumar Ramachandra 			ratio = avg / total;
11504aa9015fSStephane Eranian 			fprintf(output, " # %8.3f GHz                    ", ratio);
1151c458fe62SRamkumar Ramachandra 		}
11524cabc3d1SAndi Kleen 	} else if (transaction_run &&
11534cabc3d1SAndi Kleen 		   perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) {
11544cabc3d1SAndi Kleen 		total = avg_stats(&runtime_cycles_stats[cpu]);
11554cabc3d1SAndi Kleen 		if (total)
11564cabc3d1SAndi Kleen 			fprintf(output,
11574cabc3d1SAndi Kleen 				" #   %5.2f%% transactional cycles   ",
11584cabc3d1SAndi Kleen 				100.0 * (avg / total));
11594cabc3d1SAndi Kleen 	} else if (transaction_run &&
11604cabc3d1SAndi Kleen 		   perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX_CP))) {
11614cabc3d1SAndi Kleen 		total = avg_stats(&runtime_cycles_stats[cpu]);
11624cabc3d1SAndi Kleen 		total2 = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
11634cabc3d1SAndi Kleen 		if (total2 < avg)
11644cabc3d1SAndi Kleen 			total2 = avg;
11654cabc3d1SAndi Kleen 		if (total)
11664cabc3d1SAndi Kleen 			fprintf(output,
11674cabc3d1SAndi Kleen 				" #   %5.2f%% aborted cycles         ",
11684cabc3d1SAndi Kleen 				100.0 * ((total2-avg) / total));
11694cabc3d1SAndi Kleen 	} else if (transaction_run &&
11704cabc3d1SAndi Kleen 		   perf_evsel__cmp(evsel, nth_evsel(T_TRANSACTION_START)) &&
11714cabc3d1SAndi Kleen 		   avg > 0 &&
11724cabc3d1SAndi Kleen 		   runtime_cycles_in_tx_stats[cpu].n != 0) {
11734cabc3d1SAndi Kleen 		total = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
11744cabc3d1SAndi Kleen 
11754cabc3d1SAndi Kleen 		if (total)
11764cabc3d1SAndi Kleen 			ratio = total / avg;
11774cabc3d1SAndi Kleen 
11784cabc3d1SAndi Kleen 		fprintf(output, " # %8.0f cycles / transaction   ", ratio);
11794cabc3d1SAndi Kleen 	} else if (transaction_run &&
11804cabc3d1SAndi Kleen 		   perf_evsel__cmp(evsel, nth_evsel(T_ELISION_START)) &&
11814cabc3d1SAndi Kleen 		   avg > 0 &&
11824cabc3d1SAndi Kleen 		   runtime_cycles_in_tx_stats[cpu].n != 0) {
11834cabc3d1SAndi Kleen 		total = avg_stats(&runtime_cycles_in_tx_stats[cpu]);
11844cabc3d1SAndi Kleen 
11854cabc3d1SAndi Kleen 		if (total)
11864cabc3d1SAndi Kleen 			ratio = total / avg;
11874cabc3d1SAndi Kleen 
11884cabc3d1SAndi Kleen 		fprintf(output, " # %8.0f cycles / elision       ", ratio);
1189481f988aSIngo Molnar 	} else if (runtime_nsecs_stats[cpu].n != 0) {
11905fde2523SNamhyung Kim 		char unit = 'M';
11915fde2523SNamhyung Kim 
1192481f988aSIngo Molnar 		total = avg_stats(&runtime_nsecs_stats[cpu]);
1193481f988aSIngo Molnar 
1194481f988aSIngo Molnar 		if (total)
1195481f988aSIngo Molnar 			ratio = 1000.0 * avg / total;
11965fde2523SNamhyung Kim 		if (ratio < 0.001) {
11975fde2523SNamhyung Kim 			ratio *= 1000;
11985fde2523SNamhyung Kim 			unit = 'K';
11995fde2523SNamhyung Kim 		}
1200481f988aSIngo Molnar 
12015fde2523SNamhyung Kim 		fprintf(output, " # %8.3f %c/sec                  ", ratio, unit);
1202a5d243d0SIngo Molnar 	} else {
12034aa9015fSStephane Eranian 		fprintf(output, "                                   ");
120442202dd5SIngo Molnar 	}
120542202dd5SIngo Molnar }
120642202dd5SIngo Molnar 
120786ee6e18SStephane Eranian static void print_aggr(char *prefix)
1208d7e7a451SStephane Eranian {
1209d7e7a451SStephane Eranian 	struct perf_evsel *counter;
1210582ec082SStephane Eranian 	int cpu, cpu2, s, s2, id, nr;
1211410136f5SStephane Eranian 	double uval;
1212d7e7a451SStephane Eranian 	u64 ena, run, val;
1213d7e7a451SStephane Eranian 
121486ee6e18SStephane Eranian 	if (!(aggr_map || aggr_get_id))
1215d7e7a451SStephane Eranian 		return;
1216d7e7a451SStephane Eranian 
121786ee6e18SStephane Eranian 	for (s = 0; s < aggr_map->nr; s++) {
121886ee6e18SStephane Eranian 		id = aggr_map->map[s];
12190050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
1220d7e7a451SStephane Eranian 			val = ena = run = 0;
1221d7e7a451SStephane Eranian 			nr = 0;
1222d7e7a451SStephane Eranian 			for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1223582ec082SStephane Eranian 				cpu2 = perf_evsel__cpus(counter)->map[cpu];
1224582ec082SStephane Eranian 				s2 = aggr_get_id(evsel_list->cpus, cpu2);
122586ee6e18SStephane Eranian 				if (s2 != id)
1226d7e7a451SStephane Eranian 					continue;
1227d7e7a451SStephane Eranian 				val += counter->counts->cpu[cpu].val;
1228d7e7a451SStephane Eranian 				ena += counter->counts->cpu[cpu].ena;
1229d7e7a451SStephane Eranian 				run += counter->counts->cpu[cpu].run;
1230d7e7a451SStephane Eranian 				nr++;
1231d7e7a451SStephane Eranian 			}
1232d7e7a451SStephane Eranian 			if (prefix)
1233d7e7a451SStephane Eranian 				fprintf(output, "%s", prefix);
1234d7e7a451SStephane Eranian 
1235d7e7a451SStephane Eranian 			if (run == 0 || ena == 0) {
1236582ec082SStephane Eranian 				aggr_printout(counter, id, nr);
123786ee6e18SStephane Eranian 
1238410136f5SStephane Eranian 				fprintf(output, "%*s%s",
1239d7e7a451SStephane Eranian 					csv_output ? 0 : 18,
1240d7e7a451SStephane Eranian 					counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
1241410136f5SStephane Eranian 					csv_sep);
1242410136f5SStephane Eranian 
1243410136f5SStephane Eranian 				fprintf(output, "%-*s%s",
1244410136f5SStephane Eranian 					csv_output ? 0 : unit_width,
1245410136f5SStephane Eranian 					counter->unit, csv_sep);
1246410136f5SStephane Eranian 
1247410136f5SStephane Eranian 				fprintf(output, "%*s",
1248410136f5SStephane Eranian 					csv_output ? 0 : -25,
1249d7e7a451SStephane Eranian 					perf_evsel__name(counter));
125086ee6e18SStephane Eranian 
1251d7e7a451SStephane Eranian 				if (counter->cgrp)
1252d7e7a451SStephane Eranian 					fprintf(output, "%s%s",
1253d7e7a451SStephane Eranian 						csv_sep, counter->cgrp->name);
1254d7e7a451SStephane Eranian 
1255d7e7a451SStephane Eranian 				fputc('\n', output);
1256d7e7a451SStephane Eranian 				continue;
1257d7e7a451SStephane Eranian 			}
1258410136f5SStephane Eranian 			uval = val * counter->scale;
1259d7e7a451SStephane Eranian 
1260d7e7a451SStephane Eranian 			if (nsec_counter(counter))
1261410136f5SStephane Eranian 				nsec_printout(id, nr, counter, uval);
1262d7e7a451SStephane Eranian 			else
1263410136f5SStephane Eranian 				abs_printout(id, nr, counter, uval);
1264d7e7a451SStephane Eranian 
1265d7e7a451SStephane Eranian 			if (!csv_output) {
1266d7e7a451SStephane Eranian 				print_noise(counter, 1.0);
1267d7e7a451SStephane Eranian 
1268d7e7a451SStephane Eranian 				if (run != ena)
1269d7e7a451SStephane Eranian 					fprintf(output, "  (%.2f%%)",
1270d7e7a451SStephane Eranian 						100.0 * run / ena);
1271d7e7a451SStephane Eranian 			}
1272d7e7a451SStephane Eranian 			fputc('\n', output);
1273d7e7a451SStephane Eranian 		}
1274d7e7a451SStephane Eranian 	}
1275d7e7a451SStephane Eranian }
1276d7e7a451SStephane Eranian 
127742202dd5SIngo Molnar /*
127842202dd5SIngo Molnar  * Print out the results of a single counter:
1279f5b4a9c3SStephane Eranian  * aggregated counts in system-wide mode
128042202dd5SIngo Molnar  */
128113370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
128242202dd5SIngo Molnar {
128369aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps = counter->priv;
128469aad6f1SArnaldo Carvalho de Melo 	double avg = avg_stats(&ps->res_stats[0]);
1285c52b12edSArnaldo Carvalho de Melo 	int scaled = counter->counts->scaled;
1286410136f5SStephane Eranian 	double uval;
128742202dd5SIngo Molnar 
128813370a9bSStephane Eranian 	if (prefix)
128913370a9bSStephane Eranian 		fprintf(output, "%s", prefix);
129013370a9bSStephane Eranian 
12913b4331d9SSuzuki K. Poulose 	if (scaled == -1 || !counter->supported) {
1292410136f5SStephane Eranian 		fprintf(output, "%*s%s",
1293d7470b6aSStephane Eranian 			csv_output ? 0 : 18,
12942cee77c4SDavid Ahern 			counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
1295410136f5SStephane Eranian 			csv_sep);
1296410136f5SStephane Eranian 		fprintf(output, "%-*s%s",
1297410136f5SStephane Eranian 			csv_output ? 0 : unit_width,
1298410136f5SStephane Eranian 			counter->unit, csv_sep);
1299410136f5SStephane Eranian 		fprintf(output, "%*s",
1300410136f5SStephane Eranian 			csv_output ? 0 : -25,
13017289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter));
1302023695d9SStephane Eranian 
1303023695d9SStephane Eranian 		if (counter->cgrp)
13044aa9015fSStephane Eranian 			fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
1305023695d9SStephane Eranian 
13064aa9015fSStephane Eranian 		fputc('\n', output);
130742202dd5SIngo Molnar 		return;
130842202dd5SIngo Molnar 	}
130942202dd5SIngo Molnar 
1310410136f5SStephane Eranian 	uval = avg * counter->scale;
1311410136f5SStephane Eranian 
131242202dd5SIngo Molnar 	if (nsec_counter(counter))
1313410136f5SStephane Eranian 		nsec_printout(-1, 0, counter, uval);
131442202dd5SIngo Molnar 	else
1315410136f5SStephane Eranian 		abs_printout(-1, 0, counter, uval);
1316849abde9SPeter Zijlstra 
13173ae9a34dSZhengyu He 	print_noise(counter, avg);
13183ae9a34dSZhengyu He 
1319d7470b6aSStephane Eranian 	if (csv_output) {
13204aa9015fSStephane Eranian 		fputc('\n', output);
1321d7470b6aSStephane Eranian 		return;
1322d7470b6aSStephane Eranian 	}
1323d7470b6aSStephane Eranian 
1324506d4bc8SPeter Zijlstra 	if (scaled) {
1325506d4bc8SPeter Zijlstra 		double avg_enabled, avg_running;
1326506d4bc8SPeter Zijlstra 
132769aad6f1SArnaldo Carvalho de Melo 		avg_enabled = avg_stats(&ps->res_stats[1]);
132869aad6f1SArnaldo Carvalho de Melo 		avg_running = avg_stats(&ps->res_stats[2]);
1329506d4bc8SPeter Zijlstra 
13304aa9015fSStephane Eranian 		fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled);
1331506d4bc8SPeter Zijlstra 	}
13324aa9015fSStephane Eranian 	fprintf(output, "\n");
133342202dd5SIngo Molnar }
133442202dd5SIngo Molnar 
1335f5b4a9c3SStephane Eranian /*
1336f5b4a9c3SStephane Eranian  * Print out the results of a single counter:
1337f5b4a9c3SStephane Eranian  * does not use aggregated count in system-wide
1338f5b4a9c3SStephane Eranian  */
133913370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix)
1340f5b4a9c3SStephane Eranian {
1341f5b4a9c3SStephane Eranian 	u64 ena, run, val;
1342410136f5SStephane Eranian 	double uval;
1343f5b4a9c3SStephane Eranian 	int cpu;
1344f5b4a9c3SStephane Eranian 
13457ae92e74SYan, Zheng 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1346c52b12edSArnaldo Carvalho de Melo 		val = counter->counts->cpu[cpu].val;
1347c52b12edSArnaldo Carvalho de Melo 		ena = counter->counts->cpu[cpu].ena;
1348c52b12edSArnaldo Carvalho de Melo 		run = counter->counts->cpu[cpu].run;
134913370a9bSStephane Eranian 
135013370a9bSStephane Eranian 		if (prefix)
135113370a9bSStephane Eranian 			fprintf(output, "%s", prefix);
135213370a9bSStephane Eranian 
1353f5b4a9c3SStephane Eranian 		if (run == 0 || ena == 0) {
1354410136f5SStephane Eranian 			fprintf(output, "CPU%*d%s%*s%s",
1355d7470b6aSStephane Eranian 				csv_output ? 0 : -4,
13567ae92e74SYan, Zheng 				perf_evsel__cpus(counter)->map[cpu], csv_sep,
1357d7470b6aSStephane Eranian 				csv_output ? 0 : 18,
13582cee77c4SDavid Ahern 				counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
1359410136f5SStephane Eranian 				csv_sep);
1360410136f5SStephane Eranian 
1361410136f5SStephane Eranian 				fprintf(output, "%-*s%s",
1362410136f5SStephane Eranian 					csv_output ? 0 : unit_width,
1363410136f5SStephane Eranian 					counter->unit, csv_sep);
1364410136f5SStephane Eranian 
1365410136f5SStephane Eranian 				fprintf(output, "%*s",
1366410136f5SStephane Eranian 					csv_output ? 0 : -25,
13677289f83cSArnaldo Carvalho de Melo 					perf_evsel__name(counter));
1368f5b4a9c3SStephane Eranian 
1369023695d9SStephane Eranian 			if (counter->cgrp)
13704aa9015fSStephane Eranian 				fprintf(output, "%s%s",
13714aa9015fSStephane Eranian 					csv_sep, counter->cgrp->name);
1372023695d9SStephane Eranian 
13734aa9015fSStephane Eranian 			fputc('\n', output);
1374f5b4a9c3SStephane Eranian 			continue;
1375f5b4a9c3SStephane Eranian 		}
1376f5b4a9c3SStephane Eranian 
1377410136f5SStephane Eranian 		uval = val * counter->scale;
1378410136f5SStephane Eranian 
1379f5b4a9c3SStephane Eranian 		if (nsec_counter(counter))
1380410136f5SStephane Eranian 			nsec_printout(cpu, 0, counter, uval);
1381f5b4a9c3SStephane Eranian 		else
1382410136f5SStephane Eranian 			abs_printout(cpu, 0, counter, uval);
1383f5b4a9c3SStephane Eranian 
1384d7470b6aSStephane Eranian 		if (!csv_output) {
1385f5b4a9c3SStephane Eranian 			print_noise(counter, 1.0);
1386f5b4a9c3SStephane Eranian 
1387c6264defSIngo Molnar 			if (run != ena)
13884aa9015fSStephane Eranian 				fprintf(output, "  (%.2f%%)",
13894aa9015fSStephane Eranian 					100.0 * run / ena);
1390d7470b6aSStephane Eranian 		}
13914aa9015fSStephane Eranian 		fputc('\n', output);
1392f5b4a9c3SStephane Eranian 	}
1393f5b4a9c3SStephane Eranian }
1394f5b4a9c3SStephane Eranian 
139542202dd5SIngo Molnar static void print_stat(int argc, const char **argv)
139642202dd5SIngo Molnar {
139769aad6f1SArnaldo Carvalho de Melo 	struct perf_evsel *counter;
139869aad6f1SArnaldo Carvalho de Melo 	int i;
139942202dd5SIngo Molnar 
140086470930SIngo Molnar 	fflush(stdout);
140186470930SIngo Molnar 
1402d7470b6aSStephane Eranian 	if (!csv_output) {
14034aa9015fSStephane Eranian 		fprintf(output, "\n");
14044aa9015fSStephane Eranian 		fprintf(output, " Performance counter stats for ");
140562d3b617SDavid Ahern 		if (target.system_wide)
140662d3b617SDavid Ahern 			fprintf(output, "\'system wide");
140762d3b617SDavid Ahern 		else if (target.cpu_list)
140862d3b617SDavid Ahern 			fprintf(output, "\'CPU(s) %s", target.cpu_list);
1409602ad878SArnaldo Carvalho de Melo 		else if (!target__has_task(&target)) {
14104aa9015fSStephane Eranian 			fprintf(output, "\'%s", argv[0]);
141186470930SIngo Molnar 			for (i = 1; i < argc; i++)
14124aa9015fSStephane Eranian 				fprintf(output, " %s", argv[i]);
141320f946b4SNamhyung Kim 		} else if (target.pid)
141420f946b4SNamhyung Kim 			fprintf(output, "process id \'%s", target.pid);
1415d6d901c2SZhang, Yanmin 		else
141620f946b4SNamhyung Kim 			fprintf(output, "thread id \'%s", target.tid);
141786470930SIngo Molnar 
14184aa9015fSStephane Eranian 		fprintf(output, "\'");
141942202dd5SIngo Molnar 		if (run_count > 1)
14204aa9015fSStephane Eranian 			fprintf(output, " (%d runs)", run_count);
14214aa9015fSStephane Eranian 		fprintf(output, ":\n\n");
1422d7470b6aSStephane Eranian 	}
142386470930SIngo Molnar 
142486ee6e18SStephane Eranian 	switch (aggr_mode) {
142512c08a9fSStephane Eranian 	case AGGR_CORE:
142686ee6e18SStephane Eranian 	case AGGR_SOCKET:
142786ee6e18SStephane Eranian 		print_aggr(NULL);
142886ee6e18SStephane Eranian 		break;
142986ee6e18SStephane Eranian 	case AGGR_GLOBAL:
14300050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
143113370a9bSStephane Eranian 			print_counter_aggr(counter, NULL);
143286ee6e18SStephane Eranian 		break;
143386ee6e18SStephane Eranian 	case AGGR_NONE:
14340050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
143586ee6e18SStephane Eranian 			print_counter(counter, NULL);
143686ee6e18SStephane Eranian 		break;
143786ee6e18SStephane Eranian 	default:
143886ee6e18SStephane Eranian 		break;
1439f5b4a9c3SStephane Eranian 	}
144086470930SIngo Molnar 
1441d7470b6aSStephane Eranian 	if (!csv_output) {
1442c3305257SIngo Molnar 		if (!null_run)
14434aa9015fSStephane Eranian 			fprintf(output, "\n");
14444aa9015fSStephane Eranian 		fprintf(output, " %17.9f seconds time elapsed",
1445506d4bc8SPeter Zijlstra 				avg_stats(&walltime_nsecs_stats)/1e9);
1446566747e6SIngo Molnar 		if (run_count > 1) {
14474aa9015fSStephane Eranian 			fprintf(output, "                                        ");
1448f99844cbSIngo Molnar 			print_noise_pct(stddev_stats(&walltime_nsecs_stats),
1449506d4bc8SPeter Zijlstra 					avg_stats(&walltime_nsecs_stats));
1450566747e6SIngo Molnar 		}
14514aa9015fSStephane Eranian 		fprintf(output, "\n\n");
145286470930SIngo Molnar 	}
1453d7470b6aSStephane Eranian }
145486470930SIngo Molnar 
1455f7b7c26eSPeter Zijlstra static volatile int signr = -1;
1456f7b7c26eSPeter Zijlstra 
145786470930SIngo Molnar static void skip_signal(int signo)
145886470930SIngo Molnar {
145913370a9bSStephane Eranian 	if ((child_pid == -1) || interval)
146060666c63SLiming Wang 		done = 1;
146160666c63SLiming Wang 
1462f7b7c26eSPeter Zijlstra 	signr = signo;
1463d07f0b12SStephane Eranian 	/*
1464d07f0b12SStephane Eranian 	 * render child_pid harmless
1465d07f0b12SStephane Eranian 	 * won't send SIGTERM to a random
1466d07f0b12SStephane Eranian 	 * process in case of race condition
1467d07f0b12SStephane Eranian 	 * and fast PID recycling
1468d07f0b12SStephane Eranian 	 */
1469d07f0b12SStephane Eranian 	child_pid = -1;
1470f7b7c26eSPeter Zijlstra }
1471f7b7c26eSPeter Zijlstra 
1472f7b7c26eSPeter Zijlstra static void sig_atexit(void)
1473f7b7c26eSPeter Zijlstra {
1474d07f0b12SStephane Eranian 	sigset_t set, oset;
1475d07f0b12SStephane Eranian 
1476d07f0b12SStephane Eranian 	/*
1477d07f0b12SStephane Eranian 	 * avoid race condition with SIGCHLD handler
1478d07f0b12SStephane Eranian 	 * in skip_signal() which is modifying child_pid
1479d07f0b12SStephane Eranian 	 * goal is to avoid send SIGTERM to a random
1480d07f0b12SStephane Eranian 	 * process
1481d07f0b12SStephane Eranian 	 */
1482d07f0b12SStephane Eranian 	sigemptyset(&set);
1483d07f0b12SStephane Eranian 	sigaddset(&set, SIGCHLD);
1484d07f0b12SStephane Eranian 	sigprocmask(SIG_BLOCK, &set, &oset);
1485d07f0b12SStephane Eranian 
1486933da83aSChris Wilson 	if (child_pid != -1)
1487933da83aSChris Wilson 		kill(child_pid, SIGTERM);
1488933da83aSChris Wilson 
1489d07f0b12SStephane Eranian 	sigprocmask(SIG_SETMASK, &oset, NULL);
1490d07f0b12SStephane Eranian 
1491f7b7c26eSPeter Zijlstra 	if (signr == -1)
1492f7b7c26eSPeter Zijlstra 		return;
1493f7b7c26eSPeter Zijlstra 
1494f7b7c26eSPeter Zijlstra 	signal(signr, SIG_DFL);
1495f7b7c26eSPeter Zijlstra 	kill(getpid(), signr);
149686470930SIngo Molnar }
149786470930SIngo Molnar 
14981d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused,
14991d037ca1SIrina Tirdea 			     const char *s __maybe_unused, int unset)
1500d7470b6aSStephane Eranian {
1501d7470b6aSStephane Eranian 	big_num_opt = unset ? 0 : 1;
1502d7470b6aSStephane Eranian 	return 0;
1503d7470b6aSStephane Eranian }
1504d7470b6aSStephane Eranian 
150586ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void)
150686ee6e18SStephane Eranian {
150786ee6e18SStephane Eranian 	switch (aggr_mode) {
150886ee6e18SStephane Eranian 	case AGGR_SOCKET:
150986ee6e18SStephane Eranian 		if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
151086ee6e18SStephane Eranian 			perror("cannot build socket map");
151186ee6e18SStephane Eranian 			return -1;
151286ee6e18SStephane Eranian 		}
151386ee6e18SStephane Eranian 		aggr_get_id = cpu_map__get_socket;
151486ee6e18SStephane Eranian 		break;
151512c08a9fSStephane Eranian 	case AGGR_CORE:
151612c08a9fSStephane Eranian 		if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
151712c08a9fSStephane Eranian 			perror("cannot build core map");
151812c08a9fSStephane Eranian 			return -1;
151912c08a9fSStephane Eranian 		}
152012c08a9fSStephane Eranian 		aggr_get_id = cpu_map__get_core;
152112c08a9fSStephane Eranian 		break;
152286ee6e18SStephane Eranian 	case AGGR_NONE:
152386ee6e18SStephane Eranian 	case AGGR_GLOBAL:
152486ee6e18SStephane Eranian 	default:
152586ee6e18SStephane Eranian 		break;
152686ee6e18SStephane Eranian 	}
152786ee6e18SStephane Eranian 	return 0;
152886ee6e18SStephane Eranian }
152986ee6e18SStephane Eranian 
15304cabc3d1SAndi Kleen static int setup_events(const char * const *attrs, unsigned len)
15314cabc3d1SAndi Kleen {
15324cabc3d1SAndi Kleen 	unsigned i;
15334cabc3d1SAndi Kleen 
15344cabc3d1SAndi Kleen 	for (i = 0; i < len; i++) {
15354cabc3d1SAndi Kleen 		if (parse_events(evsel_list, attrs[i]))
15364cabc3d1SAndi Kleen 			return -1;
15374cabc3d1SAndi Kleen 	}
15384cabc3d1SAndi Kleen 	return 0;
15394cabc3d1SAndi Kleen }
154086ee6e18SStephane Eranian 
15412cba3ffbSIngo Molnar /*
15422cba3ffbSIngo Molnar  * Add default attributes, if there were no attributes specified or
15432cba3ffbSIngo Molnar  * if -d/--detailed, -d -d or -d -d -d is used:
15442cba3ffbSIngo Molnar  */
15452cba3ffbSIngo Molnar static int add_default_attributes(void)
15462cba3ffbSIngo Molnar {
1547b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr default_attrs[] = {
1548b070a547SArnaldo Carvalho de Melo 
1549b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
1550b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
1551b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
1552b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
1553b070a547SArnaldo Carvalho de Melo 
1554b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
1555b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
1556b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
1557b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
1558b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
1559b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
1560b070a547SArnaldo Carvalho de Melo 
1561b070a547SArnaldo Carvalho de Melo };
1562b070a547SArnaldo Carvalho de Melo 
1563b070a547SArnaldo Carvalho de Melo /*
1564b070a547SArnaldo Carvalho de Melo  * Detailed stats (-d), covering the L1 and last level data caches:
1565b070a547SArnaldo Carvalho de Melo  */
1566b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr detailed_attrs[] = {
1567b070a547SArnaldo Carvalho de Melo 
1568b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1569b070a547SArnaldo Carvalho de Melo     .config =
1570b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1571b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1572b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1573b070a547SArnaldo Carvalho de Melo 
1574b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1575b070a547SArnaldo Carvalho de Melo     .config =
1576b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1577b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1578b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1579b070a547SArnaldo Carvalho de Melo 
1580b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1581b070a547SArnaldo Carvalho de Melo     .config =
1582b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1583b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1584b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1585b070a547SArnaldo Carvalho de Melo 
1586b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1587b070a547SArnaldo Carvalho de Melo     .config =
1588b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1589b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1590b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1591b070a547SArnaldo Carvalho de Melo };
1592b070a547SArnaldo Carvalho de Melo 
1593b070a547SArnaldo Carvalho de Melo /*
1594b070a547SArnaldo Carvalho de Melo  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1595b070a547SArnaldo Carvalho de Melo  */
1596b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_detailed_attrs[] = {
1597b070a547SArnaldo Carvalho de Melo 
1598b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1599b070a547SArnaldo Carvalho de Melo     .config =
1600b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1601b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1602b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1603b070a547SArnaldo Carvalho de Melo 
1604b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1605b070a547SArnaldo Carvalho de Melo     .config =
1606b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1607b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1608b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1609b070a547SArnaldo Carvalho de Melo 
1610b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1611b070a547SArnaldo Carvalho de Melo     .config =
1612b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1613b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1614b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1615b070a547SArnaldo Carvalho de Melo 
1616b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1617b070a547SArnaldo Carvalho de Melo     .config =
1618b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1619b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1620b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1621b070a547SArnaldo Carvalho de Melo 
1622b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1623b070a547SArnaldo Carvalho de Melo     .config =
1624b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1625b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1626b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1627b070a547SArnaldo Carvalho de Melo 
1628b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1629b070a547SArnaldo Carvalho de Melo     .config =
1630b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1631b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1632b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1633b070a547SArnaldo Carvalho de Melo 
1634b070a547SArnaldo Carvalho de Melo };
1635b070a547SArnaldo Carvalho de Melo 
1636b070a547SArnaldo Carvalho de Melo /*
1637b070a547SArnaldo Carvalho de Melo  * Very, very detailed stats (-d -d -d), adding prefetch events:
1638b070a547SArnaldo Carvalho de Melo  */
1639b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_very_detailed_attrs[] = {
1640b070a547SArnaldo Carvalho de Melo 
1641b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1642b070a547SArnaldo Carvalho de Melo     .config =
1643b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1644b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1645b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1646b070a547SArnaldo Carvalho de Melo 
1647b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1648b070a547SArnaldo Carvalho de Melo     .config =
1649b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1650b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1651b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1652b070a547SArnaldo Carvalho de Melo };
1653b070a547SArnaldo Carvalho de Melo 
16542cba3ffbSIngo Molnar 	/* Set attrs if no event is selected and !null_run: */
16552cba3ffbSIngo Molnar 	if (null_run)
16562cba3ffbSIngo Molnar 		return 0;
16572cba3ffbSIngo Molnar 
16584cabc3d1SAndi Kleen 	if (transaction_run) {
16594cabc3d1SAndi Kleen 		int err;
16604cabc3d1SAndi Kleen 		if (pmu_have_event("cpu", "cycles-ct") &&
16614cabc3d1SAndi Kleen 		    pmu_have_event("cpu", "el-start"))
16624cabc3d1SAndi Kleen 			err = setup_events(transaction_attrs,
16634cabc3d1SAndi Kleen 					ARRAY_SIZE(transaction_attrs));
16644cabc3d1SAndi Kleen 		else
16654cabc3d1SAndi Kleen 			err = setup_events(transaction_limited_attrs,
16664cabc3d1SAndi Kleen 				 ARRAY_SIZE(transaction_limited_attrs));
16674cabc3d1SAndi Kleen 		if (err < 0) {
16684cabc3d1SAndi Kleen 			fprintf(stderr, "Cannot set up transaction events\n");
16694cabc3d1SAndi Kleen 			return -1;
16704cabc3d1SAndi Kleen 		}
16714cabc3d1SAndi Kleen 		return 0;
16724cabc3d1SAndi Kleen 	}
16734cabc3d1SAndi Kleen 
16742cba3ffbSIngo Molnar 	if (!evsel_list->nr_entries) {
167579695e1bSArnaldo Carvalho de Melo 		if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
16762cba3ffbSIngo Molnar 			return -1;
16772cba3ffbSIngo Molnar 	}
16782cba3ffbSIngo Molnar 
16792cba3ffbSIngo Molnar 	/* Detailed events get appended to the event list: */
16802cba3ffbSIngo Molnar 
16812cba3ffbSIngo Molnar 	if (detailed_run <  1)
16822cba3ffbSIngo Molnar 		return 0;
16832cba3ffbSIngo Molnar 
16842cba3ffbSIngo Molnar 	/* Append detailed run extra attributes: */
168579695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
16862cba3ffbSIngo Molnar 		return -1;
16872cba3ffbSIngo Molnar 
16882cba3ffbSIngo Molnar 	if (detailed_run < 2)
16892cba3ffbSIngo Molnar 		return 0;
16902cba3ffbSIngo Molnar 
16912cba3ffbSIngo Molnar 	/* Append very detailed run extra attributes: */
169279695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
16932cba3ffbSIngo Molnar 		return -1;
16942cba3ffbSIngo Molnar 
16952cba3ffbSIngo Molnar 	if (detailed_run < 3)
16962cba3ffbSIngo Molnar 		return 0;
16972cba3ffbSIngo Molnar 
16982cba3ffbSIngo Molnar 	/* Append very, very detailed run extra attributes: */
169979695e1bSArnaldo Carvalho de Melo 	return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
17002cba3ffbSIngo Molnar }
17012cba3ffbSIngo Molnar 
17021d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
170386470930SIngo Molnar {
17041f16c575SPeter Zijlstra 	bool append_file = false;
1705b070a547SArnaldo Carvalho de Melo 	int output_fd = 0;
1706b070a547SArnaldo Carvalho de Melo 	const char *output_name	= NULL;
1707b070a547SArnaldo Carvalho de Melo 	const struct option options[] = {
17084cabc3d1SAndi Kleen 	OPT_BOOLEAN('T', "transaction", &transaction_run,
17094cabc3d1SAndi Kleen 		    "hardware transaction statistics"),
1710b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK('e', "event", &evsel_list, "event",
1711b070a547SArnaldo Carvalho de Melo 		     "event selector. use 'perf list' to list available events",
1712b070a547SArnaldo Carvalho de Melo 		     parse_events_option),
1713b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1714b070a547SArnaldo Carvalho de Melo 		     "event filter", parse_filter),
1715b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1716b070a547SArnaldo Carvalho de Melo 		    "child tasks do not inherit counters"),
1717b070a547SArnaldo Carvalho de Melo 	OPT_STRING('p', "pid", &target.pid, "pid",
1718b070a547SArnaldo Carvalho de Melo 		   "stat events on existing process id"),
1719b070a547SArnaldo Carvalho de Melo 	OPT_STRING('t', "tid", &target.tid, "tid",
1720b070a547SArnaldo Carvalho de Melo 		   "stat events on existing thread id"),
1721b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1722b070a547SArnaldo Carvalho de Melo 		    "system-wide collection from all CPUs"),
1723b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('g', "group", &group,
1724b070a547SArnaldo Carvalho de Melo 		    "put the counters into a counter group"),
1725b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"),
1726b070a547SArnaldo Carvalho de Melo 	OPT_INCR('v', "verbose", &verbose,
1727b070a547SArnaldo Carvalho de Melo 		    "be more verbose (show counter open errors, etc)"),
1728b070a547SArnaldo Carvalho de Melo 	OPT_INTEGER('r', "repeat", &run_count,
1729a7e191c3SFrederik Deweerdt 		    "repeat command and print average + stddev (max: 100, forever: 0)"),
1730b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('n', "null", &null_run,
1731b070a547SArnaldo Carvalho de Melo 		    "null run - dont start any counters"),
1732b070a547SArnaldo Carvalho de Melo 	OPT_INCR('d', "detailed", &detailed_run,
1733b070a547SArnaldo Carvalho de Melo 		    "detailed run - start a lot of events"),
1734b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('S', "sync", &sync_run,
1735b070a547SArnaldo Carvalho de Melo 		    "call sync() before starting a run"),
1736b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1737b070a547SArnaldo Carvalho de Melo 			   "print large numbers with thousands\' separators",
1738b070a547SArnaldo Carvalho de Melo 			   stat__set_big_num),
1739b070a547SArnaldo Carvalho de Melo 	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1740b070a547SArnaldo Carvalho de Melo 		    "list of cpus to monitor in system-wide"),
174186ee6e18SStephane Eranian 	OPT_SET_UINT('A', "no-aggr", &aggr_mode,
174286ee6e18SStephane Eranian 		    "disable CPU count aggregation", AGGR_NONE),
1743b070a547SArnaldo Carvalho de Melo 	OPT_STRING('x', "field-separator", &csv_sep, "separator",
1744b070a547SArnaldo Carvalho de Melo 		   "print counts with custom separator"),
1745b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1746b070a547SArnaldo Carvalho de Melo 		     "monitor event in cgroup name only", parse_cgroups),
1747b070a547SArnaldo Carvalho de Melo 	OPT_STRING('o', "output", &output_name, "file", "output file name"),
1748b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1749b070a547SArnaldo Carvalho de Melo 	OPT_INTEGER(0, "log-fd", &output_fd,
1750b070a547SArnaldo Carvalho de Melo 		    "log output to fd, instead of stderr"),
17511f16c575SPeter Zijlstra 	OPT_STRING(0, "pre", &pre_cmd, "command",
17521f16c575SPeter Zijlstra 			"command to run prior to the measured command"),
17531f16c575SPeter Zijlstra 	OPT_STRING(0, "post", &post_cmd, "command",
17541f16c575SPeter Zijlstra 			"command to run after to the measured command"),
175513370a9bSStephane Eranian 	OPT_UINTEGER('I', "interval-print", &interval,
175613370a9bSStephane Eranian 		    "print counts at regular interval in ms (>= 100)"),
1757d4304958SStephane Eranian 	OPT_SET_UINT(0, "per-socket", &aggr_mode,
175886ee6e18SStephane Eranian 		     "aggregate counts per processor socket", AGGR_SOCKET),
175912c08a9fSStephane Eranian 	OPT_SET_UINT(0, "per-core", &aggr_mode,
176012c08a9fSStephane Eranian 		     "aggregate counts per physical processor core", AGGR_CORE),
176141191688SAndi Kleen 	OPT_UINTEGER('D', "delay", &initial_delay,
176241191688SAndi Kleen 		     "ms to wait before starting measurement after program start"),
1763b070a547SArnaldo Carvalho de Melo 	OPT_END()
1764b070a547SArnaldo Carvalho de Melo 	};
1765b070a547SArnaldo Carvalho de Melo 	const char * const stat_usage[] = {
1766b070a547SArnaldo Carvalho de Melo 		"perf stat [<options>] [<command>]",
1767b070a547SArnaldo Carvalho de Melo 		NULL
1768b070a547SArnaldo Carvalho de Melo 	};
1769cc03c542SNamhyung Kim 	int status = -EINVAL, run_idx;
17704aa9015fSStephane Eranian 	const char *mode;
177142202dd5SIngo Molnar 
17725af52b51SStephane Eranian 	setlocale(LC_ALL, "");
17735af52b51SStephane Eranian 
1774334fe7a3SNamhyung Kim 	evsel_list = perf_evlist__new();
1775361c99a6SArnaldo Carvalho de Melo 	if (evsel_list == NULL)
1776361c99a6SArnaldo Carvalho de Melo 		return -ENOMEM;
1777361c99a6SArnaldo Carvalho de Melo 
1778a0541234SAnton Blanchard 	argc = parse_options(argc, argv, options, stat_usage,
1779a0541234SAnton Blanchard 		PARSE_OPT_STOP_AT_NON_OPTION);
1780d7470b6aSStephane Eranian 
17814aa9015fSStephane Eranian 	output = stderr;
17824aa9015fSStephane Eranian 	if (output_name && strcmp(output_name, "-"))
17834aa9015fSStephane Eranian 		output = NULL;
17844aa9015fSStephane Eranian 
178556f3bae7SJim Cromie 	if (output_name && output_fd) {
178656f3bae7SJim Cromie 		fprintf(stderr, "cannot use both --output and --log-fd\n");
1787cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "o", 1);
1788cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "log-fd", 0);
1789cc03c542SNamhyung Kim 		goto out;
179056f3bae7SJim Cromie 	}
1791fc3e4d07SStephane Eranian 
1792fc3e4d07SStephane Eranian 	if (output_fd < 0) {
1793fc3e4d07SStephane Eranian 		fprintf(stderr, "argument to --log-fd must be a > 0\n");
1794cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "log-fd", 0);
1795cc03c542SNamhyung Kim 		goto out;
1796fc3e4d07SStephane Eranian 	}
1797fc3e4d07SStephane Eranian 
17984aa9015fSStephane Eranian 	if (!output) {
17994aa9015fSStephane Eranian 		struct timespec tm;
18004aa9015fSStephane Eranian 		mode = append_file ? "a" : "w";
18014aa9015fSStephane Eranian 
18024aa9015fSStephane Eranian 		output = fopen(output_name, mode);
18034aa9015fSStephane Eranian 		if (!output) {
18044aa9015fSStephane Eranian 			perror("failed to create output file");
1805fceda7feSDavid Ahern 			return -1;
18064aa9015fSStephane Eranian 		}
18074aa9015fSStephane Eranian 		clock_gettime(CLOCK_REALTIME, &tm);
18084aa9015fSStephane Eranian 		fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1809fc3e4d07SStephane Eranian 	} else if (output_fd > 0) {
181056f3bae7SJim Cromie 		mode = append_file ? "a" : "w";
181156f3bae7SJim Cromie 		output = fdopen(output_fd, mode);
181256f3bae7SJim Cromie 		if (!output) {
181356f3bae7SJim Cromie 			perror("Failed opening logfd");
181456f3bae7SJim Cromie 			return -errno;
181556f3bae7SJim Cromie 		}
18164aa9015fSStephane Eranian 	}
18174aa9015fSStephane Eranian 
1818d4ffd04dSJim Cromie 	if (csv_sep) {
1819d7470b6aSStephane Eranian 		csv_output = true;
1820d4ffd04dSJim Cromie 		if (!strcmp(csv_sep, "\\t"))
1821d4ffd04dSJim Cromie 			csv_sep = "\t";
1822d4ffd04dSJim Cromie 	} else
1823d7470b6aSStephane Eranian 		csv_sep = DEFAULT_SEPARATOR;
1824d7470b6aSStephane Eranian 
1825d7470b6aSStephane Eranian 	/*
1826d7470b6aSStephane Eranian 	 * let the spreadsheet do the pretty-printing
1827d7470b6aSStephane Eranian 	 */
1828d7470b6aSStephane Eranian 	if (csv_output) {
182961a9f324SJim Cromie 		/* User explicitly passed -B? */
1830d7470b6aSStephane Eranian 		if (big_num_opt == 1) {
1831d7470b6aSStephane Eranian 			fprintf(stderr, "-B option not supported with -x\n");
1832cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "B", 1);
1833cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "x", 1);
1834cc03c542SNamhyung Kim 			goto out;
1835d7470b6aSStephane Eranian 		} else /* Nope, so disable big number formatting */
1836d7470b6aSStephane Eranian 			big_num = false;
1837d7470b6aSStephane Eranian 	} else if (big_num_opt == 0) /* User passed --no-big-num */
1838d7470b6aSStephane Eranian 		big_num = false;
1839d7470b6aSStephane Eranian 
1840602ad878SArnaldo Carvalho de Melo 	if (!argc && target__none(&target))
184186470930SIngo Molnar 		usage_with_options(stat_usage, options);
1842ac3063bdSDavid Ahern 
1843a7e191c3SFrederik Deweerdt 	if (run_count < 0) {
1844cc03c542SNamhyung Kim 		pr_err("Run count must be a positive number\n");
1845cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "r", 1);
1846cc03c542SNamhyung Kim 		goto out;
1847a7e191c3SFrederik Deweerdt 	} else if (run_count == 0) {
1848a7e191c3SFrederik Deweerdt 		forever = true;
1849a7e191c3SFrederik Deweerdt 		run_count = 1;
1850a7e191c3SFrederik Deweerdt 	}
185186470930SIngo Molnar 
1852023695d9SStephane Eranian 	/* no_aggr, cgroup are for system-wide only */
1853602ad878SArnaldo Carvalho de Melo 	if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) &&
1854602ad878SArnaldo Carvalho de Melo 	    !target__has_cpu(&target)) {
1855023695d9SStephane Eranian 		fprintf(stderr, "both cgroup and no-aggregation "
1856023695d9SStephane Eranian 			"modes only available in system-wide mode\n");
1857023695d9SStephane Eranian 
1858cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "G", 1);
1859cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "A", 1);
1860cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "a", 1);
1861cc03c542SNamhyung Kim 		goto out;
1862d7e7a451SStephane Eranian 	}
1863d7e7a451SStephane Eranian 
18642cba3ffbSIngo Molnar 	if (add_default_attributes())
1865c6264defSIngo Molnar 		goto out;
186686470930SIngo Molnar 
1867602ad878SArnaldo Carvalho de Melo 	target__validate(&target);
18685c98d466SArnaldo Carvalho de Melo 
186977a6f014SNamhyung Kim 	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1870602ad878SArnaldo Carvalho de Melo 		if (target__has_task(&target)) {
18715c98d466SArnaldo Carvalho de Melo 			pr_err("Problems finding threads of monitor\n");
1872cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "p", 1);
1873cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "t", 1);
1874602ad878SArnaldo Carvalho de Melo 		} else if (target__has_cpu(&target)) {
187560d567e2SArnaldo Carvalho de Melo 			perror("failed to parse CPUs map");
1876cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "C", 1);
1877cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "a", 1);
1878cc03c542SNamhyung Kim 		}
1879cc03c542SNamhyung Kim 		goto out;
188060d567e2SArnaldo Carvalho de Melo 	}
188113370a9bSStephane Eranian 	if (interval && interval < 100) {
188213370a9bSStephane Eranian 		pr_err("print interval must be >= 100ms\n");
1883cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "I", 1);
188403ad9747SArnaldo Carvalho de Melo 		goto out;
188513370a9bSStephane Eranian 	}
1886c45c6ea2SStephane Eranian 
1887d134ffb9SArnaldo Carvalho de Melo 	if (perf_evlist__alloc_stats(evsel_list, interval))
188803ad9747SArnaldo Carvalho de Melo 		goto out;
1889d6d901c2SZhang, Yanmin 
189086ee6e18SStephane Eranian 	if (perf_stat_init_aggr_mode())
189103ad9747SArnaldo Carvalho de Melo 		goto out;
189286ee6e18SStephane Eranian 
189386470930SIngo Molnar 	/*
189486470930SIngo Molnar 	 * We dont want to block the signals - that would cause
189586470930SIngo Molnar 	 * child tasks to inherit that and Ctrl-C would not work.
189686470930SIngo Molnar 	 * What we want is for Ctrl-C to work in the exec()-ed
189786470930SIngo Molnar 	 * task, but being ignored by perf stat itself:
189886470930SIngo Molnar 	 */
1899f7b7c26eSPeter Zijlstra 	atexit(sig_atexit);
1900a7e191c3SFrederik Deweerdt 	if (!forever)
190186470930SIngo Molnar 		signal(SIGINT,  skip_signal);
190213370a9bSStephane Eranian 	signal(SIGCHLD, skip_signal);
190386470930SIngo Molnar 	signal(SIGALRM, skip_signal);
190486470930SIngo Molnar 	signal(SIGABRT, skip_signal);
190586470930SIngo Molnar 
190642202dd5SIngo Molnar 	status = 0;
1907a7e191c3SFrederik Deweerdt 	for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
190842202dd5SIngo Molnar 		if (run_count != 1 && verbose)
19094aa9015fSStephane Eranian 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
19104aa9015fSStephane Eranian 				run_idx + 1);
1911f9cef0a9SIngo Molnar 
191242202dd5SIngo Molnar 		status = run_perf_stat(argc, argv);
1913a7e191c3SFrederik Deweerdt 		if (forever && status != -1) {
1914a7e191c3SFrederik Deweerdt 			print_stat(argc, argv);
1915d134ffb9SArnaldo Carvalho de Melo 			perf_stat__reset_stats(evsel_list);
1916a7e191c3SFrederik Deweerdt 		}
191742202dd5SIngo Molnar 	}
191842202dd5SIngo Molnar 
1919a7e191c3SFrederik Deweerdt 	if (!forever && status != -1 && !interval)
192042202dd5SIngo Molnar 		print_stat(argc, argv);
1921d134ffb9SArnaldo Carvalho de Melo 
1922d134ffb9SArnaldo Carvalho de Melo 	perf_evlist__free_stats(evsel_list);
19230015e2e1SArnaldo Carvalho de Melo out:
19240015e2e1SArnaldo Carvalho de Melo 	perf_evlist__delete(evsel_list);
192542202dd5SIngo Molnar 	return status;
192686470930SIngo Molnar }
1927