Blame view

tools/perf/builtin-stat.c 50.4 KB
910070454   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
ddcacfa0f   Ingo Molnar   perf_counter tool...
2
  /*
bf9e18763   Ingo Molnar   perf_counter tool...
3
4
5
6
7
8
   * 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...
9

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

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

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

2cba3ffb9   Ingo Molnar   perf stat: Add -d...
16
17
18
19
20
21
22
23
24
25
26
27
28
         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...
29

5242519b0   Ingo Molnar   perf stat: Conver...
30
   *
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
31
   * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
5242519b0   Ingo Molnar   perf stat: Conver...
32
33
34
35
36
37
38
39
   *
   * 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...
40
   *   Jaswinder Singh Rajput <jaswinder@kernel.org>
ddcacfa0f   Ingo Molnar   perf_counter tool...
41
   */
1a482f38c   Peter Zijlstra   perf_counter: Fix...
42
  #include "perf.h"
16f762a2a   Ingo Molnar   perf_counter tool...
43
  #include "builtin.h"
f14d57078   Arnaldo Carvalho de Melo   perf evsel: No ne...
44
  #include "util/cgroup.h"
148be2c15   Ingo Molnar   perf_counter tool...
45
  #include "util/util.h"
4b6ab94ea   Josh Poimboeuf   perf subcmd: Crea...
46
  #include <subcmd/parse-options.h>
5242519b0   Ingo Molnar   perf stat: Conver...
47
  #include "util/parse-events.h"
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
48
  #include "util/pmu.h"
8f28827a1   Frederic Weisbecker   perf tools: Libra...
49
  #include "util/event.h"
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
50
  #include "util/evlist.h"
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
51
  #include "util/evsel.h"
8f28827a1   Frederic Weisbecker   perf tools: Libra...
52
  #include "util/debug.h"
a5d243d04   Ingo Molnar   perf stat: Print ...
53
  #include "util/color.h"
0007eceac   Xiao Guangrong   perf stat: Move s...
54
  #include "util/stat.h"
60666c630   Liming Wang   perf tools: Fix -...
55
  #include "util/header.h"
a12b51c47   Paul Mackerras   perf tools: Fix s...
56
  #include "util/cpumap.h"
d6d901c23   Zhang, Yanmin   perf events: Chan...
57
  #include "util/thread.h"
fd78260b5   Arnaldo Carvalho de Melo   perf threads: Mov...
58
  #include "util/thread_map.h"
d809560b3   Jiri Olsa   perf stat: Move p...
59
  #include "util/counts.h"
44b1e60ab   Andi Kleen   perf stat: Basic ...
60
  #include "util/group.h"
4979d0c7d   Jiri Olsa   perf stat record:...
61
  #include "util/session.h"
ba6039b6c   Jiri Olsa   perf stat report:...
62
  #include "util/tool.h"
a067558e2   Arnaldo Carvalho de Melo   perf tools: Move ...
63
  #include "util/string2.h"
b18f3e365   Andi Kleen   perf stat: Suppor...
64
  #include "util/metricgroup.h"
9660e08ee   Jiri Olsa   perf stat: Add --...
65
  #include "util/top.h"
ba6039b6c   Jiri Olsa   perf stat report:...
66
  #include "asm/bug.h"
ddcacfa0f   Ingo Molnar   perf_counter tool...
67

bd48c63eb   Arnaldo Carvalho de Melo   tools: Introduce ...
68
  #include <linux/time64.h>
44b1e60ab   Andi Kleen   perf stat: Basic ...
69
  #include <api/fs/fs.h>
a43783aee   Arnaldo Carvalho de Melo   perf tools: Inclu...
70
  #include <errno.h>
9607ad3a6   Arnaldo Carvalho de Melo   perf tools: Add s...
71
  #include <signal.h>
1f16c5754   Peter Zijlstra   perf stat: Add --...
72
  #include <stdlib.h>
ddcacfa0f   Ingo Molnar   perf_counter tool...
73
  #include <sys/prctl.h>
fd20e8111   Arnaldo Carvalho de Melo   perf tools: Inclu...
74
  #include <inttypes.h>
5af52b51f   Stephane Eranian   perf stat: add pe...
75
  #include <locale.h>
e3b03b6c1   Andi Kleen   perf stat: Avoid ...
76
  #include <math.h>
7a8ef4c4b   Arnaldo Carvalho de Melo   perf tools: Remov...
77
78
  #include <sys/types.h>
  #include <sys/stat.h>
4208735d8   Arnaldo Carvalho de Melo   perf tools: Remov...
79
  #include <sys/wait.h>
7a8ef4c4b   Arnaldo Carvalho de Melo   perf tools: Remov...
80
  #include <unistd.h>
0ce2da148   Jiri Olsa   perf stat: Displa...
81
82
  #include <sys/time.h>
  #include <sys/resource.h>
16c8a1093   Peter Zijlstra   perf_counter: too...
83

3d689ed60   Arnaldo Carvalho de Melo   perf tools: Move ...
84
  #include "sane_ctype.h"
d7470b6af   Stephane Eranian   perf stat: Add cs...
85
  #define DEFAULT_SEPARATOR	" "
daefd0bc0   Kan Liang   perf stat: Add su...
86
  #define FREEZE_ON_SMI_PATH	"devices/cpu/freeze_on_smi"
d7470b6af   Stephane Eranian   perf stat: Add cs...
87

d4f63a474   Jiri Olsa   perf stat: Introd...
88
  static void print_counters(struct timespec *ts, int argc, const char **argv);
13370a9b5   Stephane Eranian   perf stat: Add in...
89

4cabc3d1c   Andi Kleen   tools/perf/stat: ...
90
  /* Default events used for perf stat -T */
a454742c1   Jiri Olsa   perf stat: Remove...
91
92
  static const char *transaction_attrs = {
  	"task-clock,"
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
93
94
95
96
97
98
99
100
101
102
103
  	"{"
  	"instructions,"
  	"cycles,"
  	"cpu/cycles-t/,"
  	"cpu/tx-start/,"
  	"cpu/el-start/,"
  	"cpu/cycles-ct/"
  	"}"
  };
  
  /* More limited version when the CPU does not have all events. */
a454742c1   Jiri Olsa   perf stat: Remove...
104
105
  static const char * transaction_limited_attrs = {
  	"task-clock,"
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
106
107
108
109
110
111
112
  	"{"
  	"instructions,"
  	"cycles,"
  	"cpu/cycles-t/,"
  	"cpu/tx-start/"
  	"}"
  };
44b1e60ab   Andi Kleen   perf stat: Basic ...
113
114
115
116
117
118
119
120
  static const char * topdown_attrs[] = {
  	"topdown-total-slots",
  	"topdown-slots-retired",
  	"topdown-recovery-bubbles",
  	"topdown-fetch-bubbles",
  	"topdown-slots-issued",
  	NULL,
  };
daefd0bc0   Kan Liang   perf stat: Add su...
121
122
123
124
125
126
127
  static const char *smi_cost_attrs = {
  	"{"
  	"msr/aperf/,"
  	"msr/smi/,"
  	"cycles"
  	"}"
  };
666e6d48c   Robert Richter   perf stat: Declar...
128
  static struct perf_evlist	*evsel_list;
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
129

602ad878d   Arnaldo Carvalho de Melo   perf target: Shor...
130
  static struct target target = {
77a6f014e   Namhyung Kim   perf stat: Use pe...
131
132
  	.uid	= UINT_MAX,
  };
ddcacfa0f   Ingo Molnar   perf_counter tool...
133

c1a1f5d9d   Jiri Olsa   perf stat: Allow ...
134
  #define METRIC_ONLY_LEN 20
d07f0b120   Stephane Eranian   perf stat: Avoid ...
135
  static volatile pid_t		child_pid			= -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
136
  static int			detailed_run			=  0;
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
137
  static bool			transaction_run;
44b1e60ab   Andi Kleen   perf stat: Basic ...
138
  static bool			topdown_run			= false;
daefd0bc0   Kan Liang   perf stat: Add su...
139
140
  static bool			smi_cost			= false;
  static bool			smi_reset			= false;
d7470b6af   Stephane Eranian   perf stat: Add cs...
141
  static int			big_num_opt			=  -1;
43bece797   Lin Ming   perf tools: Add g...
142
  static bool			group				= false;
1f16c5754   Peter Zijlstra   perf stat: Add --...
143
144
145
  static const char		*pre_cmd			= NULL;
  static const char		*post_cmd			= NULL;
  static bool			sync_run			= false;
a7e191c37   Frederik Deweerdt   perf stat: Introd...
146
  static bool			forever				= false;
44b1e60ab   Andi Kleen   perf stat: Basic ...
147
  static bool			force_metric_only		= false;
13370a9b5   Stephane Eranian   perf stat: Add in...
148
  static struct timespec		ref_time;
e05473111   Jiri Olsa   perf stat: Make s...
149
  static bool			append_file;
db06a269e   yuzhoujian   perf stat: Add su...
150
  static bool			interval_count;
e05473111   Jiri Olsa   perf stat: Make s...
151
152
  static const char		*output_name;
  static int			output_fd;
5af52b51f   Stephane Eranian   perf stat: add pe...
153

4979d0c7d   Jiri Olsa   perf stat record:...
154
155
  struct perf_stat {
  	bool			 record;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
156
  	struct perf_data	 data;
4979d0c7d   Jiri Olsa   perf stat record:...
157
158
  	struct perf_session	*session;
  	u64			 bytes_written;
ba6039b6c   Jiri Olsa   perf stat report:...
159
  	struct perf_tool	 tool;
1975d36e1   Jiri Olsa   perf stat report:...
160
161
162
  	bool			 maps_allocated;
  	struct cpu_map		*cpus;
  	struct thread_map	*threads;
89af4e05c   Jiri Olsa   perf stat report:...
163
  	enum aggr_mode		 aggr_mode;
4979d0c7d   Jiri Olsa   perf stat record:...
164
165
166
167
  };
  
  static struct perf_stat		perf_stat;
  #define STAT_RECORD		perf_stat.record
60666c630   Liming Wang   perf tools: Fix -...
168
  static volatile int done = 0;
421a50f3f   Jiri Olsa   perf stat: Introd...
169
  static struct perf_stat_config stat_config = {
26893a601   Jiri Olsa   perf stat: Add 'w...
170
171
172
173
174
175
  	.aggr_mode		= AGGR_GLOBAL,
  	.scale			= true,
  	.unit_width		= 4, /* strlen("unit") */
  	.run_count		= 1,
  	.metric_only_len	= METRIC_ONLY_LEN,
  	.walltime_nsecs_stats	= &walltime_nsecs_stats,
34ff0866d   Jiri Olsa   perf stat: Move '...
176
  	.big_num		= true,
421a50f3f   Jiri Olsa   perf stat: Introd...
177
  };
13370a9b5   Stephane Eranian   perf stat: Add in...
178
179
180
181
182
  static inline void diff_timespec(struct timespec *r, struct timespec *a,
  				 struct timespec *b)
  {
  	r->tv_sec = a->tv_sec - b->tv_sec;
  	if (a->tv_nsec < b->tv_nsec) {
310ebb936   Arnaldo Carvalho de Melo   perf stat: Use *S...
183
  		r->tv_nsec = a->tv_nsec + NSEC_PER_SEC - b->tv_nsec;
13370a9b5   Stephane Eranian   perf stat: Add in...
184
185
186
187
188
  		r->tv_sec--;
  	} else {
  		r->tv_nsec = a->tv_nsec - b->tv_nsec ;
  	}
  }
254ecbc74   Jiri Olsa   perf stat: Introd...
189
190
  static void perf_stat__reset_stats(void)
  {
56739444d   Jin Yao   perf stat: Alloca...
191
  	int i;
254ecbc74   Jiri Olsa   perf stat: Introd...
192
  	perf_evlist__reset_stats(evsel_list);
f87027b96   Jiri Olsa   perf stat: Move s...
193
  	perf_stat__reset_shadow_stats();
56739444d   Jin Yao   perf stat: Alloca...
194
195
196
  
  	for (i = 0; i < stat_config.stats_num; i++)
  		perf_stat__reset_shadow_per_stat(&stat_config.stats[i]);
1eda3b214   Jiri Olsa   perf stat: Introd...
197
  }
8b99b1a4e   Jiri Olsa   perf stat record:...
198
199
200
201
  static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
  				     union perf_event *event,
  				     struct perf_sample *sample __maybe_unused,
  				     struct machine *machine __maybe_unused)
4979d0c7d   Jiri Olsa   perf stat record:...
202
  {
8ceb41d7e   Jiri Olsa   perf tools: Renam...
203
  	if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) {
4979d0c7d   Jiri Olsa   perf stat record:...
204
205
206
207
  		pr_err("failed to write perf data, error: %m
  ");
  		return -1;
  	}
8b99b1a4e   Jiri Olsa   perf stat record:...
208
  	perf_stat.bytes_written += event->header.size;
4979d0c7d   Jiri Olsa   perf stat record:...
209
210
  	return 0;
  }
