Blame view

tools/perf/builtin-stat.c 32.9 KB
ddcacfa0f   Ingo Molnar   perf_counter tool...
1
  /*
bf9e18763   Ingo Molnar   perf_counter tool...
2
3
4
5
6
7
   * builtin-stat.c
   *
   * Builtin stat command: Give a precise performance counters summary
   * overview about any workload, CPU or specific PID.
   *
   * Sample output:
ddcacfa0f   Ingo Molnar   perf_counter tool...
8

2cba3ffb9   Ingo Molnar   perf stat: Add -d...
9
     $ perf stat ./hackbench 10
ddcacfa0f   Ingo Molnar   perf_counter tool...
10

2cba3ffb9   Ingo Molnar   perf stat: Add -d...
11
    Time: 0.118
ddcacfa0f   Ingo Molnar   perf_counter tool...
12

2cba3ffb9   Ingo Molnar   perf stat: Add -d...
13
    Performance counter stats for './hackbench 10':
ddcacfa0f   Ingo Molnar   perf_counter tool...
14

2cba3ffb9   Ingo Molnar   perf stat: Add -d...
15
16
17
18
19
20
21
22
23
24
25
26
27
         1708.761321 task-clock                #   11.037 CPUs utilized
              41,190 context-switches          #    0.024 M/sec
               6,735 CPU-migrations            #    0.004 M/sec
              17,318 page-faults               #    0.010 M/sec
       5,205,202,243 cycles                    #    3.046 GHz
       3,856,436,920 stalled-cycles-frontend   #   74.09% frontend cycles idle
       1,600,790,871 stalled-cycles-backend    #   30.75% backend  cycles idle
       2,603,501,247 instructions              #    0.50  insns per cycle
                                               #    1.48  stalled cycles per insn
         484,357,498 branches                  #  283.455 M/sec
           6,388,934 branch-misses             #    1.32% of all branches
  
          0.154822978  seconds time elapsed
ddcacfa0f   Ingo Molnar   perf_counter tool...
28

5242519b0   Ingo Molnar   perf stat: Conver...
29
   *
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
30
   * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
5242519b0   Ingo Molnar   perf stat: Conver...
31
32
33
34
35
36
37
38
   *
   * Improvements and fixes by:
   *
   *   Arjan van de Ven <arjan@linux.intel.com>
   *   Yanmin Zhang <yanmin.zhang@intel.com>
   *   Wu Fengguang <fengguang.wu@intel.com>
   *   Mike Galbraith <efault@gmx.de>
   *   Paul Mackerras <paulus@samba.org>
6e750a8fc   Jaswinder Singh Rajput   perf stat: Improv...
39
   *   Jaswinder Singh Rajput <jaswinder@kernel.org>
5242519b0   Ingo Molnar   perf stat: Conver...
40
41
   *
   * Released under the GPL v2. (and only v2, not any later version)
ddcacfa0f   Ingo Molnar   perf_counter tool...
42
   */
1a482f38c   Peter Zijlstra   perf_counter: Fix...
43
  #include "perf.h"
16f762a2a   Ingo Molnar   perf_counter tool...
44
  #include "builtin.h"
148be2c15   Ingo Molnar   perf_counter tool...
45
  #include "util/util.h"
5242519b0   Ingo Molnar   perf stat: Conver...
46
47
  #include "util/parse-options.h"
  #include "util/parse-events.h"
8f28827a1   Frederic Weisbecker   perf tools: Libra...
48
  #include "util/event.h"
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
49
  #include "util/evlist.h"
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
50
  #include "util/evsel.h"
8f28827a1   Frederic Weisbecker   perf tools: Libra...
51
  #include "util/debug.h"
a5d243d04   Ingo Molnar   perf stat: Print ...
52
  #include "util/color.h"
60666c630   Liming Wang   perf tools: Fix -...
53
  #include "util/header.h"
a12b51c47   Paul Mackerras   perf tools: Fix s...
54
  #include "util/cpumap.h"
d6d901c23   Zhang, Yanmin   perf events: Chan...
55
  #include "util/thread.h"
fd78260b5   Arnaldo Carvalho de Melo   perf threads: Mov...
56
  #include "util/thread_map.h"
ddcacfa0f   Ingo Molnar   perf_counter tool...
57

ddcacfa0f   Ingo Molnar   perf_counter tool...
58
  #include <sys/prctl.h>
42202dd56   Ingo Molnar   perf stat: Add fe...
59
  #include <math.h>
5af52b51f   Stephane Eranian   perf stat: add pe...
60
  #include <locale.h>
16c8a1093   Peter Zijlstra   perf_counter: too...
61

d7470b6af   Stephane Eranian   perf stat: Add cs...
62
  #define DEFAULT_SEPARATOR	" "
2cee77c45   David Ahern   perf stat: clarif...
63
64
  #define CNTR_NOT_SUPPORTED	"<not supported>"
  #define CNTR_NOT_COUNTED	"<not counted>"
d7470b6af   Stephane Eranian   perf stat: Add cs...
65

