]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - tools/perf/builtin-stat.c
perf stat record: Write stat events on record
[mirror_ubuntu-bionic-kernel.git] / tools / perf / builtin-stat.c
CommitLineData
ddcacfa0 1/*
bf9e1876
IM
2 * builtin-stat.c
3 *
4 * Builtin stat command: Give a precise performance counters summary
5 * overview about any workload, CPU or specific PID.
6 *
7 * Sample output:
ddcacfa0 8
2cba3ffb 9 $ perf stat ./hackbench 10
ddcacfa0 10
2cba3ffb 11 Time: 0.118
ddcacfa0 12
2cba3ffb 13 Performance counter stats for './hackbench 10':
ddcacfa0 14
2cba3ffb
IM
15 1708.761321 task-clock # 11.037 CPUs utilized
16 41,190 context-switches # 0.024 M/sec
17 6,735 CPU-migrations # 0.004 M/sec
18 17,318 page-faults # 0.010 M/sec
19 5,205,202,243 cycles # 3.046 GHz
20 3,856,436,920 stalled-cycles-frontend # 74.09% frontend cycles idle
21 1,600,790,871 stalled-cycles-backend # 30.75% backend cycles idle
22 2,603,501,247 instructions # 0.50 insns per cycle
23 # 1.48 stalled cycles per insn
24 484,357,498 branches # 283.455 M/sec
25 6,388,934 branch-misses # 1.32% of all branches
26
27 0.154822978 seconds time elapsed
ddcacfa0 28
5242519b 29 *
2cba3ffb 30 * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
5242519b
IM
31 *
32 * Improvements and fixes by:
33 *
34 * Arjan van de Ven <arjan@linux.intel.com>
35 * Yanmin Zhang <yanmin.zhang@intel.com>
36 * Wu Fengguang <fengguang.wu@intel.com>
37 * Mike Galbraith <efault@gmx.de>
38 * Paul Mackerras <paulus@samba.org>
6e750a8f 39 * Jaswinder Singh Rajput <jaswinder@kernel.org>
5242519b
IM
40 *
41 * Released under the GPL v2. (and only v2, not any later version)
ddcacfa0
IM
42 */
43
1a482f38 44#include "perf.h"
16f762a2 45#include "builtin.h"
f14d5707 46#include "util/cgroup.h"
148be2c1 47#include "util/util.h"
4b6ab94e 48#include <subcmd/parse-options.h>
5242519b 49#include "util/parse-events.h"
4cabc3d1 50#include "util/pmu.h"
8f28827a 51#include "util/event.h"
361c99a6 52#include "util/evlist.h"
69aad6f1 53#include "util/evsel.h"
8f28827a 54#include "util/debug.h"
a5d243d0 55#include "util/color.h"
0007ecea 56#include "util/stat.h"
60666c63 57#include "util/header.h"
a12b51c4 58#include "util/cpumap.h"
d6d901c2 59#include "util/thread.h"
fd78260b 60#include "util/thread_map.h"
d809560b 61#include "util/counts.h"
4979d0c7 62#include "util/session.h"
ddcacfa0 63
1f16c575 64#include <stdlib.h>
ddcacfa0 65#include <sys/prctl.h>
5af52b51 66#include <locale.h>
16c8a109 67
d7470b6a 68#define DEFAULT_SEPARATOR " "
2cee77c4
DA
69#define CNTR_NOT_SUPPORTED "<not supported>"
70#define CNTR_NOT_COUNTED "<not counted>"
d7470b6a 71
d4f63a47 72static void print_counters(struct timespec *ts, int argc, const char **argv);
13370a9b 73
4cabc3d1 74/* Default events used for perf stat -T */
a454742c
JO
75static const char *transaction_attrs = {
76 "task-clock,"
4cabc3d1
AK
77 "{"
78 "instructions,"
79 "cycles,"
80 "cpu/cycles-t/,"
81 "cpu/tx-start/,"
82 "cpu/el-start/,"
83 "cpu/cycles-ct/"
84 "}"
85};
86
87/* More limited version when the CPU does not have all events. */
a454742c
JO
88static const char * transaction_limited_attrs = {
89 "task-clock,"
4cabc3d1
AK
90 "{"
91 "instructions,"
92 "cycles,"
93 "cpu/cycles-t/,"
94 "cpu/tx-start/"
95 "}"
96};
97
666e6d48 98static struct perf_evlist *evsel_list;
361c99a6 99
602ad878 100static struct target target = {
77a6f014
NK
101 .uid = UINT_MAX,
102};
ddcacfa0 103
1e5a2931
JO
104typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);
105
3d632595 106static int run_count = 1;
2e6cdf99 107static bool no_inherit = false;
d07f0b12 108static volatile pid_t child_pid = -1;
c0555642 109static bool null_run = false;
2cba3ffb 110static int detailed_run = 0;
4cabc3d1 111static bool transaction_run;
201e0b06 112static bool big_num = true;
d7470b6a 113static int big_num_opt = -1;
d7470b6a
SE
114static const char *csv_sep = NULL;
115static bool csv_output = false;
43bece79 116static bool group = false;
1f16c575
PZ
117static const char *pre_cmd = NULL;
118static const char *post_cmd = NULL;
119static bool sync_run = false;
41191688 120static unsigned int initial_delay = 0;
410136f5 121static unsigned int unit_width = 4; /* strlen("unit") */
a7e191c3 122static bool forever = false;
13370a9b 123static struct timespec ref_time;
86ee6e18 124static struct cpu_map *aggr_map;
1e5a2931 125static aggr_get_id_t aggr_get_id;
e0547311
JO
126static bool append_file;
127static const char *output_name;
128static int output_fd;
5af52b51 129
4979d0c7
JO
130struct perf_stat {
131 bool record;
132 struct perf_data_file file;
133 struct perf_session *session;
134 u64 bytes_written;
135};
136
137static struct perf_stat perf_stat;
138#define STAT_RECORD perf_stat.record
139
60666c63
LW
140static volatile int done = 0;
141
421a50f3
JO
142static struct perf_stat_config stat_config = {
143 .aggr_mode = AGGR_GLOBAL,
711a572e 144 .scale = true,
421a50f3
JO
145};
146
13370a9b
SE
147static inline void diff_timespec(struct timespec *r, struct timespec *a,
148 struct timespec *b)
149{
150 r->tv_sec = a->tv_sec - b->tv_sec;
151 if (a->tv_nsec < b->tv_nsec) {
152 r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec;
153 r->tv_sec--;
154 } else {
155 r->tv_nsec = a->tv_nsec - b->tv_nsec ;
156 }
157}
158
254ecbc7
JO
159static void perf_stat__reset_stats(void)
160{
161 perf_evlist__reset_stats(evsel_list);
f87027b9 162 perf_stat__reset_shadow_stats();
1eda3b21
JO
163}
164
cac21425 165static int create_perf_stat_counter(struct perf_evsel *evsel)
ddcacfa0 166{
69aad6f1 167 struct perf_event_attr *attr = &evsel->attr;
727ab04e 168
711a572e 169 if (stat_config.scale)
a21ca2ca
IM
170 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
171 PERF_FORMAT_TOTAL_TIME_RUNNING;
ddcacfa0 172
5d2cd909
ACM
173 attr->inherit = !no_inherit;
174
6acd8e92
JO
175 /*
176 * Some events get initialized with sample_(period/type) set,
177 * like tracepoints. Clear it up for counting.
178 */
179 attr->sample_period = 0;
4979d0c7
JO
180 /*
181 * But set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless
182 * while avoiding that older tools show confusing messages.
183 */
184 attr->sample_type = PERF_SAMPLE_IDENTIFIER;
6acd8e92 185
67ccdecd
JO
186 /*
187 * Disabling all counters initially, they will be enabled
188 * either manually by us or by kernel via enable_on_exec
189 * set later.
190 */
c8280cec 191 if (perf_evsel__is_group_leader(evsel)) {
67ccdecd
JO
192 attr->disabled = 1;
193
c8280cec
JO
194 /*
195 * In case of initial_delay we enable tracee
196 * events manually.
197 */
198 if (target__none(&target) && !initial_delay)
41191688 199 attr->enable_on_exec = 1;
ddcacfa0 200 }
084ab9f8 201
c8280cec
JO
202 if (target__has_cpu(&target))
203 return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
204
594ac61a 205 return perf_evsel__open_per_thread(evsel, evsel_list->threads);
ddcacfa0
IM
206}
207
c04f5e5d
IM
208/*
209 * Does the counter have nsecs as a unit?
210 */
daec78a0 211static inline int nsec_counter(struct perf_evsel *evsel)
c04f5e5d 212{
daec78a0
ACM
213 if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
214 perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
c04f5e5d
IM
215 return 1;
216
217 return 0;
218}
219
8b99b1a4
JO
220static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
221 union perf_event *event,
222 struct perf_sample *sample __maybe_unused,
223 struct machine *machine __maybe_unused)
4979d0c7 224{
8b99b1a4 225 if (perf_data_file__write(&perf_stat.file, event, event->header.size) < 0) {
4979d0c7
JO
226 pr_err("failed to write perf data, error: %m\n");
227 return -1;
228 }
229
8b99b1a4 230 perf_stat.bytes_written += event->header.size;
4979d0c7
JO
231 return 0;
232}
233
5a6ea81b
JO
234#define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
235
236static int
237perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread,
238 struct perf_counts_values *count)
239{
240 struct perf_sample_id *sid = SID(counter, cpu, thread);
241
242 return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
243 process_synthesized_event, NULL);
244}
245
f5b4a9c3
SE
246/*
247 * Read out the results of a single counter:
248 * do not aggregate counts across CPUs in system-wide mode
249 */
c52b12ed 250static int read_counter(struct perf_evsel *counter)
f5b4a9c3 251{
9bf1a529
JO
252 int nthreads = thread_map__nr(evsel_list->threads);
253 int ncpus = perf_evsel__nr_cpus(counter);
254 int cpu, thread;
f5b4a9c3 255
3b4331d9
SP
256 if (!counter->supported)
257 return -ENOENT;
258
9bf1a529
JO
259 if (counter->system_wide)
260 nthreads = 1;
261
262 for (thread = 0; thread < nthreads; thread++) {
263 for (cpu = 0; cpu < ncpus; cpu++) {
3b3eb044
JO
264 struct perf_counts_values *count;
265
266 count = perf_counts(counter->counts, cpu, thread);
267 if (perf_evsel__read(counter, cpu, thread, count))
9bf1a529 268 return -1;
5a6ea81b
JO
269
270 if (STAT_RECORD) {
271 if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
272 pr_err("failed to write stat event\n");
273 return -1;
274 }
275 }
9bf1a529 276 }
f5b4a9c3 277 }
c52b12ed
ACM
278
279 return 0;
2996f5dd
IM
280}
281
5fc472a6 282static void read_counters(bool close_counters)
13370a9b 283{
13370a9b 284 struct perf_evsel *counter;
13370a9b 285
106a94a0 286 evlist__for_each(evsel_list, counter) {
3b3eb044 287 if (read_counter(counter))
245bad8e 288 pr_debug("failed to read counter %s\n", counter->name);
3b3eb044 289
f80010eb 290 if (perf_stat_process_counter(&stat_config, counter))
3b3eb044 291 pr_warning("failed to process counter %s\n", counter->name);
106a94a0 292
5fc472a6 293 if (close_counters) {
106a94a0
JO
294 perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
295 thread_map__nr(evsel_list->threads));
13370a9b
SE
296 }
297 }
106a94a0
JO
298}
299
ba411a95 300static void process_interval(void)
106a94a0 301{
106a94a0 302 struct timespec ts, rs;
106a94a0
JO
303
304 read_counters(false);
86ee6e18 305
13370a9b
SE
306 clock_gettime(CLOCK_MONOTONIC, &ts);
307 diff_timespec(&rs, &ts, &ref_time);
13370a9b 308
d4f63a47 309 print_counters(&rs, 0, NULL);
13370a9b
SE
310}
311
67ccdecd 312static void enable_counters(void)
41191688 313{
67ccdecd 314 if (initial_delay)
41191688 315 usleep(initial_delay * 1000);
67ccdecd
JO
316
317 /*
318 * We need to enable counters only if:
319 * - we don't have tracee (attaching to task or cpu)
320 * - we have initial delay configured
321 */
322 if (!target__none(&target) || initial_delay)
ab46db0a 323 perf_evlist__enable(evsel_list);
41191688
AK
324}
325
f33cbe72 326static volatile int workload_exec_errno;
6af206fd
ACM
327
328/*
329 * perf_evlist__prepare_workload will send a SIGUSR1
330 * if the fork fails, since we asked by setting its
331 * want_signal to true.
332 */
f33cbe72
ACM
333static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
334 void *ucontext __maybe_unused)
6af206fd 335{
f33cbe72 336 workload_exec_errno = info->si_value.sival_int;
6af206fd
ACM
337}
338
664c98d4 339static int perf_stat_synthesize_config(bool is_pipe)
8b99b1a4
JO
340{
341 int err;
342
664c98d4
JO
343 if (is_pipe) {
344 err = perf_event__synthesize_attrs(NULL, perf_stat.session,
345 process_synthesized_event);
346 if (err < 0) {
347 pr_err("Couldn't synthesize attrs.\n");
348 return err;
349 }
350 }
351
8b99b1a4
JO
352 err = perf_event__synthesize_thread_map2(NULL, evsel_list->threads,
353 process_synthesized_event,
354 NULL);
355 if (err < 0) {
356 pr_err("Couldn't synthesize thread map.\n");
357 return err;
358 }
359
360 err = perf_event__synthesize_cpu_map(NULL, evsel_list->cpus,
361 process_synthesized_event, NULL);
362 if (err < 0) {
363 pr_err("Couldn't synthesize thread map.\n");
364 return err;
365 }
366
367 err = perf_event__synthesize_stat_config(NULL, &stat_config,
368 process_synthesized_event, NULL);
369 if (err < 0) {
370 pr_err("Couldn't synthesize config.\n");
371 return err;
372 }
373
374 return 0;
375}
376
2af4646d
JO
377#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
378
379static int __store_counter_ids(struct perf_evsel *counter,
380 struct cpu_map *cpus,
381 struct thread_map *threads)
382{
383 int cpu, thread;
384
385 for (cpu = 0; cpu < cpus->nr; cpu++) {
386 for (thread = 0; thread < threads->nr; thread++) {
387 int fd = FD(counter, cpu, thread);
388
389 if (perf_evlist__id_add_fd(evsel_list, counter,
390 cpu, thread, fd) < 0)
391 return -1;
392 }
393 }
394
395 return 0;
396}
397
398static int store_counter_ids(struct perf_evsel *counter)
399{
400 struct cpu_map *cpus = counter->cpus;
401 struct thread_map *threads = counter->threads;
402
403 if (perf_evsel__alloc_id(counter, cpus->nr, threads->nr))
404 return -ENOMEM;
405
406 return __store_counter_ids(counter, cpus, threads);
407}
408
acf28922 409static int __run_perf_stat(int argc, const char **argv)
42202dd5 410{
ec0d3d1f 411 int interval = stat_config.interval;
56e52e85 412 char msg[512];
42202dd5 413 unsigned long long t0, t1;
cac21425 414 struct perf_evsel *counter;
13370a9b 415 struct timespec ts;
410136f5 416 size_t l;
42202dd5 417 int status = 0;
6be2850e 418 const bool forks = (argc > 0);
664c98d4 419 bool is_pipe = STAT_RECORD ? perf_stat.file.is_pipe : false;
42202dd5 420
13370a9b
SE
421 if (interval) {
422 ts.tv_sec = interval / 1000;
423 ts.tv_nsec = (interval % 1000) * 1000000;
424 } else {
425 ts.tv_sec = 1;
426 ts.tv_nsec = 0;
427 }
428
60666c63 429 if (forks) {
664c98d4 430 if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe,
735f7e0b 431 workload_exec_failed_signal) < 0) {
acf28922
NK
432 perror("failed to prepare workload");
433 return -1;
60666c63 434 }
d20a47e7 435 child_pid = evsel_list->workload.pid;
051ae7f7
PM
436 }
437
6a4bb04c 438 if (group)
63dab225 439 perf_evlist__set_leader(evsel_list);
6a4bb04c 440
0050f7aa 441 evlist__for_each(evsel_list, counter) {
cac21425 442 if (create_perf_stat_counter(counter) < 0) {
979987a5
DA
443 /*
444 * PPC returns ENXIO for HW counters until 2.6.37
445 * (behavior changed with commit b0a873e).
446 */
38f6ae1e 447 if (errno == EINVAL || errno == ENOSYS ||
979987a5
DA
448 errno == ENOENT || errno == EOPNOTSUPP ||
449 errno == ENXIO) {
c63ca0c0
DA
450 if (verbose)
451 ui__warning("%s event is not supported by the kernel.\n",
7289f83c 452 perf_evsel__name(counter));
2cee77c4 453 counter->supported = false;
cb5ef600
KL
454
455 if ((counter->leader != counter) ||
456 !(counter->leader->nr_members > 1))
457 continue;
c63ca0c0 458 }
ede70290 459
56e52e85
ACM
460 perf_evsel__open_strerror(counter, &target,
461 errno, msg, sizeof(msg));
462 ui__error("%s\n", msg);
463
48290609
ACM
464 if (child_pid != -1)
465 kill(child_pid, SIGTERM);
fceda7fe 466
48290609
ACM
467 return -1;
468 }
2cee77c4 469 counter->supported = true;
410136f5
SE
470
471 l = strlen(counter->unit);
472 if (l > unit_width)
473 unit_width = l;
2af4646d
JO
474
475 if (STAT_RECORD && store_counter_ids(counter))
476 return -1;
084ab9f8 477 }
42202dd5 478
23d4aad4
ACM
479 if (perf_evlist__apply_filters(evsel_list, &counter)) {
480 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
481 counter->filter, perf_evsel__name(counter), errno,
759e612b 482 strerror_r(errno, msg, sizeof(msg)));
cfd748ae
FW
483 return -1;
484 }
485
4979d0c7
JO
486 if (STAT_RECORD) {
487 int err, fd = perf_data_file__fd(&perf_stat.file);
488
664c98d4
JO
489 if (is_pipe) {
490 err = perf_header__write_pipe(perf_data_file__fd(&perf_stat.file));
491 } else {
492 err = perf_session__write_header(perf_stat.session, evsel_list,
493 fd, false);
494 }
495
4979d0c7
JO
496 if (err < 0)
497 return err;
8b99b1a4 498
664c98d4 499 err = perf_stat_synthesize_config(is_pipe);
8b99b1a4
JO
500 if (err < 0)
501 return err;
4979d0c7
JO
502 }
503
42202dd5
IM
504 /*
505 * Enable counters and exec the command:
506 */
507 t0 = rdclock();
13370a9b 508 clock_gettime(CLOCK_MONOTONIC, &ref_time);
42202dd5 509
60666c63 510 if (forks) {
acf28922 511 perf_evlist__start_workload(evsel_list);
67ccdecd 512 enable_counters();
acf28922 513
13370a9b
SE
514 if (interval) {
515 while (!waitpid(child_pid, &status, WNOHANG)) {
516 nanosleep(&ts, NULL);
ba411a95 517 process_interval();
13370a9b
SE
518 }
519 }
60666c63 520 wait(&status);
6af206fd 521
f33cbe72
ACM
522 if (workload_exec_errno) {
523 const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
524 pr_err("Workload failed: %s\n", emsg);
6af206fd 525 return -1;
f33cbe72 526 }
6af206fd 527
33e49ea7
AK
528 if (WIFSIGNALED(status))
529 psignal(WTERMSIG(status), argv[0]);
60666c63 530 } else {
67ccdecd 531 enable_counters();
13370a9b
SE
532 while (!done) {
533 nanosleep(&ts, NULL);
534 if (interval)
ba411a95 535 process_interval();
13370a9b 536 }
60666c63 537 }
42202dd5 538
42202dd5
IM
539 t1 = rdclock();
540
9e9772c4 541 update_stats(&walltime_nsecs_stats, t1 - t0);
42202dd5 542
106a94a0 543 read_counters(true);
c52b12ed 544
42202dd5
IM
545 return WEXITSTATUS(status);
546}
547
41cde476 548static int run_perf_stat(int argc, const char **argv)
1f16c575
PZ
549{
550 int ret;
551
552 if (pre_cmd) {
553 ret = system(pre_cmd);
554 if (ret)
555 return ret;
556 }
557
558 if (sync_run)
559 sync();
560
561 ret = __run_perf_stat(argc, argv);
562 if (ret)
563 return ret;
564
565 if (post_cmd) {
566 ret = system(post_cmd);
567 if (ret)
568 return ret;
569 }
570
571 return ret;
572}
573
d73515c0
AK
574static void print_running(u64 run, u64 ena)
575{
576 if (csv_output) {
5821522e 577 fprintf(stat_config.output, "%s%" PRIu64 "%s%.2f",
d73515c0
AK
578 csv_sep,
579 run,
580 csv_sep,
581 ena ? 100.0 * run / ena : 100.0);
582 } else if (run != ena) {
5821522e 583 fprintf(stat_config.output, " (%.2f%%)", 100.0 * run / ena);
d73515c0
AK
584 }
585}
586
f99844cb
IM
587static void print_noise_pct(double total, double avg)
588{
0007ecea 589 double pct = rel_stddev_stats(total, avg);
f99844cb 590
3ae9a34d 591 if (csv_output)
5821522e 592 fprintf(stat_config.output, "%s%.2f%%", csv_sep, pct);
a1bca6cc 593 else if (pct)
5821522e 594 fprintf(stat_config.output, " ( +-%6.2f%% )", pct);
f99844cb
IM
595}
596
69aad6f1 597static void print_noise(struct perf_evsel *evsel, double avg)
42202dd5 598{
581cc8a2 599 struct perf_stat_evsel *ps;
69aad6f1 600
849abde9
PZ
601 if (run_count == 1)
602 return;
603
69aad6f1 604 ps = evsel->priv;
f99844cb 605 print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
42202dd5
IM
606}
607
12c08a9f 608static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
44175b6f 609{
421a50f3 610 switch (stat_config.aggr_mode) {
12c08a9f 611 case AGGR_CORE:
5821522e 612 fprintf(stat_config.output, "S%d-C%*d%s%*d%s",
12c08a9f
SE
613 cpu_map__id_to_socket(id),
614 csv_output ? 0 : -8,
615 cpu_map__id_to_cpu(id),
616 csv_sep,
617 csv_output ? 0 : 4,
618 nr,
619 csv_sep);
620 break;
86ee6e18 621 case AGGR_SOCKET:
5821522e 622 fprintf(stat_config.output, "S%*d%s%*d%s",
d7e7a451 623 csv_output ? 0 : -5,
12c08a9f 624 id,
d7e7a451
SE
625 csv_sep,
626 csv_output ? 0 : 4,
627 nr,
628 csv_sep);
86ee6e18
SE
629 break;
630 case AGGR_NONE:
5821522e 631 fprintf(stat_config.output, "CPU%*d%s",
d7470b6a 632 csv_output ? 0 : -4,
12c08a9f 633 perf_evsel__cpus(evsel)->map[id], csv_sep);
86ee6e18 634 break;
32b8af82 635 case AGGR_THREAD:
5821522e 636 fprintf(stat_config.output, "%*s-%*d%s",
32b8af82
JO
637 csv_output ? 0 : 16,
638 thread_map__comm(evsel->threads, id),
639 csv_output ? 0 : -8,
640 thread_map__pid(evsel->threads, id),
641 csv_sep);
642 break;
86ee6e18 643 case AGGR_GLOBAL:
208df99e 644 case AGGR_UNSET:
86ee6e18
SE
645 default:
646 break;
647 }
648}
649
da88c7f7 650static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
86ee6e18 651{
5821522e 652 FILE *output = stat_config.output;
86ee6e18 653 double msecs = avg / 1e6;
410136f5 654 const char *fmt_v, *fmt_n;
4bbe5a61 655 char name[25];
86ee6e18 656
410136f5
SE
657 fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
658 fmt_n = csv_output ? "%s" : "%-25s";
659
da88c7f7 660 aggr_printout(evsel, id, nr);
d7470b6a 661
4bbe5a61
DA
662 scnprintf(name, sizeof(name), "%s%s",
663 perf_evsel__name(evsel), csv_output ? "" : " (msec)");
410136f5
SE
664
665 fprintf(output, fmt_v, msecs, csv_sep);
666
667 if (csv_output)
668 fprintf(output, "%s%s", evsel->unit, csv_sep);
669 else
670 fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
671
672 fprintf(output, fmt_n, name);
d7470b6a 673
023695d9 674 if (evsel->cgrp)
4aa9015f 675 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
44175b6f
IM
676}
677
556b1fb7
JO
678static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
679{
5821522e 680 FILE *output = stat_config.output;
556b1fb7
JO
681 double sc = evsel->scale;
682 const char *fmt;
556b1fb7
JO
683
684 if (csv_output) {
685 fmt = sc != 1.0 ? "%.2f%s" : "%.0f%s";
686 } else {
687 if (big_num)
688 fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
689 else
690 fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
691 }
692
693 aggr_printout(evsel, id, nr);
694
556b1fb7
JO
695 fprintf(output, fmt, avg, csv_sep);
696
697 if (evsel->unit)
698 fprintf(output, "%-*s%s",
699 csv_output ? 0 : unit_width,
700 evsel->unit, csv_sep);
701
702 fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
703
704 if (evsel->cgrp)
705 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
eedfcb4b 706}
556b1fb7 707
eedfcb4b
AK
708static void printout(int id, int nr, struct perf_evsel *counter, double uval)
709{
710 int cpu = cpu_map__id_to_cpu(id);
711
712 if (stat_config.aggr_mode == AGGR_GLOBAL)
713 cpu = 0;
714
715 if (nsec_counter(counter))
716 nsec_printout(id, nr, counter, uval);
717 else
718 abs_printout(id, nr, counter, uval);
556b1fb7 719
eedfcb4b
AK
720 if (!csv_output && !stat_config.interval)
721 perf_stat__print_shadow_stats(stat_config.output, counter,
722 uval, cpu,
723 stat_config.aggr_mode);
556b1fb7
JO
724}
725
86ee6e18 726static void print_aggr(char *prefix)
d7e7a451 727{
5821522e 728 FILE *output = stat_config.output;
d7e7a451 729 struct perf_evsel *counter;
601083cf 730 int cpu, s, s2, id, nr;
410136f5 731 double uval;
d7e7a451 732 u64 ena, run, val;
d7e7a451 733
86ee6e18 734 if (!(aggr_map || aggr_get_id))
d7e7a451
SE
735 return;
736
86ee6e18
SE
737 for (s = 0; s < aggr_map->nr; s++) {
738 id = aggr_map->map[s];
0050f7aa 739 evlist__for_each(evsel_list, counter) {
d7e7a451
SE
740 val = ena = run = 0;
741 nr = 0;
742 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
601083cf 743 s2 = aggr_get_id(perf_evsel__cpus(counter), cpu);
86ee6e18 744 if (s2 != id)
d7e7a451 745 continue;
a6fa0038
JO
746 val += perf_counts(counter->counts, cpu, 0)->val;
747 ena += perf_counts(counter->counts, cpu, 0)->ena;
748 run += perf_counts(counter->counts, cpu, 0)->run;
d7e7a451
SE
749 nr++;
750 }
751 if (prefix)
752 fprintf(output, "%s", prefix);
753
754 if (run == 0 || ena == 0) {
582ec082 755 aggr_printout(counter, id, nr);
86ee6e18 756
410136f5 757 fprintf(output, "%*s%s",
d7e7a451
SE
758 csv_output ? 0 : 18,
759 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
410136f5
SE
760 csv_sep);
761
762 fprintf(output, "%-*s%s",
763 csv_output ? 0 : unit_width,
764 counter->unit, csv_sep);
765
766 fprintf(output, "%*s",
767 csv_output ? 0 : -25,
d7e7a451 768 perf_evsel__name(counter));
86ee6e18 769
d7e7a451
SE
770 if (counter->cgrp)
771 fprintf(output, "%s%s",
772 csv_sep, counter->cgrp->name);
773
d73515c0 774 print_running(run, ena);
d7e7a451
SE
775 fputc('\n', output);
776 continue;
777 }
410136f5 778 uval = val * counter->scale;
eedfcb4b 779 printout(id, nr, counter, uval);
d73515c0 780 if (!csv_output)
d7e7a451
SE
781 print_noise(counter, 1.0);
782
d73515c0 783 print_running(run, ena);
d7e7a451
SE
784 fputc('\n', output);
785 }
786 }
787}
788
32b8af82
JO
789static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
790{
5821522e 791 FILE *output = stat_config.output;
32b8af82
JO
792 int nthreads = thread_map__nr(counter->threads);
793 int ncpus = cpu_map__nr(counter->cpus);
794 int cpu, thread;
795 double uval;
796
797 for (thread = 0; thread < nthreads; thread++) {
798 u64 ena = 0, run = 0, val = 0;
799
800 for (cpu = 0; cpu < ncpus; cpu++) {
801 val += perf_counts(counter->counts, cpu, thread)->val;
802 ena += perf_counts(counter->counts, cpu, thread)->ena;
803 run += perf_counts(counter->counts, cpu, thread)->run;
804 }
805
806 if (prefix)
807 fprintf(output, "%s", prefix);
808
809 uval = val * counter->scale;
eedfcb4b 810 printout(thread, 0, counter, uval);
32b8af82
JO
811
812 if (!csv_output)
813 print_noise(counter, 1.0);
814
815 print_running(run, ena);
816 fputc('\n', output);
817 }
818}
819
2996f5dd
IM
820/*
821 * Print out the results of a single counter:
f5b4a9c3 822 * aggregated counts in system-wide mode
2996f5dd 823 */
13370a9b 824static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
2996f5dd 825{
5821522e 826 FILE *output = stat_config.output;
581cc8a2 827 struct perf_stat_evsel *ps = counter->priv;
69aad6f1 828 double avg = avg_stats(&ps->res_stats[0]);
c52b12ed 829 int scaled = counter->counts->scaled;
410136f5 830 double uval;
d73515c0
AK
831 double avg_enabled, avg_running;
832
833 avg_enabled = avg_stats(&ps->res_stats[1]);
834 avg_running = avg_stats(&ps->res_stats[2]);
2996f5dd 835
13370a9b
SE
836 if (prefix)
837 fprintf(output, "%s", prefix);
838
3b4331d9 839 if (scaled == -1 || !counter->supported) {
410136f5 840 fprintf(output, "%*s%s",
d7470b6a 841 csv_output ? 0 : 18,
2cee77c4 842 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
410136f5
SE
843 csv_sep);
844 fprintf(output, "%-*s%s",
845 csv_output ? 0 : unit_width,
846 counter->unit, csv_sep);
847 fprintf(output, "%*s",
848 csv_output ? 0 : -25,
7289f83c 849 perf_evsel__name(counter));
023695d9
SE
850
851 if (counter->cgrp)
4aa9015f 852 fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
023695d9 853
d73515c0 854 print_running(avg_running, avg_enabled);
4aa9015f 855 fputc('\n', output);
2996f5dd
IM
856 return;
857 }
c04f5e5d 858
410136f5 859 uval = avg * counter->scale;
eedfcb4b 860 printout(-1, 0, counter, uval);
849abde9 861
3ae9a34d
ZH
862 print_noise(counter, avg);
863
d73515c0 864 print_running(avg_running, avg_enabled);
4aa9015f 865 fprintf(output, "\n");
c04f5e5d
IM
866}
867
f5b4a9c3
SE
868/*
869 * Print out the results of a single counter:
870 * does not use aggregated count in system-wide
871 */
13370a9b 872static void print_counter(struct perf_evsel *counter, char *prefix)
f5b4a9c3 873{
5821522e 874 FILE *output = stat_config.output;
f5b4a9c3 875 u64 ena, run, val;
410136f5 876 double uval;
f5b4a9c3
SE
877 int cpu;
878
7ae92e74 879 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
a6fa0038
JO
880 val = perf_counts(counter->counts, cpu, 0)->val;
881 ena = perf_counts(counter->counts, cpu, 0)->ena;
882 run = perf_counts(counter->counts, cpu, 0)->run;
13370a9b
SE
883
884 if (prefix)
885 fprintf(output, "%s", prefix);
886
f5b4a9c3 887 if (run == 0 || ena == 0) {
410136f5 888 fprintf(output, "CPU%*d%s%*s%s",
d7470b6a 889 csv_output ? 0 : -4,
7ae92e74 890 perf_evsel__cpus(counter)->map[cpu], csv_sep,
d7470b6a 891 csv_output ? 0 : 18,
2cee77c4 892 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
410136f5
SE
893 csv_sep);
894
895 fprintf(output, "%-*s%s",
896 csv_output ? 0 : unit_width,
897 counter->unit, csv_sep);
898
899 fprintf(output, "%*s",
900 csv_output ? 0 : -25,
901 perf_evsel__name(counter));
f5b4a9c3 902
023695d9 903 if (counter->cgrp)
4aa9015f
SE
904 fprintf(output, "%s%s",
905 csv_sep, counter->cgrp->name);
023695d9 906
d73515c0 907 print_running(run, ena);
4aa9015f 908 fputc('\n', output);
f5b4a9c3
SE
909 continue;
910 }
911
410136f5 912 uval = val * counter->scale;
eedfcb4b 913 printout(cpu, 0, counter, uval);
d73515c0 914 if (!csv_output)
d7470b6a 915 print_noise(counter, 1.0);
d73515c0 916 print_running(run, ena);
f5b4a9c3 917
4aa9015f 918 fputc('\n', output);
f5b4a9c3
SE
919 }
920}
921
d4f63a47
JO
922static void print_interval(char *prefix, struct timespec *ts)
923{
5821522e 924 FILE *output = stat_config.output;
d4f63a47
JO
925 static int num_print_interval;
926
927 sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
928
929 if (num_print_interval == 0 && !csv_output) {
421a50f3 930 switch (stat_config.aggr_mode) {
d4f63a47
JO
931 case AGGR_SOCKET:
932 fprintf(output, "# time socket cpus counts %*s events\n", unit_width, "unit");
933 break;
934 case AGGR_CORE:
935 fprintf(output, "# time core cpus counts %*s events\n", unit_width, "unit");
936 break;
937 case AGGR_NONE:
938 fprintf(output, "# time CPU counts %*s events\n", unit_width, "unit");
939 break;
32b8af82
JO
940 case AGGR_THREAD:
941 fprintf(output, "# time comm-pid counts %*s events\n", unit_width, "unit");
942 break;
d4f63a47
JO
943 case AGGR_GLOBAL:
944 default:
945 fprintf(output, "# time counts %*s events\n", unit_width, "unit");
208df99e
JO
946 case AGGR_UNSET:
947 break;
d4f63a47
JO
948 }
949 }
950
951 if (++num_print_interval == 25)
952 num_print_interval = 0;
953}
954
955static void print_header(int argc, const char **argv)
42202dd5 956{
5821522e 957 FILE *output = stat_config.output;
69aad6f1 958 int i;
42202dd5 959
ddcacfa0
IM
960 fflush(stdout);
961
d7470b6a 962 if (!csv_output) {
4aa9015f
SE
963 fprintf(output, "\n");
964 fprintf(output, " Performance counter stats for ");
62d3b617
DA
965 if (target.system_wide)
966 fprintf(output, "\'system wide");
967 else if (target.cpu_list)
968 fprintf(output, "\'CPU(s) %s", target.cpu_list);
602ad878 969 else if (!target__has_task(&target)) {
4aa9015f 970 fprintf(output, "\'%s", argv[0]);
d7470b6a 971 for (i = 1; i < argc; i++)
4aa9015f 972 fprintf(output, " %s", argv[i]);
20f946b4
NK
973 } else if (target.pid)
974 fprintf(output, "process id \'%s", target.pid);
d7470b6a 975 else
20f946b4 976 fprintf(output, "thread id \'%s", target.tid);
44db76c8 977
4aa9015f 978 fprintf(output, "\'");
d7470b6a 979 if (run_count > 1)
4aa9015f
SE
980 fprintf(output, " (%d runs)", run_count);
981 fprintf(output, ":\n\n");
d7470b6a 982 }
d4f63a47
JO
983}
984
985static void print_footer(void)
986{
5821522e
JO
987 FILE *output = stat_config.output;
988
d4f63a47
JO
989 if (!null_run)
990 fprintf(output, "\n");
991 fprintf(output, " %17.9f seconds time elapsed",
992 avg_stats(&walltime_nsecs_stats)/1e9);
993 if (run_count > 1) {
994 fprintf(output, " ");
995 print_noise_pct(stddev_stats(&walltime_nsecs_stats),
996 avg_stats(&walltime_nsecs_stats));
997 }
998 fprintf(output, "\n\n");
999}
1000
1001static void print_counters(struct timespec *ts, int argc, const char **argv)
1002{
ec0d3d1f 1003 int interval = stat_config.interval;
d4f63a47
JO
1004 struct perf_evsel *counter;
1005 char buf[64], *prefix = NULL;
1006
664c98d4
JO
1007 /* Do not print anything if we record to the pipe. */
1008 if (STAT_RECORD && perf_stat.file.is_pipe)
1009 return;
1010
d4f63a47
JO
1011 if (interval)
1012 print_interval(prefix = buf, ts);
1013 else
1014 print_header(argc, argv);
2996f5dd 1015
421a50f3 1016 switch (stat_config.aggr_mode) {
12c08a9f 1017 case AGGR_CORE:
86ee6e18 1018 case AGGR_SOCKET:
d4f63a47 1019 print_aggr(prefix);
86ee6e18 1020 break;
32b8af82
JO
1021 case AGGR_THREAD:
1022 evlist__for_each(evsel_list, counter)
1023 print_aggr_thread(counter, prefix);
1024 break;
86ee6e18 1025 case AGGR_GLOBAL:
0050f7aa 1026 evlist__for_each(evsel_list, counter)
d4f63a47 1027 print_counter_aggr(counter, prefix);
86ee6e18
SE
1028 break;
1029 case AGGR_NONE:
0050f7aa 1030 evlist__for_each(evsel_list, counter)
d4f63a47 1031 print_counter(counter, prefix);
86ee6e18 1032 break;
208df99e 1033 case AGGR_UNSET:
86ee6e18
SE
1034 default:
1035 break;
f5b4a9c3 1036 }
ddcacfa0 1037
d4f63a47
JO
1038 if (!interval && !csv_output)
1039 print_footer();
1040
5821522e 1041 fflush(stat_config.output);
ddcacfa0
IM
1042}
1043
f7b7c26e
PZ
1044static volatile int signr = -1;
1045
5242519b 1046static void skip_signal(int signo)
ddcacfa0 1047{
ec0d3d1f 1048 if ((child_pid == -1) || stat_config.interval)
60666c63
LW
1049 done = 1;
1050
f7b7c26e 1051 signr = signo;
d07f0b12
SE
1052 /*
1053 * render child_pid harmless
1054 * won't send SIGTERM to a random
1055 * process in case of race condition
1056 * and fast PID recycling
1057 */
1058 child_pid = -1;
f7b7c26e
PZ
1059}
1060
1061static void sig_atexit(void)
1062{
d07f0b12
SE
1063 sigset_t set, oset;
1064
1065 /*
1066 * avoid race condition with SIGCHLD handler
1067 * in skip_signal() which is modifying child_pid
1068 * goal is to avoid send SIGTERM to a random
1069 * process
1070 */
1071 sigemptyset(&set);
1072 sigaddset(&set, SIGCHLD);
1073 sigprocmask(SIG_BLOCK, &set, &oset);
1074
933da83a
CW
1075 if (child_pid != -1)
1076 kill(child_pid, SIGTERM);
1077
d07f0b12
SE
1078 sigprocmask(SIG_SETMASK, &oset, NULL);
1079
f7b7c26e
PZ
1080 if (signr == -1)
1081 return;
1082
1083 signal(signr, SIG_DFL);
1084 kill(getpid(), signr);
5242519b
IM
1085}
1086
1d037ca1
IT
1087static int stat__set_big_num(const struct option *opt __maybe_unused,
1088 const char *s __maybe_unused, int unset)
d7470b6a
SE
1089{
1090 big_num_opt = unset ? 0 : 1;
1091 return 0;
1092}
1093
e0547311
JO
1094static const struct option stat_options[] = {
1095 OPT_BOOLEAN('T', "transaction", &transaction_run,
1096 "hardware transaction statistics"),
1097 OPT_CALLBACK('e', "event", &evsel_list, "event",
1098 "event selector. use 'perf list' to list available events",
1099 parse_events_option),
1100 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1101 "event filter", parse_filter),
1102 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1103 "child tasks do not inherit counters"),
1104 OPT_STRING('p', "pid", &target.pid, "pid",
1105 "stat events on existing process id"),
1106 OPT_STRING('t', "tid", &target.tid, "tid",
1107 "stat events on existing thread id"),
1108 OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1109 "system-wide collection from all CPUs"),
1110 OPT_BOOLEAN('g', "group", &group,
1111 "put the counters into a counter group"),
1112 OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
1113 OPT_INCR('v', "verbose", &verbose,
1114 "be more verbose (show counter open errors, etc)"),
1115 OPT_INTEGER('r', "repeat", &run_count,
1116 "repeat command and print average + stddev (max: 100, forever: 0)"),
1117 OPT_BOOLEAN('n', "null", &null_run,
1118 "null run - dont start any counters"),
1119 OPT_INCR('d', "detailed", &detailed_run,
1120 "detailed run - start a lot of events"),
1121 OPT_BOOLEAN('S', "sync", &sync_run,
1122 "call sync() before starting a run"),
1123 OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1124 "print large numbers with thousands\' separators",
1125 stat__set_big_num),
1126 OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1127 "list of cpus to monitor in system-wide"),
1128 OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
1129 "disable CPU count aggregation", AGGR_NONE),
1130 OPT_STRING('x', "field-separator", &csv_sep, "separator",
1131 "print counts with custom separator"),
1132 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1133 "monitor event in cgroup name only", parse_cgroups),
1134 OPT_STRING('o', "output", &output_name, "file", "output file name"),
1135 OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1136 OPT_INTEGER(0, "log-fd", &output_fd,
1137 "log output to fd, instead of stderr"),
1138 OPT_STRING(0, "pre", &pre_cmd, "command",
1139 "command to run prior to the measured command"),
1140 OPT_STRING(0, "post", &post_cmd, "command",
1141 "command to run after to the measured command"),
1142 OPT_UINTEGER('I', "interval-print", &stat_config.interval,
1143 "print counts at regular interval in ms (>= 10)"),
1144 OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
1145 "aggregate counts per processor socket", AGGR_SOCKET),
1146 OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
1147 "aggregate counts per physical processor core", AGGR_CORE),
1148 OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
1149 "aggregate counts per thread", AGGR_THREAD),
1150 OPT_UINTEGER('D', "delay", &initial_delay,
1151 "ms to wait before starting measurement after program start"),
1152 OPT_END()
1153};
1154
1fe7a300
JO
1155static int perf_stat__get_socket(struct cpu_map *map, int cpu)
1156{
1157 return cpu_map__get_socket(map, cpu, NULL);
1158}
1159
1160static int perf_stat__get_core(struct cpu_map *map, int cpu)
1161{
1162 return cpu_map__get_core(map, cpu, NULL);
1163}
1164
1e5a2931
JO
1165static int cpu_map__get_max(struct cpu_map *map)
1166{
1167 int i, max = -1;
1168
1169 for (i = 0; i < map->nr; i++) {
1170 if (map->map[i] > max)
1171 max = map->map[i];
1172 }
1173
1174 return max;
1175}
1176
1177static struct cpu_map *cpus_aggr_map;
1178
1179static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int idx)
1180{
1181 int cpu;
1182
1183 if (idx >= map->nr)
1184 return -1;
1185
1186 cpu = map->map[idx];
1187
1188 if (cpus_aggr_map->map[cpu] == -1)
1189 cpus_aggr_map->map[cpu] = get_id(map, idx);
1190
1191 return cpus_aggr_map->map[cpu];
1192}
1193
1194static int perf_stat__get_socket_cached(struct cpu_map *map, int idx)
1195{
1196 return perf_stat__get_aggr(perf_stat__get_socket, map, idx);
1197}
1198
1199static int perf_stat__get_core_cached(struct cpu_map *map, int idx)
1200{
1201 return perf_stat__get_aggr(perf_stat__get_core, map, idx);
1202}
1203
86ee6e18
SE
1204static int perf_stat_init_aggr_mode(void)
1205{
1e5a2931
JO
1206 int nr;
1207
421a50f3 1208 switch (stat_config.aggr_mode) {
86ee6e18
SE
1209 case AGGR_SOCKET:
1210 if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
1211 perror("cannot build socket map");
1212 return -1;
1213 }
1e5a2931 1214 aggr_get_id = perf_stat__get_socket_cached;
86ee6e18 1215 break;
12c08a9f
SE
1216 case AGGR_CORE:
1217 if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
1218 perror("cannot build core map");
1219 return -1;
1220 }
1e5a2931 1221 aggr_get_id = perf_stat__get_core_cached;
12c08a9f 1222 break;
86ee6e18
SE
1223 case AGGR_NONE:
1224 case AGGR_GLOBAL:
32b8af82 1225 case AGGR_THREAD:
208df99e 1226 case AGGR_UNSET:
86ee6e18
SE
1227 default:
1228 break;
1229 }
1e5a2931
JO
1230
1231 /*
1232 * The evsel_list->cpus is the base we operate on,
1233 * taking the highest cpu number to be the size of
1234 * the aggregation translate cpumap.
1235 */
1236 nr = cpu_map__get_max(evsel_list->cpus);
1237 cpus_aggr_map = cpu_map__empty_new(nr + 1);
1238 return cpus_aggr_map ? 0 : -ENOMEM;
86ee6e18
SE
1239}
1240
544c2ae7
MH
1241static void perf_stat__exit_aggr_mode(void)
1242{
1243 cpu_map__put(aggr_map);
1244 cpu_map__put(cpus_aggr_map);
1245 aggr_map = NULL;
1246 cpus_aggr_map = NULL;
1247}
1248
2cba3ffb
IM
1249/*
1250 * Add default attributes, if there were no attributes specified or
1251 * if -d/--detailed, -d -d or -d -d -d is used:
1252 */
1253static int add_default_attributes(void)
1254{
b070a547
ACM
1255 struct perf_event_attr default_attrs[] = {
1256
1257 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
1258 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES },
1259 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
1260 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
1261
1262 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
1263 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
1264 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
1265 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
1266 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
1267 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
1268
1269};
1270
1271/*
1272 * Detailed stats (-d), covering the L1 and last level data caches:
1273 */
1274 struct perf_event_attr detailed_attrs[] = {
1275
1276 { .type = PERF_TYPE_HW_CACHE,
1277 .config =
1278 PERF_COUNT_HW_CACHE_L1D << 0 |
1279 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1280 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
1281
1282 { .type = PERF_TYPE_HW_CACHE,
1283 .config =
1284 PERF_COUNT_HW_CACHE_L1D << 0 |
1285 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1286 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1287
1288 { .type = PERF_TYPE_HW_CACHE,
1289 .config =
1290 PERF_COUNT_HW_CACHE_LL << 0 |
1291 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1292 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
1293
1294 { .type = PERF_TYPE_HW_CACHE,
1295 .config =
1296 PERF_COUNT_HW_CACHE_LL << 0 |
1297 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1298 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1299};
1300
1301/*
1302 * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1303 */
1304 struct perf_event_attr very_detailed_attrs[] = {
1305
1306 { .type = PERF_TYPE_HW_CACHE,
1307 .config =
1308 PERF_COUNT_HW_CACHE_L1I << 0 |
1309 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1310 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
1311
1312 { .type = PERF_TYPE_HW_CACHE,
1313 .config =
1314 PERF_COUNT_HW_CACHE_L1I << 0 |
1315 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1316 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1317
1318 { .type = PERF_TYPE_HW_CACHE,
1319 .config =
1320 PERF_COUNT_HW_CACHE_DTLB << 0 |
1321 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1322 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
1323
1324 { .type = PERF_TYPE_HW_CACHE,
1325 .config =
1326 PERF_COUNT_HW_CACHE_DTLB << 0 |
1327 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1328 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1329
1330 { .type = PERF_TYPE_HW_CACHE,
1331 .config =
1332 PERF_COUNT_HW_CACHE_ITLB << 0 |
1333 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1334 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
1335
1336 { .type = PERF_TYPE_HW_CACHE,
1337 .config =
1338 PERF_COUNT_HW_CACHE_ITLB << 0 |
1339 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1340 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1341
1342};
1343
1344/*
1345 * Very, very detailed stats (-d -d -d), adding prefetch events:
1346 */
1347 struct perf_event_attr very_very_detailed_attrs[] = {
1348
1349 { .type = PERF_TYPE_HW_CACHE,
1350 .config =
1351 PERF_COUNT_HW_CACHE_L1D << 0 |
1352 (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
1353 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
1354
1355 { .type = PERF_TYPE_HW_CACHE,
1356 .config =
1357 PERF_COUNT_HW_CACHE_L1D << 0 |
1358 (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
1359 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1360};
1361
2cba3ffb
IM
1362 /* Set attrs if no event is selected and !null_run: */
1363 if (null_run)
1364 return 0;
1365
4cabc3d1
AK
1366 if (transaction_run) {
1367 int err;
1368 if (pmu_have_event("cpu", "cycles-ct") &&
1369 pmu_have_event("cpu", "el-start"))
a454742c 1370 err = parse_events(evsel_list, transaction_attrs, NULL);
4cabc3d1 1371 else
a454742c
JO
1372 err = parse_events(evsel_list, transaction_limited_attrs, NULL);
1373 if (err) {
4cabc3d1
AK
1374 fprintf(stderr, "Cannot set up transaction events\n");
1375 return -1;
1376 }
1377 return 0;
1378 }
1379
2cba3ffb 1380 if (!evsel_list->nr_entries) {
79695e1b 1381 if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
50d08e47 1382 return -1;
2cba3ffb
IM
1383 }
1384
1385 /* Detailed events get appended to the event list: */
1386
1387 if (detailed_run < 1)
1388 return 0;
1389
1390 /* Append detailed run extra attributes: */
79695e1b 1391 if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
50d08e47 1392 return -1;
2cba3ffb
IM
1393
1394 if (detailed_run < 2)
1395 return 0;
1396
1397 /* Append very detailed run extra attributes: */
79695e1b 1398 if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
50d08e47 1399 return -1;
2cba3ffb
IM
1400
1401 if (detailed_run < 3)
1402 return 0;
1403
1404 /* Append very, very detailed run extra attributes: */
79695e1b 1405 return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
2cba3ffb
IM
1406}
1407
4979d0c7
JO
1408static const char * const recort_usage[] = {
1409 "perf stat record [<options>]",
1410 NULL,
1411};
1412
3ba78bd0
JO
1413static void init_features(struct perf_session *session)
1414{
1415 int feat;
1416
1417 for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
1418 perf_header__set_feat(&session->header, feat);
1419
1420 perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
1421 perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
1422 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
1423 perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
1424}
1425
4979d0c7
JO
1426static int __cmd_record(int argc, const char **argv)
1427{
1428 struct perf_session *session;
1429 struct perf_data_file *file = &perf_stat.file;
1430
1431 argc = parse_options(argc, argv, stat_options, record_usage,
1432 PARSE_OPT_STOP_AT_NON_OPTION);
1433
1434 if (output_name)
1435 file->path = output_name;
1436
1437 session = perf_session__new(file, false, NULL);
1438 if (session == NULL) {
1439 pr_err("Perf session creation failed.\n");
1440 return -1;
1441 }
1442
3ba78bd0
JO
1443 init_features(session);
1444
4979d0c7
JO
1445 session->evlist = evsel_list;
1446 perf_stat.session = session;
1447 perf_stat.record = true;
1448 return argc;
1449}
1450
1d037ca1 1451int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
5242519b 1452{
b070a547
ACM
1453 const char * const stat_usage[] = {
1454 "perf stat [<options>] [<command>]",
1455 NULL
1456 };
cc03c542 1457 int status = -EINVAL, run_idx;
4aa9015f 1458 const char *mode;
5821522e 1459 FILE *output = stderr;
ec0d3d1f 1460 unsigned int interval;
4979d0c7 1461 const char * const stat_subcommands[] = { "record" };
42202dd5 1462
5af52b51
SE
1463 setlocale(LC_ALL, "");
1464
334fe7a3 1465 evsel_list = perf_evlist__new();
361c99a6
ACM
1466 if (evsel_list == NULL)
1467 return -ENOMEM;
1468
4979d0c7
JO
1469 argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
1470 (const char **) stat_usage,
1471 PARSE_OPT_STOP_AT_NON_OPTION);
1472
1473 if (argc && !strncmp(argv[0], "rec", 3)) {
1474 argc = __cmd_record(argc, argv);
1475 if (argc < 0)
1476 return -1;
1477 }
d7470b6a 1478
ec0d3d1f
JO
1479 interval = stat_config.interval;
1480
4979d0c7
JO
1481 /*
1482 * For record command the -o is already taken care of.
1483 */
1484 if (!STAT_RECORD && output_name && strcmp(output_name, "-"))
4aa9015f
SE
1485 output = NULL;
1486
56f3bae7
JC
1487 if (output_name && output_fd) {
1488 fprintf(stderr, "cannot use both --output and --log-fd\n");
e0547311
JO
1489 parse_options_usage(stat_usage, stat_options, "o", 1);
1490 parse_options_usage(NULL, stat_options, "log-fd", 0);
cc03c542 1491 goto out;
56f3bae7 1492 }
fc3e4d07
SE
1493
1494 if (output_fd < 0) {
1495 fprintf(stderr, "argument to --log-fd must be a > 0\n");
e0547311 1496 parse_options_usage(stat_usage, stat_options, "log-fd", 0);
cc03c542 1497 goto out;
fc3e4d07
SE
1498 }
1499
4aa9015f
SE
1500 if (!output) {
1501 struct timespec tm;
1502 mode = append_file ? "a" : "w";
1503
1504 output = fopen(output_name, mode);
1505 if (!output) {
1506 perror("failed to create output file");
fceda7fe 1507 return -1;
4aa9015f
SE
1508 }
1509 clock_gettime(CLOCK_REALTIME, &tm);
1510 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
fc3e4d07 1511 } else if (output_fd > 0) {
56f3bae7
JC
1512 mode = append_file ? "a" : "w";
1513 output = fdopen(output_fd, mode);
1514 if (!output) {
1515 perror("Failed opening logfd");
1516 return -errno;
1517 }
4aa9015f
SE
1518 }
1519
5821522e
JO
1520 stat_config.output = output;
1521
d4ffd04d 1522 if (csv_sep) {
d7470b6a 1523 csv_output = true;
d4ffd04d
JC
1524 if (!strcmp(csv_sep, "\\t"))
1525 csv_sep = "\t";
1526 } else
d7470b6a
SE
1527 csv_sep = DEFAULT_SEPARATOR;
1528
1529 /*
1530 * let the spreadsheet do the pretty-printing
1531 */
1532 if (csv_output) {
61a9f324 1533 /* User explicitly passed -B? */
d7470b6a
SE
1534 if (big_num_opt == 1) {
1535 fprintf(stderr, "-B option not supported with -x\n");
e0547311
JO
1536 parse_options_usage(stat_usage, stat_options, "B", 1);
1537 parse_options_usage(NULL, stat_options, "x", 1);
cc03c542 1538 goto out;
d7470b6a
SE
1539 } else /* Nope, so disable big number formatting */
1540 big_num = false;
1541 } else if (big_num_opt == 0) /* User passed --no-big-num */
1542 big_num = false;
1543
602ad878 1544 if (!argc && target__none(&target))
e0547311 1545 usage_with_options(stat_usage, stat_options);
ac3063bd 1546
a7e191c3 1547 if (run_count < 0) {
cc03c542 1548 pr_err("Run count must be a positive number\n");
e0547311 1549 parse_options_usage(stat_usage, stat_options, "r", 1);
cc03c542 1550 goto out;
a7e191c3
FD
1551 } else if (run_count == 0) {
1552 forever = true;
1553 run_count = 1;
1554 }
ddcacfa0 1555
421a50f3 1556 if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) {
32b8af82
JO
1557 fprintf(stderr, "The --per-thread option is only available "
1558 "when monitoring via -p -t options.\n");
e0547311
JO
1559 parse_options_usage(NULL, stat_options, "p", 1);
1560 parse_options_usage(NULL, stat_options, "t", 1);
32b8af82
JO
1561 goto out;
1562 }
1563
1564 /*
1565 * no_aggr, cgroup are for system-wide only
1566 * --per-thread is aggregated per thread, we dont mix it with cpu mode
1567 */
421a50f3
JO
1568 if (((stat_config.aggr_mode != AGGR_GLOBAL &&
1569 stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
602ad878 1570 !target__has_cpu(&target)) {
023695d9
SE
1571 fprintf(stderr, "both cgroup and no-aggregation "
1572 "modes only available in system-wide mode\n");
1573
e0547311
JO
1574 parse_options_usage(stat_usage, stat_options, "G", 1);
1575 parse_options_usage(NULL, stat_options, "A", 1);
1576 parse_options_usage(NULL, stat_options, "a", 1);
cc03c542 1577 goto out;
d7e7a451
SE
1578 }
1579
2cba3ffb
IM
1580 if (add_default_attributes())
1581 goto out;
ddcacfa0 1582
602ad878 1583 target__validate(&target);
5c98d466 1584
77a6f014 1585 if (perf_evlist__create_maps(evsel_list, &target) < 0) {
602ad878 1586 if (target__has_task(&target)) {
77a6f014 1587 pr_err("Problems finding threads of monitor\n");
e0547311
JO
1588 parse_options_usage(stat_usage, stat_options, "p", 1);
1589 parse_options_usage(NULL, stat_options, "t", 1);
602ad878 1590 } else if (target__has_cpu(&target)) {
77a6f014 1591 perror("failed to parse CPUs map");
e0547311
JO
1592 parse_options_usage(stat_usage, stat_options, "C", 1);
1593 parse_options_usage(NULL, stat_options, "a", 1);
cc03c542
NK
1594 }
1595 goto out;
60d567e2 1596 }
32b8af82
JO
1597
1598 /*
1599 * Initialize thread_map with comm names,
1600 * so we could print it out on output.
1601 */
421a50f3 1602 if (stat_config.aggr_mode == AGGR_THREAD)
32b8af82
JO
1603 thread_map__read_comms(evsel_list->threads);
1604
13370a9b 1605 if (interval && interval < 100) {
19afd104
KL
1606 if (interval < 10) {
1607 pr_err("print interval must be >= 10ms\n");
e0547311 1608 parse_options_usage(stat_usage, stat_options, "I", 1);
19afd104
KL
1609 goto out;
1610 } else
1611 pr_warning("print interval < 100ms. "
1612 "The overhead percentage could be high in some cases. "
1613 "Please proceed with caution.\n");
13370a9b 1614 }
c45c6ea2 1615
d134ffb9 1616 if (perf_evlist__alloc_stats(evsel_list, interval))
03ad9747 1617 goto out;
d6d901c2 1618
86ee6e18 1619 if (perf_stat_init_aggr_mode())
03ad9747 1620 goto out;
86ee6e18 1621
58d7e993
IM
1622 /*
1623 * We dont want to block the signals - that would cause
1624 * child tasks to inherit that and Ctrl-C would not work.
1625 * What we want is for Ctrl-C to work in the exec()-ed
1626 * task, but being ignored by perf stat itself:
1627 */
f7b7c26e 1628 atexit(sig_atexit);
a7e191c3
FD
1629 if (!forever)
1630 signal(SIGINT, skip_signal);
13370a9b 1631 signal(SIGCHLD, skip_signal);
58d7e993
IM
1632 signal(SIGALRM, skip_signal);
1633 signal(SIGABRT, skip_signal);
1634
42202dd5 1635 status = 0;
a7e191c3 1636 for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
42202dd5 1637 if (run_count != 1 && verbose)
4aa9015f
SE
1638 fprintf(output, "[ perf stat: executing run #%d ... ]\n",
1639 run_idx + 1);
f9cef0a9 1640
42202dd5 1641 status = run_perf_stat(argc, argv);
a7e191c3 1642 if (forever && status != -1) {
d4f63a47 1643 print_counters(NULL, argc, argv);
254ecbc7 1644 perf_stat__reset_stats();
a7e191c3 1645 }
42202dd5
IM
1646 }
1647
a7e191c3 1648 if (!forever && status != -1 && !interval)
d4f63a47 1649 print_counters(NULL, argc, argv);
d134ffb9 1650
4979d0c7
JO
1651 if (STAT_RECORD) {
1652 /*
1653 * We synthesize the kernel mmap record just so that older tools
1654 * don't emit warnings about not being able to resolve symbols
1655 * due to /proc/sys/kernel/kptr_restrict settings and instear provide
1656 * a saner message about no samples being in the perf.data file.
1657 *
1658 * This also serves to suppress a warning about f_header.data.size == 0
8b99b1a4
JO
1659 * in header.c at the moment 'perf stat record' gets introduced, which
1660 * is not really needed once we start adding the stat specific PERF_RECORD_
1661 * records, but the need to suppress the kptr_restrict messages in older
1662 * tools remain -acme
4979d0c7
JO
1663 */
1664 int fd = perf_data_file__fd(&perf_stat.file);
1665 int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat,
1666 process_synthesized_event,
1667 &perf_stat.session->machines.host);
1668 if (err) {
1669 pr_warning("Couldn't synthesize the kernel mmap record, harmless, "
1670 "older tools may produce warnings about this file\n.");
1671 }
1672
664c98d4
JO
1673 if (!perf_stat.file.is_pipe) {
1674 perf_stat.session->header.data_size += perf_stat.bytes_written;
1675 perf_session__write_header(perf_stat.session, evsel_list, fd, true);
1676 }
4979d0c7
JO
1677
1678 perf_session__delete(perf_stat.session);
1679 }
1680
544c2ae7 1681 perf_stat__exit_aggr_mode();
d134ffb9 1682 perf_evlist__free_stats(evsel_list);
0015e2e1
ACM
1683out:
1684 perf_evlist__delete(evsel_list);
42202dd5 1685 return status;
ddcacfa0 1686}