1975d36e1   Jiri Olsa   perf stat report:...
211
  static int write_stat_round_event(u64 tm, u64 type)
7aad0c32b   Jiri Olsa   perf stat record:...
212
  {
1975d36e1   Jiri Olsa   perf stat report:...
213
  	return perf_event__synthesize_stat_round(NULL, tm, type,
7aad0c32b   Jiri Olsa   perf stat record:...
214
215
216
217
218
219
  						 process_synthesized_event,
  						 NULL);
  }
  
  #define WRITE_STAT_ROUND_EVENT(time, interval) \
  	write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
5a6ea81b8   Jiri Olsa   perf stat record:...
220
221
222
223
224
225
226
227
228
229
230
  #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
  
  static int
  perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread,
  			     struct perf_counts_values *count)
  {
  	struct perf_sample_id *sid = SID(counter, cpu, thread);
  
  	return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
  					   process_synthesized_event, NULL);
  }
f0fbb114e   Andi Kleen   perf stat: Implem...
231
232
233
234
235
236
237
238
239
240
241
242
243
  static int read_single_counter(struct perf_evsel *counter, int cpu,
  			       int thread, struct timespec *rs)
  {
  	if (counter->tool_event == PERF_TOOL_DURATION_TIME) {
  		u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL;
  		struct perf_counts_values *count =
  			perf_counts(counter->counts, cpu, thread);
  		count->ena = count->run = val;
  		count->val = val;
  		return 0;
  	}
  	return perf_evsel__read_counter(counter, cpu, thread);
  }
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
244
245
246
247
  /*
   * Read out the results of a single counter:
   * do not aggregate counts across CPUs in system-wide mode
   */
f0fbb114e   Andi Kleen   perf stat: Implem...
248
  static int read_counter(struct perf_evsel *counter, struct timespec *rs)
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
249
  {
9bf1a5291   Jiri Olsa   perf stat: Make r...
250
  	int nthreads = thread_map__nr(evsel_list->threads);
00e727bb3   Mark Rutland   perf stat: Balanc...
251
  	int ncpus, cpu, thread;
1d9f8d1b8   Jin Yao   perf stat: Remove...
252
  	if (target__has_cpu(&target) && !target__has_per_thread(&target))
00e727bb3   Mark Rutland   perf stat: Balanc...
253
254
255
  		ncpus = perf_evsel__nr_cpus(counter);
  	else
  		ncpus = 1;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
256

3b4331d9a   Suzuki K. Poulose   perf stat: Report...
257
258
  	if (!counter->supported)
  		return -ENOENT;
9bf1a5291   Jiri Olsa   perf stat: Make r...
259
260
261
262
263
  	if (counter->system_wide)
  		nthreads = 1;
  
  	for (thread = 0; thread < nthreads; thread++) {
  		for (cpu = 0; cpu < ncpus; cpu++) {
3b3eb0445   Jiri Olsa   perf stat: Separa...
264
265
266
  			struct perf_counts_values *count;
  
  			count = perf_counts(counter->counts, cpu, thread);
82bf311e1   Jiri Olsa   perf stat: Use gr...
267
268
269
270
271
272
  
  			/*
  			 * The leader's group read loads data into its group members
  			 * (via perf_evsel__read_counter) and sets threir count->loaded.
  			 */
  			if (!count->loaded &&
f0fbb114e   Andi Kleen   perf stat: Implem...
273
  			    read_single_counter(counter, cpu, thread, rs)) {
db49a7179   Stephane Eranian   perf stat: Fix bu...
274
275
276
  				counter->counts->scaled = -1;
  				perf_counts(counter->counts, cpu, thread)->ena = 0;
  				perf_counts(counter->counts, cpu, thread)->run = 0;
9bf1a5291   Jiri Olsa   perf stat: Make r...
277
  				return -1;
db49a7179   Stephane Eranian   perf stat: Fix bu...
278
  			}
5a6ea81b8   Jiri Olsa   perf stat record:...
279

82bf311e1   Jiri Olsa   perf stat: Use gr...
280
  			count->loaded = false;
5a6ea81b8   Jiri Olsa   perf stat record:...
281
282
283
284
285
286
287
  			if (STAT_RECORD) {
  				if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
  					pr_err("failed to write stat event
  ");
  					return -1;
  				}
  			}
0b1abbf4a   Andi Kleen   perf stat: Add ex...
288
289
290
291
292
293
294
295
296
  
  			if (verbose > 1) {
  				fprintf(stat_config.output,
  					"%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "
  ",
  						perf_evsel__name(counter),
  						cpu,
  						count->val, count->ena, count->run);
  			}
9bf1a5291   Jiri Olsa   perf stat: Make r...
297
  		}
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
298
  	}
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
299
300
  
  	return 0;
2996f5ddb   Ingo Molnar   perf_counter tool...
301
  }
f0fbb114e   Andi Kleen   perf stat: Implem...
302
  static void read_counters(struct timespec *rs)
13370a9b5   Stephane Eranian   perf stat: Add in...
303
  {
13370a9b5   Stephane Eranian   perf stat: Add in...
304
  	struct perf_evsel *counter;
db49a7179   Stephane Eranian   perf stat: Fix bu...
305
  	int ret;
13370a9b5   Stephane Eranian   perf stat: Add in...
306

e5cadb93d   Arnaldo Carvalho de Melo   perf evlist: Rena...
307
  	evlist__for_each_entry(evsel_list, counter) {
f0fbb114e   Andi Kleen   perf stat: Implem...
308
  		ret = read_counter(counter, rs);
db49a7179   Stephane Eranian   perf stat: Fix bu...
309
  		if (ret)
245bad8eb   Andi Kleen   perf stat: Quiete...
310
311
  			pr_debug("failed to read counter %s
  ", counter->name);
3b3eb0445   Jiri Olsa   perf stat: Separa...
312

db49a7179   Stephane Eranian   perf stat: Fix bu...
313
  		if (ret == 0 && perf_stat_process_counter(&stat_config, counter))
3b3eb0445   Jiri Olsa   perf stat: Separa...
314
315
  			pr_warning("failed to process counter %s
  ", counter->name);
13370a9b5   Stephane Eranian   perf stat: Add in...
316
  	}
106a94a0f   Jiri Olsa   perf stat: Introd...
317
  }
ba411a954   Jiri Olsa   perf stat: Rename...
318
  static void process_interval(void)
106a94a0f   Jiri Olsa   perf stat: Introd...
319
  {
106a94a0f   Jiri Olsa   perf stat: Introd...
320
  	struct timespec ts, rs;
106a94a0f   Jiri Olsa   perf stat: Introd...
321

13370a9b5   Stephane Eranian   perf stat: Add in...
322
323
  	clock_gettime(CLOCK_MONOTONIC, &ts);
  	diff_timespec(&rs, &ts, &ref_time);
13370a9b5   Stephane Eranian   perf stat: Add in...
324

f0fbb114e   Andi Kleen   perf stat: Implem...
325
  	read_counters(&rs);
7aad0c32b   Jiri Olsa   perf stat record:...
326
  	if (STAT_RECORD) {
bd48c63eb   Arnaldo Carvalho de Melo   tools: Introduce ...
327
  		if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL))
7aad0c32b   Jiri Olsa   perf stat record:...
328
329
330
  			pr_err("failed to write stat round event
  ");
  	}
b90f1333e   Andi Kleen   perf stat: Update...
331
332
  	init_stats(&walltime_nsecs_stats);
  	update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000);
d4f63a474   Jiri Olsa   perf stat: Introd...
333
  	print_counters(&rs, 0, NULL);
13370a9b5   Stephane Eranian   perf stat: Add in...
334
  }
67ccdecd0   Jiri Olsa   perf stat: Create...
335
  static void enable_counters(void)
411916880   Andi Kleen   perf stat: Add su...
336
  {
728c0ee0a   Jiri Olsa   perf stat: Move '...
337
338
  	if (stat_config.initial_delay)
  		usleep(stat_config.initial_delay * USEC_PER_MSEC);
67ccdecd0   Jiri Olsa   perf stat: Create...
339
340
341
342
343
344
  
  	/*
  	 * We need to enable counters only if:
  	 * - we don't have tracee (attaching to task or cpu)
  	 * - we have initial delay configured
  	 */
728c0ee0a   Jiri Olsa   perf stat: Move '...
345
  	if (!target__none(&target) || stat_config.initial_delay)
ab46db0a3   Jiri Olsa   perf stat: Use pe...
346
  		perf_evlist__enable(evsel_list);
411916880   Andi Kleen   perf stat: Add su...
347
  }
3df33eff2   Mark Rutland   perf stat: Avoid ...
348
349
350
351
352
353
354
355
356
357
  static void disable_counters(void)
  {
  	/*
  	 * If we don't have tracee (attaching to task or cpu), counters may
  	 * still be running. To get accurate group ratios, we must stop groups
  	 * from counting before reading their constituent counters.
  	 */
  	if (!target__none(&target))
  		perf_evlist__disable(evsel_list);
  }
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
358
  static volatile int workload_exec_errno;
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
359
360
361
362
363
364
  
  /*
   * perf_evlist__prepare_workload will send a SIGUSR1
   * if the fork fails, since we asked by setting its
   * want_signal to true.
   */
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
365
366
  static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
  					void *ucontext __maybe_unused)
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
367
  {
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
368
  	workload_exec_errno = info->si_value.sival_int;
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
369
  }
82bf311e1   Jiri Olsa   perf stat: Use gr...
370
371
372
373
  static bool perf_evsel__should_store_id(struct perf_evsel *counter)
  {
  	return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID;
  }
cbb5df7e9   Jiri Olsa   perf stat: Poll f...
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  static bool is_target_alive(struct target *_target,
  			    struct thread_map *threads)
  {
  	struct stat st;
  	int i;
  
  	if (!target__has_task(_target))
  		return true;
  
  	for (i = 0; i < threads->nr; i++) {
  		char path[PATH_MAX];
  
  		scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(),
  			  threads->map[i].pid);
  
  		if (!stat(path, &st))
  			return true;
  	}
  
  	return false;
  }
e55c14af4   Jiri Olsa   perf stat: Add --...
395
  static int __run_perf_stat(int argc, const char **argv, int run_idx)
42202dd56   Ingo Molnar   perf stat: Add fe...
396
  {
ec0d3d1fd   Jiri Olsa   perf stat: Move '...
397
  	int interval = stat_config.interval;
db06a269e   yuzhoujian   perf stat: Add su...
398
  	int times = stat_config.times;
f1f8ad52f   yuzhoujian   perf stat: Add su...
399
  	int timeout = stat_config.timeout;
d6195a6a2   Arnaldo Carvalho de Melo   perf evsel: Infor...
400
  	char msg[BUFSIZ];
42202dd56   Ingo Molnar   perf stat: Add fe...
401
  	unsigned long long t0, t1;
cac214255   Jiri Olsa   perf tools: Fix a...
402
  	struct perf_evsel *counter;
13370a9b5   Stephane Eranian   perf stat: Add in...
403
  	struct timespec ts;
410136f5d   Stephane Eranian   tools/perf/stat: ...
404
  	size_t l;
42202dd56   Ingo Molnar   perf stat: Add fe...
405
  	int status = 0;
6be2850ef   Zhang, Yanmin   perf stat: Enable...
406
  	const bool forks = (argc > 0);
8ceb41d7e   Jiri Olsa   perf tools: Renam...
407
  	bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false;
42202dd56   Ingo Molnar   perf stat: Add fe...
408

13370a9b5   Stephane Eranian   perf stat: Add in...
409
  	if (interval) {
310ebb936   Arnaldo Carvalho de Melo   perf stat: Use *S...
410
411
  		ts.tv_sec  = interval / USEC_PER_MSEC;
  		ts.tv_nsec = (interval % USEC_PER_MSEC) * NSEC_PER_MSEC;
f1f8ad52f   yuzhoujian   perf stat: Add su...
412
413
414
  	} else if (timeout) {
  		ts.tv_sec  = timeout / USEC_PER_MSEC;
  		ts.tv_nsec = (timeout % USEC_PER_MSEC) * NSEC_PER_MSEC;
13370a9b5   Stephane Eranian   perf stat: Add in...
415
416
417
418
  	} else {
  		ts.tv_sec  = 1;
  		ts.tv_nsec = 0;
  	}
60666c630   Liming Wang   perf tools: Fix -...
419
  	if (forks) {
664c98d4e   Jiri Olsa   perf stat record:...
420
  		if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe,
735f7e0bb   Arnaldo Carvalho de Melo   perf evlist: Move...
421
  						  workload_exec_failed_signal) < 0) {
acf289227   Namhyung Kim   perf stat: Use pe...
422
423
  			perror("failed to prepare workload");
  			return -1;
60666c630   Liming Wang   perf tools: Fix -...
424
  		}
