xref: /openbmc/linux/tools/perf/builtin-stat.c (revision a8e02324)
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 */
76a454742cSJiri Olsa static const char *transaction_attrs = {
77a454742cSJiri Olsa 	"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. */
89a454742cSJiri Olsa static const char * transaction_limited_attrs = {
90a454742cSJiri Olsa 	"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 
99666e6d48SRobert Richter static struct perf_evlist	*evsel_list;
100361c99a6SArnaldo Carvalho de Melo 
101602ad878SArnaldo Carvalho de Melo static struct target target = {
10277a6f014SNamhyung Kim 	.uid	= UINT_MAX,
10377a6f014SNamhyung Kim };
10442202dd5SIngo Molnar 
1053d632595SJaswinder Singh Rajput static int			run_count			=  1;
1062e6cdf99SStephane Eranian static bool			no_inherit			= false;
107c0555642SIan Munsie static bool			scale				=  true;
10886ee6e18SStephane Eranian static enum aggr_mode		aggr_mode			= AGGR_GLOBAL;
109d07f0b12SStephane Eranian static volatile pid_t		child_pid			= -1;
110c0555642SIan Munsie static bool			null_run			=  false;
1112cba3ffbSIngo Molnar static int			detailed_run			=  0;
1124cabc3d1SAndi Kleen static bool			transaction_run;
113201e0b06SArnaldo Carvalho de Melo static bool			big_num				=  true;
114d7470b6aSStephane Eranian static int			big_num_opt			=  -1;
115d7470b6aSStephane Eranian static const char		*csv_sep			= NULL;
116d7470b6aSStephane Eranian static bool			csv_output			= false;
11743bece79SLin Ming static bool			group				= false;
1184aa9015fSStephane Eranian static FILE			*output				= NULL;
1191f16c575SPeter Zijlstra static const char		*pre_cmd			= NULL;
1201f16c575SPeter Zijlstra static const char		*post_cmd			= NULL;
1211f16c575SPeter Zijlstra static bool			sync_run			= false;
12213370a9bSStephane Eranian static unsigned int		interval			= 0;
12341191688SAndi Kleen static unsigned int		initial_delay			= 0;
124410136f5SStephane Eranian static unsigned int		unit_width			= 4; /* strlen("unit") */
125a7e191c3SFrederik Deweerdt static bool			forever				= false;
12613370a9bSStephane Eranian static struct timespec		ref_time;
12786ee6e18SStephane Eranian static struct cpu_map		*aggr_map;
12886ee6e18SStephane Eranian static int			(*aggr_get_id)(struct cpu_map *m, int cpu);
1295af52b51SStephane Eranian 
13060666c63SLiming Wang static volatile int done = 0;
13160666c63SLiming Wang 
13213370a9bSStephane Eranian static inline void diff_timespec(struct timespec *r, struct timespec *a,
13313370a9bSStephane Eranian 				 struct timespec *b)
13413370a9bSStephane Eranian {
13513370a9bSStephane Eranian 	r->tv_sec = a->tv_sec - b->tv_sec;
13613370a9bSStephane Eranian 	if (a->tv_nsec < b->tv_nsec) {
13713370a9bSStephane Eranian 		r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec;
13813370a9bSStephane Eranian 		r->tv_sec--;
13913370a9bSStephane Eranian 	} else {
14013370a9bSStephane Eranian 		r->tv_nsec = a->tv_nsec - b->tv_nsec ;
14113370a9bSStephane Eranian 	}
14213370a9bSStephane Eranian }
14313370a9bSStephane Eranian 
144a7e191c3SFrederik Deweerdt static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
145a7e191c3SFrederik Deweerdt {
14690f6bb6cSAndi Kleen 	int i;
14790f6bb6cSAndi Kleen 	struct perf_stat *ps = evsel->priv;
14890f6bb6cSAndi Kleen 
14990f6bb6cSAndi Kleen 	for (i = 0; i < 3; i++)
15090f6bb6cSAndi Kleen 		init_stats(&ps->res_stats[i]);
151e2f56da1SJiri Olsa 
152e2f56da1SJiri Olsa 	perf_stat_evsel_id_init(evsel);
153a7e191c3SFrederik Deweerdt }
154a7e191c3SFrederik Deweerdt 
155c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
15669aad6f1SArnaldo Carvalho de Melo {
157c52b12edSArnaldo Carvalho de Melo 	evsel->priv = zalloc(sizeof(struct perf_stat));
158d180ac14SJiri Olsa 	if (evsel->priv == NULL)
15990f6bb6cSAndi Kleen 		return -ENOMEM;
16090f6bb6cSAndi Kleen 	perf_evsel__reset_stat_priv(evsel);
16190f6bb6cSAndi Kleen 	return 0;
16269aad6f1SArnaldo Carvalho de Melo }
16369aad6f1SArnaldo Carvalho de Melo 
16469aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
16569aad6f1SArnaldo Carvalho de Melo {
16604662523SArnaldo Carvalho de Melo 	zfree(&evsel->priv);
16769aad6f1SArnaldo Carvalho de Melo }
16869aad6f1SArnaldo Carvalho de Melo 
16913370a9bSStephane Eranian static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
1707ae92e74SYan, Zheng {
1719df38e82SJiri Olsa 	struct perf_counts *counts;
17213370a9bSStephane Eranian 
1739df38e82SJiri Olsa 	counts = perf_counts__new(perf_evsel__nr_cpus(evsel));
1749df38e82SJiri Olsa 	if (counts)
1759df38e82SJiri Olsa 		evsel->prev_raw_counts = counts;
17613370a9bSStephane Eranian 
1779df38e82SJiri Olsa 	return counts ? 0 : -ENOMEM;
1787ae92e74SYan, Zheng }
1797ae92e74SYan, Zheng 
18013370a9bSStephane Eranian static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
1817ae92e74SYan, Zheng {
1829df38e82SJiri Olsa 	perf_counts__delete(evsel->prev_raw_counts);
1839df38e82SJiri Olsa 	evsel->prev_raw_counts = NULL;
1847ae92e74SYan, Zheng }
1857ae92e74SYan, Zheng 
186d134ffb9SArnaldo Carvalho de Melo static void perf_evlist__free_stats(struct perf_evlist *evlist)
187d134ffb9SArnaldo Carvalho de Melo {
188d134ffb9SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
189d134ffb9SArnaldo Carvalho de Melo 
1900050f7aaSArnaldo Carvalho de Melo 	evlist__for_each(evlist, evsel) {
191d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_stat_priv(evsel);
192d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_counts(evsel);
193d134ffb9SArnaldo Carvalho de Melo 		perf_evsel__free_prev_raw_counts(evsel);
194d134ffb9SArnaldo Carvalho de Melo 	}
195d134ffb9SArnaldo Carvalho de Melo }
196d134ffb9SArnaldo Carvalho de Melo 
197d134ffb9SArnaldo Carvalho de Melo static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
198d134ffb9SArnaldo Carvalho de Melo {
199d134ffb9SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
200d134ffb9SArnaldo Carvalho de Melo 
2010050f7aaSArnaldo Carvalho de Melo 	evlist__for_each(evlist, evsel) {
202d134ffb9SArnaldo Carvalho de Melo 		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
203d134ffb9SArnaldo Carvalho de Melo 		    perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
204d134ffb9SArnaldo Carvalho de Melo 		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
205d134ffb9SArnaldo Carvalho de Melo 			goto out_free;
206d134ffb9SArnaldo Carvalho de Melo 	}
207d134ffb9SArnaldo Carvalho de Melo 
208d134ffb9SArnaldo Carvalho de Melo 	return 0;
209d134ffb9SArnaldo Carvalho de Melo 
210d134ffb9SArnaldo Carvalho de Melo out_free:
211d134ffb9SArnaldo Carvalho de Melo 	perf_evlist__free_stats(evlist);
212d134ffb9SArnaldo Carvalho de Melo 	return -1;
213d134ffb9SArnaldo Carvalho de Melo }
214d134ffb9SArnaldo Carvalho de Melo 
2151eda3b21SJiri Olsa static void perf_stat__reset_stats(struct perf_evlist *evlist)
2161eda3b21SJiri Olsa {
2171eda3b21SJiri Olsa 	struct perf_evsel *evsel;
2181eda3b21SJiri Olsa 
2191eda3b21SJiri Olsa 	evlist__for_each(evlist, evsel) {
2201eda3b21SJiri Olsa 		perf_evsel__reset_stat_priv(evsel);
221a8e02324SJiri Olsa 		perf_evsel__reset_counts(evsel);
2221eda3b21SJiri Olsa 	}
2231eda3b21SJiri Olsa 
224f87027b9SJiri Olsa 	perf_stat__reset_shadow_stats();
2251eda3b21SJiri Olsa }
2261eda3b21SJiri Olsa 
227cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel)
22886470930SIngo Molnar {
22969aad6f1SArnaldo Carvalho de Melo 	struct perf_event_attr *attr = &evsel->attr;
230727ab04eSArnaldo Carvalho de Melo 
23186470930SIngo Molnar 	if (scale)
23286470930SIngo Molnar 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
23386470930SIngo Molnar 				    PERF_FORMAT_TOTAL_TIME_RUNNING;
23486470930SIngo Molnar 
2352e6cdf99SStephane Eranian 	attr->inherit = !no_inherit;
2365d2cd909SArnaldo Carvalho de Melo 
237602ad878SArnaldo Carvalho de Melo 	if (target__has_cpu(&target))
238594ac61aSArnaldo Carvalho de Melo 		return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
2395622c07bSStephane Eranian 
240602ad878SArnaldo Carvalho de Melo 	if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) {
24186470930SIngo Molnar 		attr->disabled = 1;
24241191688SAndi Kleen 		if (!initial_delay)
24357e7986eSPaul Mackerras 			attr->enable_on_exec = 1;
2446be2850eSZhang, Yanmin 	}
245084ab9f8SArnaldo Carvalho de Melo 
246594ac61aSArnaldo Carvalho de Melo 	return perf_evsel__open_per_thread(evsel, evsel_list->threads);
24786470930SIngo Molnar }
24886470930SIngo Molnar 
24986470930SIngo Molnar /*
25086470930SIngo Molnar  * Does the counter have nsecs as a unit?
25186470930SIngo Molnar  */
252daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel)
25386470930SIngo Molnar {
254daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
255daec78a0SArnaldo Carvalho de Melo 	    perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
25686470930SIngo Molnar 		return 1;
25786470930SIngo Molnar 
25886470930SIngo Molnar 	return 0;
25986470930SIngo Molnar }
26086470930SIngo Molnar 
261779d0b99SJiri Olsa static void zero_per_pkg(struct perf_evsel *counter)
262779d0b99SJiri Olsa {
263779d0b99SJiri Olsa 	if (counter->per_pkg_mask)
264779d0b99SJiri Olsa 		memset(counter->per_pkg_mask, 0, MAX_NR_CPUS);
265779d0b99SJiri Olsa }
266779d0b99SJiri Olsa 
267779d0b99SJiri Olsa static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
268779d0b99SJiri Olsa {
269779d0b99SJiri Olsa 	unsigned long *mask = counter->per_pkg_mask;
270779d0b99SJiri Olsa 	struct cpu_map *cpus = perf_evsel__cpus(counter);
271779d0b99SJiri Olsa 	int s;
272779d0b99SJiri Olsa 
273779d0b99SJiri Olsa 	*skip = false;
274779d0b99SJiri Olsa 
275779d0b99SJiri Olsa 	if (!counter->per_pkg)
276779d0b99SJiri Olsa 		return 0;
277779d0b99SJiri Olsa 
278779d0b99SJiri Olsa 	if (cpu_map__empty(cpus))
279779d0b99SJiri Olsa 		return 0;
280779d0b99SJiri Olsa 
281779d0b99SJiri Olsa 	if (!mask) {
282779d0b99SJiri Olsa 		mask = zalloc(MAX_NR_CPUS);
283779d0b99SJiri Olsa 		if (!mask)
284779d0b99SJiri Olsa 			return -ENOMEM;
285779d0b99SJiri Olsa 
286779d0b99SJiri Olsa 		counter->per_pkg_mask = mask;
287779d0b99SJiri Olsa 	}
288779d0b99SJiri Olsa 
289779d0b99SJiri Olsa 	s = cpu_map__get_socket(cpus, cpu);
290779d0b99SJiri Olsa 	if (s < 0)
291779d0b99SJiri Olsa 		return -1;
292779d0b99SJiri Olsa 
293779d0b99SJiri Olsa 	*skip = test_and_set_bit(s, mask) == 1;
294779d0b99SJiri Olsa 	return 0;
295779d0b99SJiri Olsa }
296779d0b99SJiri Olsa 
297060c4f9cSJiri Olsa static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
298060c4f9cSJiri Olsa 		   struct perf_counts_values *count)
299060c4f9cSJiri Olsa {
3001971f59fSJiri Olsa 	struct perf_counts_values *aggr = &evsel->counts->aggr;
301779d0b99SJiri Olsa 	static struct perf_counts_values zero;
302779d0b99SJiri Olsa 	bool skip = false;
303779d0b99SJiri Olsa 
304779d0b99SJiri Olsa 	if (check_per_pkg(evsel, cpu, &skip)) {
305779d0b99SJiri Olsa 		pr_err("failed to read per-pkg counter\n");
306779d0b99SJiri Olsa 		return -1;
307779d0b99SJiri Olsa 	}
308779d0b99SJiri Olsa 
309779d0b99SJiri Olsa 	if (skip)
310779d0b99SJiri Olsa 		count = &zero;
3111971f59fSJiri Olsa 
312060c4f9cSJiri Olsa 	switch (aggr_mode) {
313060c4f9cSJiri Olsa 	case AGGR_CORE:
314060c4f9cSJiri Olsa 	case AGGR_SOCKET:
315060c4f9cSJiri Olsa 	case AGGR_NONE:
3166c0345b7SJiri Olsa 		if (!evsel->snapshot)
317060c4f9cSJiri Olsa 			perf_evsel__compute_deltas(evsel, cpu, count);
318060c4f9cSJiri Olsa 		perf_counts_values__scale(count, scale, NULL);
3191ac77e1cSJiri Olsa 		*perf_counts(evsel->counts, cpu) = *count;
32056f0fd45SAndi Kleen 		if (aggr_mode == AGGR_NONE)
321f87027b9SJiri Olsa 			perf_stat__update_shadow_stats(evsel, count->values, cpu);
322060c4f9cSJiri Olsa 		break;
323060c4f9cSJiri Olsa 	case AGGR_GLOBAL:
3241971f59fSJiri Olsa 		aggr->val += count->val;
3251971f59fSJiri Olsa 		if (scale) {
3261971f59fSJiri Olsa 			aggr->ena += count->ena;
3271971f59fSJiri Olsa 			aggr->run += count->run;
3281971f59fSJiri Olsa 		}
329060c4f9cSJiri Olsa 	default:
330060c4f9cSJiri Olsa 		break;
331060c4f9cSJiri Olsa 	}
332060c4f9cSJiri Olsa 
333060c4f9cSJiri Olsa 	return 0;
334060c4f9cSJiri Olsa }
335060c4f9cSJiri Olsa 
3361971f59fSJiri Olsa static int read_counter(struct perf_evsel *counter);
3371971f59fSJiri Olsa 
338dcd9936aSIngo Molnar /*
33986470930SIngo Molnar  * Read out the results of a single counter:
340f5b4a9c3SStephane Eranian  * aggregate counts across CPUs in system-wide mode
34186470930SIngo Molnar  */
342c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter)
34386470930SIngo Molnar {
3441971f59fSJiri Olsa 	struct perf_counts_values *aggr = &counter->counts->aggr;
34569aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps = counter->priv;
346c52b12edSArnaldo Carvalho de Melo 	u64 *count = counter->counts->aggr.values;
347c52b12edSArnaldo Carvalho de Melo 	int i;
34886470930SIngo Molnar 
3491971f59fSJiri Olsa 	aggr->val = aggr->ena = aggr->run = 0;
3501971f59fSJiri Olsa 
3511971f59fSJiri Olsa 	if (read_counter(counter))
352c52b12edSArnaldo Carvalho de Melo 		return -1;
3539e9772c4SPeter Zijlstra 
3546c0345b7SJiri Olsa 	if (!counter->snapshot)
3551971f59fSJiri Olsa 		perf_evsel__compute_deltas(counter, -1, aggr);
3561971f59fSJiri Olsa 	perf_counts_values__scale(aggr, scale, &counter->counts->scaled);
3571971f59fSJiri Olsa 
3589e9772c4SPeter Zijlstra 	for (i = 0; i < 3; i++)
35969aad6f1SArnaldo Carvalho de Melo 		update_stats(&ps->res_stats[i], count[i]);
3609e9772c4SPeter Zijlstra 
3619e9772c4SPeter Zijlstra 	if (verbose) {
3624aa9015fSStephane Eranian 		fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
3637289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter), count[0], count[1], count[2]);
3649e9772c4SPeter Zijlstra 	}
3659e9772c4SPeter Zijlstra 
36686470930SIngo Molnar 	/*
36786470930SIngo Molnar 	 * Save the full runtime - to allow normalization during printout:
36886470930SIngo Molnar 	 */
369f87027b9SJiri Olsa 	perf_stat__update_shadow_stats(counter, count, 0);
370c52b12edSArnaldo Carvalho de Melo 
371c52b12edSArnaldo Carvalho de Melo 	return 0;
372f5b4a9c3SStephane Eranian }
373f5b4a9c3SStephane Eranian 
374f5b4a9c3SStephane Eranian /*
375f5b4a9c3SStephane Eranian  * Read out the results of a single counter:
376f5b4a9c3SStephane Eranian  * do not aggregate counts across CPUs in system-wide mode
377f5b4a9c3SStephane Eranian  */
378c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter)
379f5b4a9c3SStephane Eranian {
3809bf1a529SJiri Olsa 	int nthreads = thread_map__nr(evsel_list->threads);
3819bf1a529SJiri Olsa 	int ncpus = perf_evsel__nr_cpus(counter);
3829bf1a529SJiri Olsa 	int cpu, thread;
383f5b4a9c3SStephane Eranian 
3843b4331d9SSuzuki K. Poulose 	if (!counter->supported)
3853b4331d9SSuzuki K. Poulose 		return -ENOENT;
3863b4331d9SSuzuki K. Poulose 
3879bf1a529SJiri Olsa 	if (counter->system_wide)
3889bf1a529SJiri Olsa 		nthreads = 1;
3899bf1a529SJiri Olsa 
390779d0b99SJiri Olsa 	if (counter->per_pkg)
391779d0b99SJiri Olsa 		zero_per_pkg(counter);
392779d0b99SJiri Olsa 
3939bf1a529SJiri Olsa 	for (thread = 0; thread < nthreads; thread++) {
3949bf1a529SJiri Olsa 		for (cpu = 0; cpu < ncpus; cpu++) {
3959bf1a529SJiri Olsa 			if (perf_evsel__read_cb(counter, cpu, thread, read_cb))
396c52b12edSArnaldo Carvalho de Melo 				return -1;
397f5b4a9c3SStephane Eranian 		}
3989bf1a529SJiri Olsa 	}
399c52b12edSArnaldo Carvalho de Melo 
400c52b12edSArnaldo Carvalho de Melo 	return 0;
40186470930SIngo Molnar }
40286470930SIngo Molnar 
40313370a9bSStephane Eranian static void print_interval(void)
40413370a9bSStephane Eranian {
40513370a9bSStephane Eranian 	static int num_print_interval;
40613370a9bSStephane Eranian 	struct perf_evsel *counter;
40713370a9bSStephane Eranian 	struct perf_stat *ps;
40813370a9bSStephane Eranian 	struct timespec ts, rs;
40913370a9bSStephane Eranian 	char prefix[64];
41013370a9bSStephane Eranian 
41186ee6e18SStephane Eranian 	if (aggr_mode == AGGR_GLOBAL) {
4120050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
41313370a9bSStephane Eranian 			ps = counter->priv;
41413370a9bSStephane Eranian 			memset(ps->res_stats, 0, sizeof(ps->res_stats));
41513370a9bSStephane Eranian 			read_counter_aggr(counter);
41613370a9bSStephane Eranian 		}
41786ee6e18SStephane Eranian 	} else	{
4180050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
41986ee6e18SStephane Eranian 			ps = counter->priv;
42086ee6e18SStephane Eranian 			memset(ps->res_stats, 0, sizeof(ps->res_stats));
42186ee6e18SStephane Eranian 			read_counter(counter);
42213370a9bSStephane Eranian 		}
42386ee6e18SStephane Eranian 	}
42486ee6e18SStephane Eranian 
42513370a9bSStephane Eranian 	clock_gettime(CLOCK_MONOTONIC, &ts);
42613370a9bSStephane Eranian 	diff_timespec(&rs, &ts, &ref_time);
42713370a9bSStephane Eranian 	sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep);
42813370a9bSStephane Eranian 
42913370a9bSStephane Eranian 	if (num_print_interval == 0 && !csv_output) {
43086ee6e18SStephane Eranian 		switch (aggr_mode) {
43186ee6e18SStephane Eranian 		case AGGR_SOCKET:
432410136f5SStephane Eranian 			fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
43386ee6e18SStephane Eranian 			break;
43412c08a9fSStephane Eranian 		case AGGR_CORE:
435410136f5SStephane Eranian 			fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
43612c08a9fSStephane Eranian 			break;
43786ee6e18SStephane Eranian 		case AGGR_NONE:
438410136f5SStephane Eranian 			fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
43986ee6e18SStephane Eranian 			break;
44086ee6e18SStephane Eranian 		case AGGR_GLOBAL:
44186ee6e18SStephane Eranian 		default:
442410136f5SStephane Eranian 			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
44313370a9bSStephane Eranian 		}
44486ee6e18SStephane Eranian 	}
44513370a9bSStephane Eranian 
44613370a9bSStephane Eranian 	if (++num_print_interval == 25)
44713370a9bSStephane Eranian 		num_print_interval = 0;
44813370a9bSStephane Eranian 
44986ee6e18SStephane Eranian 	switch (aggr_mode) {
45012c08a9fSStephane Eranian 	case AGGR_CORE:
45186ee6e18SStephane Eranian 	case AGGR_SOCKET:
45286ee6e18SStephane Eranian 		print_aggr(prefix);
45386ee6e18SStephane Eranian 		break;
45486ee6e18SStephane Eranian 	case AGGR_NONE:
4550050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
45613370a9bSStephane Eranian 			print_counter(counter, prefix);
45786ee6e18SStephane Eranian 		break;
45886ee6e18SStephane Eranian 	case AGGR_GLOBAL:
45986ee6e18SStephane Eranian 	default:
4600050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
46113370a9bSStephane Eranian 			print_counter_aggr(counter, prefix);
46213370a9bSStephane Eranian 	}
4632bbf03f1SAndi Kleen 
4642bbf03f1SAndi Kleen 	fflush(output);
46513370a9bSStephane Eranian }
46613370a9bSStephane Eranian 
46741191688SAndi Kleen static void handle_initial_delay(void)
46841191688SAndi Kleen {
46941191688SAndi Kleen 	struct perf_evsel *counter;
47041191688SAndi Kleen 
47141191688SAndi Kleen 	if (initial_delay) {
47241191688SAndi Kleen 		const int ncpus = cpu_map__nr(evsel_list->cpus),
47341191688SAndi Kleen 			nthreads = thread_map__nr(evsel_list->threads);
47441191688SAndi Kleen 
47541191688SAndi Kleen 		usleep(initial_delay * 1000);
4760050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
47741191688SAndi Kleen 			perf_evsel__enable(counter, ncpus, nthreads);
47841191688SAndi Kleen 	}
47941191688SAndi Kleen }
48041191688SAndi Kleen 
481f33cbe72SArnaldo Carvalho de Melo static volatile int workload_exec_errno;
4826af206fdSArnaldo Carvalho de Melo 
4836af206fdSArnaldo Carvalho de Melo /*
4846af206fdSArnaldo Carvalho de Melo  * perf_evlist__prepare_workload will send a SIGUSR1
4856af206fdSArnaldo Carvalho de Melo  * if the fork fails, since we asked by setting its
4866af206fdSArnaldo Carvalho de Melo  * want_signal to true.
4876af206fdSArnaldo Carvalho de Melo  */
488f33cbe72SArnaldo Carvalho de Melo static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
489f33cbe72SArnaldo Carvalho de Melo 					void *ucontext __maybe_unused)
4906af206fdSArnaldo Carvalho de Melo {
491f33cbe72SArnaldo Carvalho de Melo 	workload_exec_errno = info->si_value.sival_int;
4926af206fdSArnaldo Carvalho de Melo }
4936af206fdSArnaldo Carvalho de Melo 
494acf28922SNamhyung Kim static int __run_perf_stat(int argc, const char **argv)
49586470930SIngo Molnar {
49656e52e85SArnaldo Carvalho de Melo 	char msg[512];
49786470930SIngo Molnar 	unsigned long long t0, t1;
498cac21425SJiri Olsa 	struct perf_evsel *counter;
49913370a9bSStephane Eranian 	struct timespec ts;
500410136f5SStephane Eranian 	size_t l;
50142202dd5SIngo Molnar 	int status = 0;
5026be2850eSZhang, Yanmin 	const bool forks = (argc > 0);
50386470930SIngo Molnar 
50413370a9bSStephane Eranian 	if (interval) {
50513370a9bSStephane Eranian 		ts.tv_sec  = interval / 1000;
50613370a9bSStephane Eranian 		ts.tv_nsec = (interval % 1000) * 1000000;
50713370a9bSStephane Eranian 	} else {
50813370a9bSStephane Eranian 		ts.tv_sec  = 1;
50913370a9bSStephane Eranian 		ts.tv_nsec = 0;
51013370a9bSStephane Eranian 	}
51113370a9bSStephane Eranian 
512acf28922SNamhyung Kim 	if (forks) {
513735f7e0bSArnaldo Carvalho de Melo 		if (perf_evlist__prepare_workload(evsel_list, &target, argv, false,
514735f7e0bSArnaldo Carvalho de Melo 						  workload_exec_failed_signal) < 0) {
515acf28922SNamhyung Kim 			perror("failed to prepare workload");
516fceda7feSDavid Ahern 			return -1;
517051ae7f7SPaul Mackerras 		}
518d20a47e7SNamhyung Kim 		child_pid = evsel_list->workload.pid;
51960666c63SLiming Wang 	}
520051ae7f7SPaul Mackerras 
5216a4bb04cSJiri Olsa 	if (group)
52263dab225SArnaldo Carvalho de Melo 		perf_evlist__set_leader(evsel_list);
5236a4bb04cSJiri Olsa 
5240050f7aaSArnaldo Carvalho de Melo 	evlist__for_each(evsel_list, counter) {
525cac21425SJiri Olsa 		if (create_perf_stat_counter(counter) < 0) {
526979987a5SDavid Ahern 			/*
527979987a5SDavid Ahern 			 * PPC returns ENXIO for HW counters until 2.6.37
528979987a5SDavid Ahern 			 * (behavior changed with commit b0a873e).
529979987a5SDavid Ahern 			 */
53038f6ae1eSAnton Blanchard 			if (errno == EINVAL || errno == ENOSYS ||
531979987a5SDavid Ahern 			    errno == ENOENT || errno == EOPNOTSUPP ||
532979987a5SDavid Ahern 			    errno == ENXIO) {
533c63ca0c0SDavid Ahern 				if (verbose)
534c63ca0c0SDavid Ahern 					ui__warning("%s event is not supported by the kernel.\n",
5357289f83cSArnaldo Carvalho de Melo 						    perf_evsel__name(counter));
5362cee77c4SDavid Ahern 				counter->supported = false;
537cb5ef600SKan Liang 
538cb5ef600SKan Liang 				if ((counter->leader != counter) ||
539cb5ef600SKan Liang 				    !(counter->leader->nr_members > 1))
540ede70290SIngo Molnar 					continue;
541c63ca0c0SDavid Ahern 			}
542ede70290SIngo Molnar 
54356e52e85SArnaldo Carvalho de Melo 			perf_evsel__open_strerror(counter, &target,
54456e52e85SArnaldo Carvalho de Melo 						  errno, msg, sizeof(msg));
54556e52e85SArnaldo Carvalho de Melo 			ui__error("%s\n", msg);
54656e52e85SArnaldo Carvalho de Melo 
547084ab9f8SArnaldo Carvalho de Melo 			if (child_pid != -1)
548084ab9f8SArnaldo Carvalho de Melo 				kill(child_pid, SIGTERM);
549fceda7feSDavid Ahern 
550084ab9f8SArnaldo Carvalho de Melo 			return -1;
551084ab9f8SArnaldo Carvalho de Melo 		}
5522cee77c4SDavid Ahern 		counter->supported = true;
553410136f5SStephane Eranian 
554410136f5SStephane Eranian 		l = strlen(counter->unit);
555410136f5SStephane Eranian 		if (l > unit_width)
556410136f5SStephane Eranian 			unit_width = l;
55748290609SArnaldo Carvalho de Melo 	}
55886470930SIngo Molnar 
55923d4aad4SArnaldo Carvalho de Melo 	if (perf_evlist__apply_filters(evsel_list, &counter)) {
56023d4aad4SArnaldo Carvalho de Melo 		error("failed to set filter \"%s\" on event %s with %d (%s)\n",
56123d4aad4SArnaldo Carvalho de Melo 			counter->filter, perf_evsel__name(counter), errno,
562759e612bSMasami Hiramatsu 			strerror_r(errno, msg, sizeof(msg)));
563cfd748aeSFrederic Weisbecker 		return -1;
564cfd748aeSFrederic Weisbecker 	}
565cfd748aeSFrederic Weisbecker 
56686470930SIngo Molnar 	/*
56786470930SIngo Molnar 	 * Enable counters and exec the command:
56886470930SIngo Molnar 	 */
56986470930SIngo Molnar 	t0 = rdclock();
57013370a9bSStephane Eranian 	clock_gettime(CLOCK_MONOTONIC, &ref_time);
57186470930SIngo Molnar 
57260666c63SLiming Wang 	if (forks) {
573acf28922SNamhyung Kim 		perf_evlist__start_workload(evsel_list);
57441191688SAndi Kleen 		handle_initial_delay();
575acf28922SNamhyung Kim 
57613370a9bSStephane Eranian 		if (interval) {
57713370a9bSStephane Eranian 			while (!waitpid(child_pid, &status, WNOHANG)) {
57813370a9bSStephane Eranian 				nanosleep(&ts, NULL);
57913370a9bSStephane Eranian 				print_interval();
58013370a9bSStephane Eranian 			}
58113370a9bSStephane Eranian 		}
58242202dd5SIngo Molnar 		wait(&status);
5836af206fdSArnaldo Carvalho de Melo 
584f33cbe72SArnaldo Carvalho de Melo 		if (workload_exec_errno) {
585f33cbe72SArnaldo Carvalho de Melo 			const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
586f33cbe72SArnaldo Carvalho de Melo 			pr_err("Workload failed: %s\n", emsg);
5876af206fdSArnaldo Carvalho de Melo 			return -1;
588f33cbe72SArnaldo Carvalho de Melo 		}
5896af206fdSArnaldo Carvalho de Melo 
59033e49ea7SAndi Kleen 		if (WIFSIGNALED(status))
59133e49ea7SAndi Kleen 			psignal(WTERMSIG(status), argv[0]);
59260666c63SLiming Wang 	} else {
59341191688SAndi Kleen 		handle_initial_delay();
59413370a9bSStephane Eranian 		while (!done) {
59513370a9bSStephane Eranian 			nanosleep(&ts, NULL);
59613370a9bSStephane Eranian 			if (interval)
59713370a9bSStephane Eranian 				print_interval();
59813370a9bSStephane Eranian 		}
59960666c63SLiming Wang 	}
60086470930SIngo Molnar 
60186470930SIngo Molnar 	t1 = rdclock();
60286470930SIngo Molnar 
6039e9772c4SPeter Zijlstra 	update_stats(&walltime_nsecs_stats, t1 - t0);
60442202dd5SIngo Molnar 
60586ee6e18SStephane Eranian 	if (aggr_mode == AGGR_GLOBAL) {
6060050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
607c52b12edSArnaldo Carvalho de Melo 			read_counter_aggr(counter);
6087ae92e74SYan, Zheng 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
609b3a319d5SNamhyung Kim 					     thread_map__nr(evsel_list->threads));
610c52b12edSArnaldo Carvalho de Melo 		}
61186ee6e18SStephane Eranian 	} else {
6120050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
61386ee6e18SStephane Eranian 			read_counter(counter);
61486ee6e18SStephane Eranian 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
61586ee6e18SStephane Eranian 		}
616c52b12edSArnaldo Carvalho de Melo 	}
617c52b12edSArnaldo Carvalho de Melo 
61842202dd5SIngo Molnar 	return WEXITSTATUS(status);
61942202dd5SIngo Molnar }
62042202dd5SIngo Molnar 
62141cde476SArnaldo Carvalho de Melo static int run_perf_stat(int argc, const char **argv)
6221f16c575SPeter Zijlstra {
6231f16c575SPeter Zijlstra 	int ret;
6241f16c575SPeter Zijlstra 
6251f16c575SPeter Zijlstra 	if (pre_cmd) {
6261f16c575SPeter Zijlstra 		ret = system(pre_cmd);
6271f16c575SPeter Zijlstra 		if (ret)
6281f16c575SPeter Zijlstra 			return ret;
6291f16c575SPeter Zijlstra 	}
6301f16c575SPeter Zijlstra 
6311f16c575SPeter Zijlstra 	if (sync_run)
6321f16c575SPeter Zijlstra 		sync();
6331f16c575SPeter Zijlstra 
6341f16c575SPeter Zijlstra 	ret = __run_perf_stat(argc, argv);
6351f16c575SPeter Zijlstra 	if (ret)
6361f16c575SPeter Zijlstra 		return ret;
6371f16c575SPeter Zijlstra 
6381f16c575SPeter Zijlstra 	if (post_cmd) {
6391f16c575SPeter Zijlstra 		ret = system(post_cmd);
6401f16c575SPeter Zijlstra 		if (ret)
6411f16c575SPeter Zijlstra 			return ret;
6421f16c575SPeter Zijlstra 	}
6431f16c575SPeter Zijlstra 
6441f16c575SPeter Zijlstra 	return ret;
6451f16c575SPeter Zijlstra }
6461f16c575SPeter Zijlstra 
647d73515c0SAndi Kleen static void print_running(u64 run, u64 ena)
648d73515c0SAndi Kleen {
649d73515c0SAndi Kleen 	if (csv_output) {
650d73515c0SAndi Kleen 		fprintf(output, "%s%" PRIu64 "%s%.2f",
651d73515c0SAndi Kleen 					csv_sep,
652d73515c0SAndi Kleen 					run,
653d73515c0SAndi Kleen 					csv_sep,
654d73515c0SAndi Kleen 					ena ? 100.0 * run / ena : 100.0);
655d73515c0SAndi Kleen 	} else if (run != ena) {
656d73515c0SAndi Kleen 		fprintf(output, "  (%.2f%%)", 100.0 * run / ena);
657d73515c0SAndi Kleen 	}
658d73515c0SAndi Kleen }
659d73515c0SAndi Kleen 
660f99844cbSIngo Molnar static void print_noise_pct(double total, double avg)
661f99844cbSIngo Molnar {
6620007eceaSXiao Guangrong 	double pct = rel_stddev_stats(total, avg);
663f99844cbSIngo Molnar 
6643ae9a34dSZhengyu He 	if (csv_output)
6654aa9015fSStephane Eranian 		fprintf(output, "%s%.2f%%", csv_sep, pct);
666a1bca6ccSJim Cromie 	else if (pct)
6674aa9015fSStephane Eranian 		fprintf(output, "  ( +-%6.2f%% )", pct);
668f99844cbSIngo Molnar }
669f99844cbSIngo Molnar 
67069aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg)
67142202dd5SIngo Molnar {
67269aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps;
67369aad6f1SArnaldo Carvalho de Melo 
674849abde9SPeter Zijlstra 	if (run_count == 1)
675849abde9SPeter Zijlstra 		return;
676849abde9SPeter Zijlstra 
67769aad6f1SArnaldo Carvalho de Melo 	ps = evsel->priv;
678f99844cbSIngo Molnar 	print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
67942202dd5SIngo Molnar }
68042202dd5SIngo Molnar 
68112c08a9fSStephane Eranian static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
68242202dd5SIngo Molnar {
68386ee6e18SStephane Eranian 	switch (aggr_mode) {
68412c08a9fSStephane Eranian 	case AGGR_CORE:
68512c08a9fSStephane Eranian 		fprintf(output, "S%d-C%*d%s%*d%s",
68612c08a9fSStephane Eranian 			cpu_map__id_to_socket(id),
68712c08a9fSStephane Eranian 			csv_output ? 0 : -8,
68812c08a9fSStephane Eranian 			cpu_map__id_to_cpu(id),
68912c08a9fSStephane Eranian 			csv_sep,
69012c08a9fSStephane Eranian 			csv_output ? 0 : 4,
69112c08a9fSStephane Eranian 			nr,
69212c08a9fSStephane Eranian 			csv_sep);
69312c08a9fSStephane Eranian 		break;
69486ee6e18SStephane Eranian 	case AGGR_SOCKET:
69586ee6e18SStephane Eranian 		fprintf(output, "S%*d%s%*d%s",
696d7e7a451SStephane Eranian 			csv_output ? 0 : -5,
69712c08a9fSStephane Eranian 			id,
698d7e7a451SStephane Eranian 			csv_sep,
699d7e7a451SStephane Eranian 			csv_output ? 0 : 4,
700d7e7a451SStephane Eranian 			nr,
701d7e7a451SStephane Eranian 			csv_sep);
70286ee6e18SStephane Eranian 			break;
70386ee6e18SStephane Eranian 	case AGGR_NONE:
70486ee6e18SStephane Eranian 		fprintf(output, "CPU%*d%s",
705d7470b6aSStephane Eranian 			csv_output ? 0 : -4,
70612c08a9fSStephane Eranian 			perf_evsel__cpus(evsel)->map[id], csv_sep);
70786ee6e18SStephane Eranian 		break;
70886ee6e18SStephane Eranian 	case AGGR_GLOBAL:
70986ee6e18SStephane Eranian 	default:
71086ee6e18SStephane Eranian 		break;
71186ee6e18SStephane Eranian 	}
71286ee6e18SStephane Eranian }
713d7470b6aSStephane Eranian 
714da88c7f7SAndi Kleen static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
71586ee6e18SStephane Eranian {
71686ee6e18SStephane Eranian 	double msecs = avg / 1e6;
717410136f5SStephane Eranian 	const char *fmt_v, *fmt_n;
7184bbe5a61SDavid Ahern 	char name[25];
71986ee6e18SStephane Eranian 
720410136f5SStephane Eranian 	fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
721410136f5SStephane Eranian 	fmt_n = csv_output ? "%s" : "%-25s";
722410136f5SStephane Eranian 
723da88c7f7SAndi Kleen 	aggr_printout(evsel, id, nr);
72486ee6e18SStephane Eranian 
7254bbe5a61SDavid Ahern 	scnprintf(name, sizeof(name), "%s%s",
7264bbe5a61SDavid Ahern 		  perf_evsel__name(evsel), csv_output ? "" : " (msec)");
727410136f5SStephane Eranian 
728410136f5SStephane Eranian 	fprintf(output, fmt_v, msecs, csv_sep);
729410136f5SStephane Eranian 
730410136f5SStephane Eranian 	if (csv_output)
731410136f5SStephane Eranian 		fprintf(output, "%s%s", evsel->unit, csv_sep);
732410136f5SStephane Eranian 	else
733410136f5SStephane Eranian 		fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
734410136f5SStephane Eranian 
735410136f5SStephane Eranian 	fprintf(output, fmt_n, name);
736d7470b6aSStephane Eranian 
737023695d9SStephane Eranian 	if (evsel->cgrp)
7384aa9015fSStephane Eranian 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
739023695d9SStephane Eranian 
74013370a9bSStephane Eranian 	if (csv_output || interval)
741d7470b6aSStephane Eranian 		return;
74242202dd5SIngo Molnar 
743daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
7444aa9015fSStephane Eranian 		fprintf(output, " # %8.3f CPUs utilized          ",
7454aa9015fSStephane Eranian 			avg / avg_stats(&walltime_nsecs_stats));
7469dac6a29SNamhyung Kim 	else
7479dac6a29SNamhyung Kim 		fprintf(output, "                                   ");
74842202dd5SIngo Molnar }
74942202dd5SIngo Molnar 
750556b1fb7SJiri Olsa static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
751556b1fb7SJiri Olsa {
752556b1fb7SJiri Olsa 	double sc =  evsel->scale;
753556b1fb7SJiri Olsa 	const char *fmt;
754556b1fb7SJiri Olsa 	int cpu = cpu_map__id_to_cpu(id);
755556b1fb7SJiri Olsa 
756556b1fb7SJiri Olsa 	if (csv_output) {
757556b1fb7SJiri Olsa 		fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
758556b1fb7SJiri Olsa 	} else {
759556b1fb7SJiri Olsa 		if (big_num)
760556b1fb7SJiri Olsa 			fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
761556b1fb7SJiri Olsa 		else
762556b1fb7SJiri Olsa 			fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
763556b1fb7SJiri Olsa 	}
764556b1fb7SJiri Olsa 
765556b1fb7SJiri Olsa 	aggr_printout(evsel, id, nr);
766556b1fb7SJiri Olsa 
767556b1fb7SJiri Olsa 	if (aggr_mode == AGGR_GLOBAL)
768556b1fb7SJiri Olsa 		cpu = 0;
769556b1fb7SJiri Olsa 
770556b1fb7SJiri Olsa 	fprintf(output, fmt, avg, csv_sep);
771556b1fb7SJiri Olsa 
772556b1fb7SJiri Olsa 	if (evsel->unit)
773556b1fb7SJiri Olsa 		fprintf(output, "%-*s%s",
774556b1fb7SJiri Olsa 			csv_output ? 0 : unit_width,
775556b1fb7SJiri Olsa 			evsel->unit, csv_sep);
776556b1fb7SJiri Olsa 
777556b1fb7SJiri Olsa 	fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
778556b1fb7SJiri Olsa 
779556b1fb7SJiri Olsa 	if (evsel->cgrp)
780556b1fb7SJiri Olsa 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
781556b1fb7SJiri Olsa 
782556b1fb7SJiri Olsa 	if (csv_output || interval)
783556b1fb7SJiri Olsa 		return;
784556b1fb7SJiri Olsa 
785f87027b9SJiri Olsa 	perf_stat__print_shadow_stats(output, evsel, avg, cpu, aggr_mode);
786556b1fb7SJiri Olsa }
787556b1fb7SJiri Olsa 
78886ee6e18SStephane Eranian static void print_aggr(char *prefix)
789d7e7a451SStephane Eranian {
790d7e7a451SStephane Eranian 	struct perf_evsel *counter;
791582ec082SStephane Eranian 	int cpu, cpu2, s, s2, id, nr;
792410136f5SStephane Eranian 	double uval;
793d7e7a451SStephane Eranian 	u64 ena, run, val;
794d7e7a451SStephane Eranian 
79586ee6e18SStephane Eranian 	if (!(aggr_map || aggr_get_id))
796d7e7a451SStephane Eranian 		return;
797d7e7a451SStephane Eranian 
79886ee6e18SStephane Eranian 	for (s = 0; s < aggr_map->nr; s++) {
79986ee6e18SStephane Eranian 		id = aggr_map->map[s];
8000050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter) {
801d7e7a451SStephane Eranian 			val = ena = run = 0;
802d7e7a451SStephane Eranian 			nr = 0;
803d7e7a451SStephane Eranian 			for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
804582ec082SStephane Eranian 				cpu2 = perf_evsel__cpus(counter)->map[cpu];
805582ec082SStephane Eranian 				s2 = aggr_get_id(evsel_list->cpus, cpu2);
80686ee6e18SStephane Eranian 				if (s2 != id)
807d7e7a451SStephane Eranian 					continue;
8081ac77e1cSJiri Olsa 				val += perf_counts(counter->counts, cpu)->val;
8091ac77e1cSJiri Olsa 				ena += perf_counts(counter->counts, cpu)->ena;
8101ac77e1cSJiri Olsa 				run += perf_counts(counter->counts, cpu)->run;
811d7e7a451SStephane Eranian 				nr++;
812d7e7a451SStephane Eranian 			}
813d7e7a451SStephane Eranian 			if (prefix)
814d7e7a451SStephane Eranian 				fprintf(output, "%s", prefix);
815d7e7a451SStephane Eranian 
816d7e7a451SStephane Eranian 			if (run == 0 || ena == 0) {
817582ec082SStephane Eranian 				aggr_printout(counter, id, nr);
81886ee6e18SStephane Eranian 
819410136f5SStephane Eranian 				fprintf(output, "%*s%s",
820d7e7a451SStephane Eranian 					csv_output ? 0 : 18,
821d7e7a451SStephane Eranian 					counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
822410136f5SStephane Eranian 					csv_sep);
823410136f5SStephane Eranian 
824410136f5SStephane Eranian 				fprintf(output, "%-*s%s",
825410136f5SStephane Eranian 					csv_output ? 0 : unit_width,
826410136f5SStephane Eranian 					counter->unit, csv_sep);
827410136f5SStephane Eranian 
828410136f5SStephane Eranian 				fprintf(output, "%*s",
829410136f5SStephane Eranian 					csv_output ? 0 : -25,
830d7e7a451SStephane Eranian 					perf_evsel__name(counter));
83186ee6e18SStephane Eranian 
832d7e7a451SStephane Eranian 				if (counter->cgrp)
833d7e7a451SStephane Eranian 					fprintf(output, "%s%s",
834d7e7a451SStephane Eranian 						csv_sep, counter->cgrp->name);
835d7e7a451SStephane Eranian 
836d73515c0SAndi Kleen 				print_running(run, ena);
837d7e7a451SStephane Eranian 				fputc('\n', output);
838d7e7a451SStephane Eranian 				continue;
839d7e7a451SStephane Eranian 			}
840410136f5SStephane Eranian 			uval = val * counter->scale;
841d7e7a451SStephane Eranian 
842d7e7a451SStephane Eranian 			if (nsec_counter(counter))
843410136f5SStephane Eranian 				nsec_printout(id, nr, counter, uval);
844d7e7a451SStephane Eranian 			else
845410136f5SStephane Eranian 				abs_printout(id, nr, counter, uval);
846d7e7a451SStephane Eranian 
847d73515c0SAndi Kleen 			if (!csv_output)
848d7e7a451SStephane Eranian 				print_noise(counter, 1.0);
849d7e7a451SStephane Eranian 
850d73515c0SAndi Kleen 			print_running(run, ena);
851d7e7a451SStephane Eranian 			fputc('\n', output);
852d7e7a451SStephane Eranian 		}
853d7e7a451SStephane Eranian 	}
854d7e7a451SStephane Eranian }
855d7e7a451SStephane Eranian 
85642202dd5SIngo Molnar /*
85742202dd5SIngo Molnar  * Print out the results of a single counter:
858f5b4a9c3SStephane Eranian  * aggregated counts in system-wide mode
85942202dd5SIngo Molnar  */
86013370a9bSStephane Eranian static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
86142202dd5SIngo Molnar {
86269aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps = counter->priv;
86369aad6f1SArnaldo Carvalho de Melo 	double avg = avg_stats(&ps->res_stats[0]);
864c52b12edSArnaldo Carvalho de Melo 	int scaled = counter->counts->scaled;
865410136f5SStephane Eranian 	double uval;
866d73515c0SAndi Kleen 	double avg_enabled, avg_running;
867d73515c0SAndi Kleen 
868d73515c0SAndi Kleen 	avg_enabled = avg_stats(&ps->res_stats[1]);
869d73515c0SAndi Kleen 	avg_running = avg_stats(&ps->res_stats[2]);
87042202dd5SIngo Molnar 
87113370a9bSStephane Eranian 	if (prefix)
87213370a9bSStephane Eranian 		fprintf(output, "%s", prefix);
87313370a9bSStephane Eranian 
8743b4331d9SSuzuki K. Poulose 	if (scaled == -1 || !counter->supported) {
875410136f5SStephane Eranian 		fprintf(output, "%*s%s",
876d7470b6aSStephane Eranian 			csv_output ? 0 : 18,
8772cee77c4SDavid Ahern 			counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
878410136f5SStephane Eranian 			csv_sep);
879410136f5SStephane Eranian 		fprintf(output, "%-*s%s",
880410136f5SStephane Eranian 			csv_output ? 0 : unit_width,
881410136f5SStephane Eranian 			counter->unit, csv_sep);
882410136f5SStephane Eranian 		fprintf(output, "%*s",
883410136f5SStephane Eranian 			csv_output ? 0 : -25,
8847289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter));
885023695d9SStephane Eranian 
886023695d9SStephane Eranian 		if (counter->cgrp)
8874aa9015fSStephane Eranian 			fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
888023695d9SStephane Eranian 
889d73515c0SAndi Kleen 		print_running(avg_running, avg_enabled);
8904aa9015fSStephane Eranian 		fputc('\n', output);
89142202dd5SIngo Molnar 		return;
89242202dd5SIngo Molnar 	}
89342202dd5SIngo Molnar 
894410136f5SStephane Eranian 	uval = avg * counter->scale;
895410136f5SStephane Eranian 
89642202dd5SIngo Molnar 	if (nsec_counter(counter))
897410136f5SStephane Eranian 		nsec_printout(-1, 0, counter, uval);
89842202dd5SIngo Molnar 	else
899410136f5SStephane Eranian 		abs_printout(-1, 0, counter, uval);
900849abde9SPeter Zijlstra 
9013ae9a34dSZhengyu He 	print_noise(counter, avg);
9023ae9a34dSZhengyu He 
903d73515c0SAndi Kleen 	print_running(avg_running, avg_enabled);
9044aa9015fSStephane Eranian 	fprintf(output, "\n");
90542202dd5SIngo Molnar }
90642202dd5SIngo Molnar 
907f5b4a9c3SStephane Eranian /*
908f5b4a9c3SStephane Eranian  * Print out the results of a single counter:
909f5b4a9c3SStephane Eranian  * does not use aggregated count in system-wide
910f5b4a9c3SStephane Eranian  */
91113370a9bSStephane Eranian static void print_counter(struct perf_evsel *counter, char *prefix)
912f5b4a9c3SStephane Eranian {
913f5b4a9c3SStephane Eranian 	u64 ena, run, val;
914410136f5SStephane Eranian 	double uval;
915f5b4a9c3SStephane Eranian 	int cpu;
916f5b4a9c3SStephane Eranian 
9177ae92e74SYan, Zheng 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
9181ac77e1cSJiri Olsa 		val = perf_counts(counter->counts, cpu)->val;
9191ac77e1cSJiri Olsa 		ena = perf_counts(counter->counts, cpu)->ena;
9201ac77e1cSJiri Olsa 		run = perf_counts(counter->counts, cpu)->run;
92113370a9bSStephane Eranian 
92213370a9bSStephane Eranian 		if (prefix)
92313370a9bSStephane Eranian 			fprintf(output, "%s", prefix);
92413370a9bSStephane Eranian 
925f5b4a9c3SStephane Eranian 		if (run == 0 || ena == 0) {
926410136f5SStephane Eranian 			fprintf(output, "CPU%*d%s%*s%s",
927d7470b6aSStephane Eranian 				csv_output ? 0 : -4,
9287ae92e74SYan, Zheng 				perf_evsel__cpus(counter)->map[cpu], csv_sep,
929d7470b6aSStephane Eranian 				csv_output ? 0 : 18,
9302cee77c4SDavid Ahern 				counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
931410136f5SStephane Eranian 				csv_sep);
932410136f5SStephane Eranian 
933410136f5SStephane Eranian 				fprintf(output, "%-*s%s",
934410136f5SStephane Eranian 					csv_output ? 0 : unit_width,
935410136f5SStephane Eranian 					counter->unit, csv_sep);
936410136f5SStephane Eranian 
937410136f5SStephane Eranian 				fprintf(output, "%*s",
938410136f5SStephane Eranian 					csv_output ? 0 : -25,
9397289f83cSArnaldo Carvalho de Melo 					perf_evsel__name(counter));
940f5b4a9c3SStephane Eranian 
941023695d9SStephane Eranian 			if (counter->cgrp)
9424aa9015fSStephane Eranian 				fprintf(output, "%s%s",
9434aa9015fSStephane Eranian 					csv_sep, counter->cgrp->name);
944023695d9SStephane Eranian 
945d73515c0SAndi Kleen 			print_running(run, ena);
9464aa9015fSStephane Eranian 			fputc('\n', output);
947f5b4a9c3SStephane Eranian 			continue;
948f5b4a9c3SStephane Eranian 		}
949f5b4a9c3SStephane Eranian 
950410136f5SStephane Eranian 		uval = val * counter->scale;
951410136f5SStephane Eranian 
952f5b4a9c3SStephane Eranian 		if (nsec_counter(counter))
953410136f5SStephane Eranian 			nsec_printout(cpu, 0, counter, uval);
954f5b4a9c3SStephane Eranian 		else
955410136f5SStephane Eranian 			abs_printout(cpu, 0, counter, uval);
956f5b4a9c3SStephane Eranian 
957d73515c0SAndi Kleen 		if (!csv_output)
958f5b4a9c3SStephane Eranian 			print_noise(counter, 1.0);
959d73515c0SAndi Kleen 		print_running(run, ena);
960f5b4a9c3SStephane Eranian 
9614aa9015fSStephane Eranian 		fputc('\n', output);
962f5b4a9c3SStephane Eranian 	}
963f5b4a9c3SStephane Eranian }
964f5b4a9c3SStephane Eranian 
96542202dd5SIngo Molnar static void print_stat(int argc, const char **argv)
96642202dd5SIngo Molnar {
96769aad6f1SArnaldo Carvalho de Melo 	struct perf_evsel *counter;
96869aad6f1SArnaldo Carvalho de Melo 	int i;
96942202dd5SIngo Molnar 
97086470930SIngo Molnar 	fflush(stdout);
97186470930SIngo Molnar 
972d7470b6aSStephane Eranian 	if (!csv_output) {
9734aa9015fSStephane Eranian 		fprintf(output, "\n");
9744aa9015fSStephane Eranian 		fprintf(output, " Performance counter stats for ");
97562d3b617SDavid Ahern 		if (target.system_wide)
97662d3b617SDavid Ahern 			fprintf(output, "\'system wide");
97762d3b617SDavid Ahern 		else if (target.cpu_list)
97862d3b617SDavid Ahern 			fprintf(output, "\'CPU(s) %s", target.cpu_list);
979602ad878SArnaldo Carvalho de Melo 		else if (!target__has_task(&target)) {
9804aa9015fSStephane Eranian 			fprintf(output, "\'%s", argv[0]);
98186470930SIngo Molnar 			for (i = 1; i < argc; i++)
9824aa9015fSStephane Eranian 				fprintf(output, " %s", argv[i]);
98320f946b4SNamhyung Kim 		} else if (target.pid)
98420f946b4SNamhyung Kim 			fprintf(output, "process id \'%s", target.pid);
985d6d901c2SZhang, Yanmin 		else
98620f946b4SNamhyung Kim 			fprintf(output, "thread id \'%s", target.tid);
98786470930SIngo Molnar 
9884aa9015fSStephane Eranian 		fprintf(output, "\'");
98942202dd5SIngo Molnar 		if (run_count > 1)
9904aa9015fSStephane Eranian 			fprintf(output, " (%d runs)", run_count);
9914aa9015fSStephane Eranian 		fprintf(output, ":\n\n");
992d7470b6aSStephane Eranian 	}
99386470930SIngo Molnar 
99486ee6e18SStephane Eranian 	switch (aggr_mode) {
99512c08a9fSStephane Eranian 	case AGGR_CORE:
99686ee6e18SStephane Eranian 	case AGGR_SOCKET:
99786ee6e18SStephane Eranian 		print_aggr(NULL);
99886ee6e18SStephane Eranian 		break;
99986ee6e18SStephane Eranian 	case AGGR_GLOBAL:
10000050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
100113370a9bSStephane Eranian 			print_counter_aggr(counter, NULL);
100286ee6e18SStephane Eranian 		break;
100386ee6e18SStephane Eranian 	case AGGR_NONE:
10040050f7aaSArnaldo Carvalho de Melo 		evlist__for_each(evsel_list, counter)
100586ee6e18SStephane Eranian 			print_counter(counter, NULL);
100686ee6e18SStephane Eranian 		break;
100786ee6e18SStephane Eranian 	default:
100886ee6e18SStephane Eranian 		break;
1009f5b4a9c3SStephane Eranian 	}
101086470930SIngo Molnar 
1011d7470b6aSStephane Eranian 	if (!csv_output) {
1012c3305257SIngo Molnar 		if (!null_run)
10134aa9015fSStephane Eranian 			fprintf(output, "\n");
10144aa9015fSStephane Eranian 		fprintf(output, " %17.9f seconds time elapsed",
1015506d4bc8SPeter Zijlstra 				avg_stats(&walltime_nsecs_stats)/1e9);
1016566747e6SIngo Molnar 		if (run_count > 1) {
10174aa9015fSStephane Eranian 			fprintf(output, "                                        ");
1018f99844cbSIngo Molnar 			print_noise_pct(stddev_stats(&walltime_nsecs_stats),
1019506d4bc8SPeter Zijlstra 					avg_stats(&walltime_nsecs_stats));
1020566747e6SIngo Molnar 		}
10214aa9015fSStephane Eranian 		fprintf(output, "\n\n");
102286470930SIngo Molnar 	}
1023d7470b6aSStephane Eranian }
102486470930SIngo Molnar 
1025f7b7c26eSPeter Zijlstra static volatile int signr = -1;
1026f7b7c26eSPeter Zijlstra 
102786470930SIngo Molnar static void skip_signal(int signo)
102886470930SIngo Molnar {
102913370a9bSStephane Eranian 	if ((child_pid == -1) || interval)
103060666c63SLiming Wang 		done = 1;
103160666c63SLiming Wang 
1032f7b7c26eSPeter Zijlstra 	signr = signo;
1033d07f0b12SStephane Eranian 	/*
1034d07f0b12SStephane Eranian 	 * render child_pid harmless
1035d07f0b12SStephane Eranian 	 * won't send SIGTERM to a random
1036d07f0b12SStephane Eranian 	 * process in case of race condition
1037d07f0b12SStephane Eranian 	 * and fast PID recycling
1038d07f0b12SStephane Eranian 	 */
1039d07f0b12SStephane Eranian 	child_pid = -1;
1040f7b7c26eSPeter Zijlstra }
1041f7b7c26eSPeter Zijlstra 
1042f7b7c26eSPeter Zijlstra static void sig_atexit(void)
1043f7b7c26eSPeter Zijlstra {
1044d07f0b12SStephane Eranian 	sigset_t set, oset;
1045d07f0b12SStephane Eranian 
1046d07f0b12SStephane Eranian 	/*
1047d07f0b12SStephane Eranian 	 * avoid race condition with SIGCHLD handler
1048d07f0b12SStephane Eranian 	 * in skip_signal() which is modifying child_pid
1049d07f0b12SStephane Eranian 	 * goal is to avoid send SIGTERM to a random
1050d07f0b12SStephane Eranian 	 * process
1051d07f0b12SStephane Eranian 	 */
1052d07f0b12SStephane Eranian 	sigemptyset(&set);
1053d07f0b12SStephane Eranian 	sigaddset(&set, SIGCHLD);
1054d07f0b12SStephane Eranian 	sigprocmask(SIG_BLOCK, &set, &oset);
1055d07f0b12SStephane Eranian 
1056933da83aSChris Wilson 	if (child_pid != -1)
1057933da83aSChris Wilson 		kill(child_pid, SIGTERM);
1058933da83aSChris Wilson 
1059d07f0b12SStephane Eranian 	sigprocmask(SIG_SETMASK, &oset, NULL);
1060d07f0b12SStephane Eranian 
1061f7b7c26eSPeter Zijlstra 	if (signr == -1)
1062f7b7c26eSPeter Zijlstra 		return;
1063f7b7c26eSPeter Zijlstra 
1064f7b7c26eSPeter Zijlstra 	signal(signr, SIG_DFL);
1065f7b7c26eSPeter Zijlstra 	kill(getpid(), signr);
106686470930SIngo Molnar }
106786470930SIngo Molnar 
10681d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused,
10691d037ca1SIrina Tirdea 			     const char *s __maybe_unused, int unset)
1070d7470b6aSStephane Eranian {
1071d7470b6aSStephane Eranian 	big_num_opt = unset ? 0 : 1;
1072d7470b6aSStephane Eranian 	return 0;
1073d7470b6aSStephane Eranian }
1074d7470b6aSStephane Eranian 
107586ee6e18SStephane Eranian static int perf_stat_init_aggr_mode(void)
107686ee6e18SStephane Eranian {
107786ee6e18SStephane Eranian 	switch (aggr_mode) {
107886ee6e18SStephane Eranian 	case AGGR_SOCKET:
107986ee6e18SStephane Eranian 		if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
108086ee6e18SStephane Eranian 			perror("cannot build socket map");
108186ee6e18SStephane Eranian 			return -1;
108286ee6e18SStephane Eranian 		}
108386ee6e18SStephane Eranian 		aggr_get_id = cpu_map__get_socket;
108486ee6e18SStephane Eranian 		break;
108512c08a9fSStephane Eranian 	case AGGR_CORE:
108612c08a9fSStephane Eranian 		if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
108712c08a9fSStephane Eranian 			perror("cannot build core map");
108812c08a9fSStephane Eranian 			return -1;
108912c08a9fSStephane Eranian 		}
109012c08a9fSStephane Eranian 		aggr_get_id = cpu_map__get_core;
109112c08a9fSStephane Eranian 		break;
109286ee6e18SStephane Eranian 	case AGGR_NONE:
109386ee6e18SStephane Eranian 	case AGGR_GLOBAL:
109486ee6e18SStephane Eranian 	default:
109586ee6e18SStephane Eranian 		break;
109686ee6e18SStephane Eranian 	}
109786ee6e18SStephane Eranian 	return 0;
109886ee6e18SStephane Eranian }
109986ee6e18SStephane Eranian 
11002cba3ffbSIngo Molnar /*
11012cba3ffbSIngo Molnar  * Add default attributes, if there were no attributes specified or
11022cba3ffbSIngo Molnar  * if -d/--detailed, -d -d or -d -d -d is used:
11032cba3ffbSIngo Molnar  */
11042cba3ffbSIngo Molnar static int add_default_attributes(void)
11052cba3ffbSIngo Molnar {
1106b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr default_attrs[] = {
1107b070a547SArnaldo Carvalho de Melo 
1108b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
1109b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
1110b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
1111b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
1112b070a547SArnaldo Carvalho de Melo 
1113b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
1114b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
1115b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
1116b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
1117b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
1118b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
1119b070a547SArnaldo Carvalho de Melo 
1120b070a547SArnaldo Carvalho de Melo };
1121b070a547SArnaldo Carvalho de Melo 
1122b070a547SArnaldo Carvalho de Melo /*
1123b070a547SArnaldo Carvalho de Melo  * Detailed stats (-d), covering the L1 and last level data caches:
1124b070a547SArnaldo Carvalho de Melo  */
1125b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr detailed_attrs[] = {
1126b070a547SArnaldo Carvalho de Melo 
1127b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1128b070a547SArnaldo Carvalho de Melo     .config =
1129b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1130b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1131b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1132b070a547SArnaldo Carvalho de Melo 
1133b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1134b070a547SArnaldo Carvalho de Melo     .config =
1135b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1136b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1137b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1138b070a547SArnaldo Carvalho de Melo 
1139b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1140b070a547SArnaldo Carvalho de Melo     .config =
1141b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1142b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1143b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1144b070a547SArnaldo Carvalho de Melo 
1145b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1146b070a547SArnaldo Carvalho de Melo     .config =
1147b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1148b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1149b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1150b070a547SArnaldo Carvalho de Melo };
1151b070a547SArnaldo Carvalho de Melo 
1152b070a547SArnaldo Carvalho de Melo /*
1153b070a547SArnaldo Carvalho de Melo  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1154b070a547SArnaldo Carvalho de Melo  */
1155b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_detailed_attrs[] = {
1156b070a547SArnaldo Carvalho de Melo 
1157b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1158b070a547SArnaldo Carvalho de Melo     .config =
1159b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1160b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1161b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1162b070a547SArnaldo Carvalho de Melo 
1163b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1164b070a547SArnaldo Carvalho de Melo     .config =
1165b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1166b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1167b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1168b070a547SArnaldo Carvalho de Melo 
1169b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1170b070a547SArnaldo Carvalho de Melo     .config =
1171b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1172b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1173b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1174b070a547SArnaldo Carvalho de Melo 
1175b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1176b070a547SArnaldo Carvalho de Melo     .config =
1177b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1178b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1179b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1180b070a547SArnaldo Carvalho de Melo 
1181b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1182b070a547SArnaldo Carvalho de Melo     .config =
1183b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1184b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1185b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1186b070a547SArnaldo Carvalho de Melo 
1187b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1188b070a547SArnaldo Carvalho de Melo     .config =
1189b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1190b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1191b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1192b070a547SArnaldo Carvalho de Melo 
1193b070a547SArnaldo Carvalho de Melo };
1194b070a547SArnaldo Carvalho de Melo 
1195b070a547SArnaldo Carvalho de Melo /*
1196b070a547SArnaldo Carvalho de Melo  * Very, very detailed stats (-d -d -d), adding prefetch events:
1197b070a547SArnaldo Carvalho de Melo  */
1198b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_very_detailed_attrs[] = {
1199b070a547SArnaldo Carvalho de Melo 
1200b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1201b070a547SArnaldo Carvalho de Melo     .config =
1202b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1203b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1204b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1205b070a547SArnaldo Carvalho de Melo 
1206b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1207b070a547SArnaldo Carvalho de Melo     .config =
1208b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1209b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1210b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1211b070a547SArnaldo Carvalho de Melo };
1212b070a547SArnaldo Carvalho de Melo 
12132cba3ffbSIngo Molnar 	/* Set attrs if no event is selected and !null_run: */
12142cba3ffbSIngo Molnar 	if (null_run)
12152cba3ffbSIngo Molnar 		return 0;
12162cba3ffbSIngo Molnar 
12174cabc3d1SAndi Kleen 	if (transaction_run) {
12184cabc3d1SAndi Kleen 		int err;
12194cabc3d1SAndi Kleen 		if (pmu_have_event("cpu", "cycles-ct") &&
12204cabc3d1SAndi Kleen 		    pmu_have_event("cpu", "el-start"))
1221a454742cSJiri Olsa 			err = parse_events(evsel_list, transaction_attrs, NULL);
12224cabc3d1SAndi Kleen 		else
1223a454742cSJiri Olsa 			err = parse_events(evsel_list, transaction_limited_attrs, NULL);
1224a454742cSJiri Olsa 		if (err) {
12254cabc3d1SAndi Kleen 			fprintf(stderr, "Cannot set up transaction events\n");
12264cabc3d1SAndi Kleen 			return -1;
12274cabc3d1SAndi Kleen 		}
12284cabc3d1SAndi Kleen 		return 0;
12294cabc3d1SAndi Kleen 	}
12304cabc3d1SAndi Kleen 
12312cba3ffbSIngo Molnar 	if (!evsel_list->nr_entries) {
123279695e1bSArnaldo Carvalho de Melo 		if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
12332cba3ffbSIngo Molnar 			return -1;
12342cba3ffbSIngo Molnar 	}
12352cba3ffbSIngo Molnar 
12362cba3ffbSIngo Molnar 	/* Detailed events get appended to the event list: */
12372cba3ffbSIngo Molnar 
12382cba3ffbSIngo Molnar 	if (detailed_run <  1)
12392cba3ffbSIngo Molnar 		return 0;
12402cba3ffbSIngo Molnar 
12412cba3ffbSIngo Molnar 	/* Append detailed run extra attributes: */
124279695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
12432cba3ffbSIngo Molnar 		return -1;
12442cba3ffbSIngo Molnar 
12452cba3ffbSIngo Molnar 	if (detailed_run < 2)
12462cba3ffbSIngo Molnar 		return 0;
12472cba3ffbSIngo Molnar 
12482cba3ffbSIngo Molnar 	/* Append very detailed run extra attributes: */
124979695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
12502cba3ffbSIngo Molnar 		return -1;
12512cba3ffbSIngo Molnar 
12522cba3ffbSIngo Molnar 	if (detailed_run < 3)
12532cba3ffbSIngo Molnar 		return 0;
12542cba3ffbSIngo Molnar 
12552cba3ffbSIngo Molnar 	/* Append very, very detailed run extra attributes: */
125679695e1bSArnaldo Carvalho de Melo 	return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
12572cba3ffbSIngo Molnar }
12582cba3ffbSIngo Molnar 
12591d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
126086470930SIngo Molnar {
12611f16c575SPeter Zijlstra 	bool append_file = false;
1262b070a547SArnaldo Carvalho de Melo 	int output_fd = 0;
1263b070a547SArnaldo Carvalho de Melo 	const char *output_name	= NULL;
1264b070a547SArnaldo Carvalho de Melo 	const struct option options[] = {
12654cabc3d1SAndi Kleen 	OPT_BOOLEAN('T', "transaction", &transaction_run,
12664cabc3d1SAndi Kleen 		    "hardware transaction statistics"),
1267b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK('e', "event", &evsel_list, "event",
1268b070a547SArnaldo Carvalho de Melo 		     "event selector. use 'perf list' to list available events",
1269b070a547SArnaldo Carvalho de Melo 		     parse_events_option),
1270b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1271b070a547SArnaldo Carvalho de Melo 		     "event filter", parse_filter),
1272b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1273b070a547SArnaldo Carvalho de Melo 		    "child tasks do not inherit counters"),
1274b070a547SArnaldo Carvalho de Melo 	OPT_STRING('p', "pid", &target.pid, "pid",
1275b070a547SArnaldo Carvalho de Melo 		   "stat events on existing process id"),
1276b070a547SArnaldo Carvalho de Melo 	OPT_STRING('t', "tid", &target.tid, "tid",
1277b070a547SArnaldo Carvalho de Melo 		   "stat events on existing thread id"),
1278b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1279b070a547SArnaldo Carvalho de Melo 		    "system-wide collection from all CPUs"),
1280b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('g', "group", &group,
1281b070a547SArnaldo Carvalho de Melo 		    "put the counters into a counter group"),
1282b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"),
1283b070a547SArnaldo Carvalho de Melo 	OPT_INCR('v', "verbose", &verbose,
1284b070a547SArnaldo Carvalho de Melo 		    "be more verbose (show counter open errors, etc)"),
1285b070a547SArnaldo Carvalho de Melo 	OPT_INTEGER('r', "repeat", &run_count,
1286a7e191c3SFrederik Deweerdt 		    "repeat command and print average + stddev (max: 100, forever: 0)"),
1287b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('n', "null", &null_run,
1288b070a547SArnaldo Carvalho de Melo 		    "null run - dont start any counters"),
1289b070a547SArnaldo Carvalho de Melo 	OPT_INCR('d', "detailed", &detailed_run,
1290b070a547SArnaldo Carvalho de Melo 		    "detailed run - start a lot of events"),
1291b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('S', "sync", &sync_run,
1292b070a547SArnaldo Carvalho de Melo 		    "call sync() before starting a run"),
1293b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1294b070a547SArnaldo Carvalho de Melo 			   "print large numbers with thousands\' separators",
1295b070a547SArnaldo Carvalho de Melo 			   stat__set_big_num),
1296b070a547SArnaldo Carvalho de Melo 	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1297b070a547SArnaldo Carvalho de Melo 		    "list of cpus to monitor in system-wide"),
129886ee6e18SStephane Eranian 	OPT_SET_UINT('A', "no-aggr", &aggr_mode,
129986ee6e18SStephane Eranian 		    "disable CPU count aggregation", AGGR_NONE),
1300b070a547SArnaldo Carvalho de Melo 	OPT_STRING('x', "field-separator", &csv_sep, "separator",
1301b070a547SArnaldo Carvalho de Melo 		   "print counts with custom separator"),
1302b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1303b070a547SArnaldo Carvalho de Melo 		     "monitor event in cgroup name only", parse_cgroups),
1304b070a547SArnaldo Carvalho de Melo 	OPT_STRING('o', "output", &output_name, "file", "output file name"),
1305b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1306b070a547SArnaldo Carvalho de Melo 	OPT_INTEGER(0, "log-fd", &output_fd,
1307b070a547SArnaldo Carvalho de Melo 		    "log output to fd, instead of stderr"),
13081f16c575SPeter Zijlstra 	OPT_STRING(0, "pre", &pre_cmd, "command",
13091f16c575SPeter Zijlstra 			"command to run prior to the measured command"),
13101f16c575SPeter Zijlstra 	OPT_STRING(0, "post", &post_cmd, "command",
13111f16c575SPeter Zijlstra 			"command to run after to the measured command"),
131213370a9bSStephane Eranian 	OPT_UINTEGER('I', "interval-print", &interval,
131313370a9bSStephane Eranian 		    "print counts at regular interval in ms (>= 100)"),
1314d4304958SStephane Eranian 	OPT_SET_UINT(0, "per-socket", &aggr_mode,
131586ee6e18SStephane Eranian 		     "aggregate counts per processor socket", AGGR_SOCKET),
131612c08a9fSStephane Eranian 	OPT_SET_UINT(0, "per-core", &aggr_mode,
131712c08a9fSStephane Eranian 		     "aggregate counts per physical processor core", AGGR_CORE),
131841191688SAndi Kleen 	OPT_UINTEGER('D', "delay", &initial_delay,
131941191688SAndi Kleen 		     "ms to wait before starting measurement after program start"),
1320b070a547SArnaldo Carvalho de Melo 	OPT_END()
1321b070a547SArnaldo Carvalho de Melo 	};
1322b070a547SArnaldo Carvalho de Melo 	const char * const stat_usage[] = {
1323b070a547SArnaldo Carvalho de Melo 		"perf stat [<options>] [<command>]",
1324b070a547SArnaldo Carvalho de Melo 		NULL
1325b070a547SArnaldo Carvalho de Melo 	};
1326cc03c542SNamhyung Kim 	int status = -EINVAL, run_idx;
13274aa9015fSStephane Eranian 	const char *mode;
132842202dd5SIngo Molnar 
13295af52b51SStephane Eranian 	setlocale(LC_ALL, "");
13305af52b51SStephane Eranian 
1331334fe7a3SNamhyung Kim 	evsel_list = perf_evlist__new();
1332361c99a6SArnaldo Carvalho de Melo 	if (evsel_list == NULL)
1333361c99a6SArnaldo Carvalho de Melo 		return -ENOMEM;
1334361c99a6SArnaldo Carvalho de Melo 
1335a0541234SAnton Blanchard 	argc = parse_options(argc, argv, options, stat_usage,
1336a0541234SAnton Blanchard 		PARSE_OPT_STOP_AT_NON_OPTION);
1337d7470b6aSStephane Eranian 
13384aa9015fSStephane Eranian 	output = stderr;
13394aa9015fSStephane Eranian 	if (output_name && strcmp(output_name, "-"))
13404aa9015fSStephane Eranian 		output = NULL;
13414aa9015fSStephane Eranian 
134256f3bae7SJim Cromie 	if (output_name && output_fd) {
134356f3bae7SJim Cromie 		fprintf(stderr, "cannot use both --output and --log-fd\n");
1344cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "o", 1);
1345cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "log-fd", 0);
1346cc03c542SNamhyung Kim 		goto out;
134756f3bae7SJim Cromie 	}
1348fc3e4d07SStephane Eranian 
1349fc3e4d07SStephane Eranian 	if (output_fd < 0) {
1350fc3e4d07SStephane Eranian 		fprintf(stderr, "argument to --log-fd must be a > 0\n");
1351cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "log-fd", 0);
1352cc03c542SNamhyung Kim 		goto out;
1353fc3e4d07SStephane Eranian 	}
1354fc3e4d07SStephane Eranian 
13554aa9015fSStephane Eranian 	if (!output) {
13564aa9015fSStephane Eranian 		struct timespec tm;
13574aa9015fSStephane Eranian 		mode = append_file ? "a" : "w";
13584aa9015fSStephane Eranian 
13594aa9015fSStephane Eranian 		output = fopen(output_name, mode);
13604aa9015fSStephane Eranian 		if (!output) {
13614aa9015fSStephane Eranian 			perror("failed to create output file");
1362fceda7feSDavid Ahern 			return -1;
13634aa9015fSStephane Eranian 		}
13644aa9015fSStephane Eranian 		clock_gettime(CLOCK_REALTIME, &tm);
13654aa9015fSStephane Eranian 		fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1366fc3e4d07SStephane Eranian 	} else if (output_fd > 0) {
136756f3bae7SJim Cromie 		mode = append_file ? "a" : "w";
136856f3bae7SJim Cromie 		output = fdopen(output_fd, mode);
136956f3bae7SJim Cromie 		if (!output) {
137056f3bae7SJim Cromie 			perror("Failed opening logfd");
137156f3bae7SJim Cromie 			return -errno;
137256f3bae7SJim Cromie 		}
13734aa9015fSStephane Eranian 	}
13744aa9015fSStephane Eranian 
1375d4ffd04dSJim Cromie 	if (csv_sep) {
1376d7470b6aSStephane Eranian 		csv_output = true;
1377d4ffd04dSJim Cromie 		if (!strcmp(csv_sep, "\\t"))
1378d4ffd04dSJim Cromie 			csv_sep = "\t";
1379d4ffd04dSJim Cromie 	} else
1380d7470b6aSStephane Eranian 		csv_sep = DEFAULT_SEPARATOR;
1381d7470b6aSStephane Eranian 
1382d7470b6aSStephane Eranian 	/*
1383d7470b6aSStephane Eranian 	 * let the spreadsheet do the pretty-printing
1384d7470b6aSStephane Eranian 	 */
1385d7470b6aSStephane Eranian 	if (csv_output) {
138661a9f324SJim Cromie 		/* User explicitly passed -B? */
1387d7470b6aSStephane Eranian 		if (big_num_opt == 1) {
1388d7470b6aSStephane Eranian 			fprintf(stderr, "-B option not supported with -x\n");
1389cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "B", 1);
1390cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "x", 1);
1391cc03c542SNamhyung Kim 			goto out;
1392d7470b6aSStephane Eranian 		} else /* Nope, so disable big number formatting */
1393d7470b6aSStephane Eranian 			big_num = false;
1394d7470b6aSStephane Eranian 	} else if (big_num_opt == 0) /* User passed --no-big-num */
1395d7470b6aSStephane Eranian 		big_num = false;
1396d7470b6aSStephane Eranian 
1397602ad878SArnaldo Carvalho de Melo 	if (!argc && target__none(&target))
139886470930SIngo Molnar 		usage_with_options(stat_usage, options);
1399ac3063bdSDavid Ahern 
1400a7e191c3SFrederik Deweerdt 	if (run_count < 0) {
1401cc03c542SNamhyung Kim 		pr_err("Run count must be a positive number\n");
1402cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "r", 1);
1403cc03c542SNamhyung Kim 		goto out;
1404a7e191c3SFrederik Deweerdt 	} else if (run_count == 0) {
1405a7e191c3SFrederik Deweerdt 		forever = true;
1406a7e191c3SFrederik Deweerdt 		run_count = 1;
1407a7e191c3SFrederik Deweerdt 	}
140886470930SIngo Molnar 
1409023695d9SStephane Eranian 	/* no_aggr, cgroup are for system-wide only */
1410602ad878SArnaldo Carvalho de Melo 	if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) &&
1411602ad878SArnaldo Carvalho de Melo 	    !target__has_cpu(&target)) {
1412023695d9SStephane Eranian 		fprintf(stderr, "both cgroup and no-aggregation "
1413023695d9SStephane Eranian 			"modes only available in system-wide mode\n");
1414023695d9SStephane Eranian 
1415cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "G", 1);
1416cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "A", 1);
1417cc03c542SNamhyung Kim 		parse_options_usage(NULL, options, "a", 1);
1418cc03c542SNamhyung Kim 		goto out;
1419d7e7a451SStephane Eranian 	}
1420d7e7a451SStephane Eranian 
14212cba3ffbSIngo Molnar 	if (add_default_attributes())
1422c6264defSIngo Molnar 		goto out;
142386470930SIngo Molnar 
1424602ad878SArnaldo Carvalho de Melo 	target__validate(&target);
14255c98d466SArnaldo Carvalho de Melo 
142677a6f014SNamhyung Kim 	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1427602ad878SArnaldo Carvalho de Melo 		if (target__has_task(&target)) {
14285c98d466SArnaldo Carvalho de Melo 			pr_err("Problems finding threads of monitor\n");
1429cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "p", 1);
1430cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "t", 1);
1431602ad878SArnaldo Carvalho de Melo 		} else if (target__has_cpu(&target)) {
143260d567e2SArnaldo Carvalho de Melo 			perror("failed to parse CPUs map");
1433cc03c542SNamhyung Kim 			parse_options_usage(stat_usage, options, "C", 1);
1434cc03c542SNamhyung Kim 			parse_options_usage(NULL, options, "a", 1);
1435cc03c542SNamhyung Kim 		}
1436cc03c542SNamhyung Kim 		goto out;
143760d567e2SArnaldo Carvalho de Melo 	}
143813370a9bSStephane Eranian 	if (interval && interval < 100) {
143913370a9bSStephane Eranian 		pr_err("print interval must be >= 100ms\n");
1440cc03c542SNamhyung Kim 		parse_options_usage(stat_usage, options, "I", 1);
144103ad9747SArnaldo Carvalho de Melo 		goto out;
144213370a9bSStephane Eranian 	}
1443c45c6ea2SStephane Eranian 
1444d134ffb9SArnaldo Carvalho de Melo 	if (perf_evlist__alloc_stats(evsel_list, interval))
144503ad9747SArnaldo Carvalho de Melo 		goto out;
1446d6d901c2SZhang, Yanmin 
144786ee6e18SStephane Eranian 	if (perf_stat_init_aggr_mode())
144803ad9747SArnaldo Carvalho de Melo 		goto out;
144986ee6e18SStephane Eranian 
145086470930SIngo Molnar 	/*
145186470930SIngo Molnar 	 * We dont want to block the signals - that would cause
145286470930SIngo Molnar 	 * child tasks to inherit that and Ctrl-C would not work.
145386470930SIngo Molnar 	 * What we want is for Ctrl-C to work in the exec()-ed
145486470930SIngo Molnar 	 * task, but being ignored by perf stat itself:
145586470930SIngo Molnar 	 */
1456f7b7c26eSPeter Zijlstra 	atexit(sig_atexit);
1457a7e191c3SFrederik Deweerdt 	if (!forever)
145886470930SIngo Molnar 		signal(SIGINT,  skip_signal);
145913370a9bSStephane Eranian 	signal(SIGCHLD, skip_signal);
146086470930SIngo Molnar 	signal(SIGALRM, skip_signal);
146186470930SIngo Molnar 	signal(SIGABRT, skip_signal);
146286470930SIngo Molnar 
146342202dd5SIngo Molnar 	status = 0;
1464a7e191c3SFrederik Deweerdt 	for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
146542202dd5SIngo Molnar 		if (run_count != 1 && verbose)
14664aa9015fSStephane Eranian 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
14674aa9015fSStephane Eranian 				run_idx + 1);
1468f9cef0a9SIngo Molnar 
146942202dd5SIngo Molnar 		status = run_perf_stat(argc, argv);
1470a7e191c3SFrederik Deweerdt 		if (forever && status != -1) {
1471a7e191c3SFrederik Deweerdt 			print_stat(argc, argv);
1472d134ffb9SArnaldo Carvalho de Melo 			perf_stat__reset_stats(evsel_list);
1473a7e191c3SFrederik Deweerdt 		}
147442202dd5SIngo Molnar 	}
147542202dd5SIngo Molnar 
1476a7e191c3SFrederik Deweerdt 	if (!forever && status != -1 && !interval)
147742202dd5SIngo Molnar 		print_stat(argc, argv);
1478d134ffb9SArnaldo Carvalho de Melo 
1479d134ffb9SArnaldo Carvalho de Melo 	perf_evlist__free_stats(evsel_list);
14800015e2e1SArnaldo Carvalho de Melo out:
14810015e2e1SArnaldo Carvalho de Melo 	perf_evlist__delete(evsel_list);
148242202dd5SIngo Molnar 	return status;
148386470930SIngo Molnar }
1484