cdd6c482c   Ingo Molnar   perf: Do the big ...
66
  static struct perf_event_attr default_attrs[] = {
ddcacfa0f   Ingo Molnar   perf_counter tool...
67

56aab464f   Ingo Molnar   perf stat: Re-ali...
68
69
70
71
    { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
    { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
    { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
    { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
f4dbfa8f3   Peter Zijlstra   perf_counter: Sta...
72

56aab464f   Ingo Molnar   perf stat: Re-ali...
73
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
129c04cb8   Ingo Molnar   perf tools: Add f...
74
75
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
56aab464f   Ingo Molnar   perf stat: Re-ali...
76
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
56aab464f   Ingo Molnar   perf stat: Re-ali...
77
78
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
f4dbfa8f3   Peter Zijlstra   perf_counter: Sta...
79

ddcacfa0f   Ingo Molnar   perf_counter tool...
80
  };
5242519b0   Ingo Molnar   perf stat: Conver...
81

c6264deff   Ingo Molnar   perf stat: Add -d...
82
  /*
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
83
   * Detailed stats (-d), covering the L1 and last level data caches:
c6264deff   Ingo Molnar   perf stat: Add -d...
84
85
   */
  static struct perf_event_attr detailed_attrs[] = {
c6264deff   Ingo Molnar   perf stat: Add -d...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_LL			<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_LL			<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
  };
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  /*
   * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
   */
  static struct perf_event_attr very_detailed_attrs[] = {
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_L1I		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_DTLB		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_ITLB		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_READ		<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
  
  };
  
  /*
   * Very, very detailed stats (-d -d -d), adding prefetch events:
   */
  static struct perf_event_attr very_very_detailed_attrs[] = {
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_ACCESS	<< 16)				},
  
    { .type = PERF_TYPE_HW_CACHE,
      .config =
  	 PERF_COUNT_HW_CACHE_L1D		<<  0  |
  	(PERF_COUNT_HW_CACHE_OP_PREFETCH	<<  8) |
  	(PERF_COUNT_HW_CACHE_RESULT_MISS	<< 16)				},
  };
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
170
  struct perf_evlist		*evsel_list;
c05556421   Ian Munsie   perf: Fix endiann...
171
  static bool			system_wide			=  false;
3d6325958   Jaswinder Singh Rajput   perf stat: Remove...
172
  static int			run_idx				=  0;
ddcacfa0f   Ingo Molnar   perf_counter tool...
173

3d6325958   Jaswinder Singh Rajput   perf stat: Remove...
174
  static int			run_count			=  1;
2e6cdf996   Stephane Eranian   perf tools: chang...
175
  static bool			no_inherit			= false;
c05556421   Ian Munsie   perf: Fix endiann...
176
  static bool			scale				=  true;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
177
  static bool			no_aggr				= false;
933da83aa   Chris Wilson   perf: Propagate t...
178
  static pid_t			target_pid			= -1;
d6d901c23   Zhang, Yanmin   perf events: Chan...
179
  static pid_t			target_tid			= -1;
933da83aa   Chris Wilson   perf: Propagate t...
180
  static pid_t			child_pid			= -1;
c05556421   Ian Munsie   perf: Fix endiann...
181
  static bool			null_run			=  false;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
182
  static int			detailed_run			=  0;
f9cef0a90   Ingo Molnar   perf stat: Add --...
183
  static bool			sync_run			=  false;
201e0b06e   Arnaldo Carvalho de Melo   perf stat: Use --...
184
  static bool			big_num				=  true;
d7470b6af   Stephane Eranian   perf stat: Add cs...
185
  static int			big_num_opt			=  -1;
c45c6ea2e   Stephane Eranian   perf tools: Add t...
186
  static const char		*cpu_list;
d7470b6af   Stephane Eranian   perf stat: Add cs...
187
188
  static const char		*csv_sep			= NULL;
  static bool			csv_output			= false;
43bece797   Lin Ming   perf tools: Add g...
189
  static bool			group				= false;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
190
191
  static const char		*output_name			= NULL;
  static FILE			*output				= NULL;
56f3bae70   Jim Cromie   perf stat: Add --...
192
  static int			output_fd;
5af52b51f   Stephane Eranian   perf stat: add pe...
193

60666c630   Liming Wang   perf tools: Fix -...
194
  static volatile int done = 0;
506d4bc8d   Peter Zijlstra   perf stat: Change...
195
196
  struct stats
  {
8a02631a4   Peter Zijlstra   perf stat: More a...
197
  	double n, mean, M2;
506d4bc8d   Peter Zijlstra   perf stat: Change...
198
  };
42202dd56   Ingo Molnar   perf stat: Add fe...
199

69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
200
201
  struct perf_stat {
  	struct stats	  res_stats[3];
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
202
  };
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
203
  static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
204
  {
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
205
  	evsel->priv = zalloc(sizeof(struct perf_stat));
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
206
207
208
209
210
211
212
213
  	return evsel->priv == NULL ? -ENOMEM : 0;
  }
  
  static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
  {
  	free(evsel->priv);
  	evsel->priv = NULL;
  }
9e9772c45   Peter Zijlstra   perf stat: Remove...
214
215
  static void update_stats(struct stats *stats, u64 val)
  {
8a02631a4   Peter Zijlstra   perf stat: More a...
216
  	double delta;
9e9772c45   Peter Zijlstra   perf stat: Remove...
217

8a02631a4   Peter Zijlstra   perf stat: More a...
218
219
220
221
  	stats->n++;
  	delta = val - stats->mean;
  	stats->mean += delta / stats->n;
  	stats->M2 += delta*(val - stats->mean);
9e9772c45   Peter Zijlstra   perf stat: Remove...
222
  }
506d4bc8d   Peter Zijlstra   perf stat: Change...
223
224
  static double avg_stats(struct stats *stats)
  {
8a02631a4   Peter Zijlstra   perf stat: More a...
225
  	return stats->mean;
506d4bc8d   Peter Zijlstra   perf stat: Change...
226
  }
42202dd56   Ingo Molnar   perf stat: Add fe...
227

506d4bc8d   Peter Zijlstra   perf stat: Change...
228
  /*
63d40deb2   Peter Zijlstra   perf stat: Use st...
229
230
   * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
   *
8a02631a4   Peter Zijlstra   perf stat: More a...
231
232
233
   *       (\Sum n_i^2) - ((\Sum n_i)^2)/n
   * s^2 = -------------------------------
   *                  n - 1
63d40deb2   Peter Zijlstra   perf stat: Use st...
234
235
236
237
238
239
240
241
242
   *
   * http://en.wikipedia.org/wiki/Stddev
   *
   * The std dev of the mean is related to the std dev by:
   *
   *             s
   * s_mean = -------
   *          sqrt(n)
   *
506d4bc8d   Peter Zijlstra   perf stat: Change...
243
244
245
   */
  static double stddev_stats(struct stats *stats)
  {
19f474025   Jim Cromie   perf stat: Fix +-...
246
247
248
249
250
251
252
  	double variance, variance_mean;
  
  	if (!stats->n)
  		return 0.0;
  
  	variance = stats->M2 / (stats->n - 1);
  	variance_mean = variance / stats->n;
42202dd56   Ingo Molnar   perf stat: Add fe...
253

63d40deb2   Peter Zijlstra   perf stat: Use st...
254
  	return sqrt(variance_mean);
506d4bc8d   Peter Zijlstra   perf stat: Change...
255
  }
42202dd56   Ingo Molnar   perf stat: Add fe...
256

f5b4a9c3a   Stephane Eranian   perf stat: Add no...
257
258
  struct stats			runtime_nsecs_stats[MAX_NR_CPUS];
  struct stats			runtime_cycles_stats[MAX_NR_CPUS];
d3d1e86da   Ingo Molnar   perf stat: Analyz...
259
260
  struct stats			runtime_stalled_cycles_front_stats[MAX_NR_CPUS];
  struct stats			runtime_stalled_cycles_back_stats[MAX_NR_CPUS];
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
261
  struct stats			runtime_branches_stats[MAX_NR_CPUS];
d58f4c82f   Ingo Molnar   perf stat: Print ...
262
  struct stats			runtime_cacherefs_stats[MAX_NR_CPUS];
8bb6c79f2   Ingo Molnar   perf stat: Print ...
263
  struct stats			runtime_l1_dcache_stats[MAX_NR_CPUS];
c3305257c   Ingo Molnar   perf stat: Add mo...
264
265
266
267
  struct stats			runtime_l1_icache_stats[MAX_NR_CPUS];
  struct stats			runtime_ll_cache_stats[MAX_NR_CPUS];
  struct stats			runtime_itlb_cache_stats[MAX_NR_CPUS];
  struct stats			runtime_dtlb_cache_stats[MAX_NR_CPUS];
506d4bc8d   Peter Zijlstra   perf stat: Change...
268
  struct stats			walltime_nsecs_stats;
be1ac0d81   Ingo Molnar   perf_counter tool...
269

727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
270
271
  static int create_perf_stat_counter(struct perf_evsel *evsel,
  				    struct perf_evsel *first)
ddcacfa0f   Ingo Molnar   perf_counter tool...
272
  {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
273
  	struct perf_event_attr *attr = &evsel->attr;
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
274
275
276
277
  	struct xyarray *group_fd = NULL;
  
  	if (group && evsel != first)
  		group_fd = first->fd;
16c8a1093   Peter Zijlstra   perf_counter: too...
278

ddcacfa0f   Ingo Molnar   perf_counter tool...
279
  	if (scale)
a21ca2cac   Ingo Molnar   perf_counter: Sep...
280
281
  		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
  				    PERF_FORMAT_TOTAL_TIME_RUNNING;
ddcacfa0f   Ingo Molnar   perf_counter tool...
282

5d2cd9092   Arnaldo Carvalho de Melo   perf evsel: Fix u...
283
  	attr->inherit = !no_inherit;
48290609c   Arnaldo Carvalho de Melo   perf evsel: Intro...
284
  	if (system_wide)
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
285
286
  		return perf_evsel__open_per_cpu(evsel, evsel_list->cpus,
  						group, group_fd);
48290609c   Arnaldo Carvalho de Melo   perf evsel: Intro...
287
288
289
  	if (target_pid == -1 && target_tid == -1) {
  		attr->disabled = 1;
  		attr->enable_on_exec = 1;
ddcacfa0f   Ingo Molnar   perf_counter tool...
290
  	}
084ab9f86   Arnaldo Carvalho de Melo   perf stat: Better...
291

727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
292
293
  	return perf_evsel__open_per_thread(evsel, evsel_list->threads,
  					   group, group_fd);
ddcacfa0f   Ingo Molnar   perf_counter tool...
294
  }
c04f5e5d7   Ingo Molnar   perf_counter tool...
295
296
297
  /*
   * Does the counter have nsecs as a unit?
   */
daec78a09   Arnaldo Carvalho de Melo   perf evsel: Adopt...
298
  static inline int nsec_counter(struct perf_evsel *evsel)
c04f5e5d7   Ingo Molnar   perf_counter tool...
299
  {
daec78a09   Arnaldo Carvalho de Melo   perf evsel: Adopt...
300
301
  	if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
  	    perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
c04f5e5d7   Ingo Molnar   perf_counter tool...
302
303
304
305
306
307
  		return 1;
  
  	return 0;
  }
  
  /*
dcd9936a5   Ingo Molnar   perf stat: Factor...
308
309
310
311
312
313
314
315
316
317
   * Update various tracking values we maintain to print
   * more semantic information such as miss/hit ratios,
   * instruction rates, etc:
   */
  static void update_shadow_stats(struct perf_evsel *counter, u64 *count)
  {
  	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
  		update_stats(&runtime_nsecs_stats[0], count[0]);
  	else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
  		update_stats(&runtime_cycles_stats[0], count[0]);
d3d1e86da   Ingo Molnar   perf stat: Analyz...
318
319
  	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
  		update_stats(&runtime_stalled_cycles_front_stats[0], count[0]);
129c04cb8   Ingo Molnar   perf tools: Add f...
320
  	else if (perf_evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
d3d1e86da   Ingo Molnar   perf stat: Analyz...
321
  		update_stats(&runtime_stalled_cycles_back_stats[0], count[0]);
dcd9936a5   Ingo Molnar   perf stat: Factor...
322
323
324
325
  	else if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
  		update_stats(&runtime_branches_stats[0], count[0]);
  	else if (perf_evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
  		update_stats(&runtime_cacherefs_stats[0], count[0]);
8bb6c79f2   Ingo Molnar   perf stat: Print ...
326
327
  	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
  		update_stats(&runtime_l1_dcache_stats[0], count[0]);
c3305257c   Ingo Molnar   perf stat: Add mo...
328
329
330
331
332
333
334
335
  	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
  		update_stats(&runtime_l1_icache_stats[0], count[0]);
  	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_LL))
  		update_stats(&runtime_ll_cache_stats[0], count[0]);
  	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
  		update_stats(&runtime_dtlb_cache_stats[0], count[0]);
  	else if (perf_evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
  		update_stats(&runtime_itlb_cache_stats[0], count[0]);
dcd9936a5   Ingo Molnar   perf stat: Factor...
336
337
338
  }
  
  /*
2996f5ddb   Ingo Molnar   perf_counter tool...
339
   * Read out the results of a single counter:
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
340
   * aggregate counts across CPUs in system-wide mode
c04f5e5d7   Ingo Molnar   perf_counter tool...
341
   */
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
342
  static int read_counter_aggr(struct perf_evsel *counter)
c04f5e5d7   Ingo Molnar   perf_counter tool...
343
  {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
344
  	struct perf_stat *ps = counter->priv;
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
345
346
  	u64 *count = counter->counts->aggr.values;
  	int i;
2996f5ddb   Ingo Molnar   perf_counter tool...
347

7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
348
349
  	if (__perf_evsel__read(counter, evsel_list->cpus->nr,
  			       evsel_list->threads->nr, scale) < 0)
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
350
  		return -1;
9e9772c45   Peter Zijlstra   perf stat: Remove...
351
352
  
  	for (i = 0; i < 3; i++)
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
353
  		update_stats(&ps->res_stats[i], count[i]);
9e9772c45   Peter Zijlstra   perf stat: Remove...
354
355
  
  	if (verbose) {
4aa9015f8   Stephane Eranian   perf stat: Add -o...
356
357
  		fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "
  ",
9486aa387   Arnaldo Carvalho de Melo   perf tools: Fix 6...
358
  			event_name(counter), count[0], count[1], count[2]);
9e9772c45   Peter Zijlstra   perf stat: Remove...
359
  	}
be1ac0d81   Ingo Molnar   perf_counter tool...
360
361
362
  	/*
  	 * Save the full runtime - to allow normalization during printout:
  	 */
dcd9936a5   Ingo Molnar   perf stat: Factor...
363
  	update_shadow_stats(counter, count);
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
364
365
  
  	return 0;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
366
367
368
369
370
371
  }
  
  /*
   * Read out the results of a single counter:
   * do not aggregate counts across CPUs in system-wide mode
   */
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
372
  static int read_counter(struct perf_evsel *counter)
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
373
  {
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
374
  	u64 *count;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
375
  	int cpu;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
376

7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
377
  	for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) {
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
378
379
  		if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0)
  			return -1;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
380

c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
381
  		count = counter->counts->cpu[cpu].values;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
382

dcd9936a5   Ingo Molnar   perf stat: Factor...
383
  		update_shadow_stats(counter, count);
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
384
  	}
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
385
386
  
  	return 0;
2996f5ddb   Ingo Molnar   perf_counter tool...
387
  }