d20a47e70   Namhyung Kim   perf stat: Set ch...
425
  		child_pid = evsel_list->workload.pid;
051ae7f73   Paul Mackerras   perf_counter tool...
426
  	}
6a4bb04ca   Jiri Olsa   perf tools: Enabl...
427
  	if (group)
63dab225f   Arnaldo Carvalho de Melo   perf evlist: Rena...
428
  		perf_evlist__set_leader(evsel_list);
6a4bb04ca   Jiri Olsa   perf tools: Enabl...
429

e5cadb93d   Arnaldo Carvalho de Melo   perf evlist: Rena...
430
  	evlist__for_each_entry(evsel_list, counter) {
42ef8a78c   Arnaldo Carvalho de Melo   perf stat: Fallba...
431
  try_again:
d09cefd2e   Jiri Olsa   perf stat: Move c...
432
  		if (create_perf_stat_counter(counter, &stat_config, &target) < 0) {
5a5dfe4b8   Andi Kleen   perf tools: Suppo...
433
434
  
  			/* Weak group failed. Reset the group. */
35c1980eb   Andi Kleen   perf stat: Fall w...
435
  			if ((errno == EINVAL || errno == EBADF) &&
5a5dfe4b8   Andi Kleen   perf tools: Suppo...
436
437
  			    counter->leader != counter &&
  			    counter->weak_group) {
c3537fc25   Andi Kleen   perf evlist: Move...
438
  				counter = perf_evlist__reset_weak_group(evsel_list, counter);
5a5dfe4b8   Andi Kleen   perf tools: Suppo...
439
440
  				goto try_again;
  			}
979987a56   David Ahern   perf stat: handle...
441
442
443
444
  			/*
  			 * PPC returns ENXIO for HW counters until 2.6.37
  			 * (behavior changed with commit b0a873e).
  			 */
38f6ae1e1   Anton Blanchard   perf stat: Failur...
445
  			if (errno == EINVAL || errno == ENOSYS ||
979987a56   David Ahern   perf stat: handle...
446
447
  			    errno == ENOENT || errno == EOPNOTSUPP ||
  			    errno == ENXIO) {
bb963e165   Namhyung Kim   perf utils: Check...
448
  				if (verbose > 0)
c63ca0c01   David Ahern   perf stat: Tell u...
449
450
  					ui__warning("%s event is not supported by the kernel.
  ",
7289f83cc   Arnaldo Carvalho de Melo   perf tools: Move ...
451
  						    perf_evsel__name(counter));
2cee77c45   David Ahern   perf stat: clarif...
452
  				counter->supported = false;
cb5ef6006   Kan Liang   perf stat: Error ...
453
454
455
456
  
  				if ((counter->leader != counter) ||
  				    !(counter->leader->nr_members > 1))
  					continue;
42ef8a78c   Arnaldo Carvalho de Melo   perf stat: Fallba...
457
  			} else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
bb963e165   Namhyung Kim   perf utils: Check...
458
                                  if (verbose > 0)
42ef8a78c   Arnaldo Carvalho de Melo   perf stat: Fallba...
459
460
461
                                          ui__warning("%s
  ", msg);
                                  goto try_again;
ab6c79b81   Jin Yao   perf stat: Ignore...
462
463
464
465
466
467
468
469
470
471
472
473
474
  			} else if (target__has_per_thread(&target) &&
  				   evsel_list->threads &&
  				   evsel_list->threads->err_thread != -1) {
  				/*
  				 * For global --per-thread case, skip current
  				 * error thread.
  				 */
  				if (!thread_map__remove(evsel_list->threads,
  							evsel_list->threads->err_thread)) {
  					evsel_list->threads->err_thread = -1;
  					goto try_again;
  				}
  			}
ede702900   Ingo Molnar   perf stat: Fix co...
475

56e52e853   Arnaldo Carvalho de Melo   perf evsel: Intro...
476
477
478
479
  			perf_evsel__open_strerror(counter, &target,
  						  errno, msg, sizeof(msg));
  			ui__error("%s
  ", msg);
48290609c   Arnaldo Carvalho de Melo   perf evsel: Intro...
480
481
  			if (child_pid != -1)
  				kill(child_pid, SIGTERM);
fceda7feb   David Ahern   perf stat: Remove...
482

48290609c   Arnaldo Carvalho de Melo   perf evsel: Intro...
483
484
  			return -1;
  		}
2cee77c45   David Ahern   perf stat: clarif...
485
  		counter->supported = true;
410136f5d   Stephane Eranian   tools/perf/stat: ...
486
487
  
  		l = strlen(counter->unit);
df4f7b4d4   Jiri Olsa   perf stat: Move '...
488
489
  		if (l > stat_config.unit_width)
  			stat_config.unit_width = l;
2af4646d1   Jiri Olsa   perf stat record:...
490

82bf311e1   Jiri Olsa   perf stat: Use gr...
491
  		if (perf_evsel__should_store_id(counter) &&
650d62204   Jiri Olsa   perf evsel: Intro...
492
  		    perf_evsel__store_ids(counter, evsel_list))
2af4646d1   Jiri Olsa   perf stat record:...
493
  			return -1;
084ab9f86   Arnaldo Carvalho de Melo   perf stat: Better...
494
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
495

23d4aad48   Arnaldo Carvalho de Melo   perf evlist: Retu...
496
  	if (perf_evlist__apply_filters(evsel_list, &counter)) {
62d94b00f   Arnaldo Carvalho de Melo   perf tools: Repla...
497
498
  		pr_err("failed to set filter \"%s\" on event %s with %d (%s)
  ",
23d4aad48   Arnaldo Carvalho de Melo   perf evlist: Retu...
499
  			counter->filter, perf_evsel__name(counter), errno,
c8b5f2c96   Arnaldo Carvalho de Melo   tools: Introduce ...
500
  			str_error_r(errno, msg, sizeof(msg)));
cfd748ae0   Frederic Weisbecker   perf stat: Provid...
501
502
  		return -1;
  	}
4979d0c7d   Jiri Olsa   perf stat record:...
503
  	if (STAT_RECORD) {
8ceb41d7e   Jiri Olsa   perf tools: Renam...
504
  		int err, fd = perf_data__fd(&perf_stat.data);
4979d0c7d   Jiri Olsa   perf stat record:...
505

664c98d4e   Jiri Olsa   perf stat record:...
506
  		if (is_pipe) {
8ceb41d7e   Jiri Olsa   perf tools: Renam...
507
  			err = perf_header__write_pipe(perf_data__fd(&perf_stat.data));
664c98d4e   Jiri Olsa   perf stat record:...
508
509
510
511
  		} else {
  			err = perf_session__write_header(perf_stat.session, evsel_list,
  							 fd, false);
  		}
4979d0c7d   Jiri Olsa   perf stat record:...
512
513
  		if (err < 0)
  			return err;
8b99b1a4e   Jiri Olsa   perf stat record:...
514

1c21e9899   Jiri Olsa   perf stat: Add 's...
515
  		err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list,
c2c247f2d   Jiri Olsa   perf stat: Add 'p...
516
  						  process_synthesized_event, is_pipe);
8b99b1a4e   Jiri Olsa   perf stat record:...
517
518
  		if (err < 0)
  			return err;
4979d0c7d   Jiri Olsa   perf stat record:...
519
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
520
521
522
523
  	/*
  	 * Enable counters and exec the command:
  	 */
  	t0 = rdclock();
13370a9b5   Stephane Eranian   perf stat: Add in...
524
  	clock_gettime(CLOCK_MONOTONIC, &ref_time);
42202dd56   Ingo Molnar   perf stat: Add fe...
525

60666c630   Liming Wang   perf tools: Fix -...
526
  	if (forks) {
acf289227   Namhyung Kim   perf stat: Use pe...
527
  		perf_evlist__start_workload(evsel_list);
67ccdecd0   Jiri Olsa   perf stat: Create...
528
  		enable_counters();
acf289227   Namhyung Kim   perf stat: Use pe...
529

f1f8ad52f   yuzhoujian   perf stat: Add su...
530
  		if (interval || timeout) {
13370a9b5   Stephane Eranian   perf stat: Add in...
531
532
  			while (!waitpid(child_pid, &status, WNOHANG)) {
  				nanosleep(&ts, NULL);
f1f8ad52f   yuzhoujian   perf stat: Add su...
533
534
  				if (timeout)
  					break;
ba411a954   Jiri Olsa   perf stat: Rename...
535
  				process_interval();
db06a269e   yuzhoujian   perf stat: Add su...
536
537
  				if (interval_count && !(--times))
  					break;
13370a9b5   Stephane Eranian   perf stat: Add in...
538
539
  			}
  		}
8a99255a5   Jin Yao   perf stat: Fix en...
540
541
  		if (child_pid != -1)
  			wait4(child_pid, &status, 0, &stat_config.ru_data);
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
542

f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
543
  		if (workload_exec_errno) {
c8b5f2c96   Arnaldo Carvalho de Melo   tools: Introduce ...
544
  			const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
545
546
  			pr_err("Workload failed: %s
  ", emsg);
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
547
  			return -1;
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
548
  		}
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
549

33e49ea70   Andi Kleen   perf tools: Make ...
550
551
  		if (WIFSIGNALED(status))
  			psignal(WTERMSIG(status), argv[0]);
60666c630   Liming Wang   perf tools: Fix -...
552
  	} else {
67ccdecd0   Jiri Olsa   perf stat: Create...
553
  		enable_counters();
13370a9b5   Stephane Eranian   perf stat: Add in...
554
555
  		while (!done) {
  			nanosleep(&ts, NULL);
cbb5df7e9   Jiri Olsa   perf stat: Poll f...
556
557
  			if (!is_target_alive(&target, evsel_list->threads))
  				break;
f1f8ad52f   yuzhoujian   perf stat: Add su...
558
559
  			if (timeout)
  				break;
db06a269e   yuzhoujian   perf stat: Add su...
560
  			if (interval) {
ba411a954   Jiri Olsa   perf stat: Rename...
561
  				process_interval();
db06a269e   yuzhoujian   perf stat: Add su...
562
563
564
  				if (interval_count && !(--times))
  					break;
  			}
13370a9b5   Stephane Eranian   perf stat: Add in...
565
  		}
60666c630   Liming Wang   perf tools: Fix -...
566
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
567

3df33eff2   Mark Rutland   perf stat: Avoid ...
568
  	disable_counters();
42202dd56   Ingo Molnar   perf stat: Add fe...
569
  	t1 = rdclock();
54ac0b1bd   Jiri Olsa   perf stat: Move '...
570
571
  	if (stat_config.walltime_run_table)
  		stat_config.walltime_run[run_idx] = t1 - t0;
e55c14af4   Jiri Olsa   perf stat: Add --...
572

9e9772c45   Peter Zijlstra   perf stat: Remove...
573
  	update_stats(&walltime_nsecs_stats, t1 - t0);
42202dd56   Ingo Molnar   perf stat: Add fe...
574

3df33eff2   Mark Rutland   perf stat: Avoid ...
575
576
577
578
579
580
  	/*
  	 * Closing a group leader splits the group, and as we only disable
  	 * group leaders, results in remaining events becoming enabled. To
  	 * avoid arbitrary skew, we must read all counters before closing any
  	 * group leaders.
  	 */
f0fbb114e   Andi Kleen   perf stat: Implem...
581
  	read_counters(&(struct timespec) { .tv_nsec = t1-t0 });
3df33eff2   Mark Rutland   perf stat: Avoid ...
582
  	perf_evlist__close(evsel_list);
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
583

42202dd56   Ingo Molnar   perf stat: Add fe...
584
585
  	return WEXITSTATUS(status);
  }
e55c14af4   Jiri Olsa   perf stat: Add --...
586
  static int run_perf_stat(int argc, const char **argv, int run_idx)
1f16c5754   Peter Zijlstra   perf stat: Add --...
587
588
589
590
591
592
593
594
595
596
597
  {
  	int ret;
  
  	if (pre_cmd) {
  		ret = system(pre_cmd);
  		if (ret)
  			return ret;
  	}
  
  	if (sync_run)
  		sync();
e55c14af4   Jiri Olsa   perf stat: Add --...
598
  	ret = __run_perf_stat(argc, argv, run_idx);
1f16c5754   Peter Zijlstra   perf stat: Add --...
599
600
601
602
603
604
605
606
607
608
609
  	if (ret)
  		return ret;
  
  	if (post_cmd) {
  		ret = system(post_cmd);
  		if (ret)
  			return ret;
  	}
  
  	return ret;
  }
a5a9eac1a   Jiri Olsa   perf stat: Introd...
610
611
  static void print_counters(struct timespec *ts, int argc, const char **argv)
  {
0174820a8   Jiri Olsa   perf stat: Move S...
612
613
614
  	/* Do not print anything if we record to the pipe. */
  	if (STAT_RECORD && perf_stat.data.is_pipe)
  		return;
c512e0eae   Jiri Olsa   perf stat: Add 't...
615
  	perf_evlist__print_counters(evsel_list, &stat_config, &target,
b64df7f33   Jiri Olsa   perf stat: Add 's...
616
  				    ts, argc, argv);
a5a9eac1a   Jiri Olsa   perf stat: Introd...
617
  }
f7b7c26e0   Peter Zijlstra   perf_counter tool...
618
  static volatile int signr = -1;
5242519b0   Ingo Molnar   perf stat: Conver...
619
  static void skip_signal(int signo)
ddcacfa0f   Ingo Molnar   perf_counter tool...
620
  {
ec0d3d1fd   Jiri Olsa   perf stat: Move '...
621
  	if ((child_pid == -1) || stat_config.interval)
60666c630   Liming Wang   perf tools: Fix -...
622
  		done = 1;
f7b7c26e0   Peter Zijlstra   perf_counter tool...
623
  	signr = signo;
d07f0b120   Stephane Eranian   perf stat: Avoid ...
624
625
626
627
628
629
630
  	/*
  	 * render child_pid harmless
  	 * won't send SIGTERM to a random
  	 * process in case of race condition
  	 * and fast PID recycling
  	 */
  	child_pid = -1;
f7b7c26e0   Peter Zijlstra   perf_counter tool...
631
632
633
634
  }
  
  static void sig_atexit(void)
  {
d07f0b120   Stephane Eranian   perf stat: Avoid ...
635
636
637
638
639
640
641
642
643
644
645
  	sigset_t set, oset;
  
  	/*
  	 * avoid race condition with SIGCHLD handler
  	 * in skip_signal() which is modifying child_pid
  	 * goal is to avoid send SIGTERM to a random
  	 * process
  	 */
  	sigemptyset(&set);
  	sigaddset(&set, SIGCHLD);
  	sigprocmask(SIG_BLOCK, &set, &oset);
933da83aa   Chris Wilson   perf: Propagate t...
646
647
  	if (child_pid != -1)
  		kill(child_pid, SIGTERM);
d07f0b120   Stephane Eranian   perf stat: Avoid ...
648
  	sigprocmask(SIG_SETMASK, &oset, NULL);
f7b7c26e0   Peter Zijlstra   perf_counter tool...
649
650
651
652
653
  	if (signr == -1)
  		return;
  
  	signal(signr, SIG_DFL);
  	kill(getpid(), signr);
5242519b0   Ingo Molnar   perf stat: Conver...
654
  }
1d037ca16   Irina Tirdea   perf tools: Use _...
655
656
  static int stat__set_big_num(const struct option *opt __maybe_unused,
  			     const char *s __maybe_unused, int unset)
d7470b6af   Stephane Eranian   perf stat: Add cs...
657
658
659
660
  {
  	big_num_opt = unset ? 0 : 1;
  	return 0;
  }
44b1e60ab   Andi Kleen   perf stat: Basic ...
661
662
663
664
  static int enable_metric_only(const struct option *opt __maybe_unused,
  			      const char *s __maybe_unused, int unset)
  {
  	force_metric_only = true;
0ce5aa026   Jiri Olsa   perf stat: Move '...
665
  	stat_config.metric_only = !unset;
44b1e60ab   Andi Kleen   perf stat: Basic ...
666
667
  	return 0;
  }
b18f3e365   Andi Kleen   perf stat: Suppor...
668
669
670
671
  static int parse_metric_groups(const struct option *opt,
  			       const char *str,
  			       int unset __maybe_unused)
  {
d0192fdba   Jiri Olsa   perf stat: Move '...
672
  	return metricgroup__parse_groups(opt, str, &stat_config.metric_events);
b18f3e365   Andi Kleen   perf stat: Suppor...
673
  }
51433ead1   Michael Petlan   perf stat: Avoid ...
674
  static struct option stat_options[] = {
e05473111   Jiri Olsa   perf stat: Make s...
675
676
677
678
679
680
681
  	OPT_BOOLEAN('T', "transaction", &transaction_run,
  		    "hardware transaction statistics"),
  	OPT_CALLBACK('e', "event", &evsel_list, "event",
  		     "event selector. use 'perf list' to list available events",
  		     parse_events_option),
  	OPT_CALLBACK(0, "filter", &evsel_list, "filter",
  		     "event filter", parse_filter),
5698f26b4   Jiri Olsa   perf stat: Move '...
682
  	OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit,
e05473111   Jiri Olsa   perf stat: Make s...
683
684
685
686
687
688
689
690
691
  		    "child tasks do not inherit counters"),
  	OPT_STRING('p', "pid", &target.pid, "pid",
  		   "stat events on existing process id"),
  	OPT_STRING('t', "tid", &target.tid, "tid",
  		   "stat events on existing thread id"),
  	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
  		    "system-wide collection from all CPUs"),
  	OPT_BOOLEAN('g', "group", &group,
  		    "put the counters into a counter group"),
75998bb26   Andi Kleen   perf stat: Fix --...
692
693
  	OPT_BOOLEAN(0, "scale", &stat_config.scale,
  		    "Use --no-scale to disable counter scaling for multiplexing"),
e05473111   Jiri Olsa   perf stat: Make s...
694
695
  	OPT_INCR('v', "verbose", &verbose,
  		    "be more verbose (show counter open errors, etc)"),
d97ae04b3   Jiri Olsa   perf stat: Move '...
696
  	OPT_INTEGER('r', "repeat", &stat_config.run_count,
e05473111   Jiri Olsa   perf stat: Make s...
697
  		    "repeat command and print average + stddev (max: 100, forever: 0)"),
54ac0b1bd   Jiri Olsa   perf stat: Move '...
698
  	OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table,
e55c14af4   Jiri Olsa   perf stat: Add --...
699
  		    "display details about each run (only with -r option)"),
aea0dca16   Jiri Olsa   perf stat: Move '...
700
  	OPT_BOOLEAN('n', "null", &stat_config.null_run,
e05473111   Jiri Olsa   perf stat: Make s...
701
702
703
704
705
706
707
708
709
710
711
712
  		    "null run - dont start any counters"),
  	OPT_INCR('d', "detailed", &detailed_run,
  		    "detailed run - start a lot of events"),
  	OPT_BOOLEAN('S', "sync", &sync_run,
  		    "call sync() before starting a run"),
  	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
  			   "print large numbers with thousands\' separators",
  			   stat__set_big_num),
  	OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
  		    "list of cpus to monitor in system-wide"),
  	OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
  		    "disable CPU count aggregation", AGGR_NONE),
