Blame view

tools/perf/builtin-stat.c 64.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
   */
16f762a2a   Ingo Molnar   perf_counter tool...
42
  #include "builtin.h"
c1a604dff   Arnaldo Carvalho de Melo   perf tools: Remov...
43
  #include "perf.h"
f14d57078   Arnaldo Carvalho de Melo   perf evsel: No ne...
44
  #include "util/cgroup.h"
4b6ab94ea   Josh Poimboeuf   perf subcmd: Crea...
45
  #include <subcmd/parse-options.h>
5242519b0   Ingo Molnar   perf stat: Conver...
46
  #include "util/parse-events.h"
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
47
  #include "util/pmu.h"
8f28827a1   Frederic Weisbecker   perf tools: Libra...
48
  #include "util/event.h"
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
49
  #include "util/evlist.h"
69aad6f1e   Arnaldo Carvalho de Melo   perf tools: Intro...
50
  #include "util/evsel.h"
8f28827a1   Frederic Weisbecker   perf tools: Libra...
51
  #include "util/debug.h"
a5d243d04   Ingo Molnar   perf stat: Print ...
52
  #include "util/color.h"
0007eceac   Xiao Guangrong   perf stat: Move s...
53
  #include "util/stat.h"
60666c630   Liming Wang   perf tools: Fix -...
54
  #include "util/header.h"
a12b51c47   Paul Mackerras   perf tools: Fix s...
55
  #include "util/cpumap.h"
fd78260b5   Arnaldo Carvalho de Melo   perf threads: Mov...
56
  #include "util/thread_map.h"
d809560b3   Jiri Olsa   perf stat: Move p...
57
  #include "util/counts.h"
687986bbe   Kan Liang   perf tools: Renam...
58
  #include "util/topdown.h"
4979d0c7d   Jiri Olsa   perf stat record:...
59
  #include "util/session.h"
ba6039b6c   Jiri Olsa   perf stat report:...
60
  #include "util/tool.h"
a067558e2   Arnaldo Carvalho de Melo   perf tools: Move ...
61
  #include "util/string2.h"
b18f3e365   Andi Kleen   perf stat: Suppor...
62
  #include "util/metricgroup.h"
ea49e01cf   Arnaldo Carvalho de Melo   perf tools: Move ...
63
  #include "util/synthetic-events.h"
aeb00b1ae   Arnaldo Carvalho de Melo   perf record: Move...
64
  #include "util/target.h"
f37110205   Arnaldo Carvalho de Melo   perf time-utils: ...
65
  #include "util/time-utils.h"
9660e08ee   Jiri Olsa   perf stat: Add --...
66
  #include "util/top.h"
4804e0111   Andi Kleen   perf stat: Use af...
67
  #include "util/affinity.h"
709434907   Stephane Eranian   perf tools: Add o...
68
  #include "util/pfm.h"
ba6039b6c   Jiri Olsa   perf stat report:...
69
  #include "asm/bug.h"
ddcacfa0f   Ingo Molnar   perf_counter tool...
70

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

3052ba56b   Arnaldo Carvalho de Melo   tools perf: Move ...
89
  #include <linux/ctype.h>
453fa0309   Jiri Olsa   libperf: Add perf...
90
  #include <perf/evlist.h>
3d689ed60   Arnaldo Carvalho de Melo   perf tools: Move ...
91

d7470b6af   Stephane Eranian   perf stat: Add cs...
92
  #define DEFAULT_SEPARATOR	" "
daefd0bc0   Kan Liang   perf stat: Add su...
93
  #define FREEZE_ON_SMI_PATH	"devices/cpu/freeze_on_smi"
d7470b6af   Stephane Eranian   perf stat: Add cs...
94

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

4cabc3d1c   Andi Kleen   tools/perf/stat: ...
97
  /* Default events used for perf stat -T */
a454742c1   Jiri Olsa   perf stat: Remove...
98
99
  static const char *transaction_attrs = {
  	"task-clock,"
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
100
101
102
103
104
105
106
107
108
109
110
  	"{"
  	"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...
111
112
  static const char * transaction_limited_attrs = {
  	"task-clock,"
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
113
114
115
116
117
118
119
  	"{"
  	"instructions,"
  	"cycles,"
  	"cpu/cycles-t/,"
  	"cpu/tx-start/"
  	"}"
  };
44b1e60ab   Andi Kleen   perf stat: Basic ...
120
121
122
123
124
125
126
127
  static const char * topdown_attrs[] = {
  	"topdown-total-slots",
  	"topdown-slots-retired",
  	"topdown-recovery-bubbles",
  	"topdown-fetch-bubbles",
  	"topdown-slots-issued",
  	NULL,
  };
55c36a9fc   Andi Kleen   perf stat: Suppor...
128
129
130
131
132
133
134
135
  static const char *topdown_metric_attrs[] = {
  	"slots",
  	"topdown-retiring",
  	"topdown-bad-spec",
  	"topdown-fe-bound",
  	"topdown-be-bound",
  	NULL,
  };
daefd0bc0   Kan Liang   perf stat: Add su...
136
137
138
139
140
141
142
  static const char *smi_cost_attrs = {
  	"{"
  	"msr/aperf/,"
  	"msr/smi/,"
  	"cycles"
  	"}"
  };
63503dba8   Jiri Olsa   perf evlist: Rena...
143
  static struct evlist	*evsel_list;
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
144

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

c1a1f5d9d   Jiri Olsa   perf stat: Allow ...
149
  #define METRIC_ONLY_LEN 20
d07f0b120   Stephane Eranian   perf stat: Avoid ...
150
  static volatile pid_t		child_pid			= -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
151
  static int			detailed_run			=  0;
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
152
  static bool			transaction_run;
44b1e60ab   Andi Kleen   perf stat: Basic ...
153
  static bool			topdown_run			= false;
daefd0bc0   Kan Liang   perf stat: Add su...
154
155
  static bool			smi_cost			= false;
  static bool			smi_reset			= false;
d7470b6af   Stephane Eranian   perf stat: Add cs...
156
  static int			big_num_opt			=  -1;
43bece797   Lin Ming   perf tools: Add g...
157
  static bool			group				= false;
1f16c5754   Peter Zijlstra   perf stat: Add --...
158
159
160
  static const char		*pre_cmd			= NULL;
  static const char		*post_cmd			= NULL;
  static bool			sync_run			= false;
a7e191c37   Frederik Deweerdt   perf stat: Introd...
161
  static bool			forever				= false;
44b1e60ab   Andi Kleen   perf stat: Basic ...
162
  static bool			force_metric_only		= false;
13370a9b5   Stephane Eranian   perf stat: Add in...
163
  static struct timespec		ref_time;
e05473111   Jiri Olsa   perf stat: Make s...
164
  static bool			append_file;
db06a269e   yuzhoujian   perf stat: Add su...
165
  static bool			interval_count;
e05473111   Jiri Olsa   perf stat: Make s...
166
167
  static const char		*output_name;
  static int			output_fd;
5af52b51f   Stephane Eranian   perf stat: add pe...
168

4979d0c7d   Jiri Olsa   perf stat record:...
169
170
  struct perf_stat {
  	bool			 record;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
171
  	struct perf_data	 data;
4979d0c7d   Jiri Olsa   perf stat record:...
172
173
  	struct perf_session	*session;
  	u64			 bytes_written;
ba6039b6c   Jiri Olsa   perf stat report:...
174
  	struct perf_tool	 tool;
1975d36e1   Jiri Olsa   perf stat report:...
175
  	bool			 maps_allocated;
f854839ba   Jiri Olsa   perf cpu_map: Ren...
176
  	struct perf_cpu_map	*cpus;
9749b90e5   Jiri Olsa   perf tools: Renam...
177
  	struct perf_thread_map *threads;
89af4e05c   Jiri Olsa   perf stat report:...
178
  	enum aggr_mode		 aggr_mode;
4979d0c7d   Jiri Olsa   perf stat record:...
179
180
181
182
  };
  
  static struct perf_stat		perf_stat;
  #define STAT_RECORD		perf_stat.record
60666c630   Liming Wang   perf tools: Fix -...
183
  static volatile int done = 0;
421a50f3f   Jiri Olsa   perf stat: Introd...
184
  static struct perf_stat_config stat_config = {
26893a601   Jiri Olsa   perf stat: Add 'w...
185
186
187
188
189
190
  	.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 '...
191
  	.big_num		= true,
27e9769aa   Alexey Budankov   perf stat: Introd...
192
193
  	.ctl_fd			= -1,
  	.ctl_fd_ack		= -1
421a50f3f   Jiri Olsa   perf stat: Introd...
194
  };
a9a179024   Jiri Olsa   perf stat: Ensure...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
  static bool cpus_map_matched(struct evsel *a, struct evsel *b)
  {
  	if (!a->core.cpus && !b->core.cpus)
  		return true;
  
  	if (!a->core.cpus || !b->core.cpus)
  		return false;
  
  	if (a->core.cpus->nr != b->core.cpus->nr)
  		return false;
  
  	for (int i = 0; i < a->core.cpus->nr; i++) {
  		if (a->core.cpus->map[i] != b->core.cpus->map[i])
  			return false;
  	}
  
  	return true;
  }
  
  static void evlist__check_cpu_maps(struct evlist *evlist)
  {
  	struct evsel *evsel, *pos, *leader;
  	char buf[1024];
  
  	evlist__for_each_entry(evlist, evsel) {
  		leader = evsel->leader;
  
  		/* Check that leader matches cpus with each member. */
  		if (leader == evsel)
  			continue;
  		if (cpus_map_matched(leader, evsel))
  			continue;
  
  		/* If there's mismatch disable the group and warn user. */
  		WARN_ONCE(1, "WARNING: grouped events cpus do not match, disabling group:
  ");
  		evsel__group_desc(leader, buf, sizeof(buf));
  		pr_warning("  %s
  ", buf);
  
  		if (verbose) {
  			cpu_map__snprint(leader->core.cpus, buf, sizeof(buf));
  			pr_warning("     %s: %s
  ", leader->name, buf);
  			cpu_map__snprint(evsel->core.cpus, buf, sizeof(buf));
  			pr_warning("     %s: %s
  ", evsel->name, buf);
  		}
  
  		for_each_group_evsel(pos, leader) {
  			pos->leader = pos;
  			pos->core.nr_members = 0;
  		}
  		evsel->leader->core.nr_members = 0;
  	}
  }
13370a9b5   Stephane Eranian   perf stat: Add in...
251
252
253
254
255
  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...
256
  		r->tv_nsec = a->tv_nsec + NSEC_PER_SEC - b->tv_nsec;
13370a9b5   Stephane Eranian   perf stat: Add in...
257
258
259
260
261
  		r->tv_sec--;
  	} else {
  		r->tv_nsec = a->tv_nsec - b->tv_nsec ;
  	}
  }
254ecbc74   Jiri Olsa   perf stat: Introd...
262
263
  static void perf_stat__reset_stats(void)
  {
56739444d   Jin Yao   perf stat: Alloca...
264
  	int i;
254ecbc74   Jiri Olsa   perf stat: Introd...
265
  	perf_evlist__reset_stats(evsel_list);
f87027b96   Jiri Olsa   perf stat: Move s...
266
  	perf_stat__reset_shadow_stats();
56739444d   Jin Yao   perf stat: Alloca...
267
268
269
  
  	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...
270
  }
8b99b1a4e   Jiri Olsa   perf stat record:...
271
272
273
274
  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:...
275
  {
8ceb41d7e   Jiri Olsa   perf tools: Renam...
276
  	if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) {
4979d0c7d   Jiri Olsa   perf stat record:...
277
278
279
280
  		pr_err("failed to write perf data, error: %m
  ");
  		return -1;
  	}
8b99b1a4e   Jiri Olsa   perf stat record:...
281
  	perf_stat.bytes_written += event->header.size;
4979d0c7d   Jiri Olsa   perf stat record:...
282
283
  	return 0;
  }
1975d36e1   Jiri Olsa   perf stat report:...
284
  static int write_stat_round_event(u64 tm, u64 type)
7aad0c32b   Jiri Olsa   perf stat record:...
285
  {
1975d36e1   Jiri Olsa   perf stat report:...
286
  	return perf_event__synthesize_stat_round(NULL, tm, type,
7aad0c32b   Jiri Olsa   perf stat record:...
287
288
289
290
291
292
  						 process_synthesized_event,
  						 NULL);
  }
  
  #define WRITE_STAT_ROUND_EVENT(time, interval) \
  	write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
8cd36f3ef   Jiri Olsa   libperf: Move 'sa...
293
  #define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y)
5a6ea81b8   Jiri Olsa   perf stat record:...
294

ddc6999ea   Arnaldo Carvalho de Melo   perf stat: Rename...
295
296
  static int evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread,
  				   struct perf_counts_values *count)
5a6ea81b8   Jiri Olsa   perf stat record:...
297
298
299
300
301
302
  {
  	struct perf_sample_id *sid = SID(counter, cpu, thread);
  
  	return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
  					   process_synthesized_event, NULL);
  }
32dcd021d   Jiri Olsa   perf evsel: Renam...
303
  static int read_single_counter(struct evsel *counter, int cpu,
f0fbb114e   Andi Kleen   perf stat: Implem...
304
305
306
307
308
309
310
311
312
313
  			       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;
  	}
ea0896927   Arnaldo Carvalho de Melo   perf evsel: Renam...
314
  	return evsel__read_counter(counter, cpu, thread);
f0fbb114e   Andi Kleen   perf stat: Implem...
315
  }
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
316
317
318
319
  /*
   * Read out the results of a single counter:
   * do not aggregate counts across CPUs in system-wide mode
   */