f37a291c5   Ingo Molnar   perf_counter tool...
388
  static int run_perf_stat(int argc __used, const char **argv)
42202dd56   Ingo Molnar   perf stat: Add fe...
389
390
  {
  	unsigned long long t0, t1;
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
391
  	struct perf_evsel *counter, *first;
42202dd56   Ingo Molnar   perf stat: Add fe...
392
  	int status = 0;
051ae7f73   Paul Mackerras   perf_counter tool...
393
  	int child_ready_pipe[2], go_pipe[2];
6be2850ef   Zhang, Yanmin   perf stat: Enable...
394
  	const bool forks = (argc > 0);
051ae7f73   Paul Mackerras   perf_counter tool...
395
  	char buf;
42202dd56   Ingo Molnar   perf stat: Add fe...
396

60666c630   Liming Wang   perf tools: Fix -...
397
  	if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
051ae7f73   Paul Mackerras   perf_counter tool...
398
399
400
  		perror("failed to create pipes");
  		exit(1);
  	}
60666c630   Liming Wang   perf tools: Fix -...
401
  	if (forks) {
6be2850ef   Zhang, Yanmin   perf stat: Enable...
402
  		if ((child_pid = fork()) < 0)
60666c630   Liming Wang   perf tools: Fix -...
403
  			perror("failed to fork");
6be2850ef   Zhang, Yanmin   perf stat: Enable...
404
  		if (!child_pid) {
60666c630   Liming Wang   perf tools: Fix -...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
  			close(child_ready_pipe[0]);
  			close(go_pipe[1]);
  			fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
  
  			/*
  			 * Do a dummy execvp to get the PLT entry resolved,
  			 * so we avoid the resolver overhead on the real
  			 * execvp call.
  			 */
  			execvp("", (char **)argv);
  
  			/*
  			 * Tell the parent we're ready to go
  			 */
  			close(child_ready_pipe[1]);
  
  			/*
  			 * Wait until the parent tells us to go.
  			 */
  			if (read(go_pipe[0], &buf, 1) == -1)
  				perror("unable to read pipe");
  
  			execvp(argv[0], (char **)argv);
  
  			perror(argv[0]);
  			exit(-1);
  		}
051ae7f73   Paul Mackerras   perf_counter tool...
432

d6d901c23   Zhang, Yanmin   perf events: Chan...
433
  		if (target_tid == -1 && target_pid == -1 && !system_wide)
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
434
  			evsel_list->threads->map[0] = child_pid;
d6d901c23   Zhang, Yanmin   perf events: Chan...
435

051ae7f73   Paul Mackerras   perf_counter tool...
436
  		/*
60666c630   Liming Wang   perf tools: Fix -...
437
  		 * Wait for the child to be ready to exec.
051ae7f73   Paul Mackerras   perf_counter tool...
438
439
  		 */
  		close(child_ready_pipe[1]);
60666c630   Liming Wang   perf tools: Fix -...
440
441
  		close(go_pipe[0]);
  		if (read(child_ready_pipe[0], &buf, 1) == -1)
a92bef0f2   Frederic Weisbecker   perf stat: Handle...
442
  			perror("unable to read pipe");
60666c630   Liming Wang   perf tools: Fix -...
443
  		close(child_ready_pipe[0]);
051ae7f73   Paul Mackerras   perf_counter tool...
444
  	}
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
445
  	first = list_entry(evsel_list->entries.next, struct perf_evsel, node);
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
446
  	list_for_each_entry(counter, &evsel_list->entries, node) {
727ab04ed   Arnaldo Carvalho de Melo   perf evlist: Fix ...
447
  		if (create_perf_stat_counter(counter, first) < 0) {
38f6ae1e1   Anton Blanchard   perf stat: Failur...
448
449
  			if (errno == EINVAL || errno == ENOSYS ||
  			    errno == ENOENT || errno == EOPNOTSUPP) {
c63ca0c01   David Ahern   perf stat: Tell u...
450
451
452
453
  				if (verbose)
  					ui__warning("%s event is not supported by the kernel.
  ",
  						    event_name(counter));
2cee77c45   David Ahern   perf stat: clarif...
454
  				counter->supported = false;
ede702900   Ingo Molnar   perf stat: Fix co...
455
  				continue;
c63ca0c01   David Ahern   perf stat: Tell u...
456
  			}
ede702900   Ingo Molnar   perf stat: Fix co...
457
458
  
  			if (errno == EPERM || errno == EACCES) {
48290609c   Arnaldo Carvalho de Melo   perf evsel: Intro...
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  				error("You may not have permission to collect %sstats.
  "
  				      "\t Consider tweaking"
  				      " /proc/sys/kernel/perf_event_paranoid or running as root.",
  				      system_wide ? "system-wide " : "");
  			} else {
  				error("open_counter returned with %d (%s). "
  				      "/bin/dmesg may provide additional information.
  ",
  				       errno, strerror(errno));
  			}
  			if (child_pid != -1)
  				kill(child_pid, SIGTERM);
  			die("Not all events could be opened.
  ");
  			return -1;
  		}
2cee77c45   David Ahern   perf stat: clarif...
476
  		counter->supported = true;
084ab9f86   Arnaldo Carvalho de Melo   perf stat: Better...
477
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
478

cfd748ae0   Frederic Weisbecker   perf stat: Provid...
479
480
481
482
483
484
  	if (perf_evlist__set_filters(evsel_list)) {
  		error("failed to set filter with %d (%s)
  ", errno,
  			strerror(errno));
  		return -1;
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
485
486
487
488
  	/*
  	 * Enable counters and exec the command:
  	 */
  	t0 = rdclock();
42202dd56   Ingo Molnar   perf stat: Add fe...
489

60666c630   Liming Wang   perf tools: Fix -...
490
491
492
  	if (forks) {
  		close(go_pipe[1]);
  		wait(&status);
33e49ea70   Andi Kleen   perf tools: Make ...
493
494
  		if (WIFSIGNALED(status))
  			psignal(WTERMSIG(status), argv[0]);
60666c630   Liming Wang   perf tools: Fix -...
495
  	} else {
6be2850ef   Zhang, Yanmin   perf stat: Enable...
496
  		while(!done) sleep(1);
60666c630   Liming Wang   perf tools: Fix -...
497
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
498

42202dd56   Ingo Molnar   perf stat: Add fe...
499
  	t1 = rdclock();
9e9772c45   Peter Zijlstra   perf stat: Remove...
500
  	update_stats(&walltime_nsecs_stats, t1 - t0);
42202dd56   Ingo Molnar   perf stat: Add fe...
501

f5b4a9c3a   Stephane Eranian   perf stat: Add no...
502
  	if (no_aggr) {
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
503
  		list_for_each_entry(counter, &evsel_list->entries, node) {
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
504
  			read_counter(counter);
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
505
  			perf_evsel__close_fd(counter, evsel_list->cpus->nr, 1);
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
506
  		}
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
507
  	} else {
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
508
  		list_for_each_entry(counter, &evsel_list->entries, node) {
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
509
  			read_counter_aggr(counter);
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
510
511
  			perf_evsel__close_fd(counter, evsel_list->cpus->nr,
  					     evsel_list->threads->nr);
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
512
  		}
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
513
  	}
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
514

42202dd56   Ingo Molnar   perf stat: Add fe...
515
516
  	return WEXITSTATUS(status);
  }
f99844cb7   Ingo Molnar   perf stat: Fix -n...
517
518
519
520
521
522
  static void print_noise_pct(double total, double avg)
  {
  	double pct = 0.0;
  
  	if (avg)
  		pct = 100.0*total/avg;
3ae9a34d7   Zhengyu He   perf stat: Add no...
523
  	if (csv_output)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
524
  		fprintf(output, "%s%.2f%%", csv_sep, pct);
a1bca6cc8   Jim Cromie   perf stat: Suppre...
525
  	else if (pct)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
526
  		fprintf(output, "  ( +-%6.2f%% )", pct);
f99844cb7   Ingo Molnar   perf stat: Fix -n...
527
  }
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
528
  static void print_noise(struct perf_evsel *evsel, double avg)
42202dd56   Ingo Molnar   perf stat: Add fe...
529
  {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
530
  	struct perf_stat *ps;
849abde92   Peter Zijlstra   perf stat: Clean ...
531
532
  	if (run_count == 1)
  		return;
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
533
  	ps = evsel->priv;
f99844cb7   Ingo Molnar   perf stat: Fix -n...
534
  	print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
42202dd56   Ingo Molnar   perf stat: Add fe...
535
  }
daec78a09   Arnaldo Carvalho de Melo   perf evsel: Adopt...
536
  static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
44175b6f3   Ingo Molnar   perf stat: Reorga...
537
  {
506d4bc8d   Peter Zijlstra   perf stat: Change...
538
  	double msecs = avg / 1e6;
d7470b6af   Stephane Eranian   perf stat: Add cs...
539
  	char cpustr[16] = { '\0', };
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
540
  	const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-25s";
44175b6f3   Ingo Molnar   perf stat: Reorga...
541

f5b4a9c3a   Stephane Eranian   perf stat: Add no...
542
  	if (no_aggr)
d7470b6af   Stephane Eranian   perf stat: Add cs...
543
544
  		sprintf(cpustr, "CPU%*d%s",
  			csv_output ? 0 : -4,
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
545
  			evsel_list->cpus->map[cpu], csv_sep);
d7470b6af   Stephane Eranian   perf stat: Add cs...
546

4aa9015f8   Stephane Eranian   perf stat: Add -o...
547
  	fprintf(output, fmt, cpustr, msecs, csv_sep, event_name(evsel));
d7470b6af   Stephane Eranian   perf stat: Add cs...
548

023695d96   Stephane Eranian   perf tool: Add cg...
549
  	if (evsel->cgrp)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
550
  		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
023695d96   Stephane Eranian   perf tool: Add cg...
551

d7470b6af   Stephane Eranian   perf stat: Add cs...
552
553
  	if (csv_output)
  		return;
44175b6f3   Ingo Molnar   perf stat: Reorga...
554

daec78a09   Arnaldo Carvalho de Melo   perf evsel: Adopt...
555
  	if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
4aa9015f8   Stephane Eranian   perf stat: Add -o...
556
557
  		fprintf(output, " # %8.3f CPUs utilized          ",
  			avg / avg_stats(&walltime_nsecs_stats));
44175b6f3   Ingo Molnar   perf stat: Reorga...
558
  }
15e6392fe   Namhyung Kim   perf stat: Introd...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
  /* used for get_ratio_color() */
  enum grc_type {
  	GRC_STALLED_CYCLES_FE,
  	GRC_STALLED_CYCLES_BE,
  	GRC_CACHE_MISSES,
  	GRC_MAX_NR
  };
  
  static const char *get_ratio_color(enum grc_type type, double ratio)
  {
  	static const double grc_table[GRC_MAX_NR][3] = {
  		[GRC_STALLED_CYCLES_FE] = { 50.0, 30.0, 10.0 },
  		[GRC_STALLED_CYCLES_BE] = { 75.0, 50.0, 20.0 },
  		[GRC_CACHE_MISSES] 	= { 20.0, 10.0, 5.0 },
  	};
  	const char *color = PERF_COLOR_NORMAL;
  
  	if (ratio > grc_table[type][0])
  		color = PERF_COLOR_RED;
  	else if (ratio > grc_table[type][1])
  		color = PERF_COLOR_MAGENTA;
  	else if (ratio > grc_table[type][2])
  		color = PERF_COLOR_YELLOW;
  
  	return color;
  }
d3d1e86da   Ingo Molnar   perf stat: Analyz...
585
586
587
588
589
590
591
592
593
  static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel __used, double avg)
  {
  	double total, ratio = 0.0;
  	const char *color;
  
  	total = avg_stats(&runtime_cycles_stats[cpu]);
  
  	if (total)
  		ratio = avg / total * 100.0;
15e6392fe   Namhyung Kim   perf stat: Introd...
594
  	color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
d3d1e86da   Ingo Molnar   perf stat: Analyz...
595

4aa9015f8   Stephane Eranian   perf stat: Add -o...
596
597
598
  	fprintf(output, " #  ");
  	color_fprintf(output, color, "%6.2f%%", ratio);
  	fprintf(output, " frontend cycles idle   ");
d3d1e86da   Ingo Molnar   perf stat: Analyz...
599
600
601
  }
  
  static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel __used, double avg)
a5d243d04   Ingo Molnar   perf stat: Print ...
602
603
604
605
606
607
608
609
  {
  	double total, ratio = 0.0;
  	const char *color;
  
  	total = avg_stats(&runtime_cycles_stats[cpu]);
  
  	if (total)
  		ratio = avg / total * 100.0;
15e6392fe   Namhyung Kim   perf stat: Introd...
610
  	color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
a5d243d04   Ingo Molnar   perf stat: Print ...
611

4aa9015f8   Stephane Eranian   perf stat: Add -o...
612
613
614
  	fprintf(output, " #  ");
  	color_fprintf(output, color, "%6.2f%%", ratio);
  	fprintf(output, " backend  cycles idle   ");
a5d243d04   Ingo Molnar   perf stat: Print ...
615
  }
c78df6c1d   Ingo Molnar   perf stat: Print ...
616
617
618
619
620
621
622
623
624
  static void print_branch_misses(int cpu, struct perf_evsel *evsel __used, double avg)
  {
  	double total, ratio = 0.0;
  	const char *color;
  
  	total = avg_stats(&runtime_branches_stats[cpu]);
  
  	if (total)
  		ratio = avg / total * 100.0;
15e6392fe   Namhyung Kim   perf stat: Introd...
625
  	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
c78df6c1d   Ingo Molnar   perf stat: Print ...
626

4aa9015f8   Stephane Eranian   perf stat: Add -o...
627
628
629
  	fprintf(output, " #  ");
  	color_fprintf(output, color, "%6.2f%%", ratio);
  	fprintf(output, " of all branches        ");
c78df6c1d   Ingo Molnar   perf stat: Print ...
630
  }
8bb6c79f2   Ingo Molnar   perf stat: Print ...
631
632
633
634
635
636
637
638
639
  static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
  {
  	double total, ratio = 0.0;
  	const char *color;
  
  	total = avg_stats(&runtime_l1_dcache_stats[cpu]);
  
  	if (total)
  		ratio = avg / total * 100.0;
15e6392fe   Namhyung Kim   perf stat: Introd...
640
  	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
8bb6c79f2   Ingo Molnar   perf stat: Print ...
641

4aa9015f8   Stephane Eranian   perf stat: Add -o...
642
643
644
  	fprintf(output, " #  ");
  	color_fprintf(output, color, "%6.2f%%", ratio);
  	fprintf(output, " of all L1-dcache hits  ");
8bb6c79f2   Ingo Molnar   perf stat: Print ...
645
  }
c3305257c   Ingo Molnar   perf stat: Add mo...
646
647
648
649
650
651
652
653
654
  static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
  {
  	double total, ratio = 0.0;
  	const char *color;
  
  	total = avg_stats(&runtime_l1_icache_stats[cpu]);
  
  	if (total)
  		ratio = avg / total * 100.0;
15e6392fe   Namhyung Kim   perf stat: Introd...
655
  	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
c3305257c   Ingo Molnar   perf stat: Add mo...
656

4aa9015f8   Stephane Eranian   perf stat: Add -o...
657
658
659
  	fprintf(output, " #  ");
  	color_fprintf(output, color, "%6.2f%%", ratio);
  	fprintf(output, " of all L1-icache hits  ");
c3305257c   Ingo Molnar   perf stat: Add mo...
660
661
662
663
664
665
666
667
668
669
670
  }
  
  static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
  {
  	double total, ratio = 0.0;
  	const char *color;
  
  	total = avg_stats(&runtime_dtlb_cache_stats[cpu]);
  
  	if (total)
  		ratio = avg / total * 100.0;
15e6392fe   Namhyung Kim   perf stat: Introd...
671
  	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
c3305257c   Ingo Molnar   perf stat: Add mo...
672

4aa9015f8   Stephane Eranian   perf stat: Add -o...
673
674
675
  	fprintf(output, " #  ");
  	color_fprintf(output, color, "%6.2f%%", ratio);
  	fprintf(output, " of all dTLB cache hits ");
c3305257c   Ingo Molnar   perf stat: Add mo...
676
677
678
679
680
681
682
683
684
685
686
  }
  
  static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
  {
  	double total, ratio = 0.0;
  	const char *color;
  
  	total = avg_stats(&runtime_itlb_cache_stats[cpu]);
  
  	if (total)
  		ratio = avg / total * 100.0;
15e6392fe   Namhyung Kim   perf stat: Introd...
687
  	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
c3305257c   Ingo Molnar   perf stat: Add mo...
688

4aa9015f8   Stephane Eranian   perf stat: Add -o...
689
690
691
  	fprintf(output, " #  ");
  	color_fprintf(output, color, "%6.2f%%", ratio);
  	fprintf(output, " of all iTLB cache hits ");
c3305257c   Ingo Molnar   perf stat: Add mo...
692
693
694
695
696
697
698
699
700
701
702
  }
  
  static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel __used, double avg)
  {
  	double total, ratio = 0.0;
  	const char *color;
  
  	total = avg_stats(&runtime_ll_cache_stats[cpu]);
  
  	if (total)
  		ratio = avg / total * 100.0;
15e6392fe   Namhyung Kim   perf stat: Introd...
703
  	color = get_ratio_color(GRC_CACHE_MISSES, ratio);
c3305257c   Ingo Molnar   perf stat: Add mo...
704

4aa9015f8   Stephane Eranian   perf stat: Add -o...
705
706
707
  	fprintf(output, " #  ");
  	color_fprintf(output, color, "%6.2f%%", ratio);
  	fprintf(output, " of all LL-cache hits   ");
c3305257c   Ingo Molnar   perf stat: Add mo...
708
  }