fdee335b0   Jiri Olsa   perf stat: Move '...
713
  	OPT_BOOLEAN(0, "no-merge", &stat_config.no_merge, "Do not merge identical named events"),
fa7070a38   Jiri Olsa   perf stat: Move c...
714
  	OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator",
e05473111   Jiri Olsa   perf stat: Make s...
715
716
717
718
719
720
721
722
723
724
725
726
  		   "print counts with custom separator"),
  	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
  		     "monitor event in cgroup name only", parse_cgroups),
  	OPT_STRING('o', "output", &output_name, "file", "output file name"),
  	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
  	OPT_INTEGER(0, "log-fd", &output_fd,
  		    "log output to fd, instead of stderr"),
  	OPT_STRING(0, "pre", &pre_cmd, "command",
  			"command to run prior to the measured command"),
  	OPT_STRING(0, "post", &post_cmd, "command",
  			"command to run after to the measured command"),
  	OPT_UINTEGER('I', "interval-print", &stat_config.interval,
9dc9a95f0   Alexey Budankov   perf stat: Enable...
727
728
  		    "print counts at regular interval in ms "
  		    "(overhead is possible for values <= 100ms)"),
db06a269e   yuzhoujian   perf stat: Add su...
729
730
  	OPT_INTEGER(0, "interval-count", &stat_config.times,
  		    "print counts for fixed number of times"),
132c6ba3c   Jiri Olsa   perf stat: Move '...
731
  	OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear,
9660e08ee   Jiri Olsa   perf stat: Add --...
732
  		    "clear screen in between new interval"),
f1f8ad52f   yuzhoujian   perf stat: Add su...
733
734
  	OPT_UINTEGER(0, "timeout", &stat_config.timeout,
  		    "stop workload and print counts after a timeout period in ms (>= 10ms)"),
e05473111   Jiri Olsa   perf stat: Make s...
735
736
737
738
739
740
  	OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
  		     "aggregate counts per processor socket", AGGR_SOCKET),
  	OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
  		     "aggregate counts per physical processor core", AGGR_CORE),
  	OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
  		     "aggregate counts per thread", AGGR_THREAD),
728c0ee0a   Jiri Olsa   perf stat: Move '...
741
  	OPT_UINTEGER('D', "delay", &stat_config.initial_delay,
e05473111   Jiri Olsa   perf stat: Make s...
742
  		     "ms to wait before starting measurement after program start"),
0ce5aa026   Jiri Olsa   perf stat: Move '...
743
  	OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
44b1e60ab   Andi Kleen   perf stat: Basic ...
744
745
746
  			"Only print computed metrics. No raw values", enable_metric_only),
  	OPT_BOOLEAN(0, "topdown", &topdown_run,
  			"measure topdown level 1 statistics"),
daefd0bc0   Kan Liang   perf stat: Add su...
747
748
  	OPT_BOOLEAN(0, "smi-cost", &smi_cost,
  			"measure SMI cost"),
b18f3e365   Andi Kleen   perf stat: Suppor...
749
750
751
  	OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list",
  		     "monitor specified metrics or metric groups (separated by ,)",
  		     parse_metric_groups),
e05473111   Jiri Olsa   perf stat: Make s...
752
753
  	OPT_END()
  };
6f6b6594b   Jiri Olsa   perf stat: Move *...
754
755
  static int perf_stat__get_socket(struct perf_stat_config *config __maybe_unused,
  				 struct cpu_map *map, int cpu)
1fe7a3002   Jiri Olsa   perf cpu_map: Add...
756
757
758
  {
  	return cpu_map__get_socket(map, cpu, NULL);
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
759
760
  static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
  			       struct cpu_map *map, int cpu)
1fe7a3002   Jiri Olsa   perf cpu_map: Add...
761
762
763
  {
  	return cpu_map__get_core(map, cpu, NULL);
  }