4b49ab708   Andi Kleen   perf stat: Use af...
320
  static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu)
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
321
  {
a2f354e3a   Jiri Olsa   libperf: Add perf...
322
  	int nthreads = perf_thread_map__nr(evsel_list->core.threads);
4b49ab708   Andi Kleen   perf stat: Use af...
323
  	int thread;
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
324

3b4331d9a   Suzuki K. Poulose   perf stat: Report...
325
326
  	if (!counter->supported)
  		return -ENOENT;
648b5af3f   Jiri Olsa   libperf: Move 'sy...
327
  	if (counter->core.system_wide)
9bf1a5291   Jiri Olsa   perf stat: Make r...
328
329
330
  		nthreads = 1;
  
  	for (thread = 0; thread < nthreads; thread++) {
4b49ab708   Andi Kleen   perf stat: Use af...
331
332
333
334
335
336
  		struct perf_counts_values *count;
  
  		count = perf_counts(counter->counts, cpu, thread);
  
  		/*
  		 * The leader's group read loads data into its group members
ea0896927   Arnaldo Carvalho de Melo   perf evsel: Renam...
337
  		 * (via evsel__read_counter()) and sets their count->loaded.
4b49ab708   Andi Kleen   perf stat: Use af...
338
339
340
341
342
343
344
345
  		 */
  		if (!perf_counts__is_loaded(counter->counts, cpu, thread) &&
  		    read_single_counter(counter, cpu, thread, rs)) {
  			counter->counts->scaled = -1;
  			perf_counts(counter->counts, cpu, thread)->ena = 0;
  			perf_counts(counter->counts, cpu, thread)->run = 0;
  			return -1;
  		}
5a6ea81b8   Jiri Olsa   perf stat record:...
346

4b49ab708   Andi Kleen   perf stat: Use af...
347
  		perf_counts__set_loaded(counter->counts, cpu, thread, false);
82bf311e1   Jiri Olsa   perf stat: Use gr...
348

4b49ab708   Andi Kleen   perf stat: Use af...
349
  		if (STAT_RECORD) {
ddc6999ea   Arnaldo Carvalho de Melo   perf stat: Rename...
350
  			if (evsel__write_stat_event(counter, cpu, thread, count)) {
4b49ab708   Andi Kleen   perf stat: Use af...
351
352
353
  				pr_err("failed to write stat event
  ");
  				return -1;
5a6ea81b8   Jiri Olsa   perf stat record:...
354
  			}
4b49ab708   Andi Kleen   perf stat: Use af...
355
  		}
0b1abbf4a   Andi Kleen   perf stat: Add ex...
356

4b49ab708   Andi Kleen   perf stat: Use af...
357
358
359
360
  		if (verbose > 1) {
  			fprintf(stat_config.output,
  				"%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "
  ",
8ab2e96d8   Arnaldo Carvalho de Melo   perf evsel: Renam...
361
  					evsel__name(counter),
4b49ab708   Andi Kleen   perf stat: Use af...
362
363
  					cpu,
  					count->val, count->ena, count->run);
9bf1a5291   Jiri Olsa   perf stat: Make r...
364
  		}
f5b4a9c3a   Stephane Eranian   perf stat: Add no...
365
  	}
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
366
367
  
  	return 0;
2996f5ddb   Ingo Molnar   perf_counter tool...
368
  }
c7e5b328a   Jin Yao   perf stat: Report...
369
  static int read_affinity_counters(struct timespec *rs)
13370a9b5   Stephane Eranian   perf stat: Add in...
370
  {
32dcd021d   Jiri Olsa   perf evsel: Renam...
371
  	struct evsel *counter;
4b49ab708   Andi Kleen   perf stat: Use af...
372
373
374
375
  	struct affinity affinity;
  	int i, ncpus, cpu;
  
  	if (affinity__setup(&affinity) < 0)
c7e5b328a   Jin Yao   perf stat: Report...
376
  		return -1;
4b49ab708   Andi Kleen   perf stat: Use af...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
  
  	ncpus = perf_cpu_map__nr(evsel_list->core.all_cpus);
  	if (!target__has_cpu(&target) || target__has_per_thread(&target))
  		ncpus = 1;
  	evlist__for_each_cpu(evsel_list, i, cpu) {
  		if (i >= ncpus)
  			break;
  		affinity__set(&affinity, cpu);
  
  		evlist__for_each_entry(evsel_list, counter) {
  			if (evsel__cpu_iter_skip(counter, cpu))
  				continue;
  			if (!counter->err) {
  				counter->err = read_counter_cpu(counter, rs,
  								counter->cpu_iter - 1);
  			}
  		}
  	}
  	affinity__cleanup(&affinity);
c7e5b328a   Jin Yao   perf stat: Report...
396
397
398
399
400
401
  	return 0;
  }
  
  static void read_counters(struct timespec *rs)
  {
  	struct evsel *counter;
ee6a96143   Jin Yao   perf stat: Turn o...
402
  	if (!stat_config.stop_read_counter && (read_affinity_counters(rs) < 0))
c7e5b328a   Jin Yao   perf stat: Report...
403
  		return;
13370a9b5   Stephane Eranian   perf stat: Add in...
404

e5cadb93d   Arnaldo Carvalho de Melo   perf evlist: Rena...
405
  	evlist__for_each_entry(evsel_list, counter) {
4b49ab708   Andi Kleen   perf stat: Use af...
406
  		if (counter->err)
245bad8eb   Andi Kleen   perf stat: Quiete...
407
408
  			pr_debug("failed to read counter %s
  ", counter->name);
4b49ab708   Andi Kleen   perf stat: Use af...
409
  		if (counter->err == 0 && perf_stat_process_counter(&stat_config, counter))
3b3eb0445   Jiri Olsa   perf stat: Separa...
410
411
  			pr_warning("failed to process counter %s
  ", counter->name);
4b49ab708   Andi Kleen   perf stat: Use af...
412
  		counter->err = 0;
13370a9b5   Stephane Eranian   perf stat: Add in...
413
  	}
106a94a0f   Jiri Olsa   perf stat: Introd...
414
  }
72f02a947   Jin Yao   perf stat: Fix wr...
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
  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]);
  
  	zfree(&config->stats);
  }
  
  static void runtime_stat_reset(struct perf_stat_config *config)
  {
  	int i;
  
  	if (!config->stats)
  		return;
  
  	for (i = 0; i < config->stats_num; i++)
  		perf_stat__reset_shadow_per_stat(&config->stats[i]);
  }
ba411a954   Jiri Olsa   perf stat: Rename...
454
  static void process_interval(void)
106a94a0f   Jiri Olsa   perf stat: Introd...
455
  {
106a94a0f   Jiri Olsa   perf stat: Introd...
456
  	struct timespec ts, rs;
106a94a0f   Jiri Olsa   perf stat: Introd...
457

13370a9b5   Stephane Eranian   perf stat: Add in...
458
459
  	clock_gettime(CLOCK_MONOTONIC, &ts);
  	diff_timespec(&rs, &ts, &ref_time);
13370a9b5   Stephane Eranian   perf stat: Add in...
460

197ba86fd   Jin Yao   perf stat: Improv...
461
  	perf_stat__reset_shadow_per_stat(&rt_stat);
72f02a947   Jin Yao   perf stat: Fix wr...
462
  	runtime_stat_reset(&stat_config);
f0fbb114e   Andi Kleen   perf stat: Implem...
463
  	read_counters(&rs);
7aad0c32b   Jiri Olsa   perf stat record:...
464
  	if (STAT_RECORD) {
bd48c63eb   Arnaldo Carvalho de Melo   tools: Introduce ...
465
  		if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL))
7aad0c32b   Jiri Olsa   perf stat record:...
466
467
468
  			pr_err("failed to write stat round event
  ");
  	}
b90f1333e   Andi Kleen   perf stat: Update...
469
  	init_stats(&walltime_nsecs_stats);
ea9eb1f45   Jiri Olsa   perf stat: Fix du...
470
  	update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000ULL);
d4f63a474   Jiri Olsa   perf stat: Introd...
471
  	print_counters(&rs, 0, NULL);
13370a9b5   Stephane Eranian   perf stat: Add in...
472
  }
dece3a4d3   Alexey Budankov   perf stat: Factor...
473
474
475
476
477
478
479
480
481
  static bool handle_interval(unsigned int interval, int *times)
  {
  	if (interval) {
  		process_interval();
  		if (interval_count && !(--(*times)))
  			return true;
  	}
  	return false;
  }
67ccdecd0   Jiri Olsa   perf stat: Create...
482
  static void enable_counters(void)
411916880   Andi Kleen   perf stat: Add su...
483
  {
2162b9c6b   Alexey Budankov   perf stat: extend...
484
485
486
487
488
489
490
  	if (stat_config.initial_delay < 0) {
  		pr_info(EVLIST_DISABLED_MSG);
  		return;
  	}
  
  	if (stat_config.initial_delay > 0) {
  		pr_info(EVLIST_DISABLED_MSG);
728c0ee0a   Jiri Olsa   perf stat: Move '...
491
  		usleep(stat_config.initial_delay * USEC_PER_MSEC);
2162b9c6b   Alexey Budankov   perf stat: extend...
492
  	}
67ccdecd0   Jiri Olsa   perf stat: Create...
493
494
495
496
497
498
  
  	/*
  	 * We need to enable counters only if:
  	 * - we don't have tracee (attaching to task or cpu)
  	 * - we have initial delay configured
  	 */
2162b9c6b   Alexey Budankov   perf stat: extend...
499
  	if (!target__none(&target) || stat_config.initial_delay) {
1c87f1654   Jiri Olsa   perf evlist: Rena...
500
  		evlist__enable(evsel_list);
2162b9c6b   Alexey Budankov   perf stat: extend...
501
502
503
  		if (stat_config.initial_delay > 0)
  			pr_info(EVLIST_ENABLED_MSG);
  	}
411916880   Andi Kleen   perf stat: Add su...
504
  }
3df33eff2   Mark Rutland   perf stat: Avoid ...
505
506
507
508
509
510
511
512
  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))
e74676deb   Jiri Olsa   perf evlist: Rena...
513
  		evlist__disable(evsel_list);
3df33eff2   Mark Rutland   perf stat: Avoid ...
514
  }
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
515
  static volatile int workload_exec_errno;
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
516
517
518
519
520
521
  
  /*
   * 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...
522
523
  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 ...
524
  {
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
525
  	workload_exec_errno = info->si_value.sival_int;
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
526
  }
ddc6999ea   Arnaldo Carvalho de Melo   perf stat: Rename...
527
  static bool evsel__should_store_id(struct evsel *counter)
82bf311e1   Jiri Olsa   perf stat: Use gr...
528
  {
1fc632cef   Jiri Olsa   libperf: Move per...
529
  	return STAT_RECORD || counter->core.attr.read_format & PERF_FORMAT_ID;
82bf311e1   Jiri Olsa   perf stat: Use gr...
530
  }
cbb5df7e9   Jiri Olsa   perf stat: Poll f...
531
  static bool is_target_alive(struct target *_target,
9749b90e5   Jiri Olsa   perf tools: Renam...
532
  			    struct perf_thread_map *threads)
cbb5df7e9   Jiri Olsa   perf stat: Poll f...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
  {
  	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;
  }
bee328cb7   Alexey Budankov   perf stat: Implem...
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
  static void process_evlist(struct evlist *evlist, unsigned int interval)
  {
  	enum evlist_ctl_cmd cmd = EVLIST_CTL_CMD_UNSUPPORTED;
  
  	if (evlist__ctlfd_process(evlist, &cmd) > 0) {
  		switch (cmd) {
  		case EVLIST_CTL_CMD_ENABLE:
  			pr_info(EVLIST_ENABLED_MSG);
  			if (interval)
  				process_interval();
  			break;
  		case EVLIST_CTL_CMD_DISABLE:
  			if (interval)
  				process_interval();
  			pr_info(EVLIST_DISABLED_MSG);
  			break;
d20aff151   Adrian Hunter   perf record: Add ...
568
  		case EVLIST_CTL_CMD_SNAPSHOT:
bee328cb7   Alexey Budankov   perf stat: Implem...
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
  		case EVLIST_CTL_CMD_ACK:
  		case EVLIST_CTL_CMD_UNSUPPORTED:
  		default:
  			break;
  		}
  	}
  }
  
  static void compute_tts(struct timespec *time_start, struct timespec *time_stop,
  			int *time_to_sleep)
  {
  	int tts = *time_to_sleep;
  	struct timespec time_diff;
  
  	diff_timespec(&time_diff, time_stop, time_start);
  
  	tts -= time_diff.tv_sec * MSEC_PER_SEC +
  	       time_diff.tv_nsec / NSEC_PER_MSEC;
  
  	if (tts < 0)
  		tts = 0;
  
  	*time_to_sleep = tts;
  }
  
  static int dispatch_events(bool forks, int timeout, int interval, int *times)
987b82381   Alexey Budankov   perf stat: Factor...
595
596
  {
  	int child_exited = 0, status = 0;
bee328cb7   Alexey Budankov   perf stat: Implem...
597
598
599
600
601
602
603
604
605
606
607
  	int time_to_sleep, sleep_time;
  	struct timespec time_start, time_stop;
  
  	if (interval)
  		sleep_time = interval;
  	else if (timeout)
  		sleep_time = timeout;
  	else
  		sleep_time = 1000;
  
  	time_to_sleep = sleep_time;
987b82381   Alexey Budankov   perf stat: Factor...
608
609
610
611
612
613
614
615
616
  
  	while (!done) {
  		if (forks)
  			child_exited = waitpid(child_pid, &status, WNOHANG);
  		else
  			child_exited = !is_target_alive(&target, evsel_list->core.threads) ? 1 : 0;
  
  		if (child_exited)
  			break;
bee328cb7   Alexey Budankov   perf stat: Implem...
617
618
619
620
621
622
623
624
625
626
  		clock_gettime(CLOCK_MONOTONIC, &time_start);
  		if (!(evlist__poll(evsel_list, time_to_sleep) > 0)) { /* poll timeout or EINTR */
  			if (timeout || handle_interval(interval, times))
  				break;
  			time_to_sleep = sleep_time;
  		} else { /* fd revent */
  			process_evlist(evsel_list, interval);
  			clock_gettime(CLOCK_MONOTONIC, &time_stop);
  			compute_tts(&time_start, &time_stop, &time_to_sleep);
  		}