daec78a09   Arnaldo Carvalho de Melo   perf evsel: Adopt...
709
  static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
44175b6f3   Ingo Molnar   perf stat: Reorga...
710
  {
c7f7fea30   Ingo Molnar   perf stat: Fix ze...
711
  	double total, ratio = 0.0;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
712
  	char cpustr[16] = { '\0', };
d7470b6af   Stephane Eranian   perf stat: Add cs...
713
714
715
716
717
  	const char *fmt;
  
  	if (csv_output)
  		fmt = "%s%.0f%s%s";
  	else if (big_num)
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
718
  		fmt = "%s%'18.0f%s%-25s";
d7470b6af   Stephane Eranian   perf stat: Add cs...
719
  	else
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
720
  		fmt = "%s%18.0f%s%-25s";
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
721
722
  
  	if (no_aggr)
d7470b6af   Stephane Eranian   perf stat: Add cs...
723
724
  		sprintf(cpustr, "CPU%*d%s",
  			csv_output ? 0 : -4,
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
725
  			evsel_list->cpus->map[cpu], csv_sep);
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
726
727
  	else
  		cpu = 0;
c7f7fea30   Ingo Molnar   perf stat: Fix ze...
728

4aa9015f8   Stephane Eranian   perf stat: Add -o...
729
  	fprintf(output, fmt, cpustr, avg, csv_sep, event_name(evsel));
d7470b6af   Stephane Eranian   perf stat: Add cs...
730

023695d96   Stephane Eranian   perf tool: Add cg...
731
  	if (evsel->cgrp)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
732
  		fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
023695d96   Stephane Eranian   perf tool: Add cg...
733

d7470b6af   Stephane Eranian   perf stat: Add cs...
734
735
  	if (csv_output)
  		return;
44175b6f3   Ingo Molnar   perf stat: Reorga...
736

daec78a09   Arnaldo Carvalho de Melo   perf evsel: Adopt...
737
  	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
738
  		total = avg_stats(&runtime_cycles_stats[cpu]);
c7f7fea30   Ingo Molnar   perf stat: Fix ze...
739
740
741
  
  		if (total)
  			ratio = avg / total;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
742
  		fprintf(output, " #   %5.2f  insns per cycle        ", ratio);
481f988a0   Ingo Molnar   perf stat: Add st...
743

d3d1e86da   Ingo Molnar   perf stat: Analyz...
744
745
  		total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
  		total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
481f988a0   Ingo Molnar   perf stat: Add st...
746
747
748
  
  		if (total && avg) {
  			ratio = total / avg;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
749
750
  			fprintf(output, "
                                               #   %5.2f  stalled cycles per insn", ratio);
481f988a0   Ingo Molnar   perf stat: Add st...
751
  		}
daec78a09   Arnaldo Carvalho de Melo   perf evsel: Adopt...
752
  	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
753
  			runtime_branches_stats[cpu].n != 0) {
c78df6c1d   Ingo Molnar   perf stat: Print ...
754
  		print_branch_misses(cpu, evsel, avg);
8bb6c79f2   Ingo Molnar   perf stat: Print ...
755
756
757
758
759
  	} else if (
  		evsel->attr.type == PERF_TYPE_HW_CACHE &&
  		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1D |
  					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
  					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
c6264deff   Ingo Molnar   perf stat: Add -d...
760
  			runtime_l1_dcache_stats[cpu].n != 0) {
8bb6c79f2   Ingo Molnar   perf stat: Print ...
761
  		print_l1_dcache_misses(cpu, evsel, avg);
c3305257c   Ingo Molnar   perf stat: Add mo...
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
  	} else if (
  		evsel->attr.type == PERF_TYPE_HW_CACHE &&
  		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_L1I |
  					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
  					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
  			runtime_l1_icache_stats[cpu].n != 0) {
  		print_l1_icache_misses(cpu, evsel, avg);
  	} else if (
  		evsel->attr.type == PERF_TYPE_HW_CACHE &&
  		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_DTLB |
  					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
  					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
  			runtime_dtlb_cache_stats[cpu].n != 0) {
  		print_dtlb_cache_misses(cpu, evsel, avg);
  	} else if (
  		evsel->attr.type == PERF_TYPE_HW_CACHE &&
  		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_ITLB |
  					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
  					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
  			runtime_itlb_cache_stats[cpu].n != 0) {
  		print_itlb_cache_misses(cpu, evsel, avg);
  	} else if (
  		evsel->attr.type == PERF_TYPE_HW_CACHE &&
  		evsel->attr.config ==  ( PERF_COUNT_HW_CACHE_LL |
  					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
  					((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) &&
  			runtime_ll_cache_stats[cpu].n != 0) {
  		print_ll_cache_misses(cpu, evsel, avg);
d58f4c82f   Ingo Molnar   perf stat: Print ...
790
791
792
793
794
795
  	} else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) &&
  			runtime_cacherefs_stats[cpu].n != 0) {
  		total = avg_stats(&runtime_cacherefs_stats[cpu]);
  
  		if (total)
  			ratio = avg * 100 / total;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
796
  		fprintf(output, " # %8.3f %% of all cache refs    ", ratio);
d58f4c82f   Ingo Molnar   perf stat: Print ...
797

d3d1e86da   Ingo Molnar   perf stat: Analyz...
798
799
  	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
  		print_stalled_cycles_frontend(cpu, evsel, avg);
129c04cb8   Ingo Molnar   perf tools: Add f...
800
  	} else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
d3d1e86da   Ingo Molnar   perf stat: Analyz...
801
  		print_stalled_cycles_backend(cpu, evsel, avg);
481f988a0   Ingo Molnar   perf stat: Add st...
802
  	} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
