xref: /openbmc/linux/tools/perf/builtin-stat.c (revision 823254ed)
186470930SIngo Molnar /*
286470930SIngo Molnar  * builtin-stat.c
386470930SIngo Molnar  *
486470930SIngo Molnar  * Builtin stat command: Give a precise performance counters summary
586470930SIngo Molnar  * overview about any workload, CPU or specific PID.
686470930SIngo Molnar  *
786470930SIngo Molnar  * Sample output:
886470930SIngo Molnar 
92cba3ffbSIngo Molnar    $ perf stat ./hackbench 10
1086470930SIngo Molnar 
112cba3ffbSIngo Molnar   Time: 0.118
1286470930SIngo Molnar 
132cba3ffbSIngo Molnar   Performance counter stats for './hackbench 10':
1486470930SIngo Molnar 
152cba3ffbSIngo Molnar        1708.761321 task-clock                #   11.037 CPUs utilized
162cba3ffbSIngo Molnar             41,190 context-switches          #    0.024 M/sec
172cba3ffbSIngo Molnar              6,735 CPU-migrations            #    0.004 M/sec
182cba3ffbSIngo Molnar             17,318 page-faults               #    0.010 M/sec
192cba3ffbSIngo Molnar      5,205,202,243 cycles                    #    3.046 GHz
202cba3ffbSIngo Molnar      3,856,436,920 stalled-cycles-frontend   #   74.09% frontend cycles idle
212cba3ffbSIngo Molnar      1,600,790,871 stalled-cycles-backend    #   30.75% backend  cycles idle
222cba3ffbSIngo Molnar      2,603,501,247 instructions              #    0.50  insns per cycle
232cba3ffbSIngo Molnar                                              #    1.48  stalled cycles per insn
242cba3ffbSIngo Molnar        484,357,498 branches                  #  283.455 M/sec
252cba3ffbSIngo Molnar          6,388,934 branch-misses             #    1.32% of all branches
262cba3ffbSIngo Molnar 
272cba3ffbSIngo Molnar         0.154822978  seconds time elapsed
2886470930SIngo Molnar 
2986470930SIngo Molnar  *
302cba3ffbSIngo Molnar  * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
3186470930SIngo Molnar  *
3286470930SIngo Molnar  * Improvements and fixes by:
3386470930SIngo Molnar  *
3486470930SIngo Molnar  *   Arjan van de Ven <arjan@linux.intel.com>
3586470930SIngo Molnar  *   Yanmin Zhang <yanmin.zhang@intel.com>
3686470930SIngo Molnar  *   Wu Fengguang <fengguang.wu@intel.com>
3786470930SIngo Molnar  *   Mike Galbraith <efault@gmx.de>
3886470930SIngo Molnar  *   Paul Mackerras <paulus@samba.org>
396e750a8fSJaswinder Singh Rajput  *   Jaswinder Singh Rajput <jaswinder@kernel.org>
4086470930SIngo Molnar  *
4186470930SIngo Molnar  * Released under the GPL v2. (and only v2, not any later version)
4286470930SIngo Molnar  */
4386470930SIngo Molnar 
4486470930SIngo Molnar #include "perf.h"
4586470930SIngo Molnar #include "builtin.h"
4686470930SIngo Molnar #include "util/util.h"
4786470930SIngo Molnar #include "util/parse-options.h"
4886470930SIngo Molnar #include "util/parse-events.h"
498f28827aSFrederic Weisbecker #include "util/event.h"
50361c99a6SArnaldo Carvalho de Melo #include "util/evlist.h"
5169aad6f1SArnaldo Carvalho de Melo #include "util/evsel.h"
528f28827aSFrederic Weisbecker #include "util/debug.h"
53a5d243d0SIngo Molnar #include "util/color.h"
540007eceaSXiao Guangrong #include "util/stat.h"
5560666c63SLiming Wang #include "util/header.h"
56a12b51c4SPaul Mackerras #include "util/cpumap.h"
57d6d901c2SZhang, Yanmin #include "util/thread.h"
58fd78260bSArnaldo Carvalho de Melo #include "util/thread_map.h"
5986470930SIngo Molnar 
601f16c575SPeter Zijlstra #include <stdlib.h>
6186470930SIngo Molnar #include <sys/prctl.h>
625af52b51SStephane Eranian #include <locale.h>
6386470930SIngo Molnar 
64d7470b6aSStephane Eranian #define DEFAULT_SEPARATOR	" "
652cee77c4SDavid Ahern #define CNTR_NOT_SUPPORTED	"<not supported>"
662cee77c4SDavid Ahern #define CNTR_NOT_COUNTED	"<not counted>"
67d7470b6aSStephane Eranian 
68666e6d48SRobert Richter static struct perf_evlist	*evsel_list;
69361c99a6SArnaldo Carvalho de Melo 
7077a6f014SNamhyung Kim static struct perf_target	target = {
7177a6f014SNamhyung Kim 	.uid	= UINT_MAX,
7277a6f014SNamhyung Kim };
7342202dd5SIngo Molnar 
743d632595SJaswinder Singh Rajput static int			run_count			=  1;
752e6cdf99SStephane Eranian static bool			no_inherit			= false;
76c0555642SIan Munsie static bool			scale				=  true;
77f5b4a9c3SStephane Eranian static bool			no_aggr				= false;
78933da83aSChris Wilson static pid_t			child_pid			= -1;
79c0555642SIan Munsie static bool			null_run			=  false;
802cba3ffbSIngo Molnar static int			detailed_run			=  0;
81201e0b06SArnaldo Carvalho de Melo static bool			big_num				=  true;
82d7470b6aSStephane Eranian static int			big_num_opt			=  -1;
83d7470b6aSStephane Eranian static const char		*csv_sep			= NULL;
84d7470b6aSStephane Eranian static bool			csv_output			= false;
8543bece79SLin Ming static bool			group				= false;
864aa9015fSStephane Eranian static FILE			*output				= NULL;
871f16c575SPeter Zijlstra static const char		*pre_cmd			= NULL;
881f16c575SPeter Zijlstra static const char		*post_cmd			= NULL;
891f16c575SPeter Zijlstra static bool			sync_run			= false;
905af52b51SStephane Eranian 
9160666c63SLiming Wang static volatile int done = 0;
9260666c63SLiming Wang 
9369aad6f1SArnaldo Carvalho de Melo struct perf_stat {
9469aad6f1SArnaldo Carvalho de Melo 	struct stats	  res_stats[3];
9569aad6f1SArnaldo Carvalho de Melo };
9669aad6f1SArnaldo Carvalho de Melo 
97c52b12edSArnaldo Carvalho de Melo static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
9869aad6f1SArnaldo Carvalho de Melo {
99c52b12edSArnaldo Carvalho de Melo 	evsel->priv = zalloc(sizeof(struct perf_stat));
10069aad6f1SArnaldo Carvalho de Melo 	return evsel->priv == NULL ? -ENOMEM : 0;
10169aad6f1SArnaldo Carvalho de Melo }
10269aad6f1SArnaldo Carvalho de Melo 
10369aad6f1SArnaldo Carvalho de Melo static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
10469aad6f1SArnaldo Carvalho de Melo {
10569aad6f1SArnaldo Carvalho de Melo 	free(evsel->priv);
10669aad6f1SArnaldo Carvalho de Melo 	evsel->priv = NULL;
10769aad6f1SArnaldo Carvalho de Melo }
10869aad6f1SArnaldo Carvalho de Melo 
1097ae92e74SYan, Zheng static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
1107ae92e74SYan, Zheng {
1117ae92e74SYan, Zheng 	return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus;
1127ae92e74SYan, Zheng }
1137ae92e74SYan, Zheng 
1147ae92e74SYan, Zheng static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
1157ae92e74SYan, Zheng {
1167ae92e74SYan, Zheng 	return perf_evsel__cpus(evsel)->nr;
1177ae92e74SYan, Zheng }
1187ae92e74SYan, Zheng 
119666e6d48SRobert Richter static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
120666e6d48SRobert Richter static struct stats runtime_cycles_stats[MAX_NR_CPUS];
121666e6d48SRobert Richter static struct stats runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
122666e6d48SRobert Richter static struct stats runtime_stalled_cycles_back_stats[MAX_NR_CPUS];
123666e6d48SRobert Richter static struct stats runtime_branches_stats[MAX_NR_CPUS];
124666e6d48SRobert Richter static struct stats runtime_cacherefs_stats[MAX_NR_CPUS];
125666e6d48SRobert Richter static struct stats runtime_l1_dcache_stats[MAX_NR_CPUS];
126666e6d48SRobert Richter static struct stats runtime_l1_icache_stats[MAX_NR_CPUS];
127666e6d48SRobert Richter static struct stats runtime_ll_cache_stats[MAX_NR_CPUS];
128666e6d48SRobert Richter static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS];
129666e6d48SRobert Richter static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS];
130666e6d48SRobert Richter static struct stats walltime_nsecs_stats;
13186470930SIngo Molnar 
132cac21425SJiri Olsa static int create_perf_stat_counter(struct perf_evsel *evsel)
13386470930SIngo Molnar {
13469aad6f1SArnaldo Carvalho de Melo 	struct perf_event_attr *attr = &evsel->attr;
1355622c07bSStephane Eranian 	bool exclude_guest_missing = false;
1365622c07bSStephane Eranian 	int ret;
137727ab04eSArnaldo Carvalho de Melo 
13886470930SIngo Molnar 	if (scale)
13986470930SIngo Molnar 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
14086470930SIngo Molnar 				    PERF_FORMAT_TOTAL_TIME_RUNNING;
14186470930SIngo Molnar 
1422e6cdf99SStephane Eranian 	attr->inherit = !no_inherit;
1435d2cd909SArnaldo Carvalho de Melo 
1445622c07bSStephane Eranian retry:
1455622c07bSStephane Eranian 	if (exclude_guest_missing)
1465622c07bSStephane Eranian 		evsel->attr.exclude_guest = evsel->attr.exclude_host = 0;
1475622c07bSStephane Eranian 
14816ee6576SArnaldo Carvalho de Melo 	if (perf_target__has_cpu(&target)) {
1497ae92e74SYan, Zheng 		ret = perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
1505622c07bSStephane Eranian 		if (ret)
1515622c07bSStephane Eranian 			goto check_ret;
1525622c07bSStephane Eranian 		return 0;
1535622c07bSStephane Eranian 	}
1545622c07bSStephane Eranian 
15507ac002fSArnaldo Carvalho de Melo 	if (!perf_target__has_task(&target) &&
156823254edSNamhyung Kim 	    perf_evsel__is_group_leader(evsel)) {
15786470930SIngo Molnar 		attr->disabled = 1;
15857e7986eSPaul Mackerras 		attr->enable_on_exec = 1;
1596be2850eSZhang, Yanmin 	}
160084ab9f8SArnaldo Carvalho de Melo 
1616a4bb04cSJiri Olsa 	ret = perf_evsel__open_per_thread(evsel, evsel_list->threads);
1625622c07bSStephane Eranian 	if (!ret)
1635622c07bSStephane Eranian 		return 0;
1645622c07bSStephane Eranian 	/* fall through */
1655622c07bSStephane Eranian check_ret:
1665622c07bSStephane Eranian 	if (ret && errno == EINVAL) {
1675622c07bSStephane Eranian 		if (!exclude_guest_missing &&
1685622c07bSStephane Eranian 		    (evsel->attr.exclude_guest || evsel->attr.exclude_host)) {
1695622c07bSStephane Eranian 			pr_debug("Old kernel, cannot exclude "
1705622c07bSStephane Eranian 				 "guest or host samples.\n");
1715622c07bSStephane Eranian 			exclude_guest_missing = true;
1725622c07bSStephane Eranian 			goto retry;
1735622c07bSStephane Eranian 		}
1745622c07bSStephane Eranian 	}
1755622c07bSStephane Eranian 	return ret;
17686470930SIngo Molnar }
17786470930SIngo Molnar 
17886470930SIngo Molnar /*
17986470930SIngo Molnar  * Does the counter have nsecs as a unit?
18086470930SIngo Molnar  */
181daec78a0SArnaldo Carvalho de Melo static inline int nsec_counter(struct perf_evsel *evsel)
18286470930SIngo Molnar {
183daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
184daec78a0SArnaldo Carvalho de Melo 	    perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
18586470930SIngo Molnar 		return 1;
18686470930SIngo Molnar 
18786470930SIngo Molnar 	return 0;
18886470930SIngo Molnar }
18986470930SIngo Molnar 
19086470930SIngo Molnar /*
191dcd9936aSIngo Molnar  * Update various tracking values we maintain to print
192dcd9936aSIngo Molnar  * more semantic information such as miss/hit ratios,
193dcd9936aSIngo Molnar  * instruction rates, etc:
194dcd9936aSIngo Molnar  */
195dcd9936aSIngo Molnar static void update_shadow_stats(struct perf_evsel *counter, u64 *count)
196dcd9936aSIngo Molnar {
197dcd9936aSIngo Molnar 	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
198dcd9936aSIngo Molnar 		update_stats(&runtime_nsecs_stats[0], count[0]);
199dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
200dcd9936aSIngo Molnar 		update_stats(&runtime_cycles_stats[0], count[0]);
201d3d1e86dSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
202d3d1e86dSIngo Molnar 		update_stats(&runtime_stalled_cycles_front_stats[0], count[0]);
203129c04cbSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
204d3d1e86dSIngo Molnar 		update_stats(&runtime_stalled_cycles_back_stats[0], count[0]);
205dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
206dcd9936aSIngo Molnar 		update_stats(&runtime_branches_stats[0], count[0]);
207dcd9936aSIngo Molnar 	else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
208dcd9936aSIngo Molnar 		update_stats(&runtime_cacherefs_stats[0], count[0]);
2098bb6c79fSIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
2108bb6c79fSIngo Molnar 		update_stats(&runtime_l1_dcache_stats[0], count[0]);
211c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
212c3305257SIngo Molnar 		update_stats(&runtime_l1_icache_stats[0], count[0]);
213c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
214c3305257SIngo Molnar 		update_stats(&runtime_ll_cache_stats[0], count[0]);
215c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
216c3305257SIngo Molnar 		update_stats(&runtime_dtlb_cache_stats[0], count[0]);
217c3305257SIngo Molnar 	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
218c3305257SIngo Molnar 		update_stats(&runtime_itlb_cache_stats[0], count[0]);
219dcd9936aSIngo Molnar }
220dcd9936aSIngo Molnar 
221dcd9936aSIngo Molnar /*
22286470930SIngo Molnar  * Read out the results of a single counter:
223f5b4a9c3SStephane Eranian  * aggregate counts across CPUs in system-wide mode
22486470930SIngo Molnar  */
225c52b12edSArnaldo Carvalho de Melo static int read_counter_aggr(struct perf_evsel *counter)
22686470930SIngo Molnar {
22769aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps = counter->priv;
228c52b12edSArnaldo Carvalho de Melo 	u64 *count = counter->counts->aggr.values;
229c52b12edSArnaldo Carvalho de Melo 	int i;
23086470930SIngo Molnar 
2317ae92e74SYan, Zheng 	if (__perf_evsel__read(counter, perf_evsel__nr_cpus(counter),
2327e2ed097SArnaldo Carvalho de Melo 			       evsel_list->threads->nr, scale) < 0)
233c52b12edSArnaldo Carvalho de Melo 		return -1;
2349e9772c4SPeter Zijlstra 
2359e9772c4SPeter Zijlstra 	for (i = 0; i < 3; i++)
23669aad6f1SArnaldo Carvalho de Melo 		update_stats(&ps->res_stats[i], count[i]);
2379e9772c4SPeter Zijlstra 
2389e9772c4SPeter Zijlstra 	if (verbose) {
2394aa9015fSStephane Eranian 		fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
2407289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter), count[0], count[1], count[2]);
2419e9772c4SPeter Zijlstra 	}
2429e9772c4SPeter Zijlstra 
24386470930SIngo Molnar 	/*
24486470930SIngo Molnar 	 * Save the full runtime - to allow normalization during printout:
24586470930SIngo Molnar 	 */
246dcd9936aSIngo Molnar 	update_shadow_stats(counter, count);
247c52b12edSArnaldo Carvalho de Melo 
248c52b12edSArnaldo Carvalho de Melo 	return 0;
249f5b4a9c3SStephane Eranian }
250f5b4a9c3SStephane Eranian 
251f5b4a9c3SStephane Eranian /*
252f5b4a9c3SStephane Eranian  * Read out the results of a single counter:
253f5b4a9c3SStephane Eranian  * do not aggregate counts across CPUs in system-wide mode
254f5b4a9c3SStephane Eranian  */
255c52b12edSArnaldo Carvalho de Melo static int read_counter(struct perf_evsel *counter)
256f5b4a9c3SStephane Eranian {
257c52b12edSArnaldo Carvalho de Melo 	u64 *count;
258f5b4a9c3SStephane Eranian 	int cpu;
259f5b4a9c3SStephane Eranian 
2607ae92e74SYan, Zheng 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
261c52b12edSArnaldo Carvalho de Melo 		if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0)
262c52b12edSArnaldo Carvalho de Melo 			return -1;
263f5b4a9c3SStephane Eranian 
264c52b12edSArnaldo Carvalho de Melo 		count = counter->counts->cpu[cpu].values;
265f5b4a9c3SStephane Eranian 
266dcd9936aSIngo Molnar 		update_shadow_stats(counter, count);
267f5b4a9c3SStephane Eranian 	}
268c52b12edSArnaldo Carvalho de Melo 
269c52b12edSArnaldo Carvalho de Melo 	return 0;
27086470930SIngo Molnar }
27186470930SIngo Molnar 
2721f16c575SPeter Zijlstra static int __run_perf_stat(int argc __maybe_unused, const char **argv)
27386470930SIngo Molnar {
27486470930SIngo Molnar 	unsigned long long t0, t1;
275cac21425SJiri Olsa 	struct perf_evsel *counter;
27642202dd5SIngo Molnar 	int status = 0;
277051ae7f7SPaul Mackerras 	int child_ready_pipe[2], go_pipe[2];
2786be2850eSZhang, Yanmin 	const bool forks = (argc > 0);
279051ae7f7SPaul Mackerras 	char buf;
28086470930SIngo Molnar 
28160666c63SLiming Wang 	if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
282051ae7f7SPaul Mackerras 		perror("failed to create pipes");
283fceda7feSDavid Ahern 		return -1;
284051ae7f7SPaul Mackerras 	}
285051ae7f7SPaul Mackerras 
28660666c63SLiming Wang 	if (forks) {
2876be2850eSZhang, Yanmin 		if ((child_pid = fork()) < 0)
288051ae7f7SPaul Mackerras 			perror("failed to fork");
289051ae7f7SPaul Mackerras 
2906be2850eSZhang, Yanmin 		if (!child_pid) {
291051ae7f7SPaul Mackerras 			close(child_ready_pipe[0]);
292051ae7f7SPaul Mackerras 			close(go_pipe[1]);
293051ae7f7SPaul Mackerras 			fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
294051ae7f7SPaul Mackerras 
295051ae7f7SPaul Mackerras 			/*
296051ae7f7SPaul Mackerras 			 * Do a dummy execvp to get the PLT entry resolved,
297051ae7f7SPaul Mackerras 			 * so we avoid the resolver overhead on the real
298051ae7f7SPaul Mackerras 			 * execvp call.
299051ae7f7SPaul Mackerras 			 */
300051ae7f7SPaul Mackerras 			execvp("", (char **)argv);
301051ae7f7SPaul Mackerras 
302051ae7f7SPaul Mackerras 			/*
303051ae7f7SPaul Mackerras 			 * Tell the parent we're ready to go
304051ae7f7SPaul Mackerras 			 */
305051ae7f7SPaul Mackerras 			close(child_ready_pipe[1]);
306051ae7f7SPaul Mackerras 
307051ae7f7SPaul Mackerras 			/*
308051ae7f7SPaul Mackerras 			 * Wait until the parent tells us to go.
309051ae7f7SPaul Mackerras 			 */
310a92bef0fSFrederic Weisbecker 			if (read(go_pipe[0], &buf, 1) == -1)
311a92bef0fSFrederic Weisbecker 				perror("unable to read pipe");
312051ae7f7SPaul Mackerras 
313051ae7f7SPaul Mackerras 			execvp(argv[0], (char **)argv);
314051ae7f7SPaul Mackerras 
315051ae7f7SPaul Mackerras 			perror(argv[0]);
316051ae7f7SPaul Mackerras 			exit(-1);
317051ae7f7SPaul Mackerras 		}
318051ae7f7SPaul Mackerras 
319d67356e7SNamhyung Kim 		if (perf_target__none(&target))
3207e2ed097SArnaldo Carvalho de Melo 			evsel_list->threads->map[0] = child_pid;
321d6d901c2SZhang, Yanmin 
322051ae7f7SPaul Mackerras 		/*
323051ae7f7SPaul Mackerras 		 * Wait for the child to be ready to exec.
324051ae7f7SPaul Mackerras 		 */
325051ae7f7SPaul Mackerras 		close(child_ready_pipe[1]);
326051ae7f7SPaul Mackerras 		close(go_pipe[0]);
327a92bef0fSFrederic Weisbecker 		if (read(child_ready_pipe[0], &buf, 1) == -1)
328a92bef0fSFrederic Weisbecker 			perror("unable to read pipe");
329051ae7f7SPaul Mackerras 		close(child_ready_pipe[0]);
33060666c63SLiming Wang 	}
331051ae7f7SPaul Mackerras 
3326a4bb04cSJiri Olsa 	if (group)
33363dab225SArnaldo Carvalho de Melo 		perf_evlist__set_leader(evsel_list);
3346a4bb04cSJiri Olsa 
335361c99a6SArnaldo Carvalho de Melo 	list_for_each_entry(counter, &evsel_list->entries, node) {
336cac21425SJiri Olsa 		if (create_perf_stat_counter(counter) < 0) {
337979987a5SDavid Ahern 			/*
338979987a5SDavid Ahern 			 * PPC returns ENXIO for HW counters until 2.6.37
339979987a5SDavid Ahern 			 * (behavior changed with commit b0a873e).
340979987a5SDavid Ahern 			 */
34138f6ae1eSAnton Blanchard 			if (errno == EINVAL || errno == ENOSYS ||
342979987a5SDavid Ahern 			    errno == ENOENT || errno == EOPNOTSUPP ||
343979987a5SDavid Ahern 			    errno == ENXIO) {
344c63ca0c0SDavid Ahern 				if (verbose)
345c63ca0c0SDavid Ahern 					ui__warning("%s event is not supported by the kernel.\n",
3467289f83cSArnaldo Carvalho de Melo 						    perf_evsel__name(counter));
3472cee77c4SDavid Ahern 				counter->supported = false;
348ede70290SIngo Molnar 				continue;
349c63ca0c0SDavid Ahern 			}
350ede70290SIngo Molnar 
351ede70290SIngo Molnar 			if (errno == EPERM || errno == EACCES) {
352d9cf837eSCorey Ashford 				error("You may not have permission to collect %sstats.\n"
353d9cf837eSCorey Ashford 				      "\t Consider tweaking"
354d9cf837eSCorey Ashford 				      " /proc/sys/kernel/perf_event_paranoid or running as root.",
35520f946b4SNamhyung Kim 				      target.system_wide ? "system-wide " : "");
35648290609SArnaldo Carvalho de Melo 			} else {
35748290609SArnaldo Carvalho de Melo 				error("open_counter returned with %d (%s). "
35848290609SArnaldo Carvalho de Melo 				      "/bin/dmesg may provide additional information.\n",
35948290609SArnaldo Carvalho de Melo 				       errno, strerror(errno));
36048290609SArnaldo Carvalho de Melo 			}
361084ab9f8SArnaldo Carvalho de Melo 			if (child_pid != -1)
362084ab9f8SArnaldo Carvalho de Melo 				kill(child_pid, SIGTERM);
363fceda7feSDavid Ahern 
364fceda7feSDavid Ahern 			pr_err("Not all events could be opened.\n");
365084ab9f8SArnaldo Carvalho de Melo 			return -1;
366084ab9f8SArnaldo Carvalho de Melo 		}
3672cee77c4SDavid Ahern 		counter->supported = true;
36848290609SArnaldo Carvalho de Melo 	}
36986470930SIngo Molnar 
3701491a632SArnaldo Carvalho de Melo 	if (perf_evlist__apply_filters(evsel_list)) {
371cfd748aeSFrederic Weisbecker 		error("failed to set filter with %d (%s)\n", errno,
372cfd748aeSFrederic Weisbecker 			strerror(errno));
373cfd748aeSFrederic Weisbecker 		return -1;
374cfd748aeSFrederic Weisbecker 	}
375cfd748aeSFrederic Weisbecker 
37686470930SIngo Molnar 	/*
37786470930SIngo Molnar 	 * Enable counters and exec the command:
37886470930SIngo Molnar 	 */
37986470930SIngo Molnar 	t0 = rdclock();
38086470930SIngo Molnar 
38160666c63SLiming Wang 	if (forks) {
382051ae7f7SPaul Mackerras 		close(go_pipe[1]);
38342202dd5SIngo Molnar 		wait(&status);
38433e49ea7SAndi Kleen 		if (WIFSIGNALED(status))
38533e49ea7SAndi Kleen 			psignal(WTERMSIG(status), argv[0]);
38660666c63SLiming Wang 	} else {
3876be2850eSZhang, Yanmin 		while(!done) sleep(1);
38860666c63SLiming Wang 	}
38986470930SIngo Molnar 
39086470930SIngo Molnar 	t1 = rdclock();
39186470930SIngo Molnar 
3929e9772c4SPeter Zijlstra 	update_stats(&walltime_nsecs_stats, t1 - t0);
39342202dd5SIngo Molnar 
394f5b4a9c3SStephane Eranian 	if (no_aggr) {
395361c99a6SArnaldo Carvalho de Melo 		list_for_each_entry(counter, &evsel_list->entries, node) {
39642202dd5SIngo Molnar 			read_counter(counter);
3977ae92e74SYan, Zheng 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
398f5b4a9c3SStephane Eranian 		}
399c52b12edSArnaldo Carvalho de Melo 	} else {
400361c99a6SArnaldo Carvalho de Melo 		list_for_each_entry(counter, &evsel_list->entries, node) {
401c52b12edSArnaldo Carvalho de Melo 			read_counter_aggr(counter);
4027ae92e74SYan, Zheng 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
4037e2ed097SArnaldo Carvalho de Melo 					     evsel_list->threads->nr);
404c52b12edSArnaldo Carvalho de Melo 		}
405c52b12edSArnaldo Carvalho de Melo 	}
406c52b12edSArnaldo Carvalho de Melo 
40742202dd5SIngo Molnar 	return WEXITSTATUS(status);
40842202dd5SIngo Molnar }
40942202dd5SIngo Molnar 
4101f16c575SPeter Zijlstra static int run_perf_stat(int argc __maybe_unused, const char **argv)
4111f16c575SPeter Zijlstra {
4121f16c575SPeter Zijlstra 	int ret;
4131f16c575SPeter Zijlstra 
4141f16c575SPeter Zijlstra 	if (pre_cmd) {
4151f16c575SPeter Zijlstra 		ret = system(pre_cmd);
4161f16c575SPeter Zijlstra 		if (ret)
4171f16c575SPeter Zijlstra 			return ret;
4181f16c575SPeter Zijlstra 	}
4191f16c575SPeter Zijlstra 
4201f16c575SPeter Zijlstra 	if (sync_run)
4211f16c575SPeter Zijlstra 		sync();
4221f16c575SPeter Zijlstra 
4231f16c575SPeter Zijlstra 	ret = __run_perf_stat(argc, argv);
4241f16c575SPeter Zijlstra 	if (ret)
4251f16c575SPeter Zijlstra 		return ret;
4261f16c575SPeter Zijlstra 
4271f16c575SPeter Zijlstra 	if (post_cmd) {
4281f16c575SPeter Zijlstra 		ret = system(post_cmd);
4291f16c575SPeter Zijlstra 		if (ret)
4301f16c575SPeter Zijlstra 			return ret;
4311f16c575SPeter Zijlstra 	}
4321f16c575SPeter Zijlstra 
4331f16c575SPeter Zijlstra 	return ret;
4341f16c575SPeter Zijlstra }
4351f16c575SPeter Zijlstra 
436f99844cbSIngo Molnar static void print_noise_pct(double total, double avg)
437f99844cbSIngo Molnar {
4380007eceaSXiao Guangrong 	double pct = rel_stddev_stats(total, avg);
439f99844cbSIngo Molnar 
4403ae9a34dSZhengyu He 	if (csv_output)
4414aa9015fSStephane Eranian 		fprintf(output, "%s%.2f%%", csv_sep, pct);
442a1bca6ccSJim Cromie 	else if (pct)
4434aa9015fSStephane Eranian 		fprintf(output, "  ( +-%6.2f%% )", pct);
444f99844cbSIngo Molnar }
445f99844cbSIngo Molnar 
44669aad6f1SArnaldo Carvalho de Melo static void print_noise(struct perf_evsel *evsel, double avg)
44742202dd5SIngo Molnar {
44869aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps;
44969aad6f1SArnaldo Carvalho de Melo 
450849abde9SPeter Zijlstra 	if (run_count == 1)
451849abde9SPeter Zijlstra 		return;
452849abde9SPeter Zijlstra 
45369aad6f1SArnaldo Carvalho de Melo 	ps = evsel->priv;
454f99844cbSIngo Molnar 	print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
45542202dd5SIngo Molnar }
45642202dd5SIngo Molnar 
457daec78a0SArnaldo Carvalho de Melo static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
45842202dd5SIngo Molnar {
459506d4bc8SPeter Zijlstra 	double msecs = avg / 1e6;
460d7470b6aSStephane Eranian 	char cpustr[16] = { '\0', };
4612cba3ffbSIngo Molnar 	const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-25s";
46242202dd5SIngo Molnar 
463f5b4a9c3SStephane Eranian 	if (no_aggr)
464d7470b6aSStephane Eranian 		sprintf(cpustr, "CPU%*d%s",
465d7470b6aSStephane Eranian 			csv_output ? 0 : -4,
4667ae92e74SYan, Zheng 			perf_evsel__cpus(evsel)->map[cpu], csv_sep);
467d7470b6aSStephane Eranian 
4687289f83cSArnaldo Carvalho de Melo 	fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel));
469d7470b6aSStephane Eranian 
470023695d9SStephane Eranian 	if (evsel->cgrp)
4714aa9015fSStephane Eranian 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
472023695d9SStephane Eranian 
473d7470b6aSStephane Eranian 	if (csv_output)
474d7470b6aSStephane Eranian 		return;
47542202dd5SIngo Molnar 
476daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
4774aa9015fSStephane Eranian 		fprintf(output, " # %8.3f CPUs utilized          ",
4784aa9015fSStephane Eranian 			avg / avg_stats(&walltime_nsecs_stats));
4799dac6a29SNamhyung Kim 	else
4809dac6a29SNamhyung Kim 		fprintf(output, "                                   ");
48142202dd5SIngo Molnar }
48242202dd5SIngo Molnar 
48315e6392fSNamhyung Kim /* used for get_ratio_color() */
48415e6392fSNamhyung Kim enum grc_type {
48515e6392fSNamhyung Kim 	GRC_STALLED_CYCLES_FE,
48615e6392fSNamhyung Kim 	GRC_STALLED_CYCLES_BE,
48715e6392fSNamhyung Kim 	GRC_CACHE_MISSES,
48815e6392fSNamhyung Kim 	GRC_MAX_NR
48915e6392fSNamhyung Kim };
49015e6392fSNamhyung Kim 
49115e6392fSNamhyung Kim static const char *get_ratio_color(enum grc_type type, double ratio)
49215e6392fSNamhyung Kim {
49315e6392fSNamhyung Kim 	static const double grc_table[GRC_MAX_NR][3] = {
49415e6392fSNamhyung Kim 		[GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 },
49515e6392fSNamhyung Kim 		[GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 },
49615e6392fSNamhyung Kim 		[GRC_CACHE_MISSES] 	= { 20.0, 10.0, 5.0 },
49715e6392fSNamhyung Kim 	};
49815e6392fSNamhyung Kim 	const char *color = PERF_COLOR_NORMAL;
49915e6392fSNamhyung Kim 
50015e6392fSNamhyung Kim 	if (ratio > grc_table[type][0])
50115e6392fSNamhyung Kim 		color = PERF_COLOR_RED;
50215e6392fSNamhyung Kim 	else if (ratio > grc_table[type][1])
50315e6392fSNamhyung Kim 		color = PERF_COLOR_MAGENTA;
50415e6392fSNamhyung Kim 	else if (ratio > grc_table[type][2])
50515e6392fSNamhyung Kim 		color = PERF_COLOR_YELLOW;
50615e6392fSNamhyung Kim 
50715e6392fSNamhyung Kim 	return color;
50815e6392fSNamhyung Kim }
50915e6392fSNamhyung Kim 
5101d037ca1SIrina Tirdea static void print_stalled_cycles_frontend(int cpu,
5111d037ca1SIrina Tirdea 					  struct perf_evsel *evsel
5121d037ca1SIrina Tirdea 					  __maybe_unused, double avg)
513d3d1e86dSIngo Molnar {
514d3d1e86dSIngo Molnar 	double total, ratio = 0.0;
515d3d1e86dSIngo Molnar 	const char *color;
516d3d1e86dSIngo Molnar 
517d3d1e86dSIngo Molnar 	total = avg_stats(&runtime_cycles_stats[cpu]);
518d3d1e86dSIngo Molnar 
519d3d1e86dSIngo Molnar 	if (total)
520d3d1e86dSIngo Molnar 		ratio = avg / total * 100.0;
521d3d1e86dSIngo Molnar 
52215e6392fSNamhyung Kim 	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
523d3d1e86dSIngo Molnar 
5244aa9015fSStephane Eranian 	fprintf(output, " #  ");
5254aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
5264aa9015fSStephane Eranian 	fprintf(output, " frontend cycles idle   ");
527d3d1e86dSIngo Molnar }
528d3d1e86dSIngo Molnar 
5291d037ca1SIrina Tirdea static void print_stalled_cycles_backend(int cpu,
5301d037ca1SIrina Tirdea 					 struct perf_evsel *evsel
5311d037ca1SIrina Tirdea 					 __maybe_unused, double avg)
532a5d243d0SIngo Molnar {
533a5d243d0SIngo Molnar 	double total, ratio = 0.0;
534a5d243d0SIngo Molnar 	const char *color;
535a5d243d0SIngo Molnar 
536a5d243d0SIngo Molnar 	total = avg_stats(&runtime_cycles_stats[cpu]);
537a5d243d0SIngo Molnar 
538a5d243d0SIngo Molnar 	if (total)
539a5d243d0SIngo Molnar 		ratio = avg / total * 100.0;
540a5d243d0SIngo Molnar 
54115e6392fSNamhyung Kim 	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
542a5d243d0SIngo Molnar 
5434aa9015fSStephane Eranian 	fprintf(output, " #  ");
5444aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
5454aa9015fSStephane Eranian 	fprintf(output, " backend  cycles idle   ");
546a5d243d0SIngo Molnar }
547a5d243d0SIngo Molnar 
5481d037ca1SIrina Tirdea static void print_branch_misses(int cpu,
5491d037ca1SIrina Tirdea 				struct perf_evsel *evsel __maybe_unused,
5501d037ca1SIrina Tirdea 				double avg)
551c78df6c1SIngo Molnar {
552c78df6c1SIngo Molnar 	double total, ratio = 0.0;
553c78df6c1SIngo Molnar 	const char *color;
554c78df6c1SIngo Molnar 
555c78df6c1SIngo Molnar 	total = avg_stats(&runtime_branches_stats[cpu]);
556c78df6c1SIngo Molnar 
557c78df6c1SIngo Molnar 	if (total)
558c78df6c1SIngo Molnar 		ratio = avg / total * 100.0;
559c78df6c1SIngo Molnar 
56015e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
561c78df6c1SIngo Molnar 
5624aa9015fSStephane Eranian 	fprintf(output, " #  ");
5634aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
5644aa9015fSStephane Eranian 	fprintf(output, " of all branches        ");
565c78df6c1SIngo Molnar }
566c78df6c1SIngo Molnar 
5671d037ca1SIrina Tirdea static void print_l1_dcache_misses(int cpu,
5681d037ca1SIrina Tirdea 				   struct perf_evsel *evsel __maybe_unused,
5691d037ca1SIrina Tirdea 				   double avg)
5708bb6c79fSIngo Molnar {
5718bb6c79fSIngo Molnar 	double total, ratio = 0.0;
5728bb6c79fSIngo Molnar 	const char *color;
5738bb6c79fSIngo Molnar 
5748bb6c79fSIngo Molnar 	total = avg_stats(&runtime_l1_dcache_stats[cpu]);
5758bb6c79fSIngo Molnar 
5768bb6c79fSIngo Molnar 	if (total)
5778bb6c79fSIngo Molnar 		ratio = avg / total * 100.0;
5788bb6c79fSIngo Molnar 
57915e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
5808bb6c79fSIngo Molnar 
5814aa9015fSStephane Eranian 	fprintf(output, " #  ");
5824aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
5834aa9015fSStephane Eranian 	fprintf(output, " of all L1-dcache hits  ");
5848bb6c79fSIngo Molnar }
5858bb6c79fSIngo Molnar 
5861d037ca1SIrina Tirdea static void print_l1_icache_misses(int cpu,
5871d037ca1SIrina Tirdea 				   struct perf_evsel *evsel __maybe_unused,
5881d037ca1SIrina Tirdea 				   double avg)
589c3305257SIngo Molnar {
590c3305257SIngo Molnar 	double total, ratio = 0.0;
591c3305257SIngo Molnar 	const char *color;
592c3305257SIngo Molnar 
593c3305257SIngo Molnar 	total = avg_stats(&runtime_l1_icache_stats[cpu]);
594c3305257SIngo Molnar 
595c3305257SIngo Molnar 	if (total)
596c3305257SIngo Molnar 		ratio = avg / total * 100.0;
597c3305257SIngo Molnar 
59815e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
599c3305257SIngo Molnar 
6004aa9015fSStephane Eranian 	fprintf(output, " #  ");
6014aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
6024aa9015fSStephane Eranian 	fprintf(output, " of all L1-icache hits  ");
603c3305257SIngo Molnar }
604c3305257SIngo Molnar 
6051d037ca1SIrina Tirdea static void print_dtlb_cache_misses(int cpu,
6061d037ca1SIrina Tirdea 				    struct perf_evsel *evsel __maybe_unused,
6071d037ca1SIrina Tirdea 				    double avg)
608c3305257SIngo Molnar {
609c3305257SIngo Molnar 	double total, ratio = 0.0;
610c3305257SIngo Molnar 	const char *color;
611c3305257SIngo Molnar 
612c3305257SIngo Molnar 	total = avg_stats(&runtime_dtlb_cache_stats[cpu]);
613c3305257SIngo Molnar 
614c3305257SIngo Molnar 	if (total)
615c3305257SIngo Molnar 		ratio = avg / total * 100.0;
616c3305257SIngo Molnar 
61715e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
618c3305257SIngo Molnar 
6194aa9015fSStephane Eranian 	fprintf(output, " #  ");
6204aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
6214aa9015fSStephane Eranian 	fprintf(output, " of all dTLB cache hits ");
622c3305257SIngo Molnar }
623c3305257SIngo Molnar 
6241d037ca1SIrina Tirdea static void print_itlb_cache_misses(int cpu,
6251d037ca1SIrina Tirdea 				    struct perf_evsel *evsel __maybe_unused,
6261d037ca1SIrina Tirdea 				    double avg)
627c3305257SIngo Molnar {
628c3305257SIngo Molnar 	double total, ratio = 0.0;
629c3305257SIngo Molnar 	const char *color;
630c3305257SIngo Molnar 
631c3305257SIngo Molnar 	total = avg_stats(&runtime_itlb_cache_stats[cpu]);
632c3305257SIngo Molnar 
633c3305257SIngo Molnar 	if (total)
634c3305257SIngo Molnar 		ratio = avg / total * 100.0;
635c3305257SIngo Molnar 
63615e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
637c3305257SIngo Molnar 
6384aa9015fSStephane Eranian 	fprintf(output, " #  ");
6394aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
6404aa9015fSStephane Eranian 	fprintf(output, " of all iTLB cache hits ");
641c3305257SIngo Molnar }
642c3305257SIngo Molnar 
6431d037ca1SIrina Tirdea static void print_ll_cache_misses(int cpu,
6441d037ca1SIrina Tirdea 				  struct perf_evsel *evsel __maybe_unused,
6451d037ca1SIrina Tirdea 				  double avg)
646c3305257SIngo Molnar {
647c3305257SIngo Molnar 	double total, ratio = 0.0;
648c3305257SIngo Molnar 	const char *color;
649c3305257SIngo Molnar 
650c3305257SIngo Molnar 	total = avg_stats(&runtime_ll_cache_stats[cpu]);
651c3305257SIngo Molnar 
652c3305257SIngo Molnar 	if (total)
653c3305257SIngo Molnar 		ratio = avg / total * 100.0;
654c3305257SIngo Molnar 
65515e6392fSNamhyung Kim 	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
656c3305257SIngo Molnar 
6574aa9015fSStephane Eranian 	fprintf(output, " #  ");
6584aa9015fSStephane Eranian 	color_fprintf(output, color, "%6.2f%%", ratio);
6594aa9015fSStephane Eranian 	fprintf(output, " of all LL-cache hits   ");
660c3305257SIngo Molnar }
661c3305257SIngo Molnar 
662daec78a0SArnaldo Carvalho de Melo static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
66342202dd5SIngo Molnar {
664c7f7fea3SIngo Molnar 	double total, ratio = 0.0;
665f5b4a9c3SStephane Eranian 	char cpustr[16] = { '\0', };
666d7470b6aSStephane Eranian 	const char *fmt;
667d7470b6aSStephane Eranian 
668d7470b6aSStephane Eranian 	if (csv_output)
669d7470b6aSStephane Eranian 		fmt = "%s%.0f%s%s";
670d7470b6aSStephane Eranian 	else if (big_num)
6712cba3ffbSIngo Molnar 		fmt = "%s%'18.0f%s%-25s";
672d7470b6aSStephane Eranian 	else
6732cba3ffbSIngo Molnar 		fmt = "%s%18.0f%s%-25s";
674f5b4a9c3SStephane Eranian 
675f5b4a9c3SStephane Eranian 	if (no_aggr)
676d7470b6aSStephane Eranian 		sprintf(cpustr, "CPU%*d%s",
677d7470b6aSStephane Eranian 			csv_output ? 0 : -4,
6787ae92e74SYan, Zheng 			perf_evsel__cpus(evsel)->map[cpu], csv_sep);
679f5b4a9c3SStephane Eranian 	else
680f5b4a9c3SStephane Eranian 		cpu = 0;
681c7f7fea3SIngo Molnar 
6827289f83cSArnaldo Carvalho de Melo 	fprintf(output, fmt, cpustr, avg, csv_sep, perf_evsel__name(evsel));
683d7470b6aSStephane Eranian 
684023695d9SStephane Eranian 	if (evsel->cgrp)
6854aa9015fSStephane Eranian 		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
686023695d9SStephane Eranian 
687d7470b6aSStephane Eranian 	if (csv_output)
688d7470b6aSStephane Eranian 		return;
68942202dd5SIngo Molnar 
690daec78a0SArnaldo Carvalho de Melo 	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
691f5b4a9c3SStephane Eranian 		total = avg_stats(&runtime_cycles_stats[cpu]);
692c7f7fea3SIngo Molnar 
693c7f7fea3SIngo Molnar 		if (total)
694c7f7fea3SIngo Molnar 			ratio = avg / total;
695c7f7fea3SIngo Molnar 
6964aa9015fSStephane Eranian 		fprintf(output, " #   %5.2f  insns per cycle        ", ratio);
697481f988aSIngo Molnar 
698d3d1e86dSIngo Molnar 		total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
699d3d1e86dSIngo Molnar 		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
700481f988aSIngo Molnar 
701481f988aSIngo Molnar 		if (total && avg) {
702481f988aSIngo Molnar 			ratio = total / avg;
7034aa9015fSStephane Eranian 			fprintf(output, "\n                                             #   %5.2f  stalled cycles per insn", ratio);
704481f988aSIngo Molnar 		}
705481f988aSIngo Molnar 
706daec78a0SArnaldo Carvalho de Melo 	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
707f5b4a9c3SStephane Eranian 			runtime_branches_stats[cpu].n != 0) {
708c78df6c1SIngo Molnar 		print_branch_misses(cpu, evsel, avg);
7098bb6c79fSIngo Molnar 	} else if (
7108bb6c79fSIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
7118bb6c79fSIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
7128bb6c79fSIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
7138bb6c79fSIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
714c6264defSIngo Molnar 			runtime_l1_dcache_stats[cpu].n != 0) {
7158bb6c79fSIngo Molnar 		print_l1_dcache_misses(cpu, evsel, avg);
716c3305257SIngo Molnar 	} else if (
717c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
718c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
719c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
720c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
721c3305257SIngo Molnar 			runtime_l1_icache_stats[cpu].n != 0) {
722c3305257SIngo Molnar 		print_l1_icache_misses(cpu, evsel, avg);
723c3305257SIngo Molnar 	} else if (
724c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
725c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
726c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
727c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
728c3305257SIngo Molnar 			runtime_dtlb_cache_stats[cpu].n != 0) {
729c3305257SIngo Molnar 		print_dtlb_cache_misses(cpu, evsel, avg);
730c3305257SIngo Molnar 	} else if (
731c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
732c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
733c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
734c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
735c3305257SIngo Molnar 			runtime_itlb_cache_stats[cpu].n != 0) {
736c3305257SIngo Molnar 		print_itlb_cache_misses(cpu, evsel, avg);
737c3305257SIngo Molnar 	} else if (
738c3305257SIngo Molnar 		evsel->attr.type == PERF_TYPE_HW_CACHE &&
739c3305257SIngo Molnar 		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
740c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
741c3305257SIngo Molnar 					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
742c3305257SIngo Molnar 			runtime_ll_cache_stats[cpu].n != 0) {
743c3305257SIngo Molnar 		print_ll_cache_misses(cpu, evsel, avg);
744d58f4c82SIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
745d58f4c82SIngo Molnar 			runtime_cacherefs_stats[cpu].n != 0) {
746d58f4c82SIngo Molnar 		total = avg_stats(&runtime_cacherefs_stats[cpu]);
747d58f4c82SIngo Molnar 
748d58f4c82SIngo Molnar 		if (total)
749d58f4c82SIngo Molnar 			ratio = avg * 100 / total;
750d58f4c82SIngo Molnar 
7514aa9015fSStephane Eranian 		fprintf(output, " # %8.3f %% of all cache refs    ", ratio);
752d58f4c82SIngo Molnar 
753d3d1e86dSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
754d3d1e86dSIngo Molnar 		print_stalled_cycles_frontend(cpu, evsel, avg);
755129c04cbSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
756d3d1e86dSIngo Molnar 		print_stalled_cycles_backend(cpu, evsel, avg);
757481f988aSIngo Molnar 	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
758481f988aSIngo Molnar 		total = avg_stats(&runtime_nsecs_stats[cpu]);
759481f988aSIngo Molnar 
760481f988aSIngo Molnar 		if (total)
761481f988aSIngo Molnar 			ratio = 1.0 * avg / total;
762481f988aSIngo Molnar 
7634aa9015fSStephane Eranian 		fprintf(output, " # %8.3f GHz                    ", ratio);
764481f988aSIngo Molnar 	} else if (runtime_nsecs_stats[cpu].n != 0) {
7655fde2523SNamhyung Kim 		char unit = 'M';
7665fde2523SNamhyung Kim 
767481f988aSIngo Molnar 		total = avg_stats(&runtime_nsecs_stats[cpu]);
768481f988aSIngo Molnar 
769481f988aSIngo Molnar 		if (total)
770481f988aSIngo Molnar 			ratio = 1000.0 * avg / total;
7715fde2523SNamhyung Kim 		if (ratio < 0.001) {
7725fde2523SNamhyung Kim 			ratio *= 1000;
7735fde2523SNamhyung Kim 			unit = 'K';
7745fde2523SNamhyung Kim 		}
775481f988aSIngo Molnar 
7765fde2523SNamhyung Kim 		fprintf(output, " # %8.3f %c/sec                  ", ratio, unit);
777a5d243d0SIngo Molnar 	} else {
7784aa9015fSStephane Eranian 		fprintf(output, "                                   ");
77942202dd5SIngo Molnar 	}
78042202dd5SIngo Molnar }
78142202dd5SIngo Molnar 
78242202dd5SIngo Molnar /*
78342202dd5SIngo Molnar  * Print out the results of a single counter:
784f5b4a9c3SStephane Eranian  * aggregated counts in system-wide mode
78542202dd5SIngo Molnar  */
78669aad6f1SArnaldo Carvalho de Melo static void print_counter_aggr(struct perf_evsel *counter)
78742202dd5SIngo Molnar {
78869aad6f1SArnaldo Carvalho de Melo 	struct perf_stat *ps = counter->priv;
78969aad6f1SArnaldo Carvalho de Melo 	double avg = avg_stats(&ps->res_stats[0]);
790c52b12edSArnaldo Carvalho de Melo 	int scaled = counter->counts->scaled;
79142202dd5SIngo Molnar 
79242202dd5SIngo Molnar 	if (scaled == -1) {
7934aa9015fSStephane Eranian 		fprintf(output, "%*s%s%*s",
794d7470b6aSStephane Eranian 			csv_output ? 0 : 18,
7952cee77c4SDavid Ahern 			counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
796023695d9SStephane Eranian 			csv_sep,
797023695d9SStephane Eranian 			csv_output ? 0 : -24,
7987289f83cSArnaldo Carvalho de Melo 			perf_evsel__name(counter));
799023695d9SStephane Eranian 
800023695d9SStephane Eranian 		if (counter->cgrp)
8014aa9015fSStephane Eranian 			fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
802023695d9SStephane Eranian 
8034aa9015fSStephane Eranian 		fputc('\n', output);
80442202dd5SIngo Molnar 		return;
80542202dd5SIngo Molnar 	}
80642202dd5SIngo Molnar 
80742202dd5SIngo Molnar 	if (nsec_counter(counter))
808f5b4a9c3SStephane Eranian 		nsec_printout(-1, counter, avg);
80942202dd5SIngo Molnar 	else
810f5b4a9c3SStephane Eranian 		abs_printout(-1, counter, avg);
811849abde9SPeter Zijlstra 
8123ae9a34dSZhengyu He 	print_noise(counter, avg);
8133ae9a34dSZhengyu He 
814d7470b6aSStephane Eranian 	if (csv_output) {
8154aa9015fSStephane Eranian 		fputc('\n', output);
816d7470b6aSStephane Eranian 		return;
817d7470b6aSStephane Eranian 	}
818d7470b6aSStephane Eranian 
819506d4bc8SPeter Zijlstra 	if (scaled) {
820506d4bc8SPeter Zijlstra 		double avg_enabled, avg_running;
821506d4bc8SPeter Zijlstra 
82269aad6f1SArnaldo Carvalho de Melo 		avg_enabled = avg_stats(&ps->res_stats[1]);
82369aad6f1SArnaldo Carvalho de Melo 		avg_running = avg_stats(&ps->res_stats[2]);
824506d4bc8SPeter Zijlstra 
8254aa9015fSStephane Eranian 		fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled);
826506d4bc8SPeter Zijlstra 	}
8274aa9015fSStephane Eranian 	fprintf(output, "\n");
82842202dd5SIngo Molnar }
82942202dd5SIngo Molnar 
830f5b4a9c3SStephane Eranian /*
831f5b4a9c3SStephane Eranian  * Print out the results of a single counter:
832f5b4a9c3SStephane Eranian  * does not use aggregated count in system-wide
833f5b4a9c3SStephane Eranian  */
83469aad6f1SArnaldo Carvalho de Melo static void print_counter(struct perf_evsel *counter)
835f5b4a9c3SStephane Eranian {
836f5b4a9c3SStephane Eranian 	u64 ena, run, val;
837f5b4a9c3SStephane Eranian 	int cpu;
838f5b4a9c3SStephane Eranian 
8397ae92e74SYan, Zheng 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
840c52b12edSArnaldo Carvalho de Melo 		val = counter->counts->cpu[cpu].val;
841c52b12edSArnaldo Carvalho de Melo 		ena = counter->counts->cpu[cpu].ena;
842c52b12edSArnaldo Carvalho de Melo 		run = counter->counts->cpu[cpu].run;
843f5b4a9c3SStephane Eranian 		if (run == 0 || ena == 0) {
8444aa9015fSStephane Eranian 			fprintf(output, "CPU%*d%s%*s%s%*s",
845d7470b6aSStephane Eranian 				csv_output ? 0 : -4,
8467ae92e74SYan, Zheng 				perf_evsel__cpus(counter)->map[cpu], csv_sep,
847d7470b6aSStephane Eranian 				csv_output ? 0 : 18,
8482cee77c4SDavid Ahern 				counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
8492cee77c4SDavid Ahern 				csv_sep,
850023695d9SStephane Eranian 				csv_output ? 0 : -24,
8517289f83cSArnaldo Carvalho de Melo 				perf_evsel__name(counter));
852f5b4a9c3SStephane Eranian 
853023695d9SStephane Eranian 			if (counter->cgrp)
8544aa9015fSStephane Eranian 				fprintf(output, "%s%s",
8554aa9015fSStephane Eranian 					csv_sep, counter->cgrp->name);
856023695d9SStephane Eranian 
8574aa9015fSStephane Eranian 			fputc('\n', output);
858f5b4a9c3SStephane Eranian 			continue;
859f5b4a9c3SStephane Eranian 		}
860f5b4a9c3SStephane Eranian 
861f5b4a9c3SStephane Eranian 		if (nsec_counter(counter))
862f5b4a9c3SStephane Eranian 			nsec_printout(cpu, counter, val);
863f5b4a9c3SStephane Eranian 		else
864f5b4a9c3SStephane Eranian 			abs_printout(cpu, counter, val);
865f5b4a9c3SStephane Eranian 
866d7470b6aSStephane Eranian 		if (!csv_output) {
867f5b4a9c3SStephane Eranian 			print_noise(counter, 1.0);
868f5b4a9c3SStephane Eranian 
869c6264defSIngo Molnar 			if (run != ena)
8704aa9015fSStephane Eranian 				fprintf(output, "  (%.2f%%)",
8714aa9015fSStephane Eranian 					100.0 * run / ena);
872d7470b6aSStephane Eranian 		}
8734aa9015fSStephane Eranian 		fputc('\n', output);
874f5b4a9c3SStephane Eranian 	}
875f5b4a9c3SStephane Eranian }
876f5b4a9c3SStephane Eranian 
87742202dd5SIngo Molnar static void print_stat(int argc, const char **argv)
87842202dd5SIngo Molnar {
87969aad6f1SArnaldo Carvalho de Melo 	struct perf_evsel *counter;
88069aad6f1SArnaldo Carvalho de Melo 	int i;
88142202dd5SIngo Molnar 
88286470930SIngo Molnar 	fflush(stdout);
88386470930SIngo Molnar 
884d7470b6aSStephane Eranian 	if (!csv_output) {
8854aa9015fSStephane Eranian 		fprintf(output, "\n");
8864aa9015fSStephane Eranian 		fprintf(output, " Performance counter stats for ");
887aa22dd49SNamhyung Kim 		if (!perf_target__has_task(&target)) {
8884aa9015fSStephane Eranian 			fprintf(output, "\'%s", argv[0]);
88986470930SIngo Molnar 			for (i = 1; i < argc; i++)
8904aa9015fSStephane Eranian 				fprintf(output, " %s", argv[i]);
89120f946b4SNamhyung Kim 		} else if (target.pid)
89220f946b4SNamhyung Kim 			fprintf(output, "process id \'%s", target.pid);
893d6d901c2SZhang, Yanmin 		else
89420f946b4SNamhyung Kim 			fprintf(output, "thread id \'%s", target.tid);
89586470930SIngo Molnar 
8964aa9015fSStephane Eranian 		fprintf(output, "\'");
89742202dd5SIngo Molnar 		if (run_count > 1)
8984aa9015fSStephane Eranian 			fprintf(output, " (%d runs)", run_count);
8994aa9015fSStephane Eranian 		fprintf(output, ":\n\n");
900d7470b6aSStephane Eranian 	}
90186470930SIngo Molnar 
902f5b4a9c3SStephane Eranian 	if (no_aggr) {
903361c99a6SArnaldo Carvalho de Melo 		list_for_each_entry(counter, &evsel_list->entries, node)
90486470930SIngo Molnar 			print_counter(counter);
905f5b4a9c3SStephane Eranian 	} else {
906361c99a6SArnaldo Carvalho de Melo 		list_for_each_entry(counter, &evsel_list->entries, node)
907f5b4a9c3SStephane Eranian 			print_counter_aggr(counter);
908f5b4a9c3SStephane Eranian 	}
90986470930SIngo Molnar 
910d7470b6aSStephane Eranian 	if (!csv_output) {
911c3305257SIngo Molnar 		if (!null_run)
9124aa9015fSStephane Eranian 			fprintf(output, "\n");
9134aa9015fSStephane Eranian 		fprintf(output, " %17.9f seconds time elapsed",
914506d4bc8SPeter Zijlstra 				avg_stats(&walltime_nsecs_stats)/1e9);
915566747e6SIngo Molnar 		if (run_count > 1) {
9164aa9015fSStephane Eranian 			fprintf(output, "                                        ");
917f99844cbSIngo Molnar 			print_noise_pct(stddev_stats(&walltime_nsecs_stats),
918506d4bc8SPeter Zijlstra 					avg_stats(&walltime_nsecs_stats));
919566747e6SIngo Molnar 		}
9204aa9015fSStephane Eranian 		fprintf(output, "\n\n");
92186470930SIngo Molnar 	}
922d7470b6aSStephane Eranian }
92386470930SIngo Molnar 
924f7b7c26eSPeter Zijlstra static volatile int signr = -1;
925f7b7c26eSPeter Zijlstra 
92686470930SIngo Molnar static void skip_signal(int signo)
92786470930SIngo Molnar {
9286be2850eSZhang, Yanmin 	if(child_pid == -1)
92960666c63SLiming Wang 		done = 1;
93060666c63SLiming Wang 
931f7b7c26eSPeter Zijlstra 	signr = signo;
932f7b7c26eSPeter Zijlstra }
933f7b7c26eSPeter Zijlstra 
934f7b7c26eSPeter Zijlstra static void sig_atexit(void)
935f7b7c26eSPeter Zijlstra {
936933da83aSChris Wilson 	if (child_pid != -1)
937933da83aSChris Wilson 		kill(child_pid, SIGTERM);
938933da83aSChris Wilson 
939f7b7c26eSPeter Zijlstra 	if (signr == -1)
940f7b7c26eSPeter Zijlstra 		return;
941f7b7c26eSPeter Zijlstra 
942f7b7c26eSPeter Zijlstra 	signal(signr, SIG_DFL);
943f7b7c26eSPeter Zijlstra 	kill(getpid(), signr);
94486470930SIngo Molnar }
94586470930SIngo Molnar 
9461d037ca1SIrina Tirdea static int stat__set_big_num(const struct option *opt __maybe_unused,
9471d037ca1SIrina Tirdea 			     const char *s __maybe_unused, int unset)
948d7470b6aSStephane Eranian {
949d7470b6aSStephane Eranian 	big_num_opt = unset ? 0 : 1;
950d7470b6aSStephane Eranian 	return 0;
951d7470b6aSStephane Eranian }
952d7470b6aSStephane Eranian 
9532cba3ffbSIngo Molnar /*
9542cba3ffbSIngo Molnar  * Add default attributes, if there were no attributes specified or
9552cba3ffbSIngo Molnar  * if -d/--detailed, -d -d or -d -d -d is used:
9562cba3ffbSIngo Molnar  */
9572cba3ffbSIngo Molnar static int add_default_attributes(void)
9582cba3ffbSIngo Molnar {
959b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr default_attrs[] = {
960b070a547SArnaldo Carvalho de Melo 
961b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
962b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
963b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
964b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
965b070a547SArnaldo Carvalho de Melo 
966b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
967b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
968b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
969b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
970b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
971b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
972b070a547SArnaldo Carvalho de Melo 
973b070a547SArnaldo Carvalho de Melo };
974b070a547SArnaldo Carvalho de Melo 
975b070a547SArnaldo Carvalho de Melo /*
976b070a547SArnaldo Carvalho de Melo  * Detailed stats (-d), covering the L1 and last level data caches:
977b070a547SArnaldo Carvalho de Melo  */
978b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr detailed_attrs[] = {
979b070a547SArnaldo Carvalho de Melo 
980b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
981b070a547SArnaldo Carvalho de Melo     .config =
982b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
983b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
984b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
985b070a547SArnaldo Carvalho de Melo 
986b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
987b070a547SArnaldo Carvalho de Melo     .config =
988b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
989b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
990b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
991b070a547SArnaldo Carvalho de Melo 
992b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
993b070a547SArnaldo Carvalho de Melo     .config =
994b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
995b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
996b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
997b070a547SArnaldo Carvalho de Melo 
998b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
999b070a547SArnaldo Carvalho de Melo     .config =
1000b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_LL			<<  0  |
1001b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1002b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1003b070a547SArnaldo Carvalho de Melo };
1004b070a547SArnaldo Carvalho de Melo 
1005b070a547SArnaldo Carvalho de Melo /*
1006b070a547SArnaldo Carvalho de Melo  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1007b070a547SArnaldo Carvalho de Melo  */
1008b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_detailed_attrs[] = {
1009b070a547SArnaldo Carvalho de Melo 
1010b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1011b070a547SArnaldo Carvalho de Melo     .config =
1012b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1013b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1014b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1015b070a547SArnaldo Carvalho de Melo 
1016b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1017b070a547SArnaldo Carvalho de Melo     .config =
1018b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
1019b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1020b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1021b070a547SArnaldo Carvalho de Melo 
1022b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1023b070a547SArnaldo Carvalho de Melo     .config =
1024b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1025b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1026b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1027b070a547SArnaldo Carvalho de Melo 
1028b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1029b070a547SArnaldo Carvalho de Melo     .config =
1030b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
1031b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1032b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1033b070a547SArnaldo Carvalho de Melo 
1034b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1035b070a547SArnaldo Carvalho de Melo     .config =
1036b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1037b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1038b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1039b070a547SArnaldo Carvalho de Melo 
1040b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1041b070a547SArnaldo Carvalho de Melo     .config =
1042b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
1043b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
1044b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1045b070a547SArnaldo Carvalho de Melo 
1046b070a547SArnaldo Carvalho de Melo };
1047b070a547SArnaldo Carvalho de Melo 
1048b070a547SArnaldo Carvalho de Melo /*
1049b070a547SArnaldo Carvalho de Melo  * Very, very detailed stats (-d -d -d), adding prefetch events:
1050b070a547SArnaldo Carvalho de Melo  */
1051b070a547SArnaldo Carvalho de Melo 	struct perf_event_attr very_very_detailed_attrs[] = {
1052b070a547SArnaldo Carvalho de Melo 
1053b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1054b070a547SArnaldo Carvalho de Melo     .config =
1055b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1056b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1057b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
1058b070a547SArnaldo Carvalho de Melo 
1059b070a547SArnaldo Carvalho de Melo   { .type = PERF_TYPE_HW_CACHE,
1060b070a547SArnaldo Carvalho de Melo     .config =
1061b070a547SArnaldo Carvalho de Melo 	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
1062b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
1063b070a547SArnaldo Carvalho de Melo 	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
1064b070a547SArnaldo Carvalho de Melo };
1065b070a547SArnaldo Carvalho de Melo 
10662cba3ffbSIngo Molnar 	/* Set attrs if no event is selected and !null_run: */
10672cba3ffbSIngo Molnar 	if (null_run)
10682cba3ffbSIngo Molnar 		return 0;
10692cba3ffbSIngo Molnar 
10702cba3ffbSIngo Molnar 	if (!evsel_list->nr_entries) {
107179695e1bSArnaldo Carvalho de Melo 		if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
10722cba3ffbSIngo Molnar 			return -1;
10732cba3ffbSIngo Molnar 	}
10742cba3ffbSIngo Molnar 
10752cba3ffbSIngo Molnar 	/* Detailed events get appended to the event list: */
10762cba3ffbSIngo Molnar 
10772cba3ffbSIngo Molnar 	if (detailed_run <  1)
10782cba3ffbSIngo Molnar 		return 0;
10792cba3ffbSIngo Molnar 
10802cba3ffbSIngo Molnar 	/* Append detailed run extra attributes: */
108179695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
10822cba3ffbSIngo Molnar 		return -1;
10832cba3ffbSIngo Molnar 
10842cba3ffbSIngo Molnar 	if (detailed_run < 2)
10852cba3ffbSIngo Molnar 		return 0;
10862cba3ffbSIngo Molnar 
10872cba3ffbSIngo Molnar 	/* Append very detailed run extra attributes: */
108879695e1bSArnaldo Carvalho de Melo 	if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
10892cba3ffbSIngo Molnar 		return -1;
10902cba3ffbSIngo Molnar 
10912cba3ffbSIngo Molnar 	if (detailed_run < 3)
10922cba3ffbSIngo Molnar 		return 0;
10932cba3ffbSIngo Molnar 
10942cba3ffbSIngo Molnar 	/* Append very, very detailed run extra attributes: */
109579695e1bSArnaldo Carvalho de Melo 	return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
10962cba3ffbSIngo Molnar }
10972cba3ffbSIngo Molnar 
10981d037ca1SIrina Tirdea int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
109986470930SIngo Molnar {
11001f16c575SPeter Zijlstra 	bool append_file = false;
1101b070a547SArnaldo Carvalho de Melo 	int output_fd = 0;
1102b070a547SArnaldo Carvalho de Melo 	const char *output_name	= NULL;
1103b070a547SArnaldo Carvalho de Melo 	const struct option options[] = {
1104b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK('e', "event", &evsel_list, "event",
1105b070a547SArnaldo Carvalho de Melo 		     "event selector. use 'perf list' to list available events",
1106b070a547SArnaldo Carvalho de Melo 		     parse_events_option),
1107b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1108b070a547SArnaldo Carvalho de Melo 		     "event filter", parse_filter),
1109b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1110b070a547SArnaldo Carvalho de Melo 		    "child tasks do not inherit counters"),
1111b070a547SArnaldo Carvalho de Melo 	OPT_STRING('p', "pid", &target.pid, "pid",
1112b070a547SArnaldo Carvalho de Melo 		   "stat events on existing process id"),
1113b070a547SArnaldo Carvalho de Melo 	OPT_STRING('t', "tid", &target.tid, "tid",
1114b070a547SArnaldo Carvalho de Melo 		   "stat events on existing thread id"),
1115b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1116b070a547SArnaldo Carvalho de Melo 		    "system-wide collection from all CPUs"),
1117b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('g', "group", &group,
1118b070a547SArnaldo Carvalho de Melo 		    "put the counters into a counter group"),
1119b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"),
1120b070a547SArnaldo Carvalho de Melo 	OPT_INCR('v', "verbose", &verbose,
1121b070a547SArnaldo Carvalho de Melo 		    "be more verbose (show counter open errors, etc)"),
1122b070a547SArnaldo Carvalho de Melo 	OPT_INTEGER('r', "repeat", &run_count,
1123b070a547SArnaldo Carvalho de Melo 		    "repeat command and print average + stddev (max: 100)"),
1124b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('n', "null", &null_run,
1125b070a547SArnaldo Carvalho de Melo 		    "null run - dont start any counters"),
1126b070a547SArnaldo Carvalho de Melo 	OPT_INCR('d', "detailed", &detailed_run,
1127b070a547SArnaldo Carvalho de Melo 		    "detailed run - start a lot of events"),
1128b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('S', "sync", &sync_run,
1129b070a547SArnaldo Carvalho de Melo 		    "call sync() before starting a run"),
1130b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1131b070a547SArnaldo Carvalho de Melo 			   "print large numbers with thousands\' separators",
1132b070a547SArnaldo Carvalho de Melo 			   stat__set_big_num),
1133b070a547SArnaldo Carvalho de Melo 	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1134b070a547SArnaldo Carvalho de Melo 		    "list of cpus to monitor in system-wide"),
1135b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN('A', "no-aggr", &no_aggr, "disable CPU count aggregation"),
1136b070a547SArnaldo Carvalho de Melo 	OPT_STRING('x', "field-separator", &csv_sep, "separator",
1137b070a547SArnaldo Carvalho de Melo 		   "print counts with custom separator"),
1138b070a547SArnaldo Carvalho de Melo 	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1139b070a547SArnaldo Carvalho de Melo 		     "monitor event in cgroup name only", parse_cgroups),
1140b070a547SArnaldo Carvalho de Melo 	OPT_STRING('o', "output", &output_name, "file", "output file name"),
1141b070a547SArnaldo Carvalho de Melo 	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1142b070a547SArnaldo Carvalho de Melo 	OPT_INTEGER(0, "log-fd", &output_fd,
1143b070a547SArnaldo Carvalho de Melo 		    "log output to fd, instead of stderr"),
11441f16c575SPeter Zijlstra 	OPT_STRING(0, "pre", &pre_cmd, "command",
11451f16c575SPeter Zijlstra 			"command to run prior to the measured command"),
11461f16c575SPeter Zijlstra 	OPT_STRING(0, "post", &post_cmd, "command",
11471f16c575SPeter Zijlstra 			"command to run after to the measured command"),
1148b070a547SArnaldo Carvalho de Melo 	OPT_END()
1149b070a547SArnaldo Carvalho de Melo 	};
1150b070a547SArnaldo Carvalho de Melo 	const char * const stat_usage[] = {
1151b070a547SArnaldo Carvalho de Melo 		"perf stat [<options>] [<command>]",
1152b070a547SArnaldo Carvalho de Melo 		NULL
1153b070a547SArnaldo Carvalho de Melo 	};
115469aad6f1SArnaldo Carvalho de Melo 	struct perf_evsel *pos;
1155b070a547SArnaldo Carvalho de Melo 	int status = -ENOMEM, run_idx;
11564aa9015fSStephane Eranian 	const char *mode;
115742202dd5SIngo Molnar 
11585af52b51SStephane Eranian 	setlocale(LC_ALL, "");
11595af52b51SStephane Eranian 
11607e2ed097SArnaldo Carvalho de Melo 	evsel_list = perf_evlist__new(NULL, NULL);
1161361c99a6SArnaldo Carvalho de Melo 	if (evsel_list == NULL)
1162361c99a6SArnaldo Carvalho de Melo 		return -ENOMEM;
1163361c99a6SArnaldo Carvalho de Melo 
1164a0541234SAnton Blanchard 	argc = parse_options(argc, argv, options, stat_usage,
1165a0541234SAnton Blanchard 		PARSE_OPT_STOP_AT_NON_OPTION);
1166d7470b6aSStephane Eranian 
11674aa9015fSStephane Eranian 	output = stderr;
11684aa9015fSStephane Eranian 	if (output_name && strcmp(output_name, "-"))
11694aa9015fSStephane Eranian 		output = NULL;
11704aa9015fSStephane Eranian 
117156f3bae7SJim Cromie 	if (output_name && output_fd) {
117256f3bae7SJim Cromie 		fprintf(stderr, "cannot use both --output and --log-fd\n");
117356f3bae7SJim Cromie 		usage_with_options(stat_usage, options);
117456f3bae7SJim Cromie 	}
1175fc3e4d07SStephane Eranian 
1176fc3e4d07SStephane Eranian 	if (output_fd < 0) {
1177fc3e4d07SStephane Eranian 		fprintf(stderr, "argument to --log-fd must be a > 0\n");
1178fc3e4d07SStephane Eranian 		usage_with_options(stat_usage, options);
1179fc3e4d07SStephane Eranian 	}
1180fc3e4d07SStephane Eranian 
11814aa9015fSStephane Eranian 	if (!output) {
11824aa9015fSStephane Eranian 		struct timespec tm;
11834aa9015fSStephane Eranian 		mode = append_file ? "a" : "w";
11844aa9015fSStephane Eranian 
11854aa9015fSStephane Eranian 		output = fopen(output_name, mode);
11864aa9015fSStephane Eranian 		if (!output) {
11874aa9015fSStephane Eranian 			perror("failed to create output file");
1188fceda7feSDavid Ahern 			return -1;
11894aa9015fSStephane Eranian 		}
11904aa9015fSStephane Eranian 		clock_gettime(CLOCK_REALTIME, &tm);
11914aa9015fSStephane Eranian 		fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1192fc3e4d07SStephane Eranian 	} else if (output_fd > 0) {
119356f3bae7SJim Cromie 		mode = append_file ? "a" : "w";
119456f3bae7SJim Cromie 		output = fdopen(output_fd, mode);
119556f3bae7SJim Cromie 		if (!output) {
119656f3bae7SJim Cromie 			perror("Failed opening logfd");
119756f3bae7SJim Cromie 			return -errno;
119856f3bae7SJim Cromie 		}
11994aa9015fSStephane Eranian 	}
12004aa9015fSStephane Eranian 
1201d4ffd04dSJim Cromie 	if (csv_sep) {
1202d7470b6aSStephane Eranian 		csv_output = true;
1203d4ffd04dSJim Cromie 		if (!strcmp(csv_sep, "\\t"))
1204d4ffd04dSJim Cromie 			csv_sep = "\t";
1205d4ffd04dSJim Cromie 	} else
1206d7470b6aSStephane Eranian 		csv_sep = DEFAULT_SEPARATOR;
1207d7470b6aSStephane Eranian 
1208d7470b6aSStephane Eranian 	/*
1209d7470b6aSStephane Eranian 	 * let the spreadsheet do the pretty-printing
1210d7470b6aSStephane Eranian 	 */
1211d7470b6aSStephane Eranian 	if (csv_output) {
121261a9f324SJim Cromie 		/* User explicitly passed -B? */
1213d7470b6aSStephane Eranian 		if (big_num_opt == 1) {
1214d7470b6aSStephane Eranian 			fprintf(stderr, "-B option not supported with -x\n");
1215d7470b6aSStephane Eranian 			usage_with_options(stat_usage, options);
1216d7470b6aSStephane Eranian 		} else /* Nope, so disable big number formatting */
1217d7470b6aSStephane Eranian 			big_num = false;
1218d7470b6aSStephane Eranian 	} else if (big_num_opt == 0) /* User passed --no-big-num */
1219d7470b6aSStephane Eranian 		big_num = false;
1220d7470b6aSStephane Eranian 
1221aa22dd49SNamhyung Kim 	if (!argc && !perf_target__has_task(&target))
122286470930SIngo Molnar 		usage_with_options(stat_usage, options);
12239e9772c4SPeter Zijlstra 	if (run_count <= 0)
122442202dd5SIngo Molnar 		usage_with_options(stat_usage, options);
122586470930SIngo Molnar 
1226023695d9SStephane Eranian 	/* no_aggr, cgroup are for system-wide only */
1227aa22dd49SNamhyung Kim 	if ((no_aggr || nr_cgroups) && !perf_target__has_cpu(&target)) {
1228023695d9SStephane Eranian 		fprintf(stderr, "both cgroup and no-aggregation "
1229023695d9SStephane Eranian 			"modes only available in system-wide mode\n");
1230023695d9SStephane Eranian 
1231f5b4a9c3SStephane Eranian 		usage_with_options(stat_usage, options);
1232023695d9SStephane Eranian 	}
1233f5b4a9c3SStephane Eranian 
12342cba3ffbSIngo Molnar 	if (add_default_attributes())
1235c6264defSIngo Molnar 		goto out;
123686470930SIngo Molnar 
12374bd0f2d2SNamhyung Kim 	perf_target__validate(&target);
12385c98d466SArnaldo Carvalho de Melo 
123977a6f014SNamhyung Kim 	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1240aa22dd49SNamhyung Kim 		if (perf_target__has_task(&target))
12415c98d466SArnaldo Carvalho de Melo 			pr_err("Problems finding threads of monitor\n");
1242aa22dd49SNamhyung Kim 		if (perf_target__has_cpu(&target))
124360d567e2SArnaldo Carvalho de Melo 			perror("failed to parse CPUs map");
124477a6f014SNamhyung Kim 
1245c45c6ea2SStephane Eranian 		usage_with_options(stat_usage, options);
124660d567e2SArnaldo Carvalho de Melo 		return -1;
124760d567e2SArnaldo Carvalho de Melo 	}
1248c45c6ea2SStephane Eranian 
1249361c99a6SArnaldo Carvalho de Melo 	list_for_each_entry(pos, &evsel_list->entries, node) {
1250c52b12edSArnaldo Carvalho de Melo 		if (perf_evsel__alloc_stat_priv(pos) < 0 ||
12517ae92e74SYan, Zheng 		    perf_evsel__alloc_counts(pos, perf_evsel__nr_cpus(pos)) < 0)
125269aad6f1SArnaldo Carvalho de Melo 			goto out_free_fd;
1253d6d901c2SZhang, Yanmin 	}
1254d6d901c2SZhang, Yanmin 
125586470930SIngo Molnar 	/*
125686470930SIngo Molnar 	 * We dont want to block the signals - that would cause
125786470930SIngo Molnar 	 * child tasks to inherit that and Ctrl-C would not work.
125886470930SIngo Molnar 	 * What we want is for Ctrl-C to work in the exec()-ed
125986470930SIngo Molnar 	 * task, but being ignored by perf stat itself:
126086470930SIngo Molnar 	 */
1261f7b7c26eSPeter Zijlstra 	atexit(sig_atexit);
126286470930SIngo Molnar 	signal(SIGINT,  skip_signal);
126386470930SIngo Molnar 	signal(SIGALRM, skip_signal);
126486470930SIngo Molnar 	signal(SIGABRT, skip_signal);
126586470930SIngo Molnar 
126642202dd5SIngo Molnar 	status = 0;
126742202dd5SIngo Molnar 	for (run_idx = 0; run_idx < run_count; run_idx++) {
126842202dd5SIngo Molnar 		if (run_count != 1 && verbose)
12694aa9015fSStephane Eranian 			fprintf(output, "[ perf stat: executing run #%d ... ]\n",
12704aa9015fSStephane Eranian 				run_idx + 1);
1271f9cef0a9SIngo Molnar 
127242202dd5SIngo Molnar 		status = run_perf_stat(argc, argv);
127342202dd5SIngo Molnar 	}
127442202dd5SIngo Molnar 
1275084ab9f8SArnaldo Carvalho de Melo 	if (status != -1)
127642202dd5SIngo Molnar 		print_stat(argc, argv);
127769aad6f1SArnaldo Carvalho de Melo out_free_fd:
1278361c99a6SArnaldo Carvalho de Melo 	list_for_each_entry(pos, &evsel_list->entries, node)
127969aad6f1SArnaldo Carvalho de Melo 		perf_evsel__free_stat_priv(pos);
12807e2ed097SArnaldo Carvalho de Melo 	perf_evlist__delete_maps(evsel_list);
12810015e2e1SArnaldo Carvalho de Melo out:
12820015e2e1SArnaldo Carvalho de Melo 	perf_evlist__delete(evsel_list);
128342202dd5SIngo Molnar 	return status;
128486470930SIngo Molnar }
1285