987b82381   Alexey Budankov   perf stat: Factor...
627
628
629
630
  	}
  
  	return status;
  }
e0e6a6ca3   Andi Kleen   perf stat: Factor...
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
  enum counter_recovery {
  	COUNTER_SKIP,
  	COUNTER_RETRY,
  	COUNTER_FATAL,
  };
  
  static enum counter_recovery stat_handle_error(struct evsel *counter)
  {
  	char msg[BUFSIZ];
  	/*
  	 * PPC returns ENXIO for HW counters until 2.6.37
  	 * (behavior changed with commit b0a873e).
  	 */
  	if (errno == EINVAL || errno == ENOSYS ||
  	    errno == ENOENT || errno == EOPNOTSUPP ||
  	    errno == ENXIO) {
  		if (verbose > 0)
  			ui__warning("%s event is not supported by the kernel.
  ",
8ab2e96d8   Arnaldo Carvalho de Melo   perf evsel: Renam...
650
  				    evsel__name(counter));
e0e6a6ca3   Andi Kleen   perf stat: Factor...
651
  		counter->supported = false;
4804e0111   Andi Kleen   perf stat: Use af...
652
653
654
655
656
  		/*
  		 * errored is a sticky flag that means one of the counter's
  		 * cpu event had a problem and needs to be reexamined.
  		 */
  		counter->errored = true;
e0e6a6ca3   Andi Kleen   perf stat: Factor...
657
658
659
660
  
  		if ((counter->leader != counter) ||
  		    !(counter->leader->core.nr_members > 1))
  			return COUNTER_SKIP;
ae4308927   Arnaldo Carvalho de Melo   perf evsel: Renam...
661
  	} else if (evsel__fallback(counter, errno, msg, sizeof(msg))) {
e0e6a6ca3   Andi Kleen   perf stat: Factor...
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
  		if (verbose > 0)
  			ui__warning("%s
  ", msg);
  		return COUNTER_RETRY;
  	} else if (target__has_per_thread(&target) &&
  		   evsel_list->core.threads &&
  		   evsel_list->core.threads->err_thread != -1) {
  		/*
  		 * For global --per-thread case, skip current
  		 * error thread.
  		 */
  		if (!thread_map__remove(evsel_list->core.threads,
  					evsel_list->core.threads->err_thread)) {
  			evsel_list->core.threads->err_thread = -1;
  			return COUNTER_RETRY;
  		}
  	}
2bb72dbb8   Arnaldo Carvalho de Melo   perf evsel: Renam...
679
  	evsel__open_strerror(counter, &target, errno, msg, sizeof(msg));
e0e6a6ca3   Andi Kleen   perf stat: Factor...
680
681
682
683
684
685
686
  	ui__error("%s
  ", msg);
  
  	if (child_pid != -1)
  		kill(child_pid, SIGTERM);
  	return COUNTER_FATAL;
  }
e55c14af4   Jiri Olsa   perf stat: Add --...
687
  static int __run_perf_stat(int argc, const char **argv, int run_idx)
42202dd56   Ingo Molnar   perf stat: Add fe...
688
  {
ec0d3d1fd   Jiri Olsa   perf stat: Move '...
689
  	int interval = stat_config.interval;
db06a269e   yuzhoujian   perf stat: Add su...
690
  	int times = stat_config.times;
f1f8ad52f   yuzhoujian   perf stat: Add su...
691
  	int timeout = stat_config.timeout;
d6195a6a2   Arnaldo Carvalho de Melo   perf evsel: Infor...
692
  	char msg[BUFSIZ];
42202dd56   Ingo Molnar   perf stat: Add fe...
693
  	unsigned long long t0, t1;
32dcd021d   Jiri Olsa   perf evsel: Renam...
694
  	struct evsel *counter;
410136f5d   Stephane Eranian   tools/perf/stat: ...
695
  	size_t l;
42202dd56   Ingo Molnar   perf stat: Add fe...
696
  	int status = 0;
6be2850ef   Zhang, Yanmin   perf stat: Enable...
697
  	const bool forks = (argc > 0);
8ceb41d7e   Jiri Olsa   perf tools: Renam...
698
  	bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false;
4804e0111   Andi Kleen   perf stat: Use af...
699
700
701
  	struct affinity affinity;
  	int i, cpu;
  	bool second_pass = false;
42202dd56   Ingo Molnar   perf stat: Add fe...
702

60666c630   Liming Wang   perf tools: Fix -...
703
  	if (forks) {
664c98d4e   Jiri Olsa   perf stat record:...
704
  		if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe,
735f7e0bb   Arnaldo Carvalho de Melo   perf evlist: Move...
705
  						  workload_exec_failed_signal) < 0) {
acf289227   Namhyung Kim   perf stat: Use pe...
706
707
  			perror("failed to prepare workload");
  			return -1;
60666c630   Liming Wang   perf tools: Fix -...
708
  		}
d20a47e70   Namhyung Kim   perf stat: Set ch...
709
  		child_pid = evsel_list->workload.pid;
051ae7f73   Paul Mackerras   perf_counter tool...
710
  	}
6a4bb04ca   Jiri Olsa   perf tools: Enabl...
711
  	if (group)
63dab225f   Arnaldo Carvalho de Melo   perf evlist: Rena...
712
  		perf_evlist__set_leader(evsel_list);
6a4bb04ca   Jiri Olsa   perf tools: Enabl...
713

4804e0111   Andi Kleen   perf stat: Use af...
714
715
716
717
718
719
720
721
722
723
724
  	if (affinity__setup(&affinity) < 0)
  		return -1;
  
  	evlist__for_each_cpu (evsel_list, i, cpu) {
  		affinity__set(&affinity, cpu);
  
  		evlist__for_each_entry(evsel_list, counter) {
  			if (evsel__cpu_iter_skip(counter, cpu))
  				continue;
  			if (counter->reset_group || counter->errored)
  				continue;
42ef8a78c   Arnaldo Carvalho de Melo   perf stat: Fallba...
725
  try_again:
4804e0111   Andi Kleen   perf stat: Use af...
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
  			if (create_perf_stat_counter(counter, &stat_config, &target,
  						     counter->cpu_iter - 1) < 0) {
  
  				/*
  				 * Weak group failed. We cannot just undo this here
  				 * because earlier CPUs might be in group mode, and the kernel
  				 * doesn't support mixing group and non group reads. Defer
  				 * it to later.
  				 * Don't close here because we're in the wrong affinity.
  				 */
  				if ((errno == EINVAL || errno == EBADF) &&
  				    counter->leader != counter &&
  				    counter->weak_group) {
  					perf_evlist__reset_weak_group(evsel_list, counter, false);
  					assert(counter->reset_group);
  					second_pass = true;
  					continue;
  				}
  
  				switch (stat_handle_error(counter)) {
  				case COUNTER_FATAL:
  					return -1;
  				case COUNTER_RETRY:
  					goto try_again;
  				case COUNTER_SKIP:
  					continue;
  				default:
  					break;
  				}
5a5dfe4b8   Andi Kleen   perf tools: Suppo...
755
  			}
4804e0111   Andi Kleen   perf stat: Use af...
756
757
758
  			counter->supported = true;
  		}
  	}
5a5dfe4b8   Andi Kleen   perf tools: Suppo...
759

4804e0111   Andi Kleen   perf stat: Use af...
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
  	if (second_pass) {
  		/*
  		 * Now redo all the weak group after closing them,
  		 * and also close errored counters.
  		 */
  
  		evlist__for_each_cpu(evsel_list, i, cpu) {
  			affinity__set(&affinity, cpu);
  			/* First close errored or weak retry */
  			evlist__for_each_entry(evsel_list, counter) {
  				if (!counter->reset_group && !counter->errored)
  					continue;
  				if (evsel__cpu_iter_skip_no_inc(counter, cpu))
  					continue;
  				perf_evsel__close_cpu(&counter->core, counter->cpu_iter);
ab6c79b81   Jin Yao   perf stat: Ignore...
775
  			}
4804e0111   Andi Kleen   perf stat: Use af...
776
777
778
779
780
781
782
783
784
  			/* Now reopen weak */
  			evlist__for_each_entry(evsel_list, counter) {
  				if (!counter->reset_group && !counter->errored)
  					continue;
  				if (evsel__cpu_iter_skip(counter, cpu))
  					continue;
  				if (!counter->reset_group)
  					continue;
  try_again_reset:
8ab2e96d8   Arnaldo Carvalho de Melo   perf evsel: Renam...
785
786
  				pr_debug2("reopening weak %s
  ", evsel__name(counter));
4804e0111   Andi Kleen   perf stat: Use af...
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
  				if (create_perf_stat_counter(counter, &stat_config, &target,
  							     counter->cpu_iter - 1) < 0) {
  
  					switch (stat_handle_error(counter)) {
  					case COUNTER_FATAL:
  						return -1;
  					case COUNTER_RETRY:
  						goto try_again_reset;
  					case COUNTER_SKIP:
  						continue;
  					default:
  						break;
  					}
  				}
  				counter->supported = true;
  			}
  		}
  	}
  	affinity__cleanup(&affinity);
  
  	evlist__for_each_entry(evsel_list, counter) {
  		if (!counter->supported) {
  			perf_evsel__free_fd(&counter->core);
  			continue;
48290609c   Arnaldo Carvalho de Melo   perf evsel: Intro...
811
  		}
410136f5d   Stephane Eranian   tools/perf/stat: ...
812
813
  
  		l = strlen(counter->unit);
df4f7b4d4   Jiri Olsa   perf stat: Move '...
814
815
  		if (l > stat_config.unit_width)
  			stat_config.unit_width = l;
2af4646d1   Jiri Olsa   perf stat record:...
816

ddc6999ea   Arnaldo Carvalho de Melo   perf stat: Rename...
817
  		if (evsel__should_store_id(counter) &&
343977534   Arnaldo Carvalho de Melo   perf evsel: Renam...
818
  		    evsel__store_ids(counter, evsel_list))
2af4646d1   Jiri Olsa   perf stat record:...
819
  			return -1;
084ab9f86   Arnaldo Carvalho de Melo   perf stat: Better...
820
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
821

23d4aad48   Arnaldo Carvalho de Melo   perf evlist: Retu...
822
  	if (perf_evlist__apply_filters(evsel_list, &counter)) {
62d94b00f   Arnaldo Carvalho de Melo   perf tools: Repla...
823
824
  		pr_err("failed to set filter \"%s\" on event %s with %d (%s)
  ",
8ab2e96d8   Arnaldo Carvalho de Melo   perf evsel: Renam...
825
  			counter->filter, evsel__name(counter), errno,
c8b5f2c96   Arnaldo Carvalho de Melo   tools: Introduce ...
826
  			str_error_r(errno, msg, sizeof(msg)));
cfd748ae0   Frederic Weisbecker   perf stat: Provid...
827
828
  		return -1;
  	}
4979d0c7d   Jiri Olsa   perf stat record:...
829
  	if (STAT_RECORD) {
8ceb41d7e   Jiri Olsa   perf tools: Renam...
830
  		int err, fd = perf_data__fd(&perf_stat.data);
4979d0c7d   Jiri Olsa   perf stat record:...
831

664c98d4e   Jiri Olsa   perf stat record:...
832
  		if (is_pipe) {
8ceb41d7e   Jiri Olsa   perf tools: Renam...
833
  			err = perf_header__write_pipe(perf_data__fd(&perf_stat.data));
664c98d4e   Jiri Olsa   perf stat record:...
834
835
836
837
  		} else {
  			err = perf_session__write_header(perf_stat.session, evsel_list,
  							 fd, false);
  		}
4979d0c7d   Jiri Olsa   perf stat record:...
838
839
  		if (err < 0)
  			return err;
8b99b1a4e   Jiri Olsa   perf stat record:...
840

b251892d6   Arnaldo Carvalho de Melo   perf stat: Move p...
841
842
  		err = perf_event__synthesize_stat_events(&stat_config, NULL, evsel_list,
  							 process_synthesized_event, is_pipe);
8b99b1a4e   Jiri Olsa   perf stat record:...
843
844
  		if (err < 0)
  			return err;
4979d0c7d   Jiri Olsa   perf stat record:...
845
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
846
847
848
849
  	/*
  	 * Enable counters and exec the command:
  	 */
  	t0 = rdclock();
13370a9b5   Stephane Eranian   perf stat: Add in...
850
  	clock_gettime(CLOCK_MONOTONIC, &ref_time);
42202dd56   Ingo Molnar   perf stat: Add fe...
851

60666c630   Liming Wang   perf tools: Fix -...
852
  	if (forks) {
acf289227   Namhyung Kim   perf stat: Use pe...
853
  		perf_evlist__start_workload(evsel_list);
67ccdecd0   Jiri Olsa   perf stat: Create...
854
  		enable_counters();
acf289227   Namhyung Kim   perf stat: Use pe...
855

27e9769aa   Alexey Budankov   perf stat: Introd...
856
  		if (interval || timeout || evlist__ctlfd_initialized(evsel_list))
bee328cb7   Alexey Budankov   perf stat: Implem...
857
  			status = dispatch_events(forks, timeout, interval, &times);
cfbd41b78   Arnaldo Carvalho de Melo   perf stat: Honour...
858
859
860
  		if (child_pid != -1) {
  			if (timeout)
  				kill(child_pid, SIGTERM);
8a99255a5   Jin Yao   perf stat: Fix en...
861
  			wait4(child_pid, &status, 0, &stat_config.ru_data);
cfbd41b78   Arnaldo Carvalho de Melo   perf stat: Honour...
862
  		}
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
863

f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
864
  		if (workload_exec_errno) {
c8b5f2c96   Arnaldo Carvalho de Melo   tools: Introduce ...
865
  			const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
866
867
  			pr_err("Workload failed: %s
  ", emsg);
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
868
  			return -1;
f33cbe72e   Arnaldo Carvalho de Melo   perf evlist: Send...
869
  		}
6af206fd9   Arnaldo Carvalho de Melo   perf stat: Don't ...
870

33e49ea70   Andi Kleen   perf tools: Make ...
871
872
  		if (WIFSIGNALED(status))
  			psignal(WTERMSIG(status), argv[0]);
60666c630   Liming Wang   perf tools: Fix -...
873
  	} else {
67ccdecd0   Jiri Olsa   perf stat: Create...
874
  		enable_counters();
bee328cb7   Alexey Budankov   perf stat: Implem...
875
  		status = dispatch_events(forks, timeout, interval, &times);
60666c630   Liming Wang   perf tools: Fix -...
876
  	}
42202dd56   Ingo Molnar   perf stat: Add fe...
877

3df33eff2   Mark Rutland   perf stat: Avoid ...
878
  	disable_counters();
42202dd56   Ingo Molnar   perf stat: Add fe...
879
  	t1 = rdclock();
54ac0b1bd   Jiri Olsa   perf stat: Move '...
880
881
  	if (stat_config.walltime_run_table)
  		stat_config.walltime_run[run_idx] = t1 - t0;
e55c14af4   Jiri Olsa   perf stat: Add --...
882

ee6a96143   Jin Yao   perf stat: Turn o...
883
  	if (interval && stat_config.summary) {
c7e5b328a   Jin Yao   perf stat: Report...
884
  		stat_config.interval = 0;
ee6a96143   Jin Yao   perf stat: Turn o...
885
  		stat_config.stop_read_counter = true;
c7e5b328a   Jin Yao   perf stat: Report...
886
887
888
889
890
891
892
893
894
895
896
897
  		init_stats(&walltime_nsecs_stats);
  		update_stats(&walltime_nsecs_stats, t1 - t0);
  
  		if (stat_config.aggr_mode == AGGR_GLOBAL)
  			perf_evlist__save_aggr_prev_raw_counts(evsel_list);
  
  		perf_evlist__copy_prev_raw_counts(evsel_list);
  		perf_evlist__reset_prev_raw_counts(evsel_list);
  		runtime_stat_reset(&stat_config);
  		perf_stat__reset_shadow_per_stat(&rt_stat);
  	} else
  		update_stats(&walltime_nsecs_stats, t1 - t0);
42202dd56   Ingo Molnar   perf stat: Add fe...
898

3df33eff2   Mark Rutland   perf stat: Avoid ...
899
900
901
902
903
904
  	/*
  	 * 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...
905
  	read_counters(&(struct timespec) { .tv_nsec = t1-t0 });
08ef3af15   Jiri Olsa   perf stat: Fix se...
906
907
908
909
910
911
  
  	/*
  	 * We need to keep evsel_list alive, because it's processed
  	 * later the evsel_list will be closed after.
  	 */
  	if (!STAT_RECORD)
750b4edeb   Jiri Olsa   perf evlist: Rena...
912
  		evlist__close(evsel_list);
c52b12ed2   Arnaldo Carvalho de Melo   perf evsel: Steal...
913

42202dd56   Ingo Molnar   perf stat: Add fe...
914
915
  	return WEXITSTATUS(status);
  }
e55c14af4   Jiri Olsa   perf stat: Add --...
916
  static int run_perf_stat(int argc, const char **argv, int run_idx)
1f16c5754   Peter Zijlstra   perf stat: Add --...
917
918
919
920
921
922
923
924
925
926
927
  {
  	int ret;
  
  	if (pre_cmd) {
  		ret = system(pre_cmd);
  		if (ret)
  			return ret;
  	}
  
  	if (sync_run)
  		sync();
e55c14af4   Jiri Olsa   perf stat: Add --...
928
  	ret = __run_perf_stat(argc, argv, run_idx);
1f16c5754   Peter Zijlstra   perf stat: Add --...
929
930
931
932
933
934
935
936
937
938
939
  	if (ret)
  		return ret;
  
  	if (post_cmd) {
  		ret = system(post_cmd);
  		if (ret)
  			return ret;
  	}
  
  	return ret;
  }
a5a9eac1a   Jiri Olsa   perf stat: Introd...
940
941
  static void print_counters(struct timespec *ts, int argc, const char **argv)
  {
0174820a8   Jiri Olsa   perf stat: Move S...
942
943
944
  	/* 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...
945
  	perf_evlist__print_counters(evsel_list, &stat_config, &target,
b64df7f33   Jiri Olsa   perf stat: Add 's...
946
  				    ts, argc, argv);
a5a9eac1a   Jiri Olsa   perf stat: Introd...
947
  }
f7b7c26e0   Peter Zijlstra   perf_counter tool...
948
  static volatile int signr = -1;
5242519b0   Ingo Molnar   perf stat: Conver...
949
  static void skip_signal(int signo)
ddcacfa0f   Ingo Molnar   perf_counter tool...
950
  {
ec0d3d1fd   Jiri Olsa   perf stat: Move '...
951
  	if ((child_pid == -1) || stat_config.interval)
60666c630   Liming Wang   perf tools: Fix -...
952
  		done = 1;
f7b7c26e0   Peter Zijlstra   perf_counter tool...
953
  	signr = signo;
d07f0b120   Stephane Eranian   perf stat: Avoid ...
954
955
956
957
958
959
960
  	/*
  	 * 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...
961
962
963
964
  }
  
  static void sig_atexit(void)
  {
d07f0b120   Stephane Eranian   perf stat: Avoid ...
965
966
967
968
969
970
971
972
973
974
975
  	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...
976
977
  	if (child_pid != -1)
  		kill(child_pid, SIGTERM);
d07f0b120   Stephane Eranian   perf stat: Avoid ...
978
  	sigprocmask(SIG_SETMASK, &oset, NULL);
f7b7c26e0   Peter Zijlstra   perf_counter tool...
979
980
981
982
983
  	if (signr == -1)
  		return;
  
  	signal(signr, SIG_DFL);
  	kill(getpid(), signr);
5242519b0   Ingo Molnar   perf stat: Conver...
984
  }
d778a778a   Paul A. Clarke   perf config: Add ...
985
986
987
988
  void perf_stat__set_big_num(int set)
  {
  	stat_config.big_num = (set != 0);
  }
1d037ca16   Irina Tirdea   perf tools: Use _...
989
990
  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...
991
992
  {
  	big_num_opt = unset ? 0 : 1;
d778a778a   Paul A. Clarke   perf config: Add ...
993
  	perf_stat__set_big_num(!unset);
d7470b6af   Stephane Eranian   perf stat: Add cs...
994
995
  	return 0;
  }
44b1e60ab   Andi Kleen   perf stat: Basic ...
996
997
998
999
  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 '...
1000
  	stat_config.metric_only = !unset;
44b1e60ab   Andi Kleen   perf stat: Basic ...
1001
1002
  	return 0;
  }
b18f3e365   Andi Kleen   perf stat: Suppor...
1003
1004
1005
1006
  static int parse_metric_groups(const struct option *opt,
  			       const char *str,
  			       int unset __maybe_unused)
  {
05530a792   Ian Rogers   perf metricgroup:...
1007
1008
1009
1010
  	return metricgroup__parse_groups(opt, str,
  					 stat_config.metric_no_group,
  					 stat_config.metric_no_merge,
  					 &stat_config.metric_events);
b18f3e365   Andi Kleen   perf stat: Suppor...
1011
  }
27e9769aa   Alexey Budankov   perf stat: Introd...
1012
1013
1014
1015
  static int parse_control_option(const struct option *opt,
  				const char *str,
  				int unset __maybe_unused)
  {
9864a66de   Adrian Hunter   perf tools: Conso...
1016
  	struct perf_stat_config *config = opt->value;
27e9769aa   Alexey Budankov   perf stat: Introd...
1017

a8fcbd269   Adrian Hunter   perf tools: Add F...
1018
1019
  	return evlist__parse_control(str, &config->ctl_fd, &config->ctl_fd_ack, &config->ctl_fd_close);
  }
d1c5a0e86   Namhyung Kim   perf stat: Add --...
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
  static int parse_stat_cgroups(const struct option *opt,
  			      const char *str, int unset)
  {
  	if (stat_config.cgroup_list) {
  		pr_err("--cgroup and --for-each-cgroup cannot be used together
  ");
  		return -1;
  	}
  
  	return parse_cgroups(opt, str, unset);
  }
51433ead1   Michael Petlan   perf stat: Avoid ...
1031
  static struct option stat_options[] = {
e05473111   Jiri Olsa   perf stat: Make s...
1032
1033
1034
1035
1036
1037
1038
  	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 '...
1039
  	OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit,
e05473111   Jiri Olsa   perf stat: Make s...
1040
1041
1042
1043
1044
1045
1046
1047
1048
  		    "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 --...
1049
1050
  	OPT_BOOLEAN(0, "scale", &stat_config.scale,
  		    "Use --no-scale to disable counter scaling for multiplexing"),
e05473111   Jiri Olsa   perf stat: Make s...
1051
1052
  	OPT_INCR('v', "verbose", &verbose,
  		    "be more verbose (show counter open errors, etc)"),
d97ae04b3   Jiri Olsa   perf stat: Move '...
1053
  	OPT_INTEGER('r', "repeat", &stat_config.run_count,
e05473111   Jiri Olsa   perf stat: Make s...
1054
  		    "repeat command and print average + stddev (max: 100, forever: 0)"),
54ac0b1bd   Jiri Olsa   perf stat: Move '...
1055
  	OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table,
e55c14af4   Jiri Olsa   perf stat: Add --...
1056
  		    "display details about each run (only with -r option)"),
aea0dca16   Jiri Olsa   perf stat: Move '...
1057
  	OPT_BOOLEAN('n', "null", &stat_config.null_run,
e05473111   Jiri Olsa   perf stat: Make s...
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
  		    "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 '...
1070
  	OPT_BOOLEAN(0, "no-merge", &stat_config.no_merge, "Do not merge identical named events"),
fa7070a38   Jiri Olsa   perf stat: Move c...
1071
  	OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator",
e05473111   Jiri Olsa   perf stat: Make s...
1072
1073
  		   "print counts with custom separator"),
  	OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
d1c5a0e86   Namhyung Kim   perf stat: Add --...
1074
1075
1076
  		     "monitor event in cgroup name only", parse_stat_cgroups),
  	OPT_STRING(0, "for-each-cgroup", &stat_config.cgroup_list, "name",
  		    "expand events for each cgroup"),
e05473111   Jiri Olsa   perf stat: Make s...
1077
1078
1079
1080
1081
1082
1083
1084
1085
  	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...
1086
1087
  		    "print counts at regular interval in ms "
  		    "(overhead is possible for values <= 100ms)"),
db06a269e   yuzhoujian   perf stat: Add su...
1088
1089
  	OPT_INTEGER(0, "interval-count", &stat_config.times,
  		    "print counts for fixed number of times"),
132c6ba3c   Jiri Olsa   perf stat: Move '...
1090
  	OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear,
9660e08ee   Jiri Olsa   perf stat: Add --...
1091
  		    "clear screen in between new interval"),
f1f8ad52f   yuzhoujian   perf stat: Add su...
1092
1093
  	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...
1094
1095
  	OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
  		     "aggregate counts per processor socket", AGGR_SOCKET),
db5742b68   Kan Liang   perf stat: Suppor...
1096
1097
  	OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
  		     "aggregate counts per processor die", AGGR_DIE),
e05473111   Jiri Olsa   perf stat: Make s...
1098
1099
1100
1101
  	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),
86895b480   Jiri Olsa   perf stat: Add --...
1102
1103
  	OPT_SET_UINT(0, "per-node", &stat_config.aggr_mode,
  		     "aggregate counts per numa node", AGGR_NODE),
2162b9c6b   Alexey Budankov   perf stat: extend...
1104
1105
  	OPT_INTEGER('D', "delay", &stat_config.initial_delay,
  		    "ms to wait before starting measurement after program start (-1: start with events disabled)"),
0ce5aa026   Jiri Olsa   perf stat: Move '...
1106
  	OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
44b1e60ab   Andi Kleen   perf stat: Basic ...
1107
  			"Only print computed metrics. No raw values", enable_metric_only),
05530a792   Ian Rogers   perf metricgroup:...
1108
1109
1110
1111
  	OPT_BOOLEAN(0, "metric-no-group", &stat_config.metric_no_group,
  		       "don't group metric events, impacts multiplexing"),
  	OPT_BOOLEAN(0, "metric-no-merge", &stat_config.metric_no_merge,
  		       "don't try to share events between metrics in a group"),
44b1e60ab   Andi Kleen   perf stat: Basic ...
1112
1113
  	OPT_BOOLEAN(0, "topdown", &topdown_run,
  			"measure topdown level 1 statistics"),
daefd0bc0   Kan Liang   perf stat: Add su...
1114
1115
  	OPT_BOOLEAN(0, "smi-cost", &smi_cost,
  			"measure SMI cost"),
b18f3e365   Andi Kleen   perf stat: Suppor...
1116
1117
1118
  	OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list",
  		     "monitor specified metrics or metric groups (separated by ,)",
  		     parse_metric_groups),
dd071024b   Jin Yao   perf stat: Suppor...
1119
1120
1121
1122
1123
1124
  	OPT_BOOLEAN_FLAG(0, "all-kernel", &stat_config.all_kernel,
  			 "Configure all used events to run in kernel space.",
  			 PARSE_OPT_EXCLUSIVE),
  	OPT_BOOLEAN_FLAG(0, "all-user", &stat_config.all_user,
  			 "Configure all used events to run in user space.",
  			 PARSE_OPT_EXCLUSIVE),
1af62ce61   Jin Yao   perf stat: Show p...
1125
1126
1127
1128
  	OPT_BOOLEAN(0, "percore-show-thread", &stat_config.percore_show_thread,
  		    "Use with 'percore' event qualifier to show the event "
  		    "counts of one hardware thread by sum up total hardware "
  		    "threads of same physical core"),
ee6a96143   Jin Yao   perf stat: Turn o...
1129
1130
  	OPT_BOOLEAN(0, "summary", &stat_config.summary,
  		       "print summary for interval mode"),
709434907   Stephane Eranian   perf tools: Add o...
1131
1132
1133
1134
1135
  #ifdef HAVE_LIBPFM
  	OPT_CALLBACK(0, "pfm-events", &evsel_list, "event",
  		"libpfm4 event selector. use 'perf list' to list available events",
  		parse_libpfm_events_option),
  #endif
a8fcbd269   Adrian Hunter   perf tools: Add F...
1136
  	OPT_CALLBACK(0, "control", &stat_config, "fd:ctl-fd[,ack-fd] or fifo:ctl-fifo[,ack-fifo]",
27e9769aa   Alexey Budankov   perf stat: Introd...
1137
1138
  		     "Listen on ctl-fd descriptor for command to control measurement ('enable': enable events, 'disable': disable events).
  "
a8fcbd269   Adrian Hunter   perf tools: Add F...
1139
1140
1141
1142
  		     "\t\t\t  Optionally send control command completion ('ack\
  ') to ack-fd descriptor.
  "
  		     "\t\t\t  Alternatively, ctl-fifo / ack-fifo will be opened and used as ctl-fd / ack-fd.",
27e9769aa   Alexey Budankov   perf stat: Introd...
1143
  		      parse_control_option),
e05473111   Jiri Olsa   perf stat: Make s...
1144
1145
  	OPT_END()
  };
6f6b6594b   Jiri Olsa   perf stat: Move *...
1146
  static int perf_stat__get_socket(struct perf_stat_config *config __maybe_unused,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1147
  				 struct perf_cpu_map *map, int cpu)
1fe7a3002   Jiri Olsa   perf cpu_map: Add...
1148
1149
1150
  {
  	return cpu_map__get_socket(map, cpu, NULL);
  }
db5742b68   Kan Liang   perf stat: Suppor...
1151
  static int perf_stat__get_die(struct perf_stat_config *config __maybe_unused,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1152
  			      struct perf_cpu_map *map, int cpu)
db5742b68   Kan Liang   perf stat: Suppor...
1153
1154
1155
  {
  	return cpu_map__get_die(map, cpu, NULL);
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
1156
  static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1157
  			       struct perf_cpu_map *map, int cpu)
1fe7a3002   Jiri Olsa   perf cpu_map: Add...
1158
1159
1160
  {
  	return cpu_map__get_core(map, cpu, NULL);
  }
86895b480   Jiri Olsa   perf stat: Add --...
1161
1162
1163
1164
1165
  static int perf_stat__get_node(struct perf_stat_config *config __maybe_unused,
  			       struct perf_cpu_map *map, int cpu)
  {
  	return cpu_map__get_node(map, cpu, NULL);
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
1166
  static int perf_stat__get_aggr(struct perf_stat_config *config,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1167
  			       aggr_get_id_t get_id, struct perf_cpu_map *map, int idx)
1e5a29318   Jiri Olsa   perf stat: Cache ...
1168
1169
1170
1171
1172
1173
1174
  {
  	int cpu;
  
  	if (idx >= map->nr)
  		return -1;
  
  	cpu = map->map[idx];
6f6b6594b   Jiri Olsa   perf stat: Move *...
1175
1176
  	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 ...
1177

6f6b6594b   Jiri Olsa   perf stat: Move *...
1178
  	return config->cpus_aggr_map->map[cpu];
1e5a29318   Jiri Olsa   perf stat: Cache ...
1179
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
1180
  static int perf_stat__get_socket_cached(struct perf_stat_config *config,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1181
  					struct perf_cpu_map *map, int idx)
1e5a29318   Jiri Olsa   perf stat: Cache ...
1182
  {
6f6b6594b   Jiri Olsa   perf stat: Move *...
1183
  	return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx);
1e5a29318   Jiri Olsa   perf stat: Cache ...
1184
  }
db5742b68   Kan Liang   perf stat: Suppor...
1185
  static int perf_stat__get_die_cached(struct perf_stat_config *config,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1186
  					struct perf_cpu_map *map, int idx)
db5742b68   Kan Liang   perf stat: Suppor...
1187
1188
1189
  {
  	return perf_stat__get_aggr(config, perf_stat__get_die, map, idx);
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
1190
  static int perf_stat__get_core_cached(struct perf_stat_config *config,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1191
  				      struct perf_cpu_map *map, int idx)
1e5a29318   Jiri Olsa   perf stat: Cache ...
1192
  {
6f6b6594b   Jiri Olsa   perf stat: Move *...
1193
  	return perf_stat__get_aggr(config, perf_stat__get_core, map, idx);
1e5a29318   Jiri Olsa   perf stat: Cache ...
1194
  }
86895b480   Jiri Olsa   perf stat: Add --...
1195
1196
1197
1198
1199
  static int perf_stat__get_node_cached(struct perf_stat_config *config,
  				      struct perf_cpu_map *map, int idx)
  {
  	return perf_stat__get_aggr(config, perf_stat__get_node, map, idx);
  }
4fc4d8dfa   Jin Yao   perf stat: Suppor...
1200
1201
  static bool term_percore_set(void)
  {
32dcd021d   Jiri Olsa   perf evsel: Renam...
1202
  	struct evsel *counter;
4fc4d8dfa   Jin Yao   perf stat: Suppor...
1203
1204
1205
1206
1207
1208
1209
1210
  
  	evlist__for_each_entry(evsel_list, counter) {
  		if (counter->percore)
  			return true;
  	}
  
  	return false;
  }
86ee6e18f   Stephane Eranian   perf stat: Refact...
1211
1212
  static int perf_stat_init_aggr_mode(void)
  {
1e5a29318   Jiri Olsa   perf stat: Cache ...
1213
  	int nr;
421a50f3f   Jiri Olsa   perf stat: Introd...
1214
  	switch (stat_config.aggr_mode) {
86ee6e18f   Stephane Eranian   perf stat: Refact...
1215
  	case AGGR_SOCKET:
f72f901d9   Jiri Olsa   libperf: Add cpus...
1216
  		if (cpu_map__build_socket_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
86ee6e18f   Stephane Eranian   perf stat: Refact...
1217
1218
1219
  			perror("cannot build socket map");
  			return -1;
  		}
6f6b6594b   Jiri Olsa   perf stat: Move *...
1220
  		stat_config.aggr_get_id = perf_stat__get_socket_cached;
86ee6e18f   Stephane Eranian   perf stat: Refact...
1221
  		break;
db5742b68   Kan Liang   perf stat: Suppor...
1222
  	case AGGR_DIE:
f72f901d9   Jiri Olsa   libperf: Add cpus...
1223
  		if (cpu_map__build_die_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
db5742b68   Kan Liang   perf stat: Suppor...
1224
1225
1226
1227
1228
  			perror("cannot build die map");
  			return -1;
  		}
  		stat_config.aggr_get_id = perf_stat__get_die_cached;
  		break;
12c08a9f5   Stephane Eranian   perf stat: Add pe...
1229
  	case AGGR_CORE:
f72f901d9   Jiri Olsa   libperf: Add cpus...
1230
  		if (cpu_map__build_core_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
12c08a9f5   Stephane Eranian   perf stat: Add pe...
1231
1232
1233
  			perror("cannot build core map");
  			return -1;
  		}
6f6b6594b   Jiri Olsa   perf stat: Move *...
1234
  		stat_config.aggr_get_id = perf_stat__get_core_cached;
12c08a9f5   Stephane Eranian   perf stat: Add pe...
1235
  		break;
86895b480   Jiri Olsa   perf stat: Add --...
1236
1237
1238
1239
1240
1241
1242
  	case AGGR_NODE:
  		if (cpu_map__build_node_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
  			perror("cannot build core map");
  			return -1;
  		}
  		stat_config.aggr_get_id = perf_stat__get_node_cached;
  		break;
86ee6e18f   Stephane Eranian   perf stat: Refact...
1243
  	case AGGR_NONE:
4fc4d8dfa   Jin Yao   perf stat: Suppor...
1244
  		if (term_percore_set()) {
f72f901d9   Jiri Olsa   libperf: Add cpus...
1245
  			if (cpu_map__build_core_map(evsel_list->core.cpus,
4fc4d8dfa   Jin Yao   perf stat: Suppor...
1246
1247
1248
1249
1250
1251
1252
  						    &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...
1253
  	case AGGR_GLOBAL:
32b8af82e   Jiri Olsa   perf stat: Introd...
1254
  	case AGGR_THREAD:
208df99ed   Jiri Olsa   perf stat: Add AG...
1255
  	case AGGR_UNSET:
86ee6e18f   Stephane Eranian   perf stat: Refact...
1256
1257
1258
  	default:
  		break;
  	}
1e5a29318   Jiri Olsa   perf stat: Cache ...
1259
1260
1261
1262
1263
1264
  
  	/*
  	 * The evsel_list->cpus is the base we operate on,
  	 * taking the highest cpu number to be the size of
  	 * the aggregation translate cpumap.
  	 */
4256d4349   Jiri Olsa   libperf: Adopt pe...
1265
  	nr = perf_cpu_map__max(evsel_list->core.cpus);
315c0a1f0   Jiri Olsa   libperf: Move per...
1266
  	stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1);
6f6b6594b   Jiri Olsa   perf stat: Move *...
1267
  	return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
86ee6e18f   Stephane Eranian   perf stat: Refact...
1268
  }
544c2ae7b   Masami Hiramatsu   perf stat: Fix cm...
1269
1270
  static void perf_stat__exit_aggr_mode(void)
  {
38f01d8da   Jiri Olsa   libperf: Add perf...
1271
1272
  	perf_cpu_map__put(stat_config.aggr_map);
  	perf_cpu_map__put(stat_config.cpus_aggr_map);
6f6b6594b   Jiri Olsa   perf stat: Move *...
1273
1274
  	stat_config.aggr_map = NULL;
  	stat_config.cpus_aggr_map = NULL;
544c2ae7b   Masami Hiramatsu   perf stat: Fix cm...
1275
  }
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1276
  static inline int perf_env__get_cpu(struct perf_env *env, struct perf_cpu_map *map, int idx)
68d702f7a   Jiri Olsa   perf stat report:...
1277
1278
1279
1280
1281
1282
1283
  {
  	int cpu;
  
  	if (idx > map->nr)
  		return -1;
  
  	cpu = map->map[idx];
da8a58b56   Jan Stancek   perf tools: Repla...
1284
  	if (cpu >= env->nr_cpus_avail)
68d702f7a   Jiri Olsa   perf stat report:...
1285
1286
1287
1288
  		return -1;
  
  	return cpu;
  }
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1289
  static int perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data)
68d702f7a   Jiri Olsa   perf stat report:...
1290
1291
1292
1293
1294
1295
  {
  	struct perf_env *env = data;
  	int cpu = perf_env__get_cpu(env, map, idx);
  
  	return cpu == -1 ? -1 : env->cpu[cpu].socket_id;
  }
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1296
  static int perf_env__get_die(struct perf_cpu_map *map, int idx, void *data)
db5742b68   Kan Liang   perf stat: Suppor...
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
  {
  	struct perf_env *env = data;
  	int die_id = -1, cpu = perf_env__get_cpu(env, map, idx);
  
  	if (cpu != -1) {
  		/*
  		 * Encode socket in bit range 15:8
  		 * die_id is relative to socket,
  		 * we need a global id. So we combine
  		 * socket + die id
  		 */
  		if (WARN_ONCE(env->cpu[cpu].socket_id >> 8, "The socket id number is too big.
  "))
  			return -1;
  
  		if (WARN_ONCE(env->cpu[cpu].die_id >> 8, "The die id number is too big.
  "))
  			return -1;
  
  		die_id = (env->cpu[cpu].socket_id << 8) | (env->cpu[cpu].die_id & 0xff);
  	}
  
  	return die_id;
  }
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1321
  static int perf_env__get_core(struct perf_cpu_map *map, int idx, void *data)
68d702f7a   Jiri Olsa   perf stat report:...
1322
1323
1324
1325
1326
  {
  	struct perf_env *env = data;
  	int core = -1, cpu = perf_env__get_cpu(env, map, idx);
  
  	if (cpu != -1) {
68d702f7a   Jiri Olsa   perf stat report:...
1327
  		/*
db5742b68   Kan Liang   perf stat: Suppor...
1328
1329
1330
  		 * Encode socket in bit range 31:24
  		 * encode die id in bit range 23:16
  		 * core_id is relative to socket and die,
68d702f7a   Jiri Olsa   perf stat report:...
1331
  		 * we need a global id. So we combine
db5742b68   Kan Liang   perf stat: Suppor...
1332
  		 * socket + die id + core id
68d702f7a   Jiri Olsa   perf stat report:...
1333
  		 */
db5742b68   Kan Liang   perf stat: Suppor...
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
  		if (WARN_ONCE(env->cpu[cpu].socket_id >> 8, "The socket id number is too big.
  "))
  			return -1;
  
  		if (WARN_ONCE(env->cpu[cpu].die_id >> 8, "The die id number is too big.
  "))
  			return -1;
  
  		if (WARN_ONCE(env->cpu[cpu].core_id >> 16, "The core id number is too big.
  "))
  			return -1;
  
  		core = (env->cpu[cpu].socket_id << 24) |
  		       (env->cpu[cpu].die_id << 16) |
  		       (env->cpu[cpu].core_id & 0xffff);
68d702f7a   Jiri Olsa   perf stat report:...
1349
1350
1351
1352
  	}
  
  	return core;
  }
86895b480   Jiri Olsa   perf stat: Add --...
1353
1354
1355
1356
1357
1358
  static int perf_env__get_node(struct perf_cpu_map *map, int idx, void *data)
  {
  	int cpu = perf_env__get_cpu(data, map, idx);
  
  	return perf_env__numa_node(data, cpu);
  }
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1359
1360
  static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
  				      struct perf_cpu_map **sockp)
68d702f7a   Jiri Olsa   perf stat report:...
1361
1362
1363
  {
  	return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
  }
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1364
1365
  static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus,
  				   struct perf_cpu_map **diep)
db5742b68   Kan Liang   perf stat: Suppor...
1366
1367
1368
  {
  	return cpu_map__build_map(cpus, diep, perf_env__get_die, env);
  }
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1369
1370
  static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus,
  				    struct perf_cpu_map **corep)
68d702f7a   Jiri Olsa   perf stat report:...
1371
1372
1373
  {
  	return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
  }
86895b480   Jiri Olsa   perf stat: Add --...
1374
1375
1376
1377
1378
  static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *cpus,
  				    struct perf_cpu_map **nodep)
  {
  	return cpu_map__build_map(cpus, nodep, perf_env__get_node, env);
  }
6f6b6594b   Jiri Olsa   perf stat: Move *...
1379
  static int perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1380
  				      struct perf_cpu_map *map, int idx)
68d702f7a   Jiri Olsa   perf stat report:...
1381
1382
1383
  {
  	return perf_env__get_socket(map, idx, &perf_stat.session->header.env);
  }
db5742b68   Kan Liang   perf stat: Suppor...
1384
  static int perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1385
  				   struct perf_cpu_map *map, int idx)
db5742b68   Kan Liang   perf stat: Suppor...
1386
1387
1388
  {
  	return perf_env__get_die(map, idx, &perf_stat.session->header.env);
  }
68d702f7a   Jiri Olsa   perf stat report:...
1389

6f6b6594b   Jiri Olsa   perf stat: Move *...
1390
  static int perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused,
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1391
  				    struct perf_cpu_map *map, int idx)
68d702f7a   Jiri Olsa   perf stat report:...
1392
1393
1394
  {
  	return perf_env__get_core(map, idx, &perf_stat.session->header.env);
  }
86895b480   Jiri Olsa   perf stat: Add --...
1395
1396
1397
1398
1399
  static int perf_stat__get_node_file(struct perf_stat_config *config __maybe_unused,
  				    struct perf_cpu_map *map, int idx)
  {
  	return perf_env__get_node(map, idx, &perf_stat.session->header.env);
  }
68d702f7a   Jiri Olsa   perf stat report:...
1400
1401
1402
1403
1404
1405
  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:
f72f901d9   Jiri Olsa   libperf: Add cpus...
1406
  		if (perf_env__build_socket_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
68d702f7a   Jiri Olsa   perf stat report:...
1407
1408
1409
  			perror("cannot build socket map");
  			return -1;
  		}
6f6b6594b   Jiri Olsa   perf stat: Move *...
1410
  		stat_config.aggr_get_id = perf_stat__get_socket_file;
68d702f7a   Jiri Olsa   perf stat report:...
1411
  		break;
db5742b68   Kan Liang   perf stat: Suppor...
1412
  	case AGGR_DIE:
f72f901d9   Jiri Olsa   libperf: Add cpus...
1413
  		if (perf_env__build_die_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
db5742b68   Kan Liang   perf stat: Suppor...
1414
1415
1416
1417
1418
  			perror("cannot build die map");
  			return -1;
  		}
  		stat_config.aggr_get_id = perf_stat__get_die_file;
  		break;
68d702f7a   Jiri Olsa   perf stat report:...
1419
  	case AGGR_CORE:
f72f901d9   Jiri Olsa   libperf: Add cpus...
1420
  		if (perf_env__build_core_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
68d702f7a   Jiri Olsa   perf stat report:...
1421
1422
1423
  			perror("cannot build core map");
  			return -1;
  		}
6f6b6594b   Jiri Olsa   perf stat: Move *...
1424
  		stat_config.aggr_get_id = perf_stat__get_core_file;
68d702f7a   Jiri Olsa   perf stat report:...
1425
  		break;
86895b480   Jiri Olsa   perf stat: Add --...
1426
1427
1428
1429
1430
1431
1432
  	case AGGR_NODE:
  		if (perf_env__build_node_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
  			perror("cannot build core map");
  			return -1;
  		}
  		stat_config.aggr_get_id = perf_stat__get_node_file;
  		break;
68d702f7a   Jiri Olsa   perf stat report:...
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
  	case AGGR_NONE:
  	case AGGR_GLOBAL:
  	case AGGR_THREAD:
  	case AGGR_UNSET:
  	default:
  		break;
  	}
  
  	return 0;
  }
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1443
1444
1445
1446
1447
1448
  /*
   * 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 ...
1449
  	int err;
9dec4473a   Andi Kleen   perf stat: Check ...
1450
  	struct perf_event_attr default_attrs0[] = {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1451
1452
1453
1454
1455
1456
1457
  
    { .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 ...
1458
1459
  };
  	struct perf_event_attr frontend_attrs[] = {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1460
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND	},
9dec4473a   Andi Kleen   perf stat: Check ...
1461
1462
  };
  	struct perf_event_attr backend_attrs[] = {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1463
    { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND	},
9dec4473a   Andi Kleen   perf stat: Check ...
1464
1465
  };
  	struct perf_event_attr default_attrs1[] = {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
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
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
    { .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...
1562
  	struct parse_events_error errinfo;
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1563

2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1564
  	/* Set attrs if no event is selected and !null_run: */
aea0dca16   Jiri Olsa   perf stat: Move '...
1565
  	if (stat_config.null_run)
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1566
  		return 0;
a910e4666   Ian Rogers   perf parse: Repor...
1567
  	bzero(&errinfo, sizeof(errinfo));
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1568
  	if (transaction_run) {
742d92ff2   Thomas Richter   perf stat: Add tr...
1569
1570
1571
1572
1573
1574
1575
1576
1577
  		/* 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",
05530a792   Ian Rogers   perf metricgroup:...
1578
1579
  							 stat_config.metric_no_group,
  							stat_config.metric_no_merge,
d0192fdba   Jiri Olsa   perf stat: Move '...
1580
  							 &stat_config.metric_events);
742d92ff2   Thomas Richter   perf stat: Add tr...
1581
  		}
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1582
1583
  		if (pmu_have_event("cpu", "cycles-ct") &&
  		    pmu_have_event("cpu", "el-start"))
fca32340a   Thomas Richter   perf stat: Fix co...
1584
1585
  			err = parse_events(evsel_list, transaction_attrs,
  					   &errinfo);
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1586
  		else
fca32340a   Thomas Richter   perf stat: Fix co...
1587
1588
1589
  			err = parse_events(evsel_list,
  					   transaction_limited_attrs,
  					   &errinfo);
a454742c1   Jiri Olsa   perf stat: Remove...
1590
  		if (err) {
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1591
1592
  			fprintf(stderr, "Cannot set up transaction events
  ");
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1593
  			parse_events_print_error(&errinfo, transaction_attrs);
4cabc3d1c   Andi Kleen   tools/perf/stat: ...
1594
1595
1596
1597
  			return -1;
  		}
  		return 0;
  	}
daefd0bc0   Kan Liang   perf stat: Add su...
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
  	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 '...
1619
  				stat_config.metric_only = true;
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1620
  			err = parse_events(evsel_list, smi_cost_attrs, &errinfo);
daefd0bc0   Kan Liang   perf stat: Add su...
1621
1622
1623
1624
  		} else {
  			fprintf(stderr, "To measure SMI cost, it needs "
  				"msr/aperf/, msr/smi/ and cpu/cycles/ support
  ");
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1625
  			parse_events_print_error(&errinfo, smi_cost_attrs);
daefd0bc0   Kan Liang   perf stat: Add su...
1626
1627
1628
  			return -1;
  		}
  		if (err) {
a910e4666   Ian Rogers   perf parse: Repor...
1629
  			parse_events_print_error(&errinfo, smi_cost_attrs);
daefd0bc0   Kan Liang   perf stat: Add su...
1630
1631
1632
1633
1634
1635
  			fprintf(stderr, "Cannot set up SMI cost events
  ");
  			return -1;
  		}
  		return 0;
  	}
44b1e60ab   Andi Kleen   perf stat: Basic ...
1636
1637
1638
  	if (topdown_run) {
  		char *str = NULL;
  		bool warn = false;
55c36a9fc   Andi Kleen   perf stat: Suppor...
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
  		if (!force_metric_only)
  			stat_config.metric_only = true;
  
  		if (topdown_filter_events(topdown_metric_attrs, &str, 1) < 0) {
  			pr_err("Out of memory
  ");
  			return -1;
  		}
  		if (topdown_metric_attrs[0] && str) {
  			if (!stat_config.interval && !stat_config.metric_only) {
  				fprintf(stat_config.output,
  					"Topdown accuracy may decrease when measuring long periods.
  "
  					"Please print the result regularly, e.g. -I1000
  ");
  			}
  			goto setup_metrics;
  		}
  
  		zfree(&str);
44b1e60ab   Andi Kleen   perf stat: Basic ...
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
  		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;
  		}
44b1e60ab   Andi Kleen   perf stat: Basic ...
1671
1672
1673
1674
1675
1676
1677
1678
1679
  		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();
55c36a9fc   Andi Kleen   perf stat: Suppor...
1680
  setup_metrics:
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1681
  			err = parse_events(evsel_list, str, &errinfo);
44b1e60ab   Andi Kleen   perf stat: Basic ...
1682
1683
1684
1685
1686
  			if (err) {
  				fprintf(stderr,
  					"Cannot set up top down events %s: %d
  ",
  					str, err);
a5cfa6217   Jiri Olsa   perf stat: Add ev...
1687
  				parse_events_print_error(&errinfo, str);
c74b05030   Leo Yan   perf stat: Fix us...
1688
  				free(str);
44b1e60ab   Andi Kleen   perf stat: Basic ...
1689
1690
1691
1692
1693
1694
1695
1696
1697
  				return -1;
  			}
  		} else {
  			fprintf(stderr, "System does not support topdown
  ");
  			return -1;
  		}
  		free(str);
  	}
6484d2f9d   Jiri Olsa   libperf: Add nr_e...
1698
  	if (!evsel_list->core.nr_entries) {
a1f3d5676   Namhyung Kim   perf stat: Use cp...
1699
1700
  		if (target__has_cpu(&target))
  			default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
e251abee8   Arnaldo Carvalho de Melo   perf evlist: Fix ...
1701
  		if (evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
9dec4473a   Andi Kleen   perf stat: Check ...
1702
1703
  			return -1;
  		if (pmu_have_event("cpu", "stalled-cycles-frontend")) {
e251abee8   Arnaldo Carvalho de Melo   perf evlist: Fix ...
1704
  			if (evlist__add_default_attrs(evsel_list, frontend_attrs) < 0)
9dec4473a   Andi Kleen   perf stat: Check ...
1705
1706
1707
  				return -1;
  		}
  		if (pmu_have_event("cpu", "stalled-cycles-backend")) {
e251abee8   Arnaldo Carvalho de Melo   perf evlist: Fix ...
1708
  			if (evlist__add_default_attrs(evsel_list, backend_attrs) < 0)
9dec4473a   Andi Kleen   perf stat: Check ...
1709
1710
  				return -1;
  		}
e251abee8   Arnaldo Carvalho de Melo   perf evlist: Fix ...
1711
  		if (evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1712
  			return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1713
1714
1715
1716
1717
1718
1719
1720
  	}
  
  	/* Detailed events get appended to the event list: */
  
  	if (detailed_run <  1)
  		return 0;
  
  	/* Append detailed run extra attributes: */
e251abee8   Arnaldo Carvalho de Melo   perf evlist: Fix ...
1721
  	if (evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1722
  		return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1723
1724
1725
1726
1727
  
  	if (detailed_run < 2)
  		return 0;
  
  	/* Append very detailed run extra attributes: */
e251abee8   Arnaldo Carvalho de Melo   perf evlist: Fix ...
1728
  	if (evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
50d08e47b   Arnaldo Carvalho de Melo   perf evlist: Intr...
1729
  		return -1;
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1730
1731
1732
1733
1734
  
  	if (detailed_run < 3)
  		return 0;
  
  	/* Append very, very detailed run extra attributes: */
e251abee8   Arnaldo Carvalho de Melo   perf evlist: Fix ...
1735
  	return evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
1736
  }
8a59f3ccb   Jiri Olsa   perf stat: Fix re...
1737
  static const char * const stat_record_usage[] = {
4979d0c7d   Jiri Olsa   perf stat record:...
1738
1739
1740
  	"perf stat record [<options>]",
  	NULL,
  };
3ba78bd00   Jiri Olsa   perf stat record:...
1741
1742
1743
1744
1745
1746
  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...
1747
  	perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
3ba78bd00   Jiri Olsa   perf stat record:...
1748
1749
1750
1751
1752
  	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:...
1753
1754
1755
  static int __cmd_record(int argc, const char **argv)
  {
  	struct perf_session *session;
8ceb41d7e   Jiri Olsa   perf tools: Renam...
1756
  	struct perf_data *data = &perf_stat.data;
4979d0c7d   Jiri Olsa   perf stat record:...
1757

8a59f3ccb   Jiri Olsa   perf stat: Fix re...
1758
  	argc = parse_options(argc, argv, stat_options, stat_record_usage,
4979d0c7d   Jiri Olsa   perf stat record:...
1759
1760
1761
  			     PARSE_OPT_STOP_AT_NON_OPTION);
  
  	if (output_name)
2d4f27999   Jiri Olsa   perf data: Add gl...
1762
  		data->path = output_name;
4979d0c7d   Jiri Olsa   perf stat record:...
1763

d97ae04b3   Jiri Olsa   perf stat: Move '...
1764
  	if (stat_config.run_count != 1 || forever) {
e9d6db8e8   Jiri Olsa   perf stat record:...
1765
1766
1767
1768
  		pr_err("Cannot use -r option with perf stat record.
  ");
  		return -1;
  	}
8ceb41d7e   Jiri Olsa   perf tools: Renam...
1769
  	session = perf_session__new(data, false, NULL);
6ef81c55a   Mamatha Inamdar   perf session: Ret...
1770
1771
1772
1773
  	if (IS_ERR(session)) {
  		pr_err("Perf session creation failed
  ");
  		return PTR_ERR(session);
4979d0c7d   Jiri Olsa   perf stat record:...
1774
  	}
3ba78bd00   Jiri Olsa   perf stat record:...
1775
  	init_features(session);
4979d0c7d   Jiri Olsa   perf stat record:...
1776
1777
1778
1779
1780
  	session->evlist   = evsel_list;
  	perf_stat.session = session;
  	perf_stat.record  = true;
  	return argc;
  }
89f1688a5   Jiri Olsa   perf tools: Remov...
1781
1782
  static int process_stat_round_event(struct perf_session *session,
  				    union perf_event *event)
a56f9390a   Jiri Olsa   perf stat report:...
1783
  {
72932371e   Jiri Olsa   libperf: Rename t...
1784
  	struct perf_record_stat_round *stat_round = &event->stat_round;
32dcd021d   Jiri Olsa   perf evsel: Renam...
1785
  	struct evsel *counter;
a56f9390a   Jiri Olsa   perf stat report:...
1786
1787
1788
  	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...
1789
  	evlist__for_each_entry(evsel_list, counter)
a56f9390a   Jiri Olsa   perf stat report:...
1790
  		perf_stat_process_counter(&stat_config, counter);
e3b03b6c1   Andi Kleen   perf stat: Avoid ...
1791
1792
  	if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
  		update_stats(&walltime_nsecs_stats, stat_round->time);
a56f9390a   Jiri Olsa   perf stat report:...
1793

e3b03b6c1   Andi Kleen   perf stat: Avoid ...
1794
  	if (stat_config.interval && stat_round->time) {
bd48c63eb   Arnaldo Carvalho de Melo   tools: Introduce ...
1795
1796
  		tsh.tv_sec  = stat_round->time / NSEC_PER_SEC;
  		tsh.tv_nsec = stat_round->time % NSEC_PER_SEC;
a56f9390a   Jiri Olsa   perf stat report:...
1797
1798
1799
1800
1801
1802
  		ts = &tsh;
  	}
  
  	print_counters(ts, argc, argv);
  	return 0;
  }
62ba18ba9   Jiri Olsa   perf stat report:...
1803
  static
89f1688a5   Jiri Olsa   perf tools: Remov...
1804
1805
  int process_stat_config_event(struct perf_session *session,
  			      union perf_event *event)
62ba18ba9   Jiri Olsa   perf stat report:...
1806
  {
89f1688a5   Jiri Olsa   perf tools: Remov...
1807
  	struct perf_tool *tool = session->tool;
68d702f7a   Jiri Olsa   perf stat report:...
1808
  	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
62ba18ba9   Jiri Olsa   perf stat report:...
1809
  	perf_event__read_stat_config(&stat_config, &event->stat_config);
68d702f7a   Jiri Olsa   perf stat report:...
1810

315c0a1f0   Jiri Olsa   libperf: Move per...
1811
  	if (perf_cpu_map__empty(st->cpus)) {
89af4e05c   Jiri Olsa   perf stat report:...
1812
1813
1814
1815
1816
1817
1818
1819
  		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...
1820
  	if (perf_stat.data.is_pipe)
68d702f7a   Jiri Olsa   perf stat report:...
1821
1822
1823
  		perf_stat_init_aggr_mode();
  	else
  		perf_stat_init_aggr_mode_file(st);
62ba18ba9   Jiri Olsa   perf stat report:...
1824
1825
  	return 0;
  }
1975d36e1   Jiri Olsa   perf stat report:...
1826
1827
1828
1829
1830
1831
1832
1833
  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;
453fa0309   Jiri Olsa   libperf: Add perf...
1834
  	perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads);
1975d36e1   Jiri Olsa   perf stat report:...
1835
1836
1837
1838
1839
1840
1841
1842
1843
  
  	if (perf_evlist__alloc_stats(evsel_list, true))
  		return -ENOMEM;
  
  	st->maps_allocated = true;
  	return 0;
  }
  
  static
89f1688a5   Jiri Olsa   perf tools: Remov...
1844
1845
  int process_thread_map_event(struct perf_session *session,
  			     union perf_event *event)
1975d36e1   Jiri Olsa   perf stat report:...
1846
  {
89f1688a5   Jiri Olsa   perf tools: Remov...
1847
  	struct perf_tool *tool = session->tool;
1975d36e1   Jiri Olsa   perf stat report:...
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
  	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...
1864
1865
  int process_cpu_map_event(struct perf_session *session,
  			  union perf_event *event)
1975d36e1   Jiri Olsa   perf stat report:...
1866
  {
89f1688a5   Jiri Olsa   perf tools: Remov...
1867
  	struct perf_tool *tool = session->tool;
1975d36e1   Jiri Olsa   perf stat report:...
1868
  	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
f854839ba   Jiri Olsa   perf cpu_map: Ren...
1869
  	struct perf_cpu_map *cpus;
1975d36e1   Jiri Olsa   perf stat report:...
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
  
  	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);
  }
8a59f3ccb   Jiri Olsa   perf stat: Fix re...
1884
  static const char * const stat_report_usage[] = {
ba6039b6c   Jiri Olsa   perf stat report:...
1885
1886
1887
1888
1889
1890
1891
  	"perf stat report [<options>]",
  	NULL,
  };
  
  static struct perf_stat perf_stat = {
  	.tool = {
  		.attr		= perf_event__process_attr,
fa6ea7817   Jiri Olsa   perf stat report:...
1892
  		.event_update	= perf_event__process_event_update,
1975d36e1   Jiri Olsa   perf stat report:...
1893
1894
  		.thread_map	= process_thread_map_event,
  		.cpu_map	= process_cpu_map_event,
62ba18ba9   Jiri Olsa   perf stat report:...
1895
  		.stat_config	= process_stat_config_event,
a56f9390a   Jiri Olsa   perf stat report:...
1896
1897
  		.stat		= perf_event__process_stat_event,
  		.stat_round	= process_stat_round_event,
ba6039b6c   Jiri Olsa   perf stat report:...
1898
  	},
89af4e05c   Jiri Olsa   perf stat report:...
1899
  	.aggr_mode = AGGR_UNSET,
ba6039b6c   Jiri Olsa   perf stat report:...
1900
1901
1902
1903
1904
1905
1906
  };
  
  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:...
1907
1908
  	OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode,
  		     "aggregate counts per processor socket", AGGR_SOCKET),
db5742b68   Kan Liang   perf stat: Suppor...
1909
1910
  	OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode,
  		     "aggregate counts per processor die", AGGR_DIE),
89af4e05c   Jiri Olsa   perf stat report:...
1911
1912
  	OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode,
  		     "aggregate counts per physical processor core", AGGR_CORE),
86895b480   Jiri Olsa   perf stat: Add --...
1913
1914
  	OPT_SET_UINT(0, "per-node", &perf_stat.aggr_mode,
  		     "aggregate counts per numa node", AGGR_NODE),
89af4e05c   Jiri Olsa   perf stat report:...
1915
1916
  	OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode,
  		     "disable CPU count aggregation", AGGR_NONE),
ba6039b6c   Jiri Olsa   perf stat report:...
1917
1918
1919
1920
  	OPT_END()
  	};
  	struct stat st;
  	int ret;
8a59f3ccb   Jiri Olsa   perf stat: Fix re...
1921
  	argc = parse_options(argc, argv, options, stat_report_usage, 0);
ba6039b6c   Jiri Olsa   perf stat report:...
1922
1923
1924
1925
1926
1927
1928
  
  	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...
1929
1930
  	perf_stat.data.path = input_name;
  	perf_stat.data.mode = PERF_DATA_MODE_READ;
ba6039b6c   Jiri Olsa   perf stat report:...
1931

8ceb41d7e   Jiri Olsa   perf tools: Renam...
1932
  	session = perf_session__new(&perf_stat.data, false, &perf_stat.tool);
6ef81c55a   Mamatha Inamdar   perf session: Ret...
1933
1934
  	if (IS_ERR(session))
  		return PTR_ERR(session);
ba6039b6c   Jiri Olsa   perf stat report:...
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
  
  	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...
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
  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 {
32dcd021d   Jiri Olsa   perf evsel: Renam...
1964
  		struct evsel *counter;
e3ba76dee   Jiri Olsa   perf tools: Force...
1965
1966
  
  		evlist__for_each_entry(evsel_list, counter) {
002a3d690   Jin Yao   perf stat: Skip d...
1967
1968
  			if (!counter->core.system_wide &&
  			    strcmp(counter->name, "duration_time")) {
e3ba76dee   Jiri Olsa   perf tools: Force...
1969
  				return;
002a3d690   Jin Yao   perf stat: Skip d...
1970
  			}
e3ba76dee   Jiri Olsa   perf tools: Force...
1971
  		}
6484d2f9d   Jiri Olsa   libperf: Add nr_e...
1972
  		if (evsel_list->core.nr_entries)
e3ba76dee   Jiri Olsa   perf tools: Force...
1973
1974
1975
  			target.system_wide = true;
  	}
  }
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
1976
  int cmd_stat(int argc, const char **argv)