803
  		total = avg_stats(&runtime_nsecs_stats[cpu]);
c7f7fea30   Ingo Molnar   perf stat: Fix ze...
804
805
  
  		if (total)
481f988a0   Ingo Molnar   perf stat: Add st...
806
  			ratio = 1.0 * avg / total;
c7f7fea30   Ingo Molnar   perf stat: Fix ze...
807

4aa9015f8   Stephane Eranian   perf stat: Add -o...
808
  		fprintf(output, " # %8.3f GHz                    ", ratio);
481f988a0   Ingo Molnar   perf stat: Add st...
809
810
  	} else if (runtime_nsecs_stats[cpu].n != 0) {
  		total = avg_stats(&runtime_nsecs_stats[cpu]);
11ba2b85f   Ingo Molnar   perf stat: Print ...
811
812
  
  		if (total)
481f988a0   Ingo Molnar   perf stat: Add st...
813
  			ratio = 1000.0 * avg / total;
11ba2b85f   Ingo Molnar   perf stat: Print ...
814

4aa9015f8   Stephane Eranian   perf stat: Add -o...
815
  		fprintf(output, " # %8.3f M/sec                  ", ratio);
a5d243d04   Ingo Molnar   perf stat: Print ...
816
  	} else {
4aa9015f8   Stephane Eranian   perf stat: Add -o...
817
  		fprintf(output, "                                   ");
44175b6f3   Ingo Molnar   perf stat: Reorga...
818
  	}