1e5a29318   Jiri Olsa   perf stat: Cache ...
764
765
766
767
768
769
770
771
772
773
774
  static int cpu_map__get_max(struct cpu_map *map)
  {
  	int i, max = -1;
  
  	for (i = 0; i < map->nr; i++) {
  		if (map->map[i] > max)
  			max = map->map[i];
  	}
  
  	return max;
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
775
776
  static int perf_stat__get_aggr(struct perf_stat_config *config,
  			       aggr_get_id_t get_id, struct cpu_map *map, int idx)
1e5a29318   Jiri Olsa   perf stat: Cache ...
777
778
779
780
781
782
783
  {
  	int cpu;
  
  	if (idx >= map->nr)
  		return -1;
  
  	cpu = map->map[idx];
6f6b6594b   Jiri Olsa   perf stat: Move *...
784
785
  	if (config->cpus_aggr_map->map[cpu] == -1)
  		config->cpus_aggr_map->map[cpu] = get_id(config, map, idx);
1e5a29318   Jiri Olsa   perf stat: Cache ...
786

6f6b6594b   Jiri Olsa   perf stat: Move *...
787
  	return config->cpus_aggr_map->map[cpu];
1e5a29318   Jiri Olsa   perf stat: Cache ...
788
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
789
790
  static int perf_stat__get_socket_cached(struct perf_stat_config *config,
  					struct cpu_map *map, int idx)
1e5a29318   Jiri Olsa   perf stat: Cache ...
791
  {
6f6b6594b   Jiri Olsa   perf stat: Move *...
792
  	return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx);
1e5a29318   Jiri Olsa   perf stat: Cache ...
793
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
794
795
  static int perf_stat__get_core_cached(struct perf_stat_config *config,
  				      struct cpu_map *map, int idx)
1e5a29318   Jiri Olsa   perf stat: Cache ...
796
  {
6f6b6594b   Jiri Olsa   perf stat: Move *...
797
  	return perf_stat__get_aggr(config, perf_stat__get_core, map, idx);
1e5a29318   Jiri Olsa   perf stat: Cache ...
798
  }
4fc4d8dfa   Jin Yao   perf stat: Suppor...
799
800
801
802
803
804
805
806
807
808
809
  static bool term_percore_set(void)
  {
  	struct perf_evsel *counter;
  
  	evlist__for_each_entry(evsel_list, counter) {
  		if (counter->percore)
  			return true;
  	}
  
  	return false;
  }
86ee6e18f   Stephane Eranian   perf stat: Refact...
810
811
  static int perf_stat_init_aggr_mode(void)
  {
1e5a29318   Jiri Olsa   perf stat: Cache ...
812
  	int nr;
421a50f3f   Jiri Olsa   perf stat: Introd...
813
  	switch (stat_config.aggr_mode) {
86ee6e18f   Stephane Eranian   perf stat: Refact...
814
  	case AGGR_SOCKET:
6f6b6594b   Jiri Olsa   perf stat: Move *...
815
  		if (cpu_map__build_socket_map(evsel_list->cpus, &stat_config.aggr_map)) {
86ee6e18f   Stephane Eranian   perf stat: Refact...
816
817
818
  			perror("cannot build socket map");
  			return -1;
  		}
6f6b6594b   Jiri Olsa   perf stat: Move *...
819
  		stat_config.aggr_get_id = perf_stat__get_socket_cached;
86ee6e18f   Stephane Eranian   perf stat: Refact...
820
  		break;
12c08a9f5   Stephane Eranian   perf stat: Add pe...
821
  	case AGGR_CORE:
6f6b6594b   Jiri Olsa   perf stat: Move *...
822
  		if (cpu_map__build_core_map(evsel_list->cpus, &stat_config.aggr_map)) {
12c08a9f5   Stephane Eranian   perf stat: Add pe...
823
824
825
  			perror("cannot build core map");
  			return -1;
  		}
6f6b6594b   Jiri Olsa   perf stat: Move *...
826
  		stat_config.aggr_get_id = perf_stat__get_core_cached;
12c08a9f5   Stephane Eranian   perf stat: Add pe...
827
  		break;
86ee6e18f   Stephane Eranian   perf stat: Refact...
828
  	case AGGR_NONE:
4fc4d8dfa   Jin Yao   perf stat: Suppor...
829
830
831
832
833
834
835
836
837
  		if (term_percore_set()) {
  			if (cpu_map__build_core_map(evsel_list->cpus,
  						    &stat_config.aggr_map)) {
  				perror("cannot build core map");
  				return -1;
  			}
  			stat_config.aggr_get_id = perf_stat__get_core_cached;
  		}
  		break;
86ee6e18f   Stephane Eranian   perf stat: Refact...
838
  	case AGGR_GLOBAL:
32b8af82e   Jiri Olsa   perf stat: Introd...
839
  	case AGGR_THREAD:
208df99ed   Jiri Olsa   perf stat: Add AG...
840
  	case AGGR_UNSET:
86ee6e18f   Stephane Eranian   perf stat: Refact...
841
842
843
  	default:
  		break;
  	}
1e5a29318   Jiri Olsa   perf stat: Cache ...
844
845
846
847
848
849
850
  
  	/*
  	 * The evsel_list->cpus is the base we operate on,
  	 * taking the highest cpu number to be the size of
  	 * the aggregation translate cpumap.
  	 */
  	nr = cpu_map__get_max(evsel_list->cpus);
6f6b6594b   Jiri Olsa   perf stat: Move *...
851
852
  	stat_config.cpus_aggr_map = cpu_map__empty_new(nr + 1);
  	return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
86ee6e18f   Stephane Eranian   perf stat: Refact...
853
  }
544c2ae7b   Masami Hiramatsu   perf stat: Fix cm...
854
855
  static void perf_stat__exit_aggr_mode(void)
  {
6f6b6594b   Jiri Olsa   perf stat: Move *...
856
857
858
859
  	cpu_map__put(stat_config.aggr_map);
  	cpu_map__put(stat_config.cpus_aggr_map);
  	stat_config.aggr_map = NULL;
  	stat_config.cpus_aggr_map = NULL;
544c2ae7b   Masami Hiramatsu   perf stat: Fix cm...
860
  }
68d702f7a   Jiri Olsa   perf stat report:...
861
862
863
864
865
866
867
868
  static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, int idx)
  {
  	int cpu;
  
  	if (idx > map->nr)
  		return -1;
  
  	cpu = map->map[idx];
da8a58b56   Jan Stancek   perf tools: Repla...
869
  	if (cpu >= env->nr_cpus_avail)
68d702f7a   Jiri Olsa   perf stat report:...
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
  		return -1;
  
  	return cpu;
  }
  
  static int perf_env__get_socket(struct cpu_map *map, int idx, void *data)
  {
  	struct perf_env *env = data;
  	int cpu = perf_env__get_cpu(env, map, idx);
  
  	return cpu == -1 ? -1 : env->cpu[cpu].socket_id;
  }
  
  static int perf_env__get_core(struct cpu_map *map, int idx, void *data)
  {
  	struct perf_env *env = data;
  	int core = -1, cpu = perf_env__get_cpu(env, map, idx);
  
  	if (cpu != -1) {
  		int socket_id = env->cpu[cpu].socket_id;
  
  		/*
  		 * Encode socket in upper 16 bits
  		 * core_id is relative to socket, and
  		 * we need a global id. So we combine
  		 * socket + core id.
  		 */
  		core = (socket_id << 16) | (env->cpu[cpu].core_id & 0xffff);
  	}
  
  	return core;
  }
  
  static int perf_env__build_socket_map(struct perf_env *env, struct cpu_map *cpus,
  				      struct cpu_map **sockp)
  {
  	return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
  }
  
  static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus,
  				    struct cpu_map **corep)
  {
  	return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
914
915
  static int perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
  				      struct cpu_map *map, int idx)
68d702f7a   Jiri Olsa   perf stat report:...
916
917
918
  {
  	return perf_env__get_socket(map, idx, &perf_stat.session->header.env);
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
919
920
  static int perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused,
  				    struct cpu_map *map, int idx)
68d702f7a   Jiri Olsa   perf stat report:...
921
922
923
924
925
926
927
928
929
930
  {
  	return perf_env__get_core(map, idx, &perf_stat.session->header.env);
  }
  
  static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
  {
  	struct perf_env *env = &st->session->header.env;
  
  	switch (stat_config.aggr_mode) {
  	case AGGR_SOCKET:
6f6b6594b   Jiri Olsa   perf stat: Move *...
931
  		if (perf_env__build_socket_map(env, evsel_list->cpus, &stat_config.aggr_map)) {
68d702f7a   Jiri Olsa   perf stat report:...
932
933
934
  			perror("cannot build socket map");
  			return -1;
  		}
6f6b6594b   Jiri Olsa   perf stat: Move *...
935
  		stat_config.aggr_get_id = perf_stat__get_socket_file;
68d702f7a   Jiri Olsa   perf stat report:...
936
937
  		break;
  	case AGGR_CORE:
6f6b6594b   Jiri Olsa   perf stat: Move *...
938
  		if (perf_env__build_core_map(env, evsel_list->cpus, &stat_config.aggr_map)) {
68d702f7a   Jiri Olsa   perf stat report:...
939
940
941
  			perror("cannot build core map");
  			return -1;
  		}
6f6b6594b   Jiri Olsa   perf stat: Move *...
942
  		stat_config.aggr_get_id = perf_stat__get_core_file;
68d702f7a   Jiri Olsa   perf stat report:...
943
944
945
946
947
948
949
950
951
952
953
  		break;
  	case AGGR_NONE:
  	case AGGR_GLOBAL:
  	case AGGR_THREAD:
  	case AGGR_UNSET:
  	default:
  		break;
  	}
  
  	return 0;
  }
44b1e60ab   Andi Kleen   perf stat: Basic ...
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
  static int topdown_filter_events(const char **attr, char **str, bool use_group)
  {
  	int off = 0;
  	int i;
  	int len = 0;
  	char *s;
  
  	for (i = 0; attr[i]; i++) {
  		if (pmu_have_event("cpu", attr[i])) {
  			len += strlen(attr[i]) + 1;
  			attr[i - off] = attr[i];
  		} else
  			off++;
  	}
  	attr[i - off] = NULL;
  
  	*str = malloc(len + 1 + 2);
  	if (!*str)
  		return -1;
  	s = *str;
  	if (i - off == 0) {
  		*s = 0;
  		return 0;
  	}
  	if (use_group)
  		*s++ = '{';
  	for (i = 0; attr[i]; i++) {
  		strcpy(s, attr[i]);
  		s += strlen(s);
  		*s++ = ',';
  	}
  	if (use_group) {
  		s[-1] = '}';
  		*s = 0;
  	} else
  		s[-1] = 0;
  	return 0;
  }
  
  __weak bool arch_topdown_check_group(bool *warn)
  {
  	*warn = false;
  	return false;
  }
  
  __weak void arch_topdown_group_warn(void)
  {
  }
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1002
1003
1004
1005
1006
1007
  /*
   * 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)
  {
44b1e60ab   Andi Kleen   perf stat: Basic ...
1008
  	int err;
9dec4473a   Andi Kleen   perf stat: Check ...
1009
  	struct perf_event_attr default_attrs0[] = {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1010
1011
1012
1013
1014
1015
1016
  
    { .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		},
  
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
9dec4473a   Andi Kleen   perf stat: Check ...
1017
1018
  };
  	struct perf_event_attr frontend_attrs[] = {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1019
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
9dec4473a   Andi Kleen   perf stat: Check ...
1020
1021
  };
  	struct perf_event_attr backend_attrs[] = {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1022
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
9dec4473a   Andi Kleen   perf stat: Check ...
1023
1024
  };
  	struct perf_event_attr default_attrs1[] = {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
  
  };
  
  /*
   * Detailed stats (-d), covering the L1 and last level data caches:
   */
  	struct perf_event_attr detailed_attrs[] = {
  
    { .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)				},
  };
  
  /*
   * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
   */
  	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:
   */
  	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)				},
  };
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1121
  	struct parse_events_error errinfo;
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1122

2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1123
  	/* Set attrs if no event is selected and !null_run: */