5242519b0   Ingo Molnar   perf stat: Conver...
1977
  {
b070a547f   Arnaldo Carvalho de Melo   perf stat: Don't ...
1978
1979
1980
1981
  	const char * const stat_usage[] = {
  		"perf stat [<options>] [<command>]",
  		NULL
  	};
cc03c5429   Namhyung Kim   perf stat: Enhanc...
1982
  	int status = -EINVAL, run_idx;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
1983
  	const char *mode;
5821522e9   Jiri Olsa   perf stat: Move '...
1984
  	FILE *output = stderr;
f1f8ad52f   yuzhoujian   perf stat: Add su...
1985
  	unsigned int interval, timeout;
ba6039b6c   Jiri Olsa   perf stat report:...
1986
  	const char * const stat_subcommands[] = { "record", "report" };
42202dd56   Ingo Molnar   perf stat: Add fe...
1987

5af52b51f   Stephane Eranian   perf stat: add pe...
1988
  	setlocale(LC_ALL, "");
0f98b11c6   Jiri Olsa   perf evlist: Rena...
1989
  	evsel_list = evlist__new();
361c99a66   Arnaldo Carvalho de Melo   perf evsel: Intro...
1990
1991
  	if (evsel_list == NULL)
  		return -ENOMEM;
1669e509e   Wang Nan   perf stat: Bail o...
1992
  	parse_events__shrink_config_terms();
51433ead1   Michael Petlan   perf stat: Avoid ...
1993
1994
1995
1996
1997
  
  	/* 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:...
1998
1999
2000
  	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...
2001
  	perf_stat__collect_metric_expr(evsel_list);
fb4605ba4   Andi Kleen   perf stat: Check ...
2002
  	perf_stat__init_shadow_stats();
4979d0c7d   Jiri Olsa   perf stat record:...
2003

fa7070a38   Jiri Olsa   perf stat: Move c...
2004
2005
2006
2007
  	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:...
2008
  	} else
fa7070a38   Jiri Olsa   perf stat: Move c...
2009
  		stat_config.csv_sep = DEFAULT_SEPARATOR;
6edb78a21   Jiri Olsa   perf stat report:...
2010

4979d0c7d   Jiri Olsa   perf stat record:...
2011
2012
2013
2014
  	if (argc && !strncmp(argv[0], "rec", 3)) {
  		argc = __cmd_record(argc, argv);
  		if (argc < 0)
  			return -1;
ba6039b6c   Jiri Olsa   perf stat report:...
2015
2016
  	} else if (argc && !strncmp(argv[0], "rep", 3))
  		return __cmd_report(argc, argv);
d7470b6af   Stephane Eranian   perf stat: Add cs...
2017

ec0d3d1fd   Jiri Olsa   perf stat: Move '...
2018
  	interval = stat_config.interval;
f1f8ad52f   yuzhoujian   perf stat: Add su...
2019
  	timeout = stat_config.timeout;
ec0d3d1fd   Jiri Olsa   perf stat: Move '...
2020

4979d0c7d   Jiri Olsa   perf stat record:...
2021
2022
2023
2024
  	/*
  	 * 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...
2025
  		output = NULL;
56f3bae70   Jim Cromie   perf stat: Add --...
2026
2027
2028
  	if (output_name && output_fd) {
  		fprintf(stderr, "cannot use both --output and --log-fd
  ");
e05473111   Jiri Olsa   perf stat: Make s...
2029
2030
  		parse_options_usage(stat_usage, stat_options, "o", 1);
  		parse_options_usage(NULL, stat_options, "log-fd", 0);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
2031
  		goto out;
56f3bae70   Jim Cromie   perf stat: Add --...
2032
  	}
fc3e4d077   Stephane Eranian   perf stat: Fix de...
2033

0ce5aa026   Jiri Olsa   perf stat: Move '...
2034
  	if (stat_config.metric_only && stat_config.aggr_mode == AGGR_THREAD) {
54b509160   Andi Kleen   perf stat: Implem...
2035
2036
2037
2038
  		fprintf(stderr, "--metric-only is not supported with --per-thread
  ");
  		goto out;
  	}
d97ae04b3   Jiri Olsa   perf stat: Move '...
2039
  	if (stat_config.metric_only && stat_config.run_count > 1) {
54b509160   Andi Kleen   perf stat: Implem...
2040
2041
2042
2043
  		fprintf(stderr, "--metric-only is not supported with -r
  ");
  		goto out;
  	}
54ac0b1bd   Jiri Olsa   perf stat: Move '...
2044
  	if (stat_config.walltime_run_table && stat_config.run_count <= 1) {
e55c14af4   Jiri Olsa   perf stat: Add --...
2045
2046
2047
2048
2049
2050
  		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...
2051
2052
2053
  	if (output_fd < 0) {
  		fprintf(stderr, "argument to --log-fd must be a > 0
  ");
e05473111   Jiri Olsa   perf stat: Make s...
2054
  		parse_options_usage(stat_usage, stat_options, "log-fd", 0);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
2055
  		goto out;
fc3e4d077   Stephane Eranian   perf stat: Fix de...
2056
  	}
4aa9015f8   Stephane Eranian   perf stat: Add -o...
2057
2058
2059
2060
2061
2062
2063
  	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...
2064
  			return -1;
4aa9015f8   Stephane Eranian   perf stat: Add -o...
2065
2066
2067
2068
  		}
  		clock_gettime(CLOCK_REALTIME, &tm);
  		fprintf(output, "# started on %s
  ", ctime(&tm.tv_sec));
fc3e4d077   Stephane Eranian   perf stat: Fix de...
2069
  	} else if (output_fd > 0) {
56f3bae70   Jim Cromie   perf stat: Add --...
2070
2071
2072
2073
2074
2075
  		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...
2076
  	}
5821522e9   Jiri Olsa   perf stat: Move '...
2077
  	stat_config.output = output;
d7470b6af   Stephane Eranian   perf stat: Add cs...
2078
2079
2080
  	/*
  	 * let the spreadsheet do the pretty-printing
  	 */
fa7070a38   Jiri Olsa   perf stat: Move c...
2081
  	if (stat_config.csv_output) {
61a9f3242   Jim Cromie   perf stat: Fix sp...
2082
  		/* User explicitly passed -B? */
d7470b6af   Stephane Eranian   perf stat: Add cs...
2083
2084
2085
  		if (big_num_opt == 1) {
  			fprintf(stderr, "-B option not supported with -x
  ");
e05473111   Jiri Olsa   perf stat: Make s...
2086
2087
  			parse_options_usage(stat_usage, stat_options, "B", 1);
  			parse_options_usage(NULL, stat_options, "x", 1);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
2088
  			goto out;
d7470b6af   Stephane Eranian   perf stat: Add cs...
2089
  		} else /* Nope, so disable big number formatting */
34ff0866d   Jiri Olsa   perf stat: Move '...
2090
  			stat_config.big_num = false;
d7470b6af   Stephane Eranian   perf stat: Add cs...
2091
  	} else if (big_num_opt == 0) /* User passed --no-big-num */
34ff0866d   Jiri Olsa   perf stat: Move '...
2092
  		stat_config.big_num = false;
d7470b6af   Stephane Eranian   perf stat: Add cs...
2093

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

0ce2da148   Jiri Olsa   perf stat: Displa...
2096
2097
2098
2099
  	/*
  	 * Display user/system times only for single
  	 * run and when there's specified tracee.
  	 */
d97ae04b3   Jiri Olsa   perf stat: Move '...
2100
  	if ((stat_config.run_count == 1) && target__none(&target))
8897a8916   Jiri Olsa   perf stat: Move r...
2101
  		stat_config.ru_display = true;
0ce2da148   Jiri Olsa   perf stat: Displa...
2102

d97ae04b3   Jiri Olsa   perf stat: Move '...
2103
  	if (stat_config.run_count < 0) {
cc03c5429   Namhyung Kim   perf stat: Enhanc...
2104
2105
  		pr_err("Run count must be a positive number
  ");
e05473111   Jiri Olsa   perf stat: Make s...
2106
  		parse_options_usage(stat_usage, stat_options, "r", 1);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
2107
  		goto out;
d97ae04b3   Jiri Olsa   perf stat: Move '...
2108
  	} else if (stat_config.run_count == 0) {
a7e191c37   Frederik Deweerdt   perf stat: Introd...
2109
  		forever = true;
d97ae04b3   Jiri Olsa   perf stat: Move '...
2110
  		stat_config.run_count = 1;
a7e191c37   Frederik Deweerdt   perf stat: Introd...
2111
  	}
ddcacfa0f   Ingo Molnar   perf_counter tool...
2112

54ac0b1bd   Jiri Olsa   perf stat: Move '...
2113
2114
2115
  	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 --...
2116
2117
2118
2119
  			pr_err("failed to setup -r option");
  			goto out;
  		}
  	}
1d9f8d1b8   Jin Yao   perf stat: Remove...
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
  	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...
2131
2132
2133
2134
2135
2136
  	}
  
  	/*
  	 * 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...
2137
2138
  	if (((stat_config.aggr_mode != AGGR_GLOBAL &&
  	      stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
602ad878d   Arnaldo Carvalho de Melo   perf target: Shor...
2139
  	    !target__has_cpu(&target)) {
023695d96   Stephane Eranian   perf tool: Add cg...
2140
2141
2142
  		fprintf(stderr, "both cgroup and no-aggregation "
  			"modes only available in system-wide mode
  ");
e05473111   Jiri Olsa   perf stat: Make s...
2143
2144
2145
  		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...
2146
  		goto out;
d7e7a451c   Stephane Eranian   perf stat: Add pe...
2147
  	}
2cba3ffb9   Ingo Molnar   perf stat: Add -d...
2148
2149
  	if (add_default_attributes())
  		goto out;
ddcacfa0f   Ingo Molnar   perf_counter tool...
2150

d1c5a0e86   Namhyung Kim   perf stat: Add --...
2151
2152
2153
2154
2155
2156
2157
2158
  	if (stat_config.cgroup_list) {
  		if (nr_cgroups > 0) {
  			pr_err("--cgroup and --for-each-cgroup cannot be used together
  ");
  			parse_options_usage(stat_usage, stat_options, "G", 1);
  			parse_options_usage(NULL, stat_options, "for-each-cgroup", 0);
  			goto out;
  		}
b214ba8c4   Namhyung Kim   perf tools: Copy ...
2159
  		if (evlist__expand_cgroup(evsel_list, stat_config.cgroup_list,
89fb1ca2a   Namhyung Kim   perf tools: Allow...
2160
  					  &stat_config.metric_events, true) < 0)
d1c5a0e86   Namhyung Kim   perf stat: Add --...
2161
2162
  			goto out;
  	}
602ad878d   Arnaldo Carvalho de Melo   perf target: Shor...
2163
  	target__validate(&target);
5c98d466e   Arnaldo Carvalho de Melo   perf tools: Refac...
2164

1d9f8d1b8   Jin Yao   perf stat: Remove...
2165
2166
  	if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide))
  		target.per_thread = true;
77a6f014e   Namhyung Kim   perf stat: Use pe...
2167
  	if (perf_evlist__create_maps(evsel_list, &target) < 0) {
602ad878d   Arnaldo Carvalho de Melo   perf target: Shor...
2168
  		if (target__has_task(&target)) {
77a6f014e   Namhyung Kim   perf stat: Use pe...
2169
2170
  			pr_err("Problems finding threads of monitor
  ");
e05473111   Jiri Olsa   perf stat: Make s...
2171
2172
  			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...
2173
  		} else if (target__has_cpu(&target)) {
77a6f014e   Namhyung Kim   perf stat: Use pe...
2174
  			perror("failed to parse CPUs map");
e05473111   Jiri Olsa   perf stat: Make s...
2175
2176
  			parse_options_usage(stat_usage, stat_options, "C", 1);
  			parse_options_usage(NULL, stat_options, "a", 1);
cc03c5429   Namhyung Kim   perf stat: Enhanc...
2177
2178
  		}
  		goto out;
60d567e2d   Arnaldo Carvalho de Melo   perf tools: Refac...
2179
  	}
32b8af82e   Jiri Olsa   perf stat: Introd...
2180

a9a179024   Jiri Olsa   perf stat: Ensure...
2181
  	evlist__check_cpu_maps(evsel_list);
32b8af82e   Jiri Olsa   perf stat: Introd...
2182
2183
2184
2185
  	/*
  	 * Initialize thread_map with comm names,
  	 * so we could print it out on output.
  	 */