44175b6f3   Ingo Molnar   perf stat: Reorga...
819
  }
2996f5ddb   Ingo Molnar   perf_counter tool...
820
821
  /*
   * Print out the results of a single counter:
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
822
   * aggregated counts in system-wide mode
2996f5ddb   Ingo Molnar   perf_counter tool...
823
   */
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
824
  static void print_counter_aggr(struct perf_evsel *counter)
2996f5ddb   Ingo Molnar   perf_counter tool...
825
  {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
826
827
  	struct perf_stat *ps = counter->priv;
  	double avg = avg_stats(&ps->res_stats[0]);
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
828
  	int scaled = counter->counts->scaled;
2996f5ddb   Ingo Molnar   perf_counter tool...
829

2996f5ddb   Ingo Molnar   perf_counter tool...
830
  	if (scaled == -1) {
4aa9015f8   Stephane Eranian   perf stat: Add -o...
831
  		fprintf(output, "%*s%s%*s",
d7470b6af   Stephane Eranian   perf stat: Add cs...
832
  			csv_output ? 0 : 18,
2cee77c45   David Ahern   perf stat: clarif...
833
  			counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
023695d96   Stephane Eranian   perf tool: Add cg...
834
835
836
837
838
  			csv_sep,
  			csv_output ? 0 : -24,
  			event_name(counter));
  
  		if (counter->cgrp)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
839
  			fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
023695d96   Stephane Eranian   perf tool: Add cg...
840

4aa9015f8   Stephane Eranian   perf stat: Add -o...
841
842
  		fputc('
  ', output);
2996f5ddb   Ingo Molnar   perf_counter tool...
843
844
  		return;
  	}
c04f5e5d7   Ingo Molnar   perf_counter tool...
845

44175b6f3   Ingo Molnar   perf stat: Reorga...
846
  	if (nsec_counter(counter))
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
847
  		nsec_printout(-1, counter, avg);
44175b6f3   Ingo Molnar   perf stat: Reorga...
848
  	else
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
849
  		abs_printout(-1, counter, avg);
849abde92   Peter Zijlstra   perf stat: Clean ...
850

3ae9a34d7   Zhengyu He   perf stat: Add no...
851
  	print_noise(counter, avg);
d7470b6af   Stephane Eranian   perf stat: Add cs...
852
  	if (csv_output) {
4aa9015f8   Stephane Eranian   perf stat: Add -o...
853
854
  		fputc('
  ', output);
d7470b6af   Stephane Eranian   perf stat: Add cs...
855
856
  		return;
  	}
506d4bc8d   Peter Zijlstra   perf stat: Change...
857
858
  	if (scaled) {
  		double avg_enabled, avg_running;
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
859
860
  		avg_enabled = avg_stats(&ps->res_stats[1]);
  		avg_running = avg_stats(&ps->res_stats[2]);
d7c29318c   Ingo Molnar   perf_counter tool...
861

4aa9015f8   Stephane Eranian   perf stat: Add -o...
862
  		fprintf(output, " [%5.2f%%]", 100 * avg_running / avg_enabled);
506d4bc8d   Peter Zijlstra   perf stat: Change...
863
  	}
4aa9015f8   Stephane Eranian   perf stat: Add -o...
864
865
  	fprintf(output, "
  ");
c04f5e5d7   Ingo Molnar   perf_counter tool...
866
  }
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
867
868
869
870
  /*
   * Print out the results of a single counter:
   * does not use aggregated count in system-wide
   */
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
871
  static void print_counter(struct perf_evsel *counter)
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
872
873
874
  {
  	u64 ena, run, val;
  	int cpu;
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
875
  	for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) {
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
876
877
878
  		val = counter->counts->cpu[cpu].val;
  		ena = counter->counts->cpu[cpu].ena;
  		run = counter->counts->cpu[cpu].run;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
879
  		if (run == 0 || ena == 0) {
4aa9015f8   Stephane Eranian   perf stat: Add -o...
880
  			fprintf(output, "CPU%*d%s%*s%s%*s",
d7470b6af   Stephane Eranian   perf stat: Add cs...
881
  				csv_output ? 0 : -4,
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
882
  				evsel_list->cpus->map[cpu], csv_sep,
d7470b6af   Stephane Eranian   perf stat: Add cs...
883
  				csv_output ? 0 : 18,
2cee77c45   David Ahern   perf stat: clarif...
884
885
  				counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
  				csv_sep,
023695d96   Stephane Eranian   perf tool: Add cg...
886
  				csv_output ? 0 : -24,
d7470b6af   Stephane Eranian   perf stat: Add cs...
887
  				event_name(counter));
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
888

023695d96   Stephane Eranian   perf tool: Add cg...
889
  			if (counter->cgrp)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
890
891
  				fprintf(output, "%s%s",
  					csv_sep, counter->cgrp->name);
023695d96   Stephane Eranian   perf tool: Add cg...
892

4aa9015f8   Stephane Eranian   perf stat: Add -o...
893
894
  			fputc('
  ', output);
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
895
896
897
898
899
900
901
  			continue;
  		}
  
  		if (nsec_counter(counter))
  			nsec_printout(cpu, counter, val);
  		else
  			abs_printout(cpu, counter, val);
d7470b6af   Stephane Eranian   perf stat: Add cs...
902
903
  		if (!csv_output) {
  			print_noise(counter, 1.0);
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
904

c6264deff   Ingo Molnar   perf stat: Add -d...
905
  			if (run != ena)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
906
907
  				fprintf(output, "  (%.2f%%)",
  					100.0 * run / ena);
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
908
  		}
4aa9015f8   Stephane Eranian   perf stat: Add -o...
909
910
  		fputc('
  ', output);
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
911
912
  	}
  }
42202dd56   Ingo Molnar   perf stat: Add fe...
913
914
  static void print_stat(int argc, const char **argv)
  {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
915
916
  	struct perf_evsel *counter;
  	int i;
42202dd56   Ingo Molnar   perf stat: Add fe...
917

ddcacfa0f   Ingo Molnar   perf_counter tool...
918
  	fflush(stdout);
d7470b6af   Stephane Eranian   perf stat: Add cs...
919
  	if (!csv_output) {
4aa9015f8   Stephane Eranian   perf stat: Add -o...
920
921
922
  		fprintf(output, "
  ");
  		fprintf(output, " Performance counter stats for ");
d7470b6af   Stephane Eranian   perf stat: Add cs...
923
  		if(target_pid == -1 && target_tid == -1) {
4aa9015f8   Stephane Eranian   perf stat: Add -o...
924
  			fprintf(output, "\'%s", argv[0]);
d7470b6af   Stephane Eranian   perf stat: Add cs...
925
  			for (i = 1; i < argc; i++)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
926
  				fprintf(output, " %s", argv[i]);
d7470b6af   Stephane Eranian   perf stat: Add cs...
927
  		} else if (target_pid != -1)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
928
  			fprintf(output, "process id \'%d", target_pid);
d7470b6af   Stephane Eranian   perf stat: Add cs...
929
  		else
4aa9015f8   Stephane Eranian   perf stat: Add -o...
930
  			fprintf(output, "thread id \'%d", target_tid);
44db76c85   Ingo Molnar   perf stat: Print ...
931

4aa9015f8   Stephane Eranian   perf stat: Add -o...
932
  		fprintf(output, "\'");
d7470b6af   Stephane Eranian   perf stat: Add cs...
933
  		if (run_count > 1)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
934
935
936
937
  			fprintf(output, " (%d runs)", run_count);
  		fprintf(output, ":
  
  ");
d7470b6af   Stephane Eranian   perf stat: Add cs...
938
  	}
2996f5ddb   Ingo Molnar   perf_counter tool...
939

f5b4a9c3a   Stephane Eranian   perf stat: Add no...
940
  	if (no_aggr) {
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
941
  		list_for_each_entry(counter, &evsel_list->entries, node)
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
942
943
  			print_counter(counter);
  	} else {
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
944
  		list_for_each_entry(counter, &evsel_list->entries, node)
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
945
946
  			print_counter_aggr(counter);
  	}
ddcacfa0f   Ingo Molnar   perf_counter tool...
947

d7470b6af   Stephane Eranian   perf stat: Add cs...
948
  	if (!csv_output) {
c3305257c   Ingo Molnar   perf stat: Add mo...
949
  		if (!null_run)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
950
951
952
  			fprintf(output, "
  ");
  		fprintf(output, " %17.9f seconds time elapsed",
d7470b6af   Stephane Eranian   perf stat: Add cs...
953
954
  				avg_stats(&walltime_nsecs_stats)/1e9);
  		if (run_count > 1) {
4aa9015f8   Stephane Eranian   perf stat: Add -o...
955
  			fprintf(output, "                                        ");
f99844cb7   Ingo Molnar   perf stat: Fix -n...
956
957
  			print_noise_pct(stddev_stats(&walltime_nsecs_stats),
  					avg_stats(&walltime_nsecs_stats));
d7470b6af   Stephane Eranian   perf stat: Add cs...
958
  		}
4aa9015f8   Stephane Eranian   perf stat: Add -o...
959
960
961
  		fprintf(output, "
  
  ");
566747e62   Ingo Molnar   perf stat: Fix mu...
962
  	}
ddcacfa0f   Ingo Molnar   perf_counter tool...
963
  }
f7b7c26e0   Peter Zijlstra   perf_counter tool...
964
  static volatile int signr = -1;
5242519b0   Ingo Molnar   perf stat: Conver...
965
  static void skip_signal(int signo)
ddcacfa0f   Ingo Molnar   perf_counter tool...
966
  {
6be2850ef   Zhang, Yanmin   perf stat: Enable...
967
  	if(child_pid == -1)
60666c630   Liming Wang   perf tools: Fix -...
968
  		done = 1;
f7b7c26e0   Peter Zijlstra   perf_counter tool...
969
970
971
972
973
  	signr = signo;
  }
  
  static void sig_atexit(void)
  {
933da83aa   Chris Wilson   perf: Propagate t...
974
975
  	if (child_pid != -1)
  		kill(child_pid, SIGTERM);
f7b7c26e0   Peter Zijlstra   perf_counter tool...
976
977
978
979
980
  	if (signr == -1)
  		return;
  
  	signal(signr, SIG_DFL);
  	kill(getpid(), signr);
5242519b0   Ingo Molnar   perf stat: Conver...
981
982
983
  }
  
  static const char * const stat_usage[] = {
60666c630   Liming Wang   perf tools: Fix -...
984
  	"perf stat [<options>] [<command>]",
5242519b0   Ingo Molnar   perf stat: Conver...
985
986
  	NULL
  };
d7470b6af   Stephane Eranian   perf stat: Add cs...
987
988
989
990
991
992
  static int stat__set_big_num(const struct option *opt __used,
  			     const char *s __used, int unset)
  {
  	big_num_opt = unset ? 0 : 1;
  	return 0;
  }
4aa9015f8   Stephane Eranian   perf stat: Add -o...
993
  static bool append_file;
5242519b0   Ingo Molnar   perf stat: Conver...
994
  static const struct option options[] = {
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
995
  	OPT_CALLBACK('e', "event", &evsel_list, "event",
86847b62f   Thomas Gleixner   perf_counter tool...
996
  		     "event selector. use 'perf list' to list available events",
f120f9d51   Jiri Olsa   perf tools: De-op...
997
  		     parse_events_option),
cfd748ae0   Frederic Weisbecker   perf stat: Provid...
998
999
  	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
  		     "event filter", parse_filter),
2e6cdf996   Stephane Eranian   perf tools: chang...
1000
1001
  	OPT_BOOLEAN('i', "no-inherit", &no_inherit,
  		    "child tasks do not inherit counters"),
5242519b0   Ingo Molnar   perf stat: Conver...
1002
  	OPT_INTEGER('p', "pid", &target_pid,
d6d901c23   Zhang, Yanmin   perf events: Chan...
1003
1004
1005
  		    "stat events on existing process id"),
  	OPT_INTEGER('t', "tid", &target_tid,
  		    "stat events on existing thread id"),
5242519b0   Ingo Molnar   perf stat: Conver...
1006
  	OPT_BOOLEAN('a', "all-cpus", &system_wide,
3d6325958   Jaswinder Singh Rajput   perf stat: Remove...
1007
  		    "system-wide collection from all CPUs"),
43bece797   Lin Ming   perf tools: Add g...
1008
1009
  	OPT_BOOLEAN('g', "group", &group,
  		    "put the counters into a counter group"),
b26bc5a7f   Brice Goglin   perf stat: Fix to...
1010
  	OPT_BOOLEAN('c', "scale", &scale,
3d6325958   Jaswinder Singh Rajput   perf stat: Remove...
1011
  		    "scale/normalize counters"),
c05556421   Ian Munsie   perf: Fix endiann...
1012
  	OPT_INCR('v', "verbose", &verbose,
743ee1f80   Ingo Molnar   perf stat: Contin...
1013
  		    "be more verbose (show counter open errors, etc)"),
42202dd56   Ingo Molnar   perf stat: Add fe...
1014
1015
  	OPT_INTEGER('r', "repeat", &run_count,
  		    "repeat command and print average + stddev (max: 100)"),
0cfb7a13b   Ingo Molnar   perf stat: Add -n...
1016
1017
  	OPT_BOOLEAN('n', "null", &null_run,
  		    "null run - dont start any counters"),
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1018
  	OPT_INCR('d', "detailed", &detailed_run,
c6264deff   Ingo Molnar   perf stat: Add -d...
1019
  		    "detailed run - start a lot of events"),
f9cef0a90   Ingo Molnar   perf stat: Add --...
1020
1021
  	OPT_BOOLEAN('S', "sync", &sync_run,
  		    "call sync() before starting a run"),
d7470b6af   Stephane Eranian   perf stat: Add cs...
1022
1023
1024
  	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, 
  			   "print large numbers with thousands\' separators",
  			   stat__set_big_num),
c45c6ea2e   Stephane Eranian   perf tools: Add t...
1025
1026
  	OPT_STRING('C', "cpu", &cpu_list, "cpu",
  		    "list of cpus to monitor in system-wide"),
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
1027
1028
  	OPT_BOOLEAN('A', "no-aggr", &no_aggr,
  		    "disable CPU count aggregation"),
d7470b6af   Stephane Eranian   perf stat: Add cs...
1029
1030
  	OPT_STRING('x', "field-separator", &csv_sep, "separator",
  		   "print counts with custom separator"),
023695d96   Stephane Eranian   perf tool: Add cg...
1031
1032
1033
  	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
  		     "monitor event in cgroup name only",
  		     parse_cgroups),
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1034
1035
1036
  	OPT_STRING('o', "output", &output_name, "file",
  		    "output file name"),
  	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
56f3bae70   Jim Cromie   perf stat: Add --...
1037
1038
  	OPT_INTEGER(0, "log-fd", &output_fd,
  		    "log output to fd, instead of stderr"),
5242519b0   Ingo Molnar   perf stat: Conver...
1039
1040
  	OPT_END()
  };
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1041
1042
1043
1044
1045
1046
  /*
   * Add default attributes, if there were no attributes specified or
   * if -d/--detailed, -d -d or -d -d -d is used:
   */
  static int add_default_attributes(void)
  {
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1047
1048
1049
1050
1051
  	/* Set attrs if no event is selected and !null_run: */
  	if (null_run)
  		return 0;
  
  	if (!evsel_list->nr_entries) {
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1052
1053
  		if (perf_evlist__add_attrs_array(evsel_list, default_attrs) < 0)
  			return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1054
1055
1056
1057
1058
1059
1060
1061
  	}
  
  	/* Detailed events get appended to the event list: */
  
  	if (detailed_run <  1)
  		return 0;
  
  	/* Append detailed run extra attributes: */
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1062
1063
  	if (perf_evlist__add_attrs_array(evsel_list, detailed_attrs) < 0)
  		return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1064
1065
1066
1067
1068
  
  	if (detailed_run < 2)
  		return 0;
  
  	/* Append very detailed run extra attributes: */
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1069
1070
  	if (perf_evlist__add_attrs_array(evsel_list, very_detailed_attrs) < 0)
  		return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1071
1072
1073
1074
1075
  
  	if (detailed_run < 3)
  		return 0;
  
  	/* Append very, very detailed run extra attributes: */
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1076
  	return perf_evlist__add_attrs_array(evsel_list, very_very_detailed_attrs);
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1077
  }
f37a291c5   Ingo Molnar   perf_counter tool...
1078
  int cmd_stat(int argc, const char **argv, const char *prefix __used)
5242519b0   Ingo Molnar   perf stat: Conver...
1079
  {
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1080
1081
  	struct perf_evsel *pos;
  	int status = -ENOMEM;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1082
  	const char *mode;
42202dd56   Ingo Molnar   perf stat: Add fe...
1083

5af52b51f   Stephane Eranian   perf stat: add pe...
1084
  	setlocale(LC_ALL, "");
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1085
  	evsel_list = perf_evlist__new(NULL, NULL);
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
1086
1087
  	if (evsel_list == NULL)
  		return -ENOMEM;
a0541234f   Anton Blanchard   perf_counter: Imp...
1088
1089
  	argc = parse_options(argc, argv, options, stat_usage,
  		PARSE_OPT_STOP_AT_NON_OPTION);
d7470b6af   Stephane Eranian   perf stat: Add cs...
1090

4aa9015f8   Stephane Eranian   perf stat: Add -o...
1091
1092
1093
  	output = stderr;
  	if (output_name && strcmp(output_name, "-"))
  		output = NULL;
56f3bae70   Jim Cromie   perf stat: Add --...
1094
1095
1096
1097
1098
  	if (output_name && output_fd) {
  		fprintf(stderr, "cannot use both --output and --log-fd
  ");
  		usage_with_options(stat_usage, options);
  	}
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
  	if (!output) {
  		struct timespec tm;
  		mode = append_file ? "a" : "w";
  
  		output = fopen(output_name, mode);
  		if (!output) {
  			perror("failed to create output file");
  			exit(-1);
  		}
  		clock_gettime(CLOCK_REALTIME, &tm);
  		fprintf(output, "# started on %s
  ", ctime(&tm.tv_sec));
56f3bae70   Jim Cromie   perf stat: Add --...
1111
1112
1113
1114
1115
1116
1117
  	} else if (output_fd != 2) {
  		mode = append_file ? "a" : "w";
  		output = fdopen(output_fd, mode);
  		if (!output) {
  			perror("Failed opening logfd");
  			return -errno;
  		}
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1118
  	}
d4ffd04df   Jim Cromie   perf stat: Allow ...
1119
  	if (csv_sep) {
d7470b6af   Stephane Eranian   perf stat: Add cs...
1120
  		csv_output = true;
d4ffd04df   Jim Cromie   perf stat: Allow ...
1121
1122
1123
  		if (!strcmp(csv_sep, "\\t"))
  			csv_sep = "\t";
  	} else
d7470b6af   Stephane Eranian   perf stat: Add cs...
1124
1125
1126
1127
1128
1129
  		csv_sep = DEFAULT_SEPARATOR;
  
  	/*
  	 * let the spreadsheet do the pretty-printing
  	 */
  	if (csv_output) {
61a9f3242   Jim Cromie   perf stat: Fix sp...
1130
  		/* User explicitly passed -B? */
d7470b6af   Stephane Eranian   perf stat: Add cs...
1131
1132
1133
1134
1135
1136
1137
1138
  		if (big_num_opt == 1) {
  			fprintf(stderr, "-B option not supported with -x
  ");
  			usage_with_options(stat_usage, options);
  		} else /* Nope, so disable big number formatting */
  			big_num = false;
  	} else if (big_num_opt == 0) /* User passed --no-big-num */
  		big_num = false;
d6d901c23   Zhang, Yanmin   perf events: Chan...
1139
  	if (!argc && target_pid == -1 && target_tid == -1)
5242519b0   Ingo Molnar   perf stat: Conver...
1140
  		usage_with_options(stat_usage, options);
9e9772c45   Peter Zijlstra   perf stat: Remove...
1141
  	if (run_count <= 0)
42202dd56   Ingo Molnar   perf stat: Add fe...
1142
  		usage_with_options(stat_usage, options);
ddcacfa0f   Ingo Molnar   perf_counter tool...
1143

023695d96   Stephane Eranian   perf tool: Add cg...
1144
1145
1146
1147
1148
  	/* no_aggr, cgroup are for system-wide only */
  	if ((no_aggr || nr_cgroups) && !system_wide) {
  		fprintf(stderr, "both cgroup and no-aggregation "
  			"modes only available in system-wide mode
  ");
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
1149
  		usage_with_options(stat_usage, options);
023695d96   Stephane Eranian   perf tool: Add cg...
1150
  	}
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
1151

2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1152
1153
  	if (add_default_attributes())
  		goto out;
ddcacfa0f   Ingo Molnar   perf_counter tool...
1154

5c98d466e   Arnaldo Carvalho de Melo   perf tools: Refac...
1155
1156
  	if (target_pid != -1)
  		target_tid = target_pid;
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1157
1158
  	evsel_list->threads = thread_map__new(target_pid, target_tid);
  	if (evsel_list->threads == NULL) {
5c98d466e   Arnaldo Carvalho de Melo   perf tools: Refac...
1159
1160
1161
1162
  		pr_err("Problems finding threads of monitor
  ");
  		usage_with_options(stat_usage, options);
  	}
a12b51c47   Paul Mackerras   perf tools: Fix s...
1163
  	if (system_wide)
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1164
  		evsel_list->cpus = cpu_map__new(cpu_list);
a12b51c47   Paul Mackerras   perf tools: Fix s...
1165
  	else
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1166
  		evsel_list->cpus = cpu_map__dummy_new();
ddcacfa0f   Ingo Molnar   perf_counter tool...
1167

7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1168
  	if (evsel_list->cpus == NULL) {
60d567e2d   Arnaldo Carvalho de Melo   perf tools: Refac...
1169
  		perror("failed to parse CPUs map");
c45c6ea2e   Stephane Eranian   perf tools: Add t...
1170
  		usage_with_options(stat_usage, options);
60d567e2d   Arnaldo Carvalho de Melo   perf tools: Refac...
1171
1172
  		return -1;
  	}
c45c6ea2e   Stephane Eranian   perf tools: Add t...
1173

361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
1174
  	list_for_each_entry(pos, &evsel_list->entries, node) {
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
1175
  		if (perf_evsel__alloc_stat_priv(pos) < 0 ||
806fb6300   Arnaldo Carvalho de Melo   perf evlist: Alwa...
1176
  		    perf_evsel__alloc_counts(pos, evsel_list->cpus->nr) < 0)
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1177
  			goto out_free_fd;
d6d901c23   Zhang, Yanmin   perf events: Chan...
1178
  	}
58d7e993b   Ingo Molnar   perf stat: handle...
1179
1180
1181
1182
1183
1184
  	/*
  	 * We dont want to block the signals - that would cause
  	 * child tasks to inherit that and Ctrl-C would not work.
  	 * What we want is for Ctrl-C to work in the exec()-ed
  	 * task, but being ignored by perf stat itself:
  	 */
f7b7c26e0   Peter Zijlstra   perf_counter tool...
1185
  	atexit(sig_atexit);
58d7e993b   Ingo Molnar   perf stat: handle...
1186
1187
1188
  	signal(SIGINT,  skip_signal);
  	signal(SIGALRM, skip_signal);
  	signal(SIGABRT, skip_signal);
42202dd56   Ingo Molnar   perf stat: Add fe...
1189
1190
1191
  	status = 0;
  	for (run_idx = 0; run_idx < run_count; run_idx++) {
  		if (run_count != 1 && verbose)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1192
1193
1194
  			fprintf(output, "[ perf stat: executing run #%d ... ]
  ",
  				run_idx + 1);
f9cef0a90   Ingo Molnar   perf stat: Add --...
1195
1196
1197
  
  		if (sync_run)
  			sync();
42202dd56   Ingo Molnar   perf stat: Add fe...
1198
1199
  		status = run_perf_stat(argc, argv);
  	}
084ab9f86   Arnaldo Carvalho de Melo   perf stat: Better...
1200
1201
  	if (status != -1)
  		print_stat(argc, argv);
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1202
  out_free_fd:
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
1203
  	list_for_each_entry(pos, &evsel_list->entries, node)
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
1204
  		perf_evsel__free_stat_priv(pos);
7e2ed0975   Arnaldo Carvalho de Melo   perf evlist: Stor...
1205
  	perf_evlist__delete_maps(evsel_list);
0015e2e10   Arnaldo Carvalho de Melo   perf stat: Fix up...
1206
1207
  out:
  	perf_evlist__delete(evsel_list);
42202dd56   Ingo Molnar   perf stat: Add fe...
1208
  	return status;
ddcacfa0f   Ingo Molnar   perf_counter tool...
1209
  }