aea0dca16   Jiri Olsa   perf stat: Move '...
1124
  	if (stat_config.null_run)
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1125
  		return 0;
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1126
  	if (transaction_run) {
742d92ff2   Thomas Richter   perf stat: Add tr...
1127
1128
1129
1130
1131
1132
1133
1134
1135
  		/* Handle -T as -M transaction. Once platform specific metrics
  		 * support has been added to the json files, all archictures
  		 * will use this approach. To determine transaction support
  		 * on an architecture test for such a metric name.
  		 */
  		if (metricgroup__has_metric("transaction")) {
  			struct option opt = { .value = &evsel_list };
  
  			return metricgroup__parse_groups(&opt, "transaction",
d0192fdba   Jiri Olsa   perf stat: Move '...
1136
  							 &stat_config.metric_events);
742d92ff2   Thomas Richter   perf stat: Add tr...
1137
  		}
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1138
1139
  		if (pmu_have_event("cpu", "cycles-ct") &&
  		    pmu_have_event("cpu", "el-start"))
fca32340a   Thomas Richter   perf stat: Fix co...
1140
1141
  			err = parse_events(evsel_list, transaction_attrs,
  					   &errinfo);
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1142
  		else
fca32340a   Thomas Richter   perf stat: Fix co...
1143
1144
1145
  			err = parse_events(evsel_list,
  					   transaction_limited_attrs,
  					   &errinfo);
a454742c1   Jiri Olsa   perf stat: Remove...
1146
  		if (err) {
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1147
1148
  			fprintf(stderr, "Cannot set up transaction events
  ");
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1149
  			parse_events_print_error(&errinfo, transaction_attrs);
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1150
1151
1152
1153
  			return -1;
  		}
  		return 0;
  	}
daefd0bc0   Kan Liang   perf stat: Add su...
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
  	if (smi_cost) {
  		int smi;
  
  		if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) {
  			fprintf(stderr, "freeze_on_smi is not supported.
  ");
  			return -1;
  		}
  
  		if (!smi) {
  			if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) {
  				fprintf(stderr, "Failed to set freeze_on_smi.
  ");
  				return -1;
  			}
  			smi_reset = true;
  		}
  
  		if (pmu_have_event("msr", "aperf") &&
  		    pmu_have_event("msr", "smi")) {
  			if (!force_metric_only)
0ce5aa026   Jiri Olsa   perf stat: Move '...
1175
  				stat_config.metric_only = true;
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1176
  			err = parse_events(evsel_list, smi_cost_attrs, &errinfo);
daefd0bc0   Kan Liang   perf stat: Add su...
1177
1178
1179
1180
  		} else {
  			fprintf(stderr, "To measure SMI cost, it needs "
  				"msr/aperf/, msr/smi/ and cpu/cycles/ support
  ");
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1181
  			parse_events_print_error(&errinfo, smi_cost_attrs);
daefd0bc0   Kan Liang   perf stat: Add su...
1182
1183
1184
1185
1186
1187
1188
1189
1190
  			return -1;
  		}
  		if (err) {
  			fprintf(stderr, "Cannot set up SMI cost events
  ");
  			return -1;
  		}
  		return 0;
  	}
44b1e60ab   Andi Kleen   perf stat: Basic ...
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
  	if (topdown_run) {
  		char *str = NULL;
  		bool warn = false;
  
  		if (stat_config.aggr_mode != AGGR_GLOBAL &&
  		    stat_config.aggr_mode != AGGR_CORE) {
  			pr_err("top down event configuration requires --per-core mode
  ");
  			return -1;
  		}
  		stat_config.aggr_mode = AGGR_CORE;
  		if (nr_cgroups || !target__has_cpu(&target)) {
  			pr_err("top down event configuration requires system-wide mode (-a)
  ");
  			return -1;
  		}
  
  		if (!force_metric_only)
0ce5aa026   Jiri Olsa   perf stat: Move '...
1209
  			stat_config.metric_only = true;
44b1e60ab   Andi Kleen   perf stat: Basic ...
1210
1211
1212
1213
1214
1215
1216
1217
1218
  		if (topdown_filter_events(topdown_attrs, &str,
  				arch_topdown_check_group(&warn)) < 0) {
  			pr_err("Out of memory
  ");
  			return -1;
  		}
  		if (topdown_attrs[0] && str) {
  			if (warn)
  				arch_topdown_group_warn();
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1219
  			err = parse_events(evsel_list, str, &errinfo);
44b1e60ab   Andi Kleen   perf stat: Basic ...
1220
1221
1222
1223
1224
1225
  			if (err) {
  				fprintf(stderr,
  					"Cannot set up top down events %s: %d
  ",
  					str, err);
  				free(str);
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1226
  				parse_events_print_error(&errinfo, str);
44b1e60ab   Andi Kleen   perf stat: Basic ...
1227
1228
1229
1230
1231
1232
1233
1234
1235
  				return -1;
  			}
  		} else {
  			fprintf(stderr, "System does not support topdown
  ");
  			return -1;
  		}
  		free(str);
  	}
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1236
  	if (!evsel_list->nr_entries) {
a1f3d5676   Namhyung Kim   perf stat: Use cp...
1237
1238
  		if (target__has_cpu(&target))
  			default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
9dec4473a   Andi Kleen   perf stat: Check ...
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
  		if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
  			return -1;
  		if (pmu_have_event("cpu", "stalled-cycles-frontend")) {
  			if (perf_evlist__add_default_attrs(evsel_list,
  						frontend_attrs) < 0)
  				return -1;
  		}
  		if (pmu_have_event("cpu", "stalled-cycles-backend")) {
  			if (perf_evlist__add_default_attrs(evsel_list,
  						backend_attrs) < 0)
  				return -1;
  		}
  		if (perf_evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1252
  			return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1253
1254
1255
1256
1257
1258
1259
1260
  	}
  
  	/* Detailed events get appended to the event list: */
  
  	if (detailed_run <  1)
  		return 0;
  
  	/* Append detailed run extra attributes: */
79695e1bb   Arnaldo Carvalho de Melo   perf stat: Initia...
1261
  	if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1262
  		return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1263
1264
1265
1266
1267
  
  	if (detailed_run < 2)
  		return 0;
  
  	/* Append very detailed run extra attributes: */
79695e1bb   Arnaldo Carvalho de Melo   perf stat: Initia...
1268
  	if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1269
  		return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1270
1271
1272
1273
1274
  
  	if (detailed_run < 3)
  		return 0;
  
  	/* Append very, very detailed run extra attributes: */
79695e1bb   Arnaldo Carvalho de Melo   perf stat: Initia...
1275
  	return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1276
  }
8a59f3ccb   Jiri Olsa   perf stat: Fix re...
1277
  static const char * const stat_record_usage[] = {
4979d0c7d   Jiri Olsa   perf stat record:...
1278
1279
1280
  	"perf stat record [<options>]",
  	NULL,
  };
3ba78bd00   Jiri Olsa   perf stat record:...
1281
1282
1283
1284
1285
1286
  static void init_features(struct perf_session *session)
  {
  	int feat;
  
  	for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
  		perf_header__set_feat(&session->header, feat);
8002a63f9   Jiri Olsa   perf stat: Disabl...
1287
  	perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
3ba78bd00   Jiri Olsa   perf stat record:...
1288
1289
1290
1291
1292
  	perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
  	perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
  	perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
  	perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
  }
4979d0c7d   Jiri Olsa   perf stat record:...
1293
1294
1295
  static int __cmd_record(int argc, const char **argv)
  {
  	struct perf_session *session;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
1296
  	struct perf_data *data = &perf_stat.data;
4979d0c7d   Jiri Olsa   perf stat record:...
1297

8a59f3ccb   Jiri Olsa   perf stat: Fix re...
1298
  	argc = parse_options(argc, argv, stat_options, stat_record_usage,
4979d0c7d   Jiri Olsa   perf stat record:...
1299
1300
1301
  			     PARSE_OPT_STOP_AT_NON_OPTION);
  
  	if (output_name)
2d4f27999   Jiri Olsa   perf data: Add gl...
1302
  		data->path = output_name;
4979d0c7d   Jiri Olsa   perf stat record:...
1303

d97ae04b3   Jiri Olsa   perf stat: Move '...
1304
  	if (stat_config.run_count != 1 || forever) {
e9d6db8e8   Jiri Olsa   perf stat record:...
1305
1306
1307
1308
  		pr_err("Cannot use -r option with perf stat record.
  ");
  		return -1;
  	}
8ceb41d7e   Jiri Olsa   perf tools: Renam...
1309
  	session = perf_session__new(data, false, NULL);
4979d0c7d   Jiri Olsa   perf stat record:...
1310
1311
1312
1313
1314
  	if (session == NULL) {
  		pr_err("Perf session creation failed.
  ");
  		return -1;
  	}
3ba78bd00   Jiri Olsa   perf stat record:...
1315
  	init_features(session);
4979d0c7d   Jiri Olsa   perf stat record:...
1316
1317
1318
1319
1320
  	session->evlist   = evsel_list;
  	perf_stat.session = session;
  	perf_stat.record  = true;
  	return argc;
  }
89f1688a5   Jiri Olsa   perf tools: Remov...
1321
1322
  static int process_stat_round_event(struct perf_session *session,
  				    union perf_event *event)
a56f9390a   Jiri Olsa   perf stat report:...
1323
  {
e3b03b6c1   Andi Kleen   perf stat: Avoid ...
1324
  	struct stat_round_event *stat_round = &event->stat_round;
a56f9390a   Jiri Olsa   perf stat report:...
1325
1326
1327
1328
  	struct perf_evsel *counter;
  	struct timespec tsh, *ts = NULL;
  	const char **argv = session->header.env.cmdline_argv;
  	int argc = session->header.env.nr_cmdline;
e5cadb93d   Arnaldo Carvalho de Melo   perf evlist: Rena...
1329
  	evlist__for_each_entry(evsel_list, counter)
a56f9390a   Jiri Olsa   perf stat report:...
1330
  		perf_stat_process_counter(&stat_config, counter);
e3b03b6c1   Andi Kleen   perf stat: Avoid ...
1331
1332
  	if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
  		update_stats(&walltime_nsecs_stats, stat_round->time);
a56f9390a   Jiri Olsa   perf stat report:...
1333

e3b03b6c1   Andi Kleen   perf stat: Avoid ...
1334
  	if (stat_config.interval && stat_round->time) {
bd48c63eb   Arnaldo Carvalho de Melo   tools: Introduce ...
1335
1336
  		tsh.tv_sec  = stat_round->time / NSEC_PER_SEC;
  		tsh.tv_nsec = stat_round->time % NSEC_PER_SEC;
a56f9390a   Jiri Olsa   perf stat report:...
1337
1338
1339
1340
1341
1342
  		ts = &tsh;
  	}
  
  	print_counters(ts, argc, argv);
  	return 0;
  }
62ba18ba9   Jiri Olsa   perf stat report:...
1343
  static
89f1688a5   Jiri Olsa   perf tools: Remov...
1344
1345
  int process_stat_config_event(struct perf_session *session,
  			      union perf_event *event)
62ba18ba9   Jiri Olsa   perf stat report:...
1346
  {
89f1688a5   Jiri Olsa   perf tools: Remov...
1347
  	struct perf_tool *tool = session->tool;
68d702f7a   Jiri Olsa   perf stat report:...
1348
  	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
62ba18ba9   Jiri Olsa   perf stat report:...
1349
  	perf_event__read_stat_config(&stat_config, &event->stat_config);
68d702f7a   Jiri Olsa   perf stat report:...
1350

89af4e05c   Jiri Olsa   perf stat report:...
1351
1352
1353
1354
1355
1356
1357
1358
1359
  	if (cpu_map__empty(st->cpus)) {
  		if (st->aggr_mode != AGGR_UNSET)
  			pr_warning("warning: processing task data, aggregation mode not set
  ");
  		return 0;
  	}
  
  	if (st->aggr_mode != AGGR_UNSET)
  		stat_config.aggr_mode = st->aggr_mode;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
1360
  	if (perf_stat.data.is_pipe)
68d702f7a   Jiri Olsa   perf stat report:...
1361
1362
1363
  		perf_stat_init_aggr_mode();
  	else
  		perf_stat_init_aggr_mode_file(st);
62ba18ba9   Jiri Olsa   perf stat report:...
1364
1365
  	return 0;
  }
1975d36e1   Jiri Olsa   perf stat report:...
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
  static int set_maps(struct perf_stat *st)
  {
  	if (!st->cpus || !st->threads)
  		return 0;
  
  	if (WARN_ONCE(st->maps_allocated, "stats double allocation
  "))
  		return -EINVAL;
  
  	perf_evlist__set_maps(evsel_list, st->cpus, st->threads);
  
  	if (perf_evlist__alloc_stats(evsel_list, true))
  		return -ENOMEM;
  
  	st->maps_allocated = true;
  	return 0;
  }
  
  static
89f1688a5   Jiri Olsa   perf tools: Remov...
1385
1386
  int process_thread_map_event(struct perf_session *session,
  			     union perf_event *event)
1975d36e1   Jiri Olsa   perf stat report:...
1387
  {
89f1688a5   Jiri Olsa   perf tools: Remov...
1388
  	struct perf_tool *tool = session->tool;
1975d36e1   Jiri Olsa   perf stat report:...
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
  	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
  
  	if (st->threads) {
  		pr_warning("Extra thread map event, ignoring.
  ");
  		return 0;
  	}
  
  	st->threads = thread_map__new_event(&event->thread_map);
  	if (!st->threads)
  		return -ENOMEM;
  
  	return set_maps(st);
  }
  
  static
89f1688a5   Jiri Olsa   perf tools: Remov...
1405
1406
  int process_cpu_map_event(struct perf_session *session,
  			  union perf_event *event)
1975d36e1   Jiri Olsa   perf stat report:...
1407
  {
89f1688a5   Jiri Olsa   perf tools: Remov...
1408
  	struct perf_tool *tool = session->tool;
1975d36e1   Jiri Olsa   perf stat report:...
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
  	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
  	struct cpu_map *cpus;
  
  	if (st->cpus) {
  		pr_warning("Extra cpu map event, ignoring.
  ");
  		return 0;
  	}
  
  	cpus = cpu_map__new_data(&event->cpu_map.data);
  	if (!cpus)
  		return -ENOMEM;
  
  	st->cpus = cpus;
  	return set_maps(st);
  }
56739444d   Jin Yao   perf stat: Alloca...
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
  static int runtime_stat_new(struct perf_stat_config *config, int nthreads)
  {
  	int i;
  
  	config->stats = calloc(nthreads, sizeof(struct runtime_stat));
  	if (!config->stats)
  		return -1;
  
  	config->stats_num = nthreads;
  
  	for (i = 0; i < nthreads; i++)
  		runtime_stat__init(&config->stats[i]);
  
  	return 0;
  }
  
  static void runtime_stat_delete(struct perf_stat_config *config)
  {
  	int i;
  
  	if (!config->stats)
  		return;
  
  	for (i = 0; i < config->stats_num; i++)
  		runtime_stat__exit(&config->stats[i]);
  
  	free(config->stats);
  }
8a59f3ccb   Jiri Olsa   perf stat: Fix re...
1453
  static const char * const stat_report_usage[] = {
ba6039b6c   Jiri Olsa   perf stat report:...
1454
1455
1456
1457
1458
1459
1460
  	"perf stat report [<options>]",
  	NULL,
  };
  
  static struct perf_stat perf_stat = {
  	.tool = {
  		.attr		= perf_event__process_attr,
fa6ea7817   Jiri Olsa   perf stat report:...
1461
  		.event_update	= perf_event__process_event_update,
1975d36e1   Jiri Olsa   perf stat report:...
1462
1463
  		.thread_map	= process_thread_map_event,
  		.cpu_map	= process_cpu_map_event,
62ba18ba9   Jiri Olsa   perf stat report:...
1464
  		.stat_config	= process_stat_config_event,
a56f9390a   Jiri Olsa   perf stat report:...
1465
1466
  		.stat		= perf_event__process_stat_event,
  		.stat_round	= process_stat_round_event,
ba6039b6c   Jiri Olsa   perf stat report:...
1467
  	},
89af4e05c   Jiri Olsa   perf stat report:...
1468
  	.aggr_mode = AGGR_UNSET,
ba6039b6c   Jiri Olsa   perf stat report:...
1469
1470
1471
1472
1473
1474
1475
  };
  
  static int __cmd_report(int argc, const char **argv)
  {
  	struct perf_session *session;
  	const struct option options[] = {
  	OPT_STRING('i', "input", &input_name, "file", "input file name"),
89af4e05c   Jiri Olsa   perf stat report:...
1476
1477
1478
1479
1480
1481
  	OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode,
  		     "aggregate counts per processor socket", AGGR_SOCKET),
  	OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode,
  		     "aggregate counts per physical processor core", AGGR_CORE),
  	OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode,
  		     "disable CPU count aggregation", AGGR_NONE),
ba6039b6c   Jiri Olsa   perf stat report:...
1482
1483
1484
1485
  	OPT_END()
  	};
  	struct stat st;
  	int ret;
8a59f3ccb   Jiri Olsa   perf stat: Fix re...
1486
  	argc = parse_options(argc, argv, options, stat_report_usage, 0);
ba6039b6c   Jiri Olsa   perf stat report:...
1487
1488
1489
1490
1491
1492
1493
  
  	if (!input_name || !strlen(input_name)) {
  		if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
  			input_name = "-";
  		else
  			input_name = "perf.data";
  	}
2d4f27999   Jiri Olsa   perf data: Add gl...
1494
1495
  	perf_stat.data.path = input_name;
  	perf_stat.data.mode = PERF_DATA_MODE_READ;
ba6039b6c   Jiri Olsa   perf stat report:...
1496

8ceb41d7e   Jiri Olsa   perf tools: Renam...
1497
  	session = perf_session__new(&perf_stat.data, false, &perf_stat.tool);
ba6039b6c   Jiri Olsa   perf stat report:...
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
  	if (session == NULL)
  		return -1;
  
  	perf_stat.session  = session;
  	stat_config.output = stderr;
  	evsel_list         = session->evlist;
  
  	ret = perf_session__process_events(session);
  	if (ret)
  		return ret;
  
  	perf_session__delete(session);
  	return 0;
  }
e3ba76dee   Jiri Olsa   perf tools: Force...
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
  static void setup_system_wide(int forks)
  {
  	/*
  	 * Make system wide (-a) the default target if
  	 * no target was specified and one of following
  	 * conditions is met:
  	 *
  	 *   - there's no workload specified
  	 *   - there is workload specified but all requested
  	 *     events are system wide events
  	 */
  	if (!target__none(&target))
  		return;
  
  	if (!forks)
  		target.system_wide = true;
  	else {
  		struct perf_evsel *counter;
  
  		evlist__for_each_entry(evsel_list, counter) {
  			if (!counter->system_wide)
  				return;
  		}
  
  		if (evsel_list->nr_entries)
  			target.system_wide = true;
  	}
  }
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
1540
  int cmd_stat(int argc, const char **argv)
5242519b0   Ingo Molnar   perf stat: Conver...
1541
  {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1542
1543
1544
1545
  	const char * const stat_usage[] = {
  		"perf stat [<options>] [<command>]",
  		NULL
  	};
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1546
  	int status = -EINVAL, run_idx;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1547
  	const char *mode;
5821522e9   Jiri Olsa   perf stat: Move '...
1548
  	FILE *output = stderr;
f1f8ad52f   yuzhoujian   perf stat: Add su...
1549
  	unsigned int interval, timeout;
ba6039b6c   Jiri Olsa   perf stat report:...
1550
  	const char * const stat_subcommands[] = { "record", "report" };
42202dd56   Ingo Molnar   perf stat: Add fe...
1551

5af52b51f   Stephane Eranian   perf stat: add pe...
1552
  	setlocale(LC_ALL, "");
334fe7a3c   Namhyung Kim   perf evlist: Remo...
1553
  	evsel_list = perf_evlist__new();
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
1554
1555
  	if (evsel_list == NULL)
  		return -ENOMEM;
1669e509e   Wang Nan   perf stat: Bail o...
1556
  	parse_events__shrink_config_terms();
51433ead1   Michael Petlan   perf stat: Avoid ...
1557
1558
1559
1560
1561
  
  	/* String-parsing callback-based options would segfault when negated */
  	set_option_flag(stat_options, 'e', "event", PARSE_OPT_NONEG);
  	set_option_flag(stat_options, 'M', "metrics", PARSE_OPT_NONEG);
  	set_option_flag(stat_options, 'G', "cgroup", PARSE_OPT_NONEG);
4979d0c7d   Jiri Olsa   perf stat record:...
1562
1563
1564
  	argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
  					(const char **) stat_usage,
  					PARSE_OPT_STOP_AT_NON_OPTION);
37932c188   Andi Kleen   perf stat: Output...
1565
  	perf_stat__collect_metric_expr(evsel_list);
fb4605ba4   Andi Kleen   perf stat: Check ...
1566
  	perf_stat__init_shadow_stats();
4979d0c7d   Jiri Olsa   perf stat record:...
1567

fa7070a38   Jiri Olsa   perf stat: Move c...
1568
1569
1570
1571
  	if (stat_config.csv_sep) {
  		stat_config.csv_output = true;
  		if (!strcmp(stat_config.csv_sep, "\\t"))
  			stat_config.csv_sep = "\t";
6edb78a21   Jiri Olsa   perf stat report:...
1572
  	} else
fa7070a38   Jiri Olsa   perf stat: Move c...
1573
  		stat_config.csv_sep = DEFAULT_SEPARATOR;
6edb78a21   Jiri Olsa   perf stat report:...
1574

4979d0c7d   Jiri Olsa   perf stat record:...
1575
1576
1577
1578
  	if (argc && !strncmp(argv[0], "rec", 3)) {
  		argc = __cmd_record(argc, argv);
  		if (argc < 0)
  			return -1;
ba6039b6c   Jiri Olsa   perf stat report:...
1579
1580
  	} else if (argc && !strncmp(argv[0], "rep", 3))
  		return __cmd_report(argc, argv);
d7470b6af   Stephane Eranian   perf stat: Add cs...
1581

ec0d3d1fd   Jiri Olsa   perf stat: Move '...
1582
  	interval = stat_config.interval;
f1f8ad52f   yuzhoujian   perf stat: Add su...
1583
  	timeout = stat_config.timeout;
ec0d3d1fd   Jiri Olsa   perf stat: Move '...
1584

4979d0c7d   Jiri Olsa   perf stat record:...
1585
1586
1587
1588
  	/*
  	 * For record command the -o is already taken care of.
  	 */
  	if (!STAT_RECORD && output_name && strcmp(output_name, "-"))
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1589
  		output = NULL;
56f3bae70   Jim Cromie   perf stat: Add --...
1590
1591
1592
  	if (output_name && output_fd) {
  		fprintf(stderr, "cannot use both --output and --log-fd
  ");
e05473111   Jiri Olsa   perf stat: Make s...
1593
1594
  		parse_options_usage(stat_usage, stat_options, "o", 1);
  		parse_options_usage(NULL, stat_options, "log-fd", 0);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1595
  		goto out;
56f3bae70   Jim Cromie   perf stat: Add --...
1596
  	}
fc3e4d077   Stephane Eranian   perf stat: Fix de...
1597

0ce5aa026   Jiri Olsa   perf stat: Move '...
1598
  	if (stat_config.metric_only && stat_config.aggr_mode == AGGR_THREAD) {
54b509160   Andi Kleen   perf stat: Implem...
1599
1600
1601
1602
  		fprintf(stderr, "--metric-only is not supported with --per-thread
  ");
  		goto out;
  	}
d97ae04b3   Jiri Olsa   perf stat: Move '...
1603
  	if (stat_config.metric_only && stat_config.run_count > 1) {
54b509160   Andi Kleen   perf stat: Implem...
1604
1605
1606
1607
  		fprintf(stderr, "--metric-only is not supported with -r
  ");
  		goto out;
  	}
54ac0b1bd   Jiri Olsa   perf stat: Move '...
1608
  	if (stat_config.walltime_run_table && stat_config.run_count <= 1) {
e55c14af4   Jiri Olsa   perf stat: Add --...
1609
1610
1611
1612
1613
1614
  		fprintf(stderr, "--table is only supported with -r
  ");
  		parse_options_usage(stat_usage, stat_options, "r", 1);
  		parse_options_usage(NULL, stat_options, "table", 0);
  		goto out;
  	}
fc3e4d077   Stephane Eranian   perf stat: Fix de...
1615
1616
1617
  	if (output_fd < 0) {
  		fprintf(stderr, "argument to --log-fd must be a > 0
  ");
e05473111   Jiri Olsa   perf stat: Make s...
1618
  		parse_options_usage(stat_usage, stat_options, "log-fd", 0);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1619
  		goto out;
fc3e4d077   Stephane Eranian   perf stat: Fix de...
1620
  	}
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1621
1622
1623
1624
1625
1626
1627
  	if (!output) {
  		struct timespec tm;
  		mode = append_file ? "a" : "w";
  
  		output = fopen(output_name, mode);
  		if (!output) {
  			perror("failed to create output file");
fceda7feb   David Ahern   perf stat: Remove...
1628
  			return -1;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1629
1630
1631
1632
  		}
  		clock_gettime(CLOCK_REALTIME, &tm);
  		fprintf(output, "# started on %s
  ", ctime(&tm.tv_sec));
fc3e4d077   Stephane Eranian   perf stat: Fix de...
1633
  	} else if (output_fd > 0) {
56f3bae70   Jim Cromie   perf stat: Add --...
1634
1635
1636
1637
1638
1639
  		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...
1640
  	}
5821522e9   Jiri Olsa   perf stat: Move '...
1641
  	stat_config.output = output;
d7470b6af   Stephane Eranian   perf stat: Add cs...
1642
1643
1644
  	/*
  	 * let the spreadsheet do the pretty-printing
  	 */
fa7070a38   Jiri Olsa   perf stat: Move c...
1645
  	if (stat_config.csv_output) {
61a9f3242   Jim Cromie   perf stat: Fix sp...
1646
  		/* User explicitly passed -B? */
d7470b6af   Stephane Eranian   perf stat: Add cs...
1647
1648
1649
  		if (big_num_opt == 1) {
  			fprintf(stderr, "-B option not supported with -x
  ");
e05473111   Jiri Olsa   perf stat: Make s...
1650
1651
  			parse_options_usage(stat_usage, stat_options, "B", 1);
  			parse_options_usage(NULL, stat_options, "x", 1);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1652
  			goto out;
d7470b6af   Stephane Eranian   perf stat: Add cs...
1653
  		} else /* Nope, so disable big number formatting */
34ff0866d   Jiri Olsa   perf stat: Move '...
1654
  			stat_config.big_num = false;
d7470b6af   Stephane Eranian   perf stat: Add cs...
1655
  	} else if (big_num_opt == 0) /* User passed --no-big-num */
34ff0866d   Jiri Olsa   perf stat: Move '...
1656
  		stat_config.big_num = false;
d7470b6af   Stephane Eranian   perf stat: Add cs...
1657

e3ba76dee   Jiri Olsa   perf tools: Force...
1658
  	setup_system_wide(argc);
ac3063bd4   David Ahern   perf stat: Don't ...
1659

0ce2da148   Jiri Olsa   perf stat: Displa...
1660
1661
1662
1663
  	/*
  	 * Display user/system times only for single
  	 * run and when there's specified tracee.
  	 */
d97ae04b3   Jiri Olsa   perf stat: Move '...
1664
  	if ((stat_config.run_count == 1) && target__none(&target))
8897a8916   Jiri Olsa   perf stat: Move r...
1665
  		stat_config.ru_display = true;
0ce2da148   Jiri Olsa   perf stat: Displa...
1666

d97ae04b3   Jiri Olsa   perf stat: Move '...
1667
  	if (stat_config.run_count < 0) {
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1668
1669
  		pr_err("Run count must be a positive number
  ");
e05473111   Jiri Olsa   perf stat: Make s...
1670
  		parse_options_usage(stat_usage, stat_options, "r", 1);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1671
  		goto out;
d97ae04b3   Jiri Olsa   perf stat: Move '...
1672
  	} else if (stat_config.run_count == 0) {
a7e191c37   Frederik Deweerdt   perf stat: Introd...
1673
  		forever = true;
d97ae04b3   Jiri Olsa   perf stat: Move '...
1674
  		stat_config.run_count = 1;
a7e191c37   Frederik Deweerdt   perf stat: Introd...
1675
  	}
ddcacfa0f   Ingo Molnar   perf_counter tool...
1676

54ac0b1bd   Jiri Olsa   perf stat: Move '...
1677
1678
1679
  	if (stat_config.walltime_run_table) {
  		stat_config.walltime_run = zalloc(stat_config.run_count * sizeof(stat_config.walltime_run[0]));
  		if (!stat_config.walltime_run) {
e55c14af4   Jiri Olsa   perf stat: Add --...
1680
1681
1682
1683
  			pr_err("failed to setup -r option");
  			goto out;
  		}
  	}
1d9f8d1b8   Jin Yao   perf stat: Remove...
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
  	if ((stat_config.aggr_mode == AGGR_THREAD) &&
  		!target__has_task(&target)) {
  		if (!target.system_wide || target.cpu_list) {
  			fprintf(stderr, "The --per-thread option is only "
  				"available when monitoring via -p -t -a "
  				"options or only --per-thread.
  ");
  			parse_options_usage(NULL, stat_options, "p", 1);
  			parse_options_usage(NULL, stat_options, "t", 1);
  			goto out;
  		}
32b8af82e   Jiri Olsa   perf stat: Introd...
1695
1696
1697
1698
1699
1700
  	}
  
  	/*
  	 * no_aggr, cgroup are for system-wide only
  	 * --per-thread is aggregated per thread, we dont mix it with cpu mode
  	 */
421a50f3f   Jiri Olsa   perf stat: Introd...
1701
1702
  	if (((stat_config.aggr_mode != AGGR_GLOBAL &&
  	      stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
602ad878d   Arnaldo Carvalho de Melo   perf target: Shor...
1703
  	    !target__has_cpu(&target)) {
023695d96   Stephane Eranian   perf tool: Add cg...
1704
1705
1706
  		fprintf(stderr, "both cgroup and no-aggregation "
  			"modes only available in system-wide mode
  ");
e05473111   Jiri Olsa   perf stat: Make s...
1707
1708
1709
  		parse_options_usage(stat_usage, stat_options, "G", 1);
  		parse_options_usage(NULL, stat_options, "A", 1);
  		parse_options_usage(NULL, stat_options, "a", 1);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1710
  		goto out;
d7e7a451c   Stephane Eranian   perf stat: Add pe...
1711
  	}
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1712
1713
  	if (add_default_attributes())
  		goto out;
ddcacfa0f   Ingo Molnar   perf_counter tool...
1714

602ad878d   Arnaldo Carvalho de Melo   perf target: Shor...
1715
  	target__validate(&target);
5c98d466e   Arnaldo Carvalho de Melo   perf tools: Refac...
1716

1d9f8d1b8   Jin Yao   perf stat: Remove...
1717
1718
  	if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide))
  		target.per_thread = true;
77a6f014e   Namhyung Kim   perf stat: Use pe...
1719
  	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
602ad878d   Arnaldo Carvalho de Melo   perf target: Shor...
1720
  		if (target__has_task(&target)) {
77a6f014e   Namhyung Kim   perf stat: Use pe...
1721
1722
  			pr_err("Problems finding threads of monitor
  ");
e05473111   Jiri Olsa   perf stat: Make s...
1723
1724
  			parse_options_usage(stat_usage, stat_options, "p", 1);
  			parse_options_usage(NULL, stat_options, "t", 1);
602ad878d   Arnaldo Carvalho de Melo   perf target: Shor...
1725
  		} else if (target__has_cpu(&target)) {
77a6f014e   Namhyung Kim   perf stat: Use pe...
1726
  			perror("failed to parse CPUs map");
e05473111   Jiri Olsa   perf stat: Make s...
1727
1728
  			parse_options_usage(stat_usage, stat_options, "C", 1);
  			parse_options_usage(NULL, stat_options, "a", 1);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1729
1730
  		}
  		goto out;
60d567e2d   Arnaldo Carvalho de Melo   perf tools: Refac...
1731
  	}
32b8af82e   Jiri Olsa   perf stat: Introd...
1732
1733
1734
1735
1736
  
  	/*
  	 * Initialize thread_map with comm names,
  	 * so we could print it out on output.
  	 */
56739444d   Jin Yao   perf stat: Alloca...
1737
  	if (stat_config.aggr_mode == AGGR_THREAD) {
32b8af82e   Jiri Olsa   perf stat: Introd...
1738
  		thread_map__read_comms(evsel_list->threads);
56739444d   Jin Yao   perf stat: Alloca...
1739
1740
1741
1742
1743
1744
1745
  		if (target.system_wide) {
  			if (runtime_stat_new(&stat_config,
  				thread_map__nr(evsel_list->threads))) {
  				goto out;
  			}
  		}
  	}
32b8af82e   Jiri Olsa   perf stat: Introd...
1746

db06a269e   yuzhoujian   perf stat: Add su...
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
  	if (stat_config.times && interval)
  		interval_count = true;
  	else if (stat_config.times && !interval) {
  		pr_err("interval-count option should be used together with "
  				"interval-print.
  ");
  		parse_options_usage(stat_usage, stat_options, "interval-count", 0);
  		parse_options_usage(stat_usage, stat_options, "I", 1);
  		goto out;
  	}
c45c6ea2e   Stephane Eranian   perf tools: Add t...
1757

f1f8ad52f   yuzhoujian   perf stat: Add su...
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
  	if (timeout && timeout < 100) {
  		if (timeout < 10) {
  			pr_err("timeout must be >= 10ms.
  ");
  			parse_options_usage(stat_usage, stat_options, "timeout", 0);
  			goto out;
  		} else
  			pr_warning("timeout < 100ms. "
  				   "The overhead percentage could be high in some cases. "
  				   "Please proceed with caution.
  ");
  	}
  	if (timeout && interval) {
  		pr_err("timeout option is not supported with interval-print.
  ");
  		parse_options_usage(stat_usage, stat_options, "timeout", 0);
  		parse_options_usage(stat_usage, stat_options, "I", 1);
  		goto out;
  	}
d134ffb91   Arnaldo Carvalho de Melo   perf stat: Introd...
1777
  	if (perf_evlist__alloc_stats(evsel_list, interval))
03ad9747c   Arnaldo Carvalho de Melo   perf evlist: Move...
1778
  		goto out;
d6d901c23   Zhang, Yanmin   perf events: Chan...
1779

86ee6e18f   Stephane Eranian   perf stat: Refact...
1780
  	if (perf_stat_init_aggr_mode())
03ad9747c   Arnaldo Carvalho de Melo   perf evlist: Move...
1781
  		goto out;
86ee6e18f   Stephane Eranian   perf stat: Refact...
1782

58d7e993b   Ingo Molnar   perf stat: handle...
1783
  	/*
7d9ad16af   Jiri Olsa   perf stat: Add 'i...
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
  	 * Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless
  	 * while avoiding that older tools show confusing messages.
  	 *
  	 * However for pipe sessions we need to keep it zero,
  	 * because script's perf_evsel__check_attr is triggered
  	 * by attr->sample_type != 0, and we can't run it on
  	 * stat sessions.
  	 */
  	stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe);
  
  	/*
58d7e993b   Ingo Molnar   perf stat: handle...
1795
1796
1797
1798
1799
  	 * 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...
1800
  	atexit(sig_atexit);
a7e191c37   Frederik Deweerdt   perf stat: Introd...
1801
1802
  	if (!forever)
  		signal(SIGINT,  skip_signal);
13370a9b5   Stephane Eranian   perf stat: Add in...
1803
  	signal(SIGCHLD, skip_signal);
58d7e993b   Ingo Molnar   perf stat: handle...
1804
1805
  	signal(SIGALRM, skip_signal);
  	signal(SIGABRT, skip_signal);
42202dd56   Ingo Molnar   perf stat: Add fe...
1806
  	status = 0;
d97ae04b3   Jiri Olsa   perf stat: Move '...
1807
1808
  	for (run_idx = 0; forever || run_idx < stat_config.run_count; run_idx++) {
  		if (stat_config.run_count != 1 && verbose > 0)
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1809
1810
1811
  			fprintf(output, "[ perf stat: executing run #%d ... ]
  ",
  				run_idx + 1);
f9cef0a90   Ingo Molnar   perf stat: Add --...
1812

e55c14af4   Jiri Olsa   perf stat: Add --...
1813
  		status = run_perf_stat(argc, argv, run_idx);
a7e191c37   Frederik Deweerdt   perf stat: Introd...
1814
  		if (forever && status != -1) {
d4f63a474   Jiri Olsa   perf stat: Introd...
1815
  			print_counters(NULL, argc, argv);
254ecbc74   Jiri Olsa   perf stat: Introd...
1816
  			perf_stat__reset_stats();
a7e191c37   Frederik Deweerdt   perf stat: Introd...
1817
  		}
42202dd56   Ingo Molnar   perf stat: Add fe...
1818
  	}
a7e191c37   Frederik Deweerdt   perf stat: Introd...
1819
  	if (!forever && status != -1 && !interval)
d4f63a474   Jiri Olsa   perf stat: Introd...
1820
  		print_counters(NULL, argc, argv);
d134ffb91   Arnaldo Carvalho de Melo   perf stat: Introd...
1821

4979d0c7d   Jiri Olsa   perf stat record:...
1822
1823
1824
1825
1826
1827
1828
1829
  	if (STAT_RECORD) {
  		/*
  		 * We synthesize the kernel mmap record just so that older tools
  		 * don't emit warnings about not being able to resolve symbols
  		 * due to /proc/sys/kernel/kptr_restrict settings and instear provide
  		 * a saner message about no samples being in the perf.data file.
  		 *
  		 * This also serves to suppress a warning about f_header.data.size == 0
8b99b1a4e   Jiri Olsa   perf stat record:...
1830
1831
1832
1833
  		 * in header.c at the moment 'perf stat record' gets introduced, which
  		 * is not really needed once we start adding the stat specific PERF_RECORD_
  		 * records, but the need to suppress the kptr_restrict messages in older
  		 * tools remain  -acme
4979d0c7d   Jiri Olsa   perf stat record:...
1834
  		 */
8ceb41d7e   Jiri Olsa   perf tools: Renam...
1835
  		int fd = perf_data__fd(&perf_stat.data);
4979d0c7d   Jiri Olsa   perf stat record:...
1836
1837
1838
1839
1840
1841
1842
1843
  		int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat,
  							     process_synthesized_event,
  							     &perf_stat.session->machines.host);
  		if (err) {
  			pr_warning("Couldn't synthesize the kernel mmap record, harmless, "
  				   "older tools may produce warnings about this file
  .");
  		}
7aad0c32b   Jiri Olsa   perf stat record:...
1844
1845
1846
1847
1848
  		if (!interval) {
  			if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL))
  				pr_err("failed to write stat round event
  ");
  		}
8ceb41d7e   Jiri Olsa   perf tools: Renam...
1849
  		if (!perf_stat.data.is_pipe) {
664c98d4e   Jiri Olsa   perf stat record:...
1850
1851
1852
  			perf_stat.session->header.data_size += perf_stat.bytes_written;
  			perf_session__write_header(perf_stat.session, evsel_list, fd, true);
  		}
4979d0c7d   Jiri Olsa   perf stat record:...
1853
1854
1855
  
  		perf_session__delete(perf_stat.session);
  	}
544c2ae7b   Masami Hiramatsu   perf stat: Fix cm...
1856
  	perf_stat__exit_aggr_mode();
d134ffb91   Arnaldo Carvalho de Melo   perf stat: Introd...
1857
  	perf_evlist__free_stats(evsel_list);
0015e2e10   Arnaldo Carvalho de Melo   perf stat: Fix up...
1858
  out:
54ac0b1bd   Jiri Olsa   perf stat: Move '...
1859
  	free(stat_config.walltime_run);
e55c14af4   Jiri Olsa   perf stat: Add --...
1860

daefd0bc0   Kan Liang   perf stat: Add su...
1861
1862
  	if (smi_cost && smi_reset)
  		sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
0015e2e10   Arnaldo Carvalho de Melo   perf stat: Fix up...
1863
  	perf_evlist__delete(evsel_list);
56739444d   Jin Yao   perf stat: Alloca...
1864
1865
  
  	runtime_stat_delete(&stat_config);
42202dd56   Ingo Molnar   perf stat: Add fe...
1866
  	return status;
ddcacfa0f   Ingo Molnar   perf_counter tool...
1867
  }