56739444d   Jin Yao   perf stat: Alloca...
2186
  	if (stat_config.aggr_mode == AGGR_THREAD) {
03617c22e   Jiri Olsa   libperf: Add thre...
2187
  		thread_map__read_comms(evsel_list->core.threads);
56739444d   Jin Yao   perf stat: Alloca...
2188
2189
  		if (target.system_wide) {
  			if (runtime_stat_new(&stat_config,
a2f354e3a   Jiri Olsa   libperf: Add perf...
2190
  				perf_thread_map__nr(evsel_list->core.threads))) {
56739444d   Jin Yao   perf stat: Alloca...
2191
2192
2193
2194
  				goto out;
  			}
  		}
  	}
32b8af82e   Jiri Olsa   perf stat: Introd...
2195

86895b480   Jiri Olsa   perf stat: Add --...
2196
2197
  	if (stat_config.aggr_mode == AGGR_NODE)
  		cpu__setup_cpunode_map();
db06a269e   yuzhoujian   perf stat: Add su...
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
  	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...
2208

f1f8ad52f   yuzhoujian   perf stat: Add su...
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
  	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...
2228
  	if (perf_evlist__alloc_stats(evsel_list, interval))
03ad9747c   Arnaldo Carvalho de Melo   perf evlist: Move...
2229
  		goto out;
d6d901c23   Zhang, Yanmin   perf events: Chan...
2230

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

58d7e993b   Ingo Molnar   perf stat: handle...
2234
  	/*
7d9ad16af   Jiri Olsa   perf stat: Add 'i...
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
  	 * 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...
2246
2247
2248
2249
2250
  	 * 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...
2251
  	atexit(sig_atexit);
a7e191c37   Frederik Deweerdt   perf stat: Introd...
2252
2253
  	if (!forever)
  		signal(SIGINT,  skip_signal);
13370a9b5   Stephane Eranian   perf stat: Add in...
2254
  	signal(SIGCHLD, skip_signal);
58d7e993b   Ingo Molnar   perf stat: handle...
2255
2256
  	signal(SIGALRM, skip_signal);
  	signal(SIGABRT, skip_signal);
27e9769aa   Alexey Budankov   perf stat: Introd...
2257
2258
  	if (evlist__initialize_ctlfd(evsel_list, stat_config.ctl_fd, stat_config.ctl_fd_ack))
  		goto out;
42202dd56   Ingo Molnar   perf stat: Add fe...
2259
  	status = 0;
d97ae04b3   Jiri Olsa   perf stat: Move '...
2260
2261
  	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...
2262
2263
2264
  			fprintf(output, "[ perf stat: executing run #%d ... ]
  ",
  				run_idx + 1);
f9cef0a90   Ingo Molnar   perf stat: Add --...
2265

b63fd11cc   Srikar Dronamraju   perf stat: Reset ...
2266
2267
  		if (run_idx != 0)
  			perf_evlist__reset_prev_raw_counts(evsel_list);
e55c14af4   Jiri Olsa   perf stat: Add --...
2268
  		status = run_perf_stat(argc, argv, run_idx);
443f2d5ba   Srikar Dronamraju   perf stat: Fix a ...
2269
  		if (forever && status != -1 && !interval) {
d4f63a474   Jiri Olsa   perf stat: Introd...
2270
  			print_counters(NULL, argc, argv);
254ecbc74   Jiri Olsa   perf stat: Introd...
2271
  			perf_stat__reset_stats();
a7e191c37   Frederik Deweerdt   perf stat: Introd...
2272
  		}
42202dd56   Ingo Molnar   perf stat: Add fe...
2273
  	}
c7e5b328a   Jin Yao   perf stat: Report...
2274
  	if (!forever && status != -1 && (!interval || stat_config.summary))
d4f63a474   Jiri Olsa   perf stat: Introd...
2275
  		print_counters(NULL, argc, argv);
d134ffb91   Arnaldo Carvalho de Melo   perf stat: Introd...
2276

27e9769aa   Alexey Budankov   perf stat: Introd...
2277
  	evlist__finalize_ctlfd(evsel_list);
4979d0c7d   Jiri Olsa   perf stat record:...
2278
2279
2280
2281
2282
2283
2284
2285
  	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:...
2286
2287
2288
2289
  		 * 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:...
2290
  		 */
8ceb41d7e   Jiri Olsa   perf tools: Renam...
2291
  		int fd = perf_data__fd(&perf_stat.data);
4979d0c7d   Jiri Olsa   perf stat record:...
2292
2293
2294
2295
2296
2297
2298
2299
  		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:...
2300
2301
2302
2303
2304
  		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...
2305
  		if (!perf_stat.data.is_pipe) {
664c98d4e   Jiri Olsa   perf stat record:...
2306
2307
2308
  			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:...
2309

750b4edeb   Jiri Olsa   perf evlist: Rena...
2310
  		evlist__close(evsel_list);
4979d0c7d   Jiri Olsa   perf stat record:...
2311
2312
  		perf_session__delete(perf_stat.session);
  	}
544c2ae7b   Masami Hiramatsu   perf stat: Fix cm...
2313
  	perf_stat__exit_aggr_mode();
d134ffb91   Arnaldo Carvalho de Melo   perf stat: Introd...
2314
  	perf_evlist__free_stats(evsel_list);
0015e2e10   Arnaldo Carvalho de Melo   perf stat: Fix up...
2315
  out:
d8f9da240   Arnaldo Carvalho de Melo   perf tools: Use z...
2316
  	zfree(&stat_config.walltime_run);
e55c14af4   Jiri Olsa   perf stat: Add --...
2317

daefd0bc0   Kan Liang   perf stat: Add su...
2318
2319
  	if (smi_cost && smi_reset)
  		sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
c12995a55   Jiri Olsa   perf evlist: Rena...
2320
  	evlist__delete(evsel_list);
56739444d   Jin Yao   perf stat: Alloca...
2321

9afe5658a   Jiri Olsa   perf tools: Relea...
2322
  	metricgroup__rblist_exit(&stat_config.metric_events);
56739444d   Jin Yao   perf stat: Alloca...
2323
  	runtime_stat_delete(&stat_config);
ee7fe31e6   Adrian Hunter   perf tools: Conso...
2324
  	evlist__close_control(stat_config.ctl_fd, stat_config.ctl_fd_ack, &stat_config.ctl_fd_close);
56739444d   Jin Yao   perf stat: Alloca...
2325

42202dd56   Ingo Molnar   perf stat: Add fe...
2326
  	return status;
ddcacfa0f   Ingo Molnar   perf_counter tool...
2327
  }