perf stat: Pass a 'struct perf_stat_config' argument to global print functions
[sfrench/cifs-2.6.git] / tools / perf / builtin-stat.c
1 /*
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:
8
9    $ perf stat ./hackbench 10
10
11   Time: 0.118
12
13   Performance counter stats for './hackbench 10':
14
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
28
29  *
30  * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
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>
39  *   Jaswinder Singh Rajput <jaswinder@kernel.org>
40  *
41  * Released under the GPL v2. (and only v2, not any later version)
42  */
43
44 #include "perf.h"
45 #include "builtin.h"
46 #include "util/cgroup.h"
47 #include "util/util.h"
48 #include <subcmd/parse-options.h>
49 #include "util/parse-events.h"
50 #include "util/pmu.h"
51 #include "util/event.h"
52 #include "util/evlist.h"
53 #include "util/evsel.h"
54 #include "util/debug.h"
55 #include "util/drv_configs.h"
56 #include "util/color.h"
57 #include "util/stat.h"
58 #include "util/header.h"
59 #include "util/cpumap.h"
60 #include "util/thread.h"
61 #include "util/thread_map.h"
62 #include "util/counts.h"
63 #include "util/group.h"
64 #include "util/session.h"
65 #include "util/tool.h"
66 #include "util/string2.h"
67 #include "util/metricgroup.h"
68 #include "util/top.h"
69 #include "asm/bug.h"
70
71 #include <linux/time64.h>
72 #include <api/fs/fs.h>
73 #include <errno.h>
74 #include <signal.h>
75 #include <stdlib.h>
76 #include <sys/prctl.h>
77 #include <inttypes.h>
78 #include <locale.h>
79 #include <math.h>
80 #include <sys/types.h>
81 #include <sys/stat.h>
82 #include <sys/wait.h>
83 #include <unistd.h>
84 #include <sys/time.h>
85 #include <sys/resource.h>
86 #include <sys/wait.h>
87
88 #include "sane_ctype.h"
89
90 #define DEFAULT_SEPARATOR       " "
91 #define CNTR_NOT_SUPPORTED      "<not supported>"
92 #define CNTR_NOT_COUNTED        "<not counted>"
93 #define FREEZE_ON_SMI_PATH      "devices/cpu/freeze_on_smi"
94
95 static void print_counters(struct timespec *ts, int argc, const char **argv);
96
97 /* Default events used for perf stat -T */
98 static const char *transaction_attrs = {
99         "task-clock,"
100         "{"
101         "instructions,"
102         "cycles,"
103         "cpu/cycles-t/,"
104         "cpu/tx-start/,"
105         "cpu/el-start/,"
106         "cpu/cycles-ct/"
107         "}"
108 };
109
110 /* More limited version when the CPU does not have all events. */
111 static const char * transaction_limited_attrs = {
112         "task-clock,"
113         "{"
114         "instructions,"
115         "cycles,"
116         "cpu/cycles-t/,"
117         "cpu/tx-start/"
118         "}"
119 };
120
121 static const char * topdown_attrs[] = {
122         "topdown-total-slots",
123         "topdown-slots-retired",
124         "topdown-recovery-bubbles",
125         "topdown-fetch-bubbles",
126         "topdown-slots-issued",
127         NULL,
128 };
129
130 static const char *smi_cost_attrs = {
131         "{"
132         "msr/aperf/,"
133         "msr/smi/,"
134         "cycles"
135         "}"
136 };
137
138 static struct perf_evlist       *evsel_list;
139
140 static struct rblist             metric_events;
141
142 static struct target target = {
143         .uid    = UINT_MAX,
144 };
145
146 typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);
147
148 #define METRIC_ONLY_LEN 20
149
150 static int                      run_count                       =  1;
151 static volatile pid_t           child_pid                       = -1;
152 static bool                     null_run                        =  false;
153 static int                      detailed_run                    =  0;
154 static bool                     transaction_run;
155 static bool                     topdown_run                     = false;
156 static bool                     smi_cost                        = false;
157 static bool                     smi_reset                       = false;
158 static bool                     big_num                         =  true;
159 static int                      big_num_opt                     =  -1;
160 static const char               *csv_sep                        = NULL;
161 static bool                     csv_output                      = false;
162 static bool                     group                           = false;
163 static const char               *pre_cmd                        = NULL;
164 static const char               *post_cmd                       = NULL;
165 static bool                     sync_run                        = false;
166 static unsigned int             unit_width                      = 4; /* strlen("unit") */
167 static bool                     forever                         = false;
168 static bool                     metric_only                     = false;
169 static bool                     force_metric_only               = false;
170 static bool                     no_merge                        = false;
171 static bool                     walltime_run_table              = false;
172 static struct timespec          ref_time;
173 static struct cpu_map           *aggr_map;
174 static aggr_get_id_t            aggr_get_id;
175 static bool                     append_file;
176 static bool                     interval_count;
177 static bool                     interval_clear;
178 static const char               *output_name;
179 static int                      output_fd;
180 static int                      print_free_counters_hint;
181 static int                      print_mixed_hw_group_error;
182 static u64                      *walltime_run;
183 static bool                     ru_display                      = false;
184 static struct rusage            ru_data;
185 static unsigned int             metric_only_len                 = METRIC_ONLY_LEN;
186
187 struct perf_stat {
188         bool                     record;
189         struct perf_data         data;
190         struct perf_session     *session;
191         u64                      bytes_written;
192         struct perf_tool         tool;
193         bool                     maps_allocated;
194         struct cpu_map          *cpus;
195         struct thread_map       *threads;
196         enum aggr_mode           aggr_mode;
197 };
198
199 static struct perf_stat         perf_stat;
200 #define STAT_RECORD             perf_stat.record
201
202 static volatile int done = 0;
203
204 static struct perf_stat_config stat_config = {
205         .aggr_mode      = AGGR_GLOBAL,
206         .scale          = true,
207 };
208
209 static bool is_duration_time(struct perf_evsel *evsel)
210 {
211         return !strcmp(evsel->name, "duration_time");
212 }
213
214 static inline void diff_timespec(struct timespec *r, struct timespec *a,
215                                  struct timespec *b)
216 {
217         r->tv_sec = a->tv_sec - b->tv_sec;
218         if (a->tv_nsec < b->tv_nsec) {
219                 r->tv_nsec = a->tv_nsec + NSEC_PER_SEC - b->tv_nsec;
220                 r->tv_sec--;
221         } else {
222                 r->tv_nsec = a->tv_nsec - b->tv_nsec ;
223         }
224 }
225
226 static void perf_stat__reset_stats(void)
227 {
228         int i;
229
230         perf_evlist__reset_stats(evsel_list);
231         perf_stat__reset_shadow_stats();
232
233         for (i = 0; i < stat_config.stats_num; i++)
234                 perf_stat__reset_shadow_per_stat(&stat_config.stats[i]);
235 }
236
237 static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
238                                      union perf_event *event,
239                                      struct perf_sample *sample __maybe_unused,
240                                      struct machine *machine __maybe_unused)
241 {
242         if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) {
243                 pr_err("failed to write perf data, error: %m\n");
244                 return -1;
245         }
246
247         perf_stat.bytes_written += event->header.size;
248         return 0;
249 }
250
251 static int write_stat_round_event(u64 tm, u64 type)
252 {
253         return perf_event__synthesize_stat_round(NULL, tm, type,
254                                                  process_synthesized_event,
255                                                  NULL);
256 }
257
258 #define WRITE_STAT_ROUND_EVENT(time, interval) \
259         write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
260
261 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
262
263 static int
264 perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread,
265                              struct perf_counts_values *count)
266 {
267         struct perf_sample_id *sid = SID(counter, cpu, thread);
268
269         return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
270                                            process_synthesized_event, NULL);
271 }
272
273 /*
274  * Read out the results of a single counter:
275  * do not aggregate counts across CPUs in system-wide mode
276  */
277 static int read_counter(struct perf_evsel *counter)
278 {
279         int nthreads = thread_map__nr(evsel_list->threads);
280         int ncpus, cpu, thread;
281
282         if (target__has_cpu(&target) && !target__has_per_thread(&target))
283                 ncpus = perf_evsel__nr_cpus(counter);
284         else
285                 ncpus = 1;
286
287         if (!counter->supported)
288                 return -ENOENT;
289
290         if (counter->system_wide)
291                 nthreads = 1;
292
293         for (thread = 0; thread < nthreads; thread++) {
294                 for (cpu = 0; cpu < ncpus; cpu++) {
295                         struct perf_counts_values *count;
296
297                         count = perf_counts(counter->counts, cpu, thread);
298
299                         /*
300                          * The leader's group read loads data into its group members
301                          * (via perf_evsel__read_counter) and sets threir count->loaded.
302                          */
303                         if (!count->loaded &&
304                             perf_evsel__read_counter(counter, cpu, thread)) {
305                                 counter->counts->scaled = -1;
306                                 perf_counts(counter->counts, cpu, thread)->ena = 0;
307                                 perf_counts(counter->counts, cpu, thread)->run = 0;
308                                 return -1;
309                         }
310
311                         count->loaded = false;
312
313                         if (STAT_RECORD) {
314                                 if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
315                                         pr_err("failed to write stat event\n");
316                                         return -1;
317                                 }
318                         }
319
320                         if (verbose > 1) {
321                                 fprintf(stat_config.output,
322                                         "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
323                                                 perf_evsel__name(counter),
324                                                 cpu,
325                                                 count->val, count->ena, count->run);
326                         }
327                 }
328         }
329
330         return 0;
331 }
332
333 static void read_counters(void)
334 {
335         struct perf_evsel *counter;
336         int ret;
337
338         evlist__for_each_entry(evsel_list, counter) {
339                 ret = read_counter(counter);
340                 if (ret)
341                         pr_debug("failed to read counter %s\n", counter->name);
342
343                 if (ret == 0 && perf_stat_process_counter(&stat_config, counter))
344                         pr_warning("failed to process counter %s\n", counter->name);
345         }
346 }
347
348 static void process_interval(void)
349 {
350         struct timespec ts, rs;
351
352         read_counters();
353
354         clock_gettime(CLOCK_MONOTONIC, &ts);
355         diff_timespec(&rs, &ts, &ref_time);
356
357         if (STAT_RECORD) {
358                 if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL))
359                         pr_err("failed to write stat round event\n");
360         }
361
362         init_stats(&walltime_nsecs_stats);
363         update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000);
364         print_counters(&rs, 0, NULL);
365 }
366
367 static void enable_counters(void)
368 {
369         if (stat_config.initial_delay)
370                 usleep(stat_config.initial_delay * USEC_PER_MSEC);
371
372         /*
373          * We need to enable counters only if:
374          * - we don't have tracee (attaching to task or cpu)
375          * - we have initial delay configured
376          */
377         if (!target__none(&target) || stat_config.initial_delay)
378                 perf_evlist__enable(evsel_list);
379 }
380
381 static void disable_counters(void)
382 {
383         /*
384          * If we don't have tracee (attaching to task or cpu), counters may
385          * still be running. To get accurate group ratios, we must stop groups
386          * from counting before reading their constituent counters.
387          */
388         if (!target__none(&target))
389                 perf_evlist__disable(evsel_list);
390 }
391
392 static volatile int workload_exec_errno;
393
394 /*
395  * perf_evlist__prepare_workload will send a SIGUSR1
396  * if the fork fails, since we asked by setting its
397  * want_signal to true.
398  */
399 static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
400                                         void *ucontext __maybe_unused)
401 {
402         workload_exec_errno = info->si_value.sival_int;
403 }
404
405 static bool perf_evsel__should_store_id(struct perf_evsel *counter)
406 {
407         return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID;
408 }
409
410 static struct perf_evsel *perf_evsel__reset_weak_group(struct perf_evsel *evsel)
411 {
412         struct perf_evsel *c2, *leader;
413         bool is_open = true;
414
415         leader = evsel->leader;
416         pr_debug("Weak group for %s/%d failed\n",
417                         leader->name, leader->nr_members);
418
419         /*
420          * for_each_group_member doesn't work here because it doesn't
421          * include the first entry.
422          */
423         evlist__for_each_entry(evsel_list, c2) {
424                 if (c2 == evsel)
425                         is_open = false;
426                 if (c2->leader == leader) {
427                         if (is_open)
428                                 perf_evsel__close(c2);
429                         c2->leader = c2;
430                         c2->nr_members = 0;
431                 }
432         }
433         return leader;
434 }
435
436 static int __run_perf_stat(int argc, const char **argv, int run_idx)
437 {
438         int interval = stat_config.interval;
439         int times = stat_config.times;
440         int timeout = stat_config.timeout;
441         char msg[BUFSIZ];
442         unsigned long long t0, t1;
443         struct perf_evsel *counter;
444         struct timespec ts;
445         size_t l;
446         int status = 0;
447         const bool forks = (argc > 0);
448         bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false;
449         struct perf_evsel_config_term *err_term;
450
451         if (interval) {
452                 ts.tv_sec  = interval / USEC_PER_MSEC;
453                 ts.tv_nsec = (interval % USEC_PER_MSEC) * NSEC_PER_MSEC;
454         } else if (timeout) {
455                 ts.tv_sec  = timeout / USEC_PER_MSEC;
456                 ts.tv_nsec = (timeout % USEC_PER_MSEC) * NSEC_PER_MSEC;
457         } else {
458                 ts.tv_sec  = 1;
459                 ts.tv_nsec = 0;
460         }
461
462         if (forks) {
463                 if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe,
464                                                   workload_exec_failed_signal) < 0) {
465                         perror("failed to prepare workload");
466                         return -1;
467                 }
468                 child_pid = evsel_list->workload.pid;
469         }
470
471         if (group)
472                 perf_evlist__set_leader(evsel_list);
473
474         evlist__for_each_entry(evsel_list, counter) {
475 try_again:
476                 if (create_perf_stat_counter(counter, &stat_config, &target) < 0) {
477
478                         /* Weak group failed. Reset the group. */
479                         if ((errno == EINVAL || errno == EBADF) &&
480                             counter->leader != counter &&
481                             counter->weak_group) {
482                                 counter = perf_evsel__reset_weak_group(counter);
483                                 goto try_again;
484                         }
485
486                         /*
487                          * PPC returns ENXIO for HW counters until 2.6.37
488                          * (behavior changed with commit b0a873e).
489                          */
490                         if (errno == EINVAL || errno == ENOSYS ||
491                             errno == ENOENT || errno == EOPNOTSUPP ||
492                             errno == ENXIO) {
493                                 if (verbose > 0)
494                                         ui__warning("%s event is not supported by the kernel.\n",
495                                                     perf_evsel__name(counter));
496                                 counter->supported = false;
497
498                                 if ((counter->leader != counter) ||
499                                     !(counter->leader->nr_members > 1))
500                                         continue;
501                         } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
502                                 if (verbose > 0)
503                                         ui__warning("%s\n", msg);
504                                 goto try_again;
505                         } else if (target__has_per_thread(&target) &&
506                                    evsel_list->threads &&
507                                    evsel_list->threads->err_thread != -1) {
508                                 /*
509                                  * For global --per-thread case, skip current
510                                  * error thread.
511                                  */
512                                 if (!thread_map__remove(evsel_list->threads,
513                                                         evsel_list->threads->err_thread)) {
514                                         evsel_list->threads->err_thread = -1;
515                                         goto try_again;
516                                 }
517                         }
518
519                         perf_evsel__open_strerror(counter, &target,
520                                                   errno, msg, sizeof(msg));
521                         ui__error("%s\n", msg);
522
523                         if (child_pid != -1)
524                                 kill(child_pid, SIGTERM);
525
526                         return -1;
527                 }
528                 counter->supported = true;
529
530                 l = strlen(counter->unit);
531                 if (l > unit_width)
532                         unit_width = l;
533
534                 if (perf_evsel__should_store_id(counter) &&
535                     perf_evsel__store_ids(counter, evsel_list))
536                         return -1;
537         }
538
539         if (perf_evlist__apply_filters(evsel_list, &counter)) {
540                 pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
541                         counter->filter, perf_evsel__name(counter), errno,
542                         str_error_r(errno, msg, sizeof(msg)));
543                 return -1;
544         }
545
546         if (perf_evlist__apply_drv_configs(evsel_list, &counter, &err_term)) {
547                 pr_err("failed to set config \"%s\" on event %s with %d (%s)\n",
548                       err_term->val.drv_cfg, perf_evsel__name(counter), errno,
549                       str_error_r(errno, msg, sizeof(msg)));
550                 return -1;
551         }
552
553         if (STAT_RECORD) {
554                 int err, fd = perf_data__fd(&perf_stat.data);
555
556                 if (is_pipe) {
557                         err = perf_header__write_pipe(perf_data__fd(&perf_stat.data));
558                 } else {
559                         err = perf_session__write_header(perf_stat.session, evsel_list,
560                                                          fd, false);
561                 }
562
563                 if (err < 0)
564                         return err;
565
566                 err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list,
567                                                   process_synthesized_event, is_pipe);
568                 if (err < 0)
569                         return err;
570         }
571
572         /*
573          * Enable counters and exec the command:
574          */
575         t0 = rdclock();
576         clock_gettime(CLOCK_MONOTONIC, &ref_time);
577
578         if (forks) {
579                 perf_evlist__start_workload(evsel_list);
580                 enable_counters();
581
582                 if (interval || timeout) {
583                         while (!waitpid(child_pid, &status, WNOHANG)) {
584                                 nanosleep(&ts, NULL);
585                                 if (timeout)
586                                         break;
587                                 process_interval();
588                                 if (interval_count && !(--times))
589                                         break;
590                         }
591                 }
592                 wait4(child_pid, &status, 0, &ru_data);
593
594                 if (workload_exec_errno) {
595                         const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
596                         pr_err("Workload failed: %s\n", emsg);
597                         return -1;
598                 }
599
600                 if (WIFSIGNALED(status))
601                         psignal(WTERMSIG(status), argv[0]);
602         } else {
603                 enable_counters();
604                 while (!done) {
605                         nanosleep(&ts, NULL);
606                         if (timeout)
607                                 break;
608                         if (interval) {
609                                 process_interval();
610                                 if (interval_count && !(--times))
611                                         break;
612                         }
613                 }
614         }
615
616         disable_counters();
617
618         t1 = rdclock();
619
620         if (walltime_run_table)
621                 walltime_run[run_idx] = t1 - t0;
622
623         update_stats(&walltime_nsecs_stats, t1 - t0);
624
625         /*
626          * Closing a group leader splits the group, and as we only disable
627          * group leaders, results in remaining events becoming enabled. To
628          * avoid arbitrary skew, we must read all counters before closing any
629          * group leaders.
630          */
631         read_counters();
632         perf_evlist__close(evsel_list);
633
634         return WEXITSTATUS(status);
635 }
636
637 static int run_perf_stat(int argc, const char **argv, int run_idx)
638 {
639         int ret;
640
641         if (pre_cmd) {
642                 ret = system(pre_cmd);
643                 if (ret)
644                         return ret;
645         }
646
647         if (sync_run)
648                 sync();
649
650         ret = __run_perf_stat(argc, argv, run_idx);
651         if (ret)
652                 return ret;
653
654         if (post_cmd) {
655                 ret = system(post_cmd);
656                 if (ret)
657                         return ret;
658         }
659
660         return ret;
661 }
662
663 static void print_running(struct perf_stat_config *config,
664                           u64 run, u64 ena)
665 {
666         if (csv_output) {
667                 fprintf(config->output, "%s%" PRIu64 "%s%.2f",
668                                         csv_sep,
669                                         run,
670                                         csv_sep,
671                                         ena ? 100.0 * run / ena : 100.0);
672         } else if (run != ena) {
673                 fprintf(config->output, "  (%.2f%%)", 100.0 * run / ena);
674         }
675 }
676
677 static void print_noise_pct(struct perf_stat_config *config,
678                             double total, double avg)
679 {
680         double pct = rel_stddev_stats(total, avg);
681
682         if (csv_output)
683                 fprintf(config->output, "%s%.2f%%", csv_sep, pct);
684         else if (pct)
685                 fprintf(config->output, "  ( +-%6.2f%% )", pct);
686 }
687
688 static void print_noise(struct perf_stat_config *config,
689                         struct perf_evsel *evsel, double avg)
690 {
691         struct perf_stat_evsel *ps;
692
693         if (run_count == 1)
694                 return;
695
696         ps = evsel->stats;
697         print_noise_pct(config, stddev_stats(&ps->res_stats[0]), avg);
698 }
699
700 static void aggr_printout(struct perf_stat_config *config,
701                           struct perf_evsel *evsel, int id, int nr)
702 {
703         switch (config->aggr_mode) {
704         case AGGR_CORE:
705                 fprintf(config->output, "S%d-C%*d%s%*d%s",
706                         cpu_map__id_to_socket(id),
707                         csv_output ? 0 : -8,
708                         cpu_map__id_to_cpu(id),
709                         csv_sep,
710                         csv_output ? 0 : 4,
711                         nr,
712                         csv_sep);
713                 break;
714         case AGGR_SOCKET:
715                 fprintf(config->output, "S%*d%s%*d%s",
716                         csv_output ? 0 : -5,
717                         id,
718                         csv_sep,
719                         csv_output ? 0 : 4,
720                         nr,
721                         csv_sep);
722                         break;
723         case AGGR_NONE:
724                 fprintf(config->output, "CPU%*d%s",
725                         csv_output ? 0 : -4,
726                         perf_evsel__cpus(evsel)->map[id], csv_sep);
727                 break;
728         case AGGR_THREAD:
729                 fprintf(config->output, "%*s-%*d%s",
730                         csv_output ? 0 : 16,
731                         thread_map__comm(evsel->threads, id),
732                         csv_output ? 0 : -8,
733                         thread_map__pid(evsel->threads, id),
734                         csv_sep);
735                 break;
736         case AGGR_GLOBAL:
737         case AGGR_UNSET:
738         default:
739                 break;
740         }
741 }
742
743 struct outstate {
744         FILE *fh;
745         bool newline;
746         const char *prefix;
747         int  nfields;
748         int  id, nr;
749         struct perf_evsel *evsel;
750 };
751
752 #define METRIC_LEN  35
753
754 static void new_line_std(struct perf_stat_config *config __maybe_unused,
755                          void *ctx)
756 {
757         struct outstate *os = ctx;
758
759         os->newline = true;
760 }
761
762 static void do_new_line_std(struct perf_stat_config *config,
763                             struct outstate *os)
764 {
765         fputc('\n', os->fh);
766         fputs(os->prefix, os->fh);
767         aggr_printout(config, os->evsel, os->id, os->nr);
768         if (config->aggr_mode == AGGR_NONE)
769                 fprintf(os->fh, "        ");
770         fprintf(os->fh, "                                                 ");
771 }
772
773 static void print_metric_std(struct perf_stat_config *config,
774                              void *ctx, const char *color, const char *fmt,
775                              const char *unit, double val)
776 {
777         struct outstate *os = ctx;
778         FILE *out = os->fh;
779         int n;
780         bool newline = os->newline;
781
782         os->newline = false;
783
784         if (unit == NULL || fmt == NULL) {
785                 fprintf(out, "%-*s", METRIC_LEN, "");
786                 return;
787         }
788
789         if (newline)
790                 do_new_line_std(config, os);
791
792         n = fprintf(out, " # ");
793         if (color)
794                 n += color_fprintf(out, color, fmt, val);
795         else
796                 n += fprintf(out, fmt, val);
797         fprintf(out, " %-*s", METRIC_LEN - n - 1, unit);
798 }
799
800 static void new_line_csv(struct perf_stat_config *config, void *ctx)
801 {
802         struct outstate *os = ctx;
803         int i;
804
805         fputc('\n', os->fh);
806         if (os->prefix)
807                 fprintf(os->fh, "%s%s", os->prefix, csv_sep);
808         aggr_printout(config, os->evsel, os->id, os->nr);
809         for (i = 0; i < os->nfields; i++)
810                 fputs(csv_sep, os->fh);
811 }
812
813 static void print_metric_csv(struct perf_stat_config *config __maybe_unused,
814                              void *ctx,
815                              const char *color __maybe_unused,
816                              const char *fmt, const char *unit, double val)
817 {
818         struct outstate *os = ctx;
819         FILE *out = os->fh;
820         char buf[64], *vals, *ends;
821
822         if (unit == NULL || fmt == NULL) {
823                 fprintf(out, "%s%s", csv_sep, csv_sep);
824                 return;
825         }
826         snprintf(buf, sizeof(buf), fmt, val);
827         ends = vals = ltrim(buf);
828         while (isdigit(*ends) || *ends == '.')
829                 ends++;
830         *ends = 0;
831         while (isspace(*unit))
832                 unit++;
833         fprintf(out, "%s%s%s%s", csv_sep, vals, csv_sep, unit);
834 }
835
836 /* Filter out some columns that don't work well in metrics only mode */
837
838 static bool valid_only_metric(const char *unit)
839 {
840         if (!unit)
841                 return false;
842         if (strstr(unit, "/sec") ||
843             strstr(unit, "hz") ||
844             strstr(unit, "Hz") ||
845             strstr(unit, "CPUs utilized"))
846                 return false;
847         return true;
848 }
849
850 static const char *fixunit(char *buf, struct perf_evsel *evsel,
851                            const char *unit)
852 {
853         if (!strncmp(unit, "of all", 6)) {
854                 snprintf(buf, 1024, "%s %s", perf_evsel__name(evsel),
855                          unit);
856                 return buf;
857         }
858         return unit;
859 }
860
861 static void print_metric_only(struct perf_stat_config *config __maybe_unused,
862                               void *ctx, const char *color, const char *fmt,
863                               const char *unit, double val)
864 {
865         struct outstate *os = ctx;
866         FILE *out = os->fh;
867         char buf[1024], str[1024];
868         unsigned mlen = metric_only_len;
869
870         if (!valid_only_metric(unit))
871                 return;
872         unit = fixunit(buf, os->evsel, unit);
873         if (mlen < strlen(unit))
874                 mlen = strlen(unit) + 1;
875
876         if (color)
877                 mlen += strlen(color) + sizeof(PERF_COLOR_RESET) - 1;
878
879         color_snprintf(str, sizeof(str), color ?: "", fmt, val);
880         fprintf(out, "%*s ", mlen, str);
881 }
882
883 static void print_metric_only_csv(struct perf_stat_config *config __maybe_unused,
884                                   void *ctx, const char *color __maybe_unused,
885                                   const char *fmt,
886                                   const char *unit, double val)
887 {
888         struct outstate *os = ctx;
889         FILE *out = os->fh;
890         char buf[64], *vals, *ends;
891         char tbuf[1024];
892
893         if (!valid_only_metric(unit))
894                 return;
895         unit = fixunit(tbuf, os->evsel, unit);
896         snprintf(buf, sizeof buf, fmt, val);
897         ends = vals = ltrim(buf);
898         while (isdigit(*ends) || *ends == '.')
899                 ends++;
900         *ends = 0;
901         fprintf(out, "%s%s", vals, csv_sep);
902 }
903
904 static void new_line_metric(struct perf_stat_config *config __maybe_unused,
905                             void *ctx __maybe_unused)
906 {
907 }
908
909 static void print_metric_header(struct perf_stat_config *config __maybe_unused,
910                                 void *ctx, const char *color __maybe_unused,
911                                 const char *fmt __maybe_unused,
912                                 const char *unit, double val __maybe_unused)
913 {
914         struct outstate *os = ctx;
915         char tbuf[1024];
916
917         if (!valid_only_metric(unit))
918                 return;
919         unit = fixunit(tbuf, os->evsel, unit);
920         if (csv_output)
921                 fprintf(os->fh, "%s%s", unit, csv_sep);
922         else
923                 fprintf(os->fh, "%*s ", metric_only_len, unit);
924 }
925
926 static int first_shadow_cpu(struct perf_evsel *evsel, int id)
927 {
928         int i;
929
930         if (!aggr_get_id)
931                 return 0;
932
933         if (stat_config.aggr_mode == AGGR_NONE)
934                 return id;
935
936         if (stat_config.aggr_mode == AGGR_GLOBAL)
937                 return 0;
938
939         for (i = 0; i < perf_evsel__nr_cpus(evsel); i++) {
940                 int cpu2 = perf_evsel__cpus(evsel)->map[i];
941
942                 if (aggr_get_id(evsel_list->cpus, cpu2) == id)
943                         return cpu2;
944         }
945         return 0;
946 }
947
948 static void abs_printout(struct perf_stat_config *config,
949                          int id, int nr, struct perf_evsel *evsel, double avg)
950 {
951         FILE *output = config->output;
952         double sc =  evsel->scale;
953         const char *fmt;
954
955         if (csv_output) {
956                 fmt = floor(sc) != sc ?  "%.2f%s" : "%.0f%s";
957         } else {
958                 if (big_num)
959                         fmt = floor(sc) != sc ? "%'18.2f%s" : "%'18.0f%s";
960                 else
961                         fmt = floor(sc) != sc ? "%18.2f%s" : "%18.0f%s";
962         }
963
964         aggr_printout(config, evsel, id, nr);
965
966         fprintf(output, fmt, avg, csv_sep);
967
968         if (evsel->unit)
969                 fprintf(output, "%-*s%s",
970                         csv_output ? 0 : unit_width,
971                         evsel->unit, csv_sep);
972
973         fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
974
975         if (evsel->cgrp)
976                 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
977 }
978
979 static bool is_mixed_hw_group(struct perf_evsel *counter)
980 {
981         struct perf_evlist *evlist = counter->evlist;
982         u32 pmu_type = counter->attr.type;
983         struct perf_evsel *pos;
984
985         if (counter->nr_members < 2)
986                 return false;
987
988         evlist__for_each_entry(evlist, pos) {
989                 /* software events can be part of any hardware group */
990                 if (pos->attr.type == PERF_TYPE_SOFTWARE)
991                         continue;
992                 if (pmu_type == PERF_TYPE_SOFTWARE) {
993                         pmu_type = pos->attr.type;
994                         continue;
995                 }
996                 if (pmu_type != pos->attr.type)
997                         return true;
998         }
999
1000         return false;
1001 }
1002
1003 static void printout(struct perf_stat_config *config, int id, int nr,
1004                      struct perf_evsel *counter, double uval,
1005                      char *prefix, u64 run, u64 ena, double noise,
1006                      struct runtime_stat *st)
1007 {
1008         struct perf_stat_output_ctx out;
1009         struct outstate os = {
1010                 .fh = config->output,
1011                 .prefix = prefix ? prefix : "",
1012                 .id = id,
1013                 .nr = nr,
1014                 .evsel = counter,
1015         };
1016         print_metric_t pm = print_metric_std;
1017         new_line_t nl;
1018
1019         if (metric_only) {
1020                 nl = new_line_metric;
1021                 if (csv_output)
1022                         pm = print_metric_only_csv;
1023                 else
1024                         pm = print_metric_only;
1025         } else
1026                 nl = new_line_std;
1027
1028         if (csv_output && !metric_only) {
1029                 static int aggr_fields[] = {
1030                         [AGGR_GLOBAL] = 0,
1031                         [AGGR_THREAD] = 1,
1032                         [AGGR_NONE] = 1,
1033                         [AGGR_SOCKET] = 2,
1034                         [AGGR_CORE] = 2,
1035                 };
1036
1037                 pm = print_metric_csv;
1038                 nl = new_line_csv;
1039                 os.nfields = 3;
1040                 os.nfields += aggr_fields[config->aggr_mode];
1041                 if (counter->cgrp)
1042                         os.nfields++;
1043         }
1044         if (run == 0 || ena == 0 || counter->counts->scaled == -1) {
1045                 if (metric_only) {
1046                         pm(config, &os, NULL, "", "", 0);
1047                         return;
1048                 }
1049                 aggr_printout(config, counter, id, nr);
1050
1051                 fprintf(config->output, "%*s%s",
1052                         csv_output ? 0 : 18,
1053                         counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
1054                         csv_sep);
1055
1056                 if (counter->supported) {
1057                         print_free_counters_hint = 1;
1058                         if (is_mixed_hw_group(counter))
1059                                 print_mixed_hw_group_error = 1;
1060                 }
1061
1062                 fprintf(config->output, "%-*s%s",
1063                         csv_output ? 0 : unit_width,
1064                         counter->unit, csv_sep);
1065
1066                 fprintf(config->output, "%*s",
1067                         csv_output ? 0 : -25,
1068                         perf_evsel__name(counter));
1069
1070                 if (counter->cgrp)
1071                         fprintf(config->output, "%s%s",
1072                                 csv_sep, counter->cgrp->name);
1073
1074                 if (!csv_output)
1075                         pm(config, &os, NULL, NULL, "", 0);
1076                 print_noise(config, counter, noise);
1077                 print_running(config, run, ena);
1078                 if (csv_output)
1079                         pm(config, &os, NULL, NULL, "", 0);
1080                 return;
1081         }
1082
1083         if (!metric_only)
1084                 abs_printout(config, id, nr, counter, uval);
1085
1086         out.print_metric = pm;
1087         out.new_line = nl;
1088         out.ctx = &os;
1089         out.force_header = false;
1090
1091         if (csv_output && !metric_only) {
1092                 print_noise(config, counter, noise);
1093                 print_running(config, run, ena);
1094         }
1095
1096         perf_stat__print_shadow_stats(config, counter, uval,
1097                                 first_shadow_cpu(counter, id),
1098                                 &out, &metric_events, st);
1099         if (!csv_output && !metric_only) {
1100                 print_noise(config, counter, noise);
1101                 print_running(config, run, ena);
1102         }
1103 }
1104
1105 static void aggr_update_shadow(void)
1106 {
1107         int cpu, s2, id, s;
1108         u64 val;
1109         struct perf_evsel *counter;
1110
1111         for (s = 0; s < aggr_map->nr; s++) {
1112                 id = aggr_map->map[s];
1113                 evlist__for_each_entry(evsel_list, counter) {
1114                         val = 0;
1115                         for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1116                                 s2 = aggr_get_id(evsel_list->cpus, cpu);
1117                                 if (s2 != id)
1118                                         continue;
1119                                 val += perf_counts(counter->counts, cpu, 0)->val;
1120                         }
1121                         perf_stat__update_shadow_stats(counter, val,
1122                                         first_shadow_cpu(counter, id),
1123                                         &rt_stat);
1124                 }
1125         }
1126 }
1127
1128 static void uniquify_event_name(struct perf_evsel *counter)
1129 {
1130         char *new_name;
1131         char *config;
1132
1133         if (counter->uniquified_name ||
1134             !counter->pmu_name || !strncmp(counter->name, counter->pmu_name,
1135                                            strlen(counter->pmu_name)))
1136                 return;
1137
1138         config = strchr(counter->name, '/');
1139         if (config) {
1140                 if (asprintf(&new_name,
1141                              "%s%s", counter->pmu_name, config) > 0) {
1142                         free(counter->name);
1143                         counter->name = new_name;
1144                 }
1145         } else {
1146                 if (asprintf(&new_name,
1147                              "%s [%s]", counter->name, counter->pmu_name) > 0) {
1148                         free(counter->name);
1149                         counter->name = new_name;
1150                 }
1151         }
1152
1153         counter->uniquified_name = true;
1154 }
1155
1156 static void collect_all_aliases(struct perf_evsel *counter,
1157                             void (*cb)(struct perf_evsel *counter, void *data,
1158                                        bool first),
1159                             void *data)
1160 {
1161         struct perf_evsel *alias;
1162
1163         alias = list_prepare_entry(counter, &(evsel_list->entries), node);
1164         list_for_each_entry_continue (alias, &evsel_list->entries, node) {
1165                 if (strcmp(perf_evsel__name(alias), perf_evsel__name(counter)) ||
1166                     alias->scale != counter->scale ||
1167                     alias->cgrp != counter->cgrp ||
1168                     strcmp(alias->unit, counter->unit) ||
1169                     perf_evsel__is_clock(alias) != perf_evsel__is_clock(counter))
1170                         break;
1171                 alias->merged_stat = true;
1172                 cb(alias, data, false);
1173         }
1174 }
1175
1176 static bool collect_data(struct perf_evsel *counter,
1177                             void (*cb)(struct perf_evsel *counter, void *data,
1178                                        bool first),
1179                             void *data)
1180 {
1181         if (counter->merged_stat)
1182                 return false;
1183         cb(counter, data, true);
1184         if (no_merge)
1185                 uniquify_event_name(counter);
1186         else if (counter->auto_merge_stats)
1187                 collect_all_aliases(counter, cb, data);
1188         return true;
1189 }
1190
1191 struct aggr_data {
1192         u64 ena, run, val;
1193         int id;
1194         int nr;
1195         int cpu;
1196 };
1197
1198 static void aggr_cb(struct perf_evsel *counter, void *data, bool first)
1199 {
1200         struct aggr_data *ad = data;
1201         int cpu, s2;
1202
1203         for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1204                 struct perf_counts_values *counts;
1205
1206                 s2 = aggr_get_id(perf_evsel__cpus(counter), cpu);
1207                 if (s2 != ad->id)
1208                         continue;
1209                 if (first)
1210                         ad->nr++;
1211                 counts = perf_counts(counter->counts, cpu, 0);
1212                 /*
1213                  * When any result is bad, make them all to give
1214                  * consistent output in interval mode.
1215                  */
1216                 if (counts->ena == 0 || counts->run == 0 ||
1217                     counter->counts->scaled == -1) {
1218                         ad->ena = 0;
1219                         ad->run = 0;
1220                         break;
1221                 }
1222                 ad->val += counts->val;
1223                 ad->ena += counts->ena;
1224                 ad->run += counts->run;
1225         }
1226 }
1227
1228 static void print_aggr(struct perf_stat_config *config,
1229                        char *prefix)
1230 {
1231         FILE *output = config->output;
1232         struct perf_evsel *counter;
1233         int s, id, nr;
1234         double uval;
1235         u64 ena, run, val;
1236         bool first;
1237
1238         if (!(aggr_map || aggr_get_id))
1239                 return;
1240
1241         aggr_update_shadow();
1242
1243         /*
1244          * With metric_only everything is on a single line.
1245          * Without each counter has its own line.
1246          */
1247         for (s = 0; s < aggr_map->nr; s++) {
1248                 struct aggr_data ad;
1249                 if (prefix && metric_only)
1250                         fprintf(output, "%s", prefix);
1251
1252                 ad.id = id = aggr_map->map[s];
1253                 first = true;
1254                 evlist__for_each_entry(evsel_list, counter) {
1255                         if (is_duration_time(counter))
1256                                 continue;
1257
1258                         ad.val = ad.ena = ad.run = 0;
1259                         ad.nr = 0;
1260                         if (!collect_data(counter, aggr_cb, &ad))
1261                                 continue;
1262                         nr = ad.nr;
1263                         ena = ad.ena;
1264                         run = ad.run;
1265                         val = ad.val;
1266                         if (first && metric_only) {
1267                                 first = false;
1268                                 aggr_printout(config, counter, id, nr);
1269                         }
1270                         if (prefix && !metric_only)
1271                                 fprintf(output, "%s", prefix);
1272
1273                         uval = val * counter->scale;
1274                         printout(config, id, nr, counter, uval, prefix,
1275                                  run, ena, 1.0, &rt_stat);
1276                         if (!metric_only)
1277                                 fputc('\n', output);
1278                 }
1279                 if (metric_only)
1280                         fputc('\n', output);
1281         }
1282 }
1283
1284 static int cmp_val(const void *a, const void *b)
1285 {
1286         return ((struct perf_aggr_thread_value *)b)->val -
1287                 ((struct perf_aggr_thread_value *)a)->val;
1288 }
1289
1290 static struct perf_aggr_thread_value *sort_aggr_thread(
1291                                         struct perf_evsel *counter,
1292                                         int nthreads, int ncpus,
1293                                         int *ret)
1294 {
1295         int cpu, thread, i = 0;
1296         double uval;
1297         struct perf_aggr_thread_value *buf;
1298
1299         buf = calloc(nthreads, sizeof(struct perf_aggr_thread_value));
1300         if (!buf)
1301                 return NULL;
1302
1303         for (thread = 0; thread < nthreads; thread++) {
1304                 u64 ena = 0, run = 0, val = 0;
1305
1306                 for (cpu = 0; cpu < ncpus; cpu++) {
1307                         val += perf_counts(counter->counts, cpu, thread)->val;
1308                         ena += perf_counts(counter->counts, cpu, thread)->ena;
1309                         run += perf_counts(counter->counts, cpu, thread)->run;
1310                 }
1311
1312                 uval = val * counter->scale;
1313
1314                 /*
1315                  * Skip value 0 when enabling --per-thread globally,
1316                  * otherwise too many 0 output.
1317                  */
1318                 if (uval == 0.0 && target__has_per_thread(&target))
1319                         continue;
1320
1321                 buf[i].counter = counter;
1322                 buf[i].id = thread;
1323                 buf[i].uval = uval;
1324                 buf[i].val = val;
1325                 buf[i].run = run;
1326                 buf[i].ena = ena;
1327                 i++;
1328         }
1329
1330         qsort(buf, i, sizeof(struct perf_aggr_thread_value), cmp_val);
1331
1332         if (ret)
1333                 *ret = i;
1334
1335         return buf;
1336 }
1337
1338 static void print_aggr_thread(struct perf_stat_config *config,
1339                               struct perf_evsel *counter, char *prefix)
1340 {
1341         FILE *output = config->output;
1342         int nthreads = thread_map__nr(counter->threads);
1343         int ncpus = cpu_map__nr(counter->cpus);
1344         int thread, sorted_threads, id;
1345         struct perf_aggr_thread_value *buf;
1346
1347         buf = sort_aggr_thread(counter, nthreads, ncpus, &sorted_threads);
1348         if (!buf) {
1349                 perror("cannot sort aggr thread");
1350                 return;
1351         }
1352
1353         for (thread = 0; thread < sorted_threads; thread++) {
1354                 if (prefix)
1355                         fprintf(output, "%s", prefix);
1356
1357                 id = buf[thread].id;
1358                 if (config->stats)
1359                         printout(config, id, 0, buf[thread].counter, buf[thread].uval,
1360                                  prefix, buf[thread].run, buf[thread].ena, 1.0,
1361                                  &config->stats[id]);
1362                 else
1363                         printout(config, id, 0, buf[thread].counter, buf[thread].uval,
1364                                  prefix, buf[thread].run, buf[thread].ena, 1.0,
1365                                  &rt_stat);
1366                 fputc('\n', output);
1367         }
1368
1369         free(buf);
1370 }
1371
1372 struct caggr_data {
1373         double avg, avg_enabled, avg_running;
1374 };
1375
1376 static void counter_aggr_cb(struct perf_evsel *counter, void *data,
1377                             bool first __maybe_unused)
1378 {
1379         struct caggr_data *cd = data;
1380         struct perf_stat_evsel *ps = counter->stats;
1381
1382         cd->avg += avg_stats(&ps->res_stats[0]);
1383         cd->avg_enabled += avg_stats(&ps->res_stats[1]);
1384         cd->avg_running += avg_stats(&ps->res_stats[2]);
1385 }
1386
1387 /*
1388  * Print out the results of a single counter:
1389  * aggregated counts in system-wide mode
1390  */
1391 static void print_counter_aggr(struct perf_stat_config *config,
1392                                struct perf_evsel *counter, char *prefix)
1393 {
1394         FILE *output = config->output;
1395         double uval;
1396         struct caggr_data cd = { .avg = 0.0 };
1397
1398         if (!collect_data(counter, counter_aggr_cb, &cd))
1399                 return;
1400
1401         if (prefix && !metric_only)
1402                 fprintf(output, "%s", prefix);
1403
1404         uval = cd.avg * counter->scale;
1405         printout(config, -1, 0, counter, uval, prefix, cd.avg_running, cd.avg_enabled,
1406                  cd.avg, &rt_stat);
1407         if (!metric_only)
1408                 fprintf(output, "\n");
1409 }
1410
1411 static void counter_cb(struct perf_evsel *counter, void *data,
1412                        bool first __maybe_unused)
1413 {
1414         struct aggr_data *ad = data;
1415
1416         ad->val += perf_counts(counter->counts, ad->cpu, 0)->val;
1417         ad->ena += perf_counts(counter->counts, ad->cpu, 0)->ena;
1418         ad->run += perf_counts(counter->counts, ad->cpu, 0)->run;
1419 }
1420
1421 /*
1422  * Print out the results of a single counter:
1423  * does not use aggregated count in system-wide
1424  */
1425 static void print_counter(struct perf_stat_config *config,
1426                           struct perf_evsel *counter, char *prefix)
1427 {
1428         FILE *output = config->output;
1429         u64 ena, run, val;
1430         double uval;
1431         int cpu;
1432
1433         for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1434                 struct aggr_data ad = { .cpu = cpu };
1435
1436                 if (!collect_data(counter, counter_cb, &ad))
1437                         return;
1438                 val = ad.val;
1439                 ena = ad.ena;
1440                 run = ad.run;
1441
1442                 if (prefix)
1443                         fprintf(output, "%s", prefix);
1444
1445                 uval = val * counter->scale;
1446                 printout(config, cpu, 0, counter, uval, prefix, run, ena, 1.0,
1447                          &rt_stat);
1448
1449                 fputc('\n', output);
1450         }
1451 }
1452
1453 static void print_no_aggr_metric(struct perf_stat_config *config,
1454                                  char *prefix)
1455 {
1456         int cpu;
1457         int nrcpus = 0;
1458         struct perf_evsel *counter;
1459         u64 ena, run, val;
1460         double uval;
1461
1462         nrcpus = evsel_list->cpus->nr;
1463         for (cpu = 0; cpu < nrcpus; cpu++) {
1464                 bool first = true;
1465
1466                 if (prefix)
1467                         fputs(prefix, config->output);
1468                 evlist__for_each_entry(evsel_list, counter) {
1469                         if (is_duration_time(counter))
1470                                 continue;
1471                         if (first) {
1472                                 aggr_printout(config, counter, cpu, 0);
1473                                 first = false;
1474                         }
1475                         val = perf_counts(counter->counts, cpu, 0)->val;
1476                         ena = perf_counts(counter->counts, cpu, 0)->ena;
1477                         run = perf_counts(counter->counts, cpu, 0)->run;
1478
1479                         uval = val * counter->scale;
1480                         printout(config, cpu, 0, counter, uval, prefix, run, ena, 1.0,
1481                                  &rt_stat);
1482                 }
1483                 fputc('\n', config->output);
1484         }
1485 }
1486
1487 static int aggr_header_lens[] = {
1488         [AGGR_CORE] = 18,
1489         [AGGR_SOCKET] = 12,
1490         [AGGR_NONE] = 6,
1491         [AGGR_THREAD] = 24,
1492         [AGGR_GLOBAL] = 0,
1493 };
1494
1495 static const char *aggr_header_csv[] = {
1496         [AGGR_CORE]     =       "core,cpus,",
1497         [AGGR_SOCKET]   =       "socket,cpus",
1498         [AGGR_NONE]     =       "cpu,",
1499         [AGGR_THREAD]   =       "comm-pid,",
1500         [AGGR_GLOBAL]   =       ""
1501 };
1502
1503 static void print_metric_headers(struct perf_stat_config *config,
1504                                  const char *prefix, bool no_indent)
1505 {
1506         struct perf_stat_output_ctx out;
1507         struct perf_evsel *counter;
1508         struct outstate os = {
1509                 .fh = config->output
1510         };
1511
1512         if (prefix)
1513                 fprintf(config->output, "%s", prefix);
1514
1515         if (!csv_output && !no_indent)
1516                 fprintf(config->output, "%*s",
1517                         aggr_header_lens[config->aggr_mode], "");
1518         if (csv_output) {
1519                 if (config->interval)
1520                         fputs("time,", config->output);
1521                 fputs(aggr_header_csv[config->aggr_mode], config->output);
1522         }
1523
1524         /* Print metrics headers only */
1525         evlist__for_each_entry(evsel_list, counter) {
1526                 if (is_duration_time(counter))
1527                         continue;
1528                 os.evsel = counter;
1529                 out.ctx = &os;
1530                 out.print_metric = print_metric_header;
1531                 out.new_line = new_line_metric;
1532                 out.force_header = true;
1533                 os.evsel = counter;
1534                 perf_stat__print_shadow_stats(config, counter, 0,
1535                                               0,
1536                                               &out,
1537                                               &metric_events,
1538                                               &rt_stat);
1539         }
1540         fputc('\n', config->output);
1541 }
1542
1543 static void print_interval(struct perf_stat_config *config,
1544                            char *prefix, struct timespec *ts)
1545 {
1546         FILE *output = config->output;
1547         static int num_print_interval;
1548
1549         if (interval_clear)
1550                 puts(CONSOLE_CLEAR);
1551
1552         sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
1553
1554         if ((num_print_interval == 0 && !csv_output) || interval_clear) {
1555                 switch (config->aggr_mode) {
1556                 case AGGR_SOCKET:
1557                         fprintf(output, "#           time socket cpus");
1558                         if (!metric_only)
1559                                 fprintf(output, "             counts %*s events\n", unit_width, "unit");
1560                         break;
1561                 case AGGR_CORE:
1562                         fprintf(output, "#           time core         cpus");
1563                         if (!metric_only)
1564                                 fprintf(output, "             counts %*s events\n", unit_width, "unit");
1565                         break;
1566                 case AGGR_NONE:
1567                         fprintf(output, "#           time CPU    ");
1568                         if (!metric_only)
1569                                 fprintf(output, "                counts %*s events\n", unit_width, "unit");
1570                         break;
1571                 case AGGR_THREAD:
1572                         fprintf(output, "#           time             comm-pid");
1573                         if (!metric_only)
1574                                 fprintf(output, "                  counts %*s events\n", unit_width, "unit");
1575                         break;
1576                 case AGGR_GLOBAL:
1577                 default:
1578                         fprintf(output, "#           time");
1579                         if (!metric_only)
1580                                 fprintf(output, "             counts %*s events\n", unit_width, "unit");
1581                 case AGGR_UNSET:
1582                         break;
1583                 }
1584         }
1585
1586         if ((num_print_interval == 0 || interval_clear) && metric_only)
1587                 print_metric_headers(config, " ", true);
1588         if (++num_print_interval == 25)
1589                 num_print_interval = 0;
1590 }
1591
1592 static void print_header(struct perf_stat_config *config,
1593                          int argc, const char **argv)
1594 {
1595         FILE *output = config->output;
1596         int i;
1597
1598         fflush(stdout);
1599
1600         if (!csv_output) {
1601                 fprintf(output, "\n");
1602                 fprintf(output, " Performance counter stats for ");
1603                 if (target.system_wide)
1604                         fprintf(output, "\'system wide");
1605                 else if (target.cpu_list)
1606                         fprintf(output, "\'CPU(s) %s", target.cpu_list);
1607                 else if (!target__has_task(&target)) {
1608                         fprintf(output, "\'%s", argv ? argv[0] : "pipe");
1609                         for (i = 1; argv && (i < argc); i++)
1610                                 fprintf(output, " %s", argv[i]);
1611                 } else if (target.pid)
1612                         fprintf(output, "process id \'%s", target.pid);
1613                 else
1614                         fprintf(output, "thread id \'%s", target.tid);
1615
1616                 fprintf(output, "\'");
1617                 if (run_count > 1)
1618                         fprintf(output, " (%d runs)", run_count);
1619                 fprintf(output, ":\n\n");
1620         }
1621 }
1622
1623 static int get_precision(double num)
1624 {
1625         if (num > 1)
1626                 return 0;
1627
1628         return lround(ceil(-log10(num)));
1629 }
1630
1631 static void print_table(FILE *output, int precision, double avg)
1632 {
1633         char tmp[64];
1634         int idx, indent = 0;
1635
1636         scnprintf(tmp, 64, " %17.*f", precision, avg);
1637         while (tmp[indent] == ' ')
1638                 indent++;
1639
1640         fprintf(output, "%*s# Table of individual measurements:\n", indent, "");
1641
1642         for (idx = 0; idx < run_count; idx++) {
1643                 double run = (double) walltime_run[idx] / NSEC_PER_SEC;
1644                 int h, n = 1 + abs((int) (100.0 * (run - avg)/run) / 5);
1645
1646                 fprintf(output, " %17.*f (%+.*f) ",
1647                         precision, run, precision, run - avg);
1648
1649                 for (h = 0; h < n; h++)
1650                         fprintf(output, "#");
1651
1652                 fprintf(output, "\n");
1653         }
1654
1655         fprintf(output, "\n%*s# Final result:\n", indent, "");
1656 }
1657
1658 static double timeval2double(struct timeval *t)
1659 {
1660         return t->tv_sec + (double) t->tv_usec/USEC_PER_SEC;
1661 }
1662
1663 static void print_footer(struct perf_stat_config *config)
1664 {
1665         double avg = avg_stats(&walltime_nsecs_stats) / NSEC_PER_SEC;
1666         FILE *output = config->output;
1667         int n;
1668
1669         if (!null_run)
1670                 fprintf(output, "\n");
1671
1672         if (run_count == 1) {
1673                 fprintf(output, " %17.9f seconds time elapsed", avg);
1674
1675                 if (ru_display) {
1676                         double ru_utime = timeval2double(&ru_data.ru_utime);
1677                         double ru_stime = timeval2double(&ru_data.ru_stime);
1678
1679                         fprintf(output, "\n\n");
1680                         fprintf(output, " %17.9f seconds user\n", ru_utime);
1681                         fprintf(output, " %17.9f seconds sys\n", ru_stime);
1682                 }
1683         } else {
1684                 double sd = stddev_stats(&walltime_nsecs_stats) / NSEC_PER_SEC;
1685                 /*
1686                  * Display at most 2 more significant
1687                  * digits than the stddev inaccuracy.
1688                  */
1689                 int precision = get_precision(sd) + 2;
1690
1691                 if (walltime_run_table)
1692                         print_table(output, precision, avg);
1693
1694                 fprintf(output, " %17.*f +- %.*f seconds time elapsed",
1695                         precision, avg, precision, sd);
1696
1697                 print_noise_pct(config, sd, avg);
1698         }
1699         fprintf(output, "\n\n");
1700
1701         if (print_free_counters_hint &&
1702             sysctl__read_int("kernel/nmi_watchdog", &n) >= 0 &&
1703             n > 0)
1704                 fprintf(output,
1705 "Some events weren't counted. Try disabling the NMI watchdog:\n"
1706 "       echo 0 > /proc/sys/kernel/nmi_watchdog\n"
1707 "       perf stat ...\n"
1708 "       echo 1 > /proc/sys/kernel/nmi_watchdog\n");
1709
1710         if (print_mixed_hw_group_error)
1711                 fprintf(output,
1712                         "The events in group usually have to be from "
1713                         "the same PMU. Try reorganizing the group.\n");
1714 }
1715
1716 static void
1717 perf_evlist__print_counters(struct perf_evlist *evlist,
1718                             struct perf_stat_config *config,
1719                             struct timespec *ts,
1720                             int argc, const char **argv)
1721 {
1722         int interval = config->interval;
1723         struct perf_evsel *counter;
1724         char buf[64], *prefix = NULL;
1725
1726         if (interval)
1727                 print_interval(config, prefix = buf, ts);
1728         else
1729                 print_header(config, argc, argv);
1730
1731         if (metric_only) {
1732                 static int num_print_iv;
1733
1734                 if (num_print_iv == 0 && !interval)
1735                         print_metric_headers(config, prefix, false);
1736                 if (num_print_iv++ == 25)
1737                         num_print_iv = 0;
1738                 if (config->aggr_mode == AGGR_GLOBAL && prefix)
1739                         fprintf(config->output, "%s", prefix);
1740         }
1741
1742         switch (config->aggr_mode) {
1743         case AGGR_CORE:
1744         case AGGR_SOCKET:
1745                 print_aggr(config, prefix);
1746                 break;
1747         case AGGR_THREAD:
1748                 evlist__for_each_entry(evlist, counter) {
1749                         if (is_duration_time(counter))
1750                                 continue;
1751                         print_aggr_thread(config, counter, prefix);
1752                 }
1753                 break;
1754         case AGGR_GLOBAL:
1755                 evlist__for_each_entry(evlist, counter) {
1756                         if (is_duration_time(counter))
1757                                 continue;
1758                         print_counter_aggr(config, counter, prefix);
1759                 }
1760                 if (metric_only)
1761                         fputc('\n', config->output);
1762                 break;
1763         case AGGR_NONE:
1764                 if (metric_only)
1765                         print_no_aggr_metric(config, prefix);
1766                 else {
1767                         evlist__for_each_entry(evlist, counter) {
1768                                 if (is_duration_time(counter))
1769                                         continue;
1770                                 print_counter(config, counter, prefix);
1771                         }
1772                 }
1773                 break;
1774         case AGGR_UNSET:
1775         default:
1776                 break;
1777         }
1778
1779         if (!interval && !csv_output)
1780                 print_footer(config);
1781
1782         fflush(config->output);
1783 }
1784
1785 static void print_counters(struct timespec *ts, int argc, const char **argv)
1786 {
1787         /* Do not print anything if we record to the pipe. */
1788         if (STAT_RECORD && perf_stat.data.is_pipe)
1789                 return;
1790
1791         perf_evlist__print_counters(evsel_list, &stat_config,
1792                                     ts, argc, argv);
1793 }
1794
1795 static volatile int signr = -1;
1796
1797 static void skip_signal(int signo)
1798 {
1799         if ((child_pid == -1) || stat_config.interval)
1800                 done = 1;
1801
1802         signr = signo;
1803         /*
1804          * render child_pid harmless
1805          * won't send SIGTERM to a random
1806          * process in case of race condition
1807          * and fast PID recycling
1808          */
1809         child_pid = -1;
1810 }
1811
1812 static void sig_atexit(void)
1813 {
1814         sigset_t set, oset;
1815
1816         /*
1817          * avoid race condition with SIGCHLD handler
1818          * in skip_signal() which is modifying child_pid
1819          * goal is to avoid send SIGTERM to a random
1820          * process
1821          */
1822         sigemptyset(&set);
1823         sigaddset(&set, SIGCHLD);
1824         sigprocmask(SIG_BLOCK, &set, &oset);
1825
1826         if (child_pid != -1)
1827                 kill(child_pid, SIGTERM);
1828
1829         sigprocmask(SIG_SETMASK, &oset, NULL);
1830
1831         if (signr == -1)
1832                 return;
1833
1834         signal(signr, SIG_DFL);
1835         kill(getpid(), signr);
1836 }
1837
1838 static int stat__set_big_num(const struct option *opt __maybe_unused,
1839                              const char *s __maybe_unused, int unset)
1840 {
1841         big_num_opt = unset ? 0 : 1;
1842         return 0;
1843 }
1844
1845 static int enable_metric_only(const struct option *opt __maybe_unused,
1846                               const char *s __maybe_unused, int unset)
1847 {
1848         force_metric_only = true;
1849         metric_only = !unset;
1850         return 0;
1851 }
1852
1853 static int parse_metric_groups(const struct option *opt,
1854                                const char *str,
1855                                int unset __maybe_unused)
1856 {
1857         return metricgroup__parse_groups(opt, str, &metric_events);
1858 }
1859
1860 static const struct option stat_options[] = {
1861         OPT_BOOLEAN('T', "transaction", &transaction_run,
1862                     "hardware transaction statistics"),
1863         OPT_CALLBACK('e', "event", &evsel_list, "event",
1864                      "event selector. use 'perf list' to list available events",
1865                      parse_events_option),
1866         OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1867                      "event filter", parse_filter),
1868         OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit,
1869                     "child tasks do not inherit counters"),
1870         OPT_STRING('p', "pid", &target.pid, "pid",
1871                    "stat events on existing process id"),
1872         OPT_STRING('t', "tid", &target.tid, "tid",
1873                    "stat events on existing thread id"),
1874         OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1875                     "system-wide collection from all CPUs"),
1876         OPT_BOOLEAN('g', "group", &group,
1877                     "put the counters into a counter group"),
1878         OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
1879         OPT_INCR('v', "verbose", &verbose,
1880                     "be more verbose (show counter open errors, etc)"),
1881         OPT_INTEGER('r', "repeat", &run_count,
1882                     "repeat command and print average + stddev (max: 100, forever: 0)"),
1883         OPT_BOOLEAN(0, "table", &walltime_run_table,
1884                     "display details about each run (only with -r option)"),
1885         OPT_BOOLEAN('n', "null", &null_run,
1886                     "null run - dont start any counters"),
1887         OPT_INCR('d', "detailed", &detailed_run,
1888                     "detailed run - start a lot of events"),
1889         OPT_BOOLEAN('S', "sync", &sync_run,
1890                     "call sync() before starting a run"),
1891         OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1892                            "print large numbers with thousands\' separators",
1893                            stat__set_big_num),
1894         OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1895                     "list of cpus to monitor in system-wide"),
1896         OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
1897                     "disable CPU count aggregation", AGGR_NONE),
1898         OPT_BOOLEAN(0, "no-merge", &no_merge, "Do not merge identical named events"),
1899         OPT_STRING('x', "field-separator", &csv_sep, "separator",
1900                    "print counts with custom separator"),
1901         OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1902                      "monitor event in cgroup name only", parse_cgroups),
1903         OPT_STRING('o', "output", &output_name, "file", "output file name"),
1904         OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1905         OPT_INTEGER(0, "log-fd", &output_fd,
1906                     "log output to fd, instead of stderr"),
1907         OPT_STRING(0, "pre", &pre_cmd, "command",
1908                         "command to run prior to the measured command"),
1909         OPT_STRING(0, "post", &post_cmd, "command",
1910                         "command to run after to the measured command"),
1911         OPT_UINTEGER('I', "interval-print", &stat_config.interval,
1912                     "print counts at regular interval in ms "
1913                     "(overhead is possible for values <= 100ms)"),
1914         OPT_INTEGER(0, "interval-count", &stat_config.times,
1915                     "print counts for fixed number of times"),
1916         OPT_BOOLEAN(0, "interval-clear", &interval_clear,
1917                     "clear screen in between new interval"),
1918         OPT_UINTEGER(0, "timeout", &stat_config.timeout,
1919                     "stop workload and print counts after a timeout period in ms (>= 10ms)"),
1920         OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
1921                      "aggregate counts per processor socket", AGGR_SOCKET),
1922         OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
1923                      "aggregate counts per physical processor core", AGGR_CORE),
1924         OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
1925                      "aggregate counts per thread", AGGR_THREAD),
1926         OPT_UINTEGER('D', "delay", &stat_config.initial_delay,
1927                      "ms to wait before starting measurement after program start"),
1928         OPT_CALLBACK_NOOPT(0, "metric-only", &metric_only, NULL,
1929                         "Only print computed metrics. No raw values", enable_metric_only),
1930         OPT_BOOLEAN(0, "topdown", &topdown_run,
1931                         "measure topdown level 1 statistics"),
1932         OPT_BOOLEAN(0, "smi-cost", &smi_cost,
1933                         "measure SMI cost"),
1934         OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list",
1935                      "monitor specified metrics or metric groups (separated by ,)",
1936                      parse_metric_groups),
1937         OPT_END()
1938 };
1939
1940 static int perf_stat__get_socket(struct cpu_map *map, int cpu)
1941 {
1942         return cpu_map__get_socket(map, cpu, NULL);
1943 }
1944
1945 static int perf_stat__get_core(struct cpu_map *map, int cpu)
1946 {
1947         return cpu_map__get_core(map, cpu, NULL);
1948 }
1949
1950 static int cpu_map__get_max(struct cpu_map *map)
1951 {
1952         int i, max = -1;
1953
1954         for (i = 0; i < map->nr; i++) {
1955                 if (map->map[i] > max)
1956                         max = map->map[i];
1957         }
1958
1959         return max;
1960 }
1961
1962 static struct cpu_map *cpus_aggr_map;
1963
1964 static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int idx)
1965 {
1966         int cpu;
1967
1968         if (idx >= map->nr)
1969                 return -1;
1970
1971         cpu = map->map[idx];
1972
1973         if (cpus_aggr_map->map[cpu] == -1)
1974                 cpus_aggr_map->map[cpu] = get_id(map, idx);
1975
1976         return cpus_aggr_map->map[cpu];
1977 }
1978
1979 static int perf_stat__get_socket_cached(struct cpu_map *map, int idx)
1980 {
1981         return perf_stat__get_aggr(perf_stat__get_socket, map, idx);
1982 }
1983
1984 static int perf_stat__get_core_cached(struct cpu_map *map, int idx)
1985 {
1986         return perf_stat__get_aggr(perf_stat__get_core, map, idx);
1987 }
1988
1989 static int perf_stat_init_aggr_mode(void)
1990 {
1991         int nr;
1992
1993         switch (stat_config.aggr_mode) {
1994         case AGGR_SOCKET:
1995                 if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
1996                         perror("cannot build socket map");
1997                         return -1;
1998                 }
1999                 aggr_get_id = perf_stat__get_socket_cached;
2000                 break;
2001         case AGGR_CORE:
2002                 if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
2003                         perror("cannot build core map");
2004                         return -1;
2005                 }
2006                 aggr_get_id = perf_stat__get_core_cached;
2007                 break;
2008         case AGGR_NONE:
2009         case AGGR_GLOBAL:
2010         case AGGR_THREAD:
2011         case AGGR_UNSET:
2012         default:
2013                 break;
2014         }
2015
2016         /*
2017          * The evsel_list->cpus is the base we operate on,
2018          * taking the highest cpu number to be the size of
2019          * the aggregation translate cpumap.
2020          */
2021         nr = cpu_map__get_max(evsel_list->cpus);
2022         cpus_aggr_map = cpu_map__empty_new(nr + 1);
2023         return cpus_aggr_map ? 0 : -ENOMEM;
2024 }
2025
2026 static void perf_stat__exit_aggr_mode(void)
2027 {
2028         cpu_map__put(aggr_map);
2029         cpu_map__put(cpus_aggr_map);
2030         aggr_map = NULL;
2031         cpus_aggr_map = NULL;
2032 }
2033
2034 static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, int idx)
2035 {
2036         int cpu;
2037
2038         if (idx > map->nr)
2039                 return -1;
2040
2041         cpu = map->map[idx];
2042
2043         if (cpu >= env->nr_cpus_avail)
2044                 return -1;
2045
2046         return cpu;
2047 }
2048
2049 static int perf_env__get_socket(struct cpu_map *map, int idx, void *data)
2050 {
2051         struct perf_env *env = data;
2052         int cpu = perf_env__get_cpu(env, map, idx);
2053
2054         return cpu == -1 ? -1 : env->cpu[cpu].socket_id;
2055 }
2056
2057 static int perf_env__get_core(struct cpu_map *map, int idx, void *data)
2058 {
2059         struct perf_env *env = data;
2060         int core = -1, cpu = perf_env__get_cpu(env, map, idx);
2061
2062         if (cpu != -1) {
2063                 int socket_id = env->cpu[cpu].socket_id;
2064
2065                 /*
2066                  * Encode socket in upper 16 bits
2067                  * core_id is relative to socket, and
2068                  * we need a global id. So we combine
2069                  * socket + core id.
2070                  */
2071                 core = (socket_id << 16) | (env->cpu[cpu].core_id & 0xffff);
2072         }
2073
2074         return core;
2075 }
2076
2077 static int perf_env__build_socket_map(struct perf_env *env, struct cpu_map *cpus,
2078                                       struct cpu_map **sockp)
2079 {
2080         return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
2081 }
2082
2083 static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus,
2084                                     struct cpu_map **corep)
2085 {
2086         return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
2087 }
2088
2089 static int perf_stat__get_socket_file(struct cpu_map *map, int idx)
2090 {
2091         return perf_env__get_socket(map, idx, &perf_stat.session->header.env);
2092 }
2093
2094 static int perf_stat__get_core_file(struct cpu_map *map, int idx)
2095 {
2096         return perf_env__get_core(map, idx, &perf_stat.session->header.env);
2097 }
2098
2099 static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
2100 {
2101         struct perf_env *env = &st->session->header.env;
2102
2103         switch (stat_config.aggr_mode) {
2104         case AGGR_SOCKET:
2105                 if (perf_env__build_socket_map(env, evsel_list->cpus, &aggr_map)) {
2106                         perror("cannot build socket map");
2107                         return -1;
2108                 }
2109                 aggr_get_id = perf_stat__get_socket_file;
2110                 break;
2111         case AGGR_CORE:
2112                 if (perf_env__build_core_map(env, evsel_list->cpus, &aggr_map)) {
2113                         perror("cannot build core map");
2114                         return -1;
2115                 }
2116                 aggr_get_id = perf_stat__get_core_file;
2117                 break;
2118         case AGGR_NONE:
2119         case AGGR_GLOBAL:
2120         case AGGR_THREAD:
2121         case AGGR_UNSET:
2122         default:
2123                 break;
2124         }
2125
2126         return 0;
2127 }
2128
2129 static int topdown_filter_events(const char **attr, char **str, bool use_group)
2130 {
2131         int off = 0;
2132         int i;
2133         int len = 0;
2134         char *s;
2135
2136         for (i = 0; attr[i]; i++) {
2137                 if (pmu_have_event("cpu", attr[i])) {
2138                         len += strlen(attr[i]) + 1;
2139                         attr[i - off] = attr[i];
2140                 } else
2141                         off++;
2142         }
2143         attr[i - off] = NULL;
2144
2145         *str = malloc(len + 1 + 2);
2146         if (!*str)
2147                 return -1;
2148         s = *str;
2149         if (i - off == 0) {
2150                 *s = 0;
2151                 return 0;
2152         }
2153         if (use_group)
2154                 *s++ = '{';
2155         for (i = 0; attr[i]; i++) {
2156                 strcpy(s, attr[i]);
2157                 s += strlen(s);
2158                 *s++ = ',';
2159         }
2160         if (use_group) {
2161                 s[-1] = '}';
2162                 *s = 0;
2163         } else
2164                 s[-1] = 0;
2165         return 0;
2166 }
2167
2168 __weak bool arch_topdown_check_group(bool *warn)
2169 {
2170         *warn = false;
2171         return false;
2172 }
2173
2174 __weak void arch_topdown_group_warn(void)
2175 {
2176 }
2177
2178 /*
2179  * Add default attributes, if there were no attributes specified or
2180  * if -d/--detailed, -d -d or -d -d -d is used:
2181  */
2182 static int add_default_attributes(void)
2183 {
2184         int err;
2185         struct perf_event_attr default_attrs0[] = {
2186
2187   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK              },
2188   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES        },
2189   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS          },
2190   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS             },
2191
2192   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES              },
2193 };
2194         struct perf_event_attr frontend_attrs[] = {
2195   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
2196 };
2197         struct perf_event_attr backend_attrs[] = {
2198   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND  },
2199 };
2200         struct perf_event_attr default_attrs1[] = {
2201   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS            },
2202   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS     },
2203   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES           },
2204
2205 };
2206
2207 /*
2208  * Detailed stats (-d), covering the L1 and last level data caches:
2209  */
2210         struct perf_event_attr detailed_attrs[] = {
2211
2212   { .type = PERF_TYPE_HW_CACHE,
2213     .config =
2214          PERF_COUNT_HW_CACHE_L1D                <<  0  |
2215         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2216         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
2217
2218   { .type = PERF_TYPE_HW_CACHE,
2219     .config =
2220          PERF_COUNT_HW_CACHE_L1D                <<  0  |
2221         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2222         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
2223
2224   { .type = PERF_TYPE_HW_CACHE,
2225     .config =
2226          PERF_COUNT_HW_CACHE_LL                 <<  0  |
2227         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2228         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
2229
2230   { .type = PERF_TYPE_HW_CACHE,
2231     .config =
2232          PERF_COUNT_HW_CACHE_LL                 <<  0  |
2233         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2234         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
2235 };
2236
2237 /*
2238  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
2239  */
2240         struct perf_event_attr very_detailed_attrs[] = {
2241
2242   { .type = PERF_TYPE_HW_CACHE,
2243     .config =
2244          PERF_COUNT_HW_CACHE_L1I                <<  0  |
2245         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2246         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
2247
2248   { .type = PERF_TYPE_HW_CACHE,
2249     .config =
2250          PERF_COUNT_HW_CACHE_L1I                <<  0  |
2251         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2252         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
2253
2254   { .type = PERF_TYPE_HW_CACHE,
2255     .config =
2256          PERF_COUNT_HW_CACHE_DTLB               <<  0  |
2257         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2258         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
2259
2260   { .type = PERF_TYPE_HW_CACHE,
2261     .config =
2262          PERF_COUNT_HW_CACHE_DTLB               <<  0  |
2263         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2264         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
2265
2266   { .type = PERF_TYPE_HW_CACHE,
2267     .config =
2268          PERF_COUNT_HW_CACHE_ITLB               <<  0  |
2269         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2270         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
2271
2272   { .type = PERF_TYPE_HW_CACHE,
2273     .config =
2274          PERF_COUNT_HW_CACHE_ITLB               <<  0  |
2275         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
2276         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
2277
2278 };
2279
2280 /*
2281  * Very, very detailed stats (-d -d -d), adding prefetch events:
2282  */
2283         struct perf_event_attr very_very_detailed_attrs[] = {
2284
2285   { .type = PERF_TYPE_HW_CACHE,
2286     .config =
2287          PERF_COUNT_HW_CACHE_L1D                <<  0  |
2288         (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
2289         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
2290
2291   { .type = PERF_TYPE_HW_CACHE,
2292     .config =
2293          PERF_COUNT_HW_CACHE_L1D                <<  0  |
2294         (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
2295         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
2296 };
2297         struct parse_events_error errinfo;
2298
2299         /* Set attrs if no event is selected and !null_run: */
2300         if (null_run)
2301                 return 0;
2302
2303         if (transaction_run) {
2304                 /* Handle -T as -M transaction. Once platform specific metrics
2305                  * support has been added to the json files, all archictures
2306                  * will use this approach. To determine transaction support
2307                  * on an architecture test for such a metric name.
2308                  */
2309                 if (metricgroup__has_metric("transaction")) {
2310                         struct option opt = { .value = &evsel_list };
2311
2312                         return metricgroup__parse_groups(&opt, "transaction",
2313                                                          &metric_events);
2314                 }
2315
2316                 if (pmu_have_event("cpu", "cycles-ct") &&
2317                     pmu_have_event("cpu", "el-start"))
2318                         err = parse_events(evsel_list, transaction_attrs,
2319                                            &errinfo);
2320                 else
2321                         err = parse_events(evsel_list,
2322                                            transaction_limited_attrs,
2323                                            &errinfo);
2324                 if (err) {
2325                         fprintf(stderr, "Cannot set up transaction events\n");
2326                         parse_events_print_error(&errinfo, transaction_attrs);
2327                         return -1;
2328                 }
2329                 return 0;
2330         }
2331
2332         if (smi_cost) {
2333                 int smi;
2334
2335                 if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) {
2336                         fprintf(stderr, "freeze_on_smi is not supported.\n");
2337                         return -1;
2338                 }
2339
2340                 if (!smi) {
2341                         if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) {
2342                                 fprintf(stderr, "Failed to set freeze_on_smi.\n");
2343                                 return -1;
2344                         }
2345                         smi_reset = true;
2346                 }
2347
2348                 if (pmu_have_event("msr", "aperf") &&
2349                     pmu_have_event("msr", "smi")) {
2350                         if (!force_metric_only)
2351                                 metric_only = true;
2352                         err = parse_events(evsel_list, smi_cost_attrs, &errinfo);
2353                 } else {
2354                         fprintf(stderr, "To measure SMI cost, it needs "
2355                                 "msr/aperf/, msr/smi/ and cpu/cycles/ support\n");
2356                         parse_events_print_error(&errinfo, smi_cost_attrs);
2357                         return -1;
2358                 }
2359                 if (err) {
2360                         fprintf(stderr, "Cannot set up SMI cost events\n");
2361                         return -1;
2362                 }
2363                 return 0;
2364         }
2365
2366         if (topdown_run) {
2367                 char *str = NULL;
2368                 bool warn = false;
2369
2370                 if (stat_config.aggr_mode != AGGR_GLOBAL &&
2371                     stat_config.aggr_mode != AGGR_CORE) {
2372                         pr_err("top down event configuration requires --per-core mode\n");
2373                         return -1;
2374                 }
2375                 stat_config.aggr_mode = AGGR_CORE;
2376                 if (nr_cgroups || !target__has_cpu(&target)) {
2377                         pr_err("top down event configuration requires system-wide mode (-a)\n");
2378                         return -1;
2379                 }
2380
2381                 if (!force_metric_only)
2382                         metric_only = true;
2383                 if (topdown_filter_events(topdown_attrs, &str,
2384                                 arch_topdown_check_group(&warn)) < 0) {
2385                         pr_err("Out of memory\n");
2386                         return -1;
2387                 }
2388                 if (topdown_attrs[0] && str) {
2389                         if (warn)
2390                                 arch_topdown_group_warn();
2391                         err = parse_events(evsel_list, str, &errinfo);
2392                         if (err) {
2393                                 fprintf(stderr,
2394                                         "Cannot set up top down events %s: %d\n",
2395                                         str, err);
2396                                 free(str);
2397                                 parse_events_print_error(&errinfo, str);
2398                                 return -1;
2399                         }
2400                 } else {
2401                         fprintf(stderr, "System does not support topdown\n");
2402                         return -1;
2403                 }
2404                 free(str);
2405         }
2406
2407         if (!evsel_list->nr_entries) {
2408                 if (target__has_cpu(&target))
2409                         default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
2410
2411                 if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
2412                         return -1;
2413                 if (pmu_have_event("cpu", "stalled-cycles-frontend")) {
2414                         if (perf_evlist__add_default_attrs(evsel_list,
2415                                                 frontend_attrs) < 0)
2416                                 return -1;
2417                 }
2418                 if (pmu_have_event("cpu", "stalled-cycles-backend")) {
2419                         if (perf_evlist__add_default_attrs(evsel_list,
2420                                                 backend_attrs) < 0)
2421                                 return -1;
2422                 }
2423                 if (perf_evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
2424                         return -1;
2425         }
2426
2427         /* Detailed events get appended to the event list: */
2428
2429         if (detailed_run <  1)
2430                 return 0;
2431
2432         /* Append detailed run extra attributes: */
2433         if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
2434                 return -1;
2435
2436         if (detailed_run < 2)
2437                 return 0;
2438
2439         /* Append very detailed run extra attributes: */
2440         if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
2441                 return -1;
2442
2443         if (detailed_run < 3)
2444                 return 0;
2445
2446         /* Append very, very detailed run extra attributes: */
2447         return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
2448 }
2449
2450 static const char * const stat_record_usage[] = {
2451         "perf stat record [<options>]",
2452         NULL,
2453 };
2454
2455 static void init_features(struct perf_session *session)
2456 {
2457         int feat;
2458
2459         for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
2460                 perf_header__set_feat(&session->header, feat);
2461
2462         perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
2463         perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
2464         perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
2465         perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
2466 }
2467
2468 static int __cmd_record(int argc, const char **argv)
2469 {
2470         struct perf_session *session;
2471         struct perf_data *data = &perf_stat.data;
2472
2473         argc = parse_options(argc, argv, stat_options, stat_record_usage,
2474                              PARSE_OPT_STOP_AT_NON_OPTION);
2475
2476         if (output_name)
2477                 data->file.path = output_name;
2478
2479         if (run_count != 1 || forever) {
2480                 pr_err("Cannot use -r option with perf stat record.\n");
2481                 return -1;
2482         }
2483
2484         session = perf_session__new(data, false, NULL);
2485         if (session == NULL) {
2486                 pr_err("Perf session creation failed.\n");
2487                 return -1;
2488         }
2489
2490         init_features(session);
2491
2492         session->evlist   = evsel_list;
2493         perf_stat.session = session;
2494         perf_stat.record  = true;
2495         return argc;
2496 }
2497
2498 static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
2499                                     union perf_event *event,
2500                                     struct perf_session *session)
2501 {
2502         struct stat_round_event *stat_round = &event->stat_round;
2503         struct perf_evsel *counter;
2504         struct timespec tsh, *ts = NULL;
2505         const char **argv = session->header.env.cmdline_argv;
2506         int argc = session->header.env.nr_cmdline;
2507
2508         evlist__for_each_entry(evsel_list, counter)
2509                 perf_stat_process_counter(&stat_config, counter);
2510
2511         if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
2512                 update_stats(&walltime_nsecs_stats, stat_round->time);
2513
2514         if (stat_config.interval && stat_round->time) {
2515                 tsh.tv_sec  = stat_round->time / NSEC_PER_SEC;
2516                 tsh.tv_nsec = stat_round->time % NSEC_PER_SEC;
2517                 ts = &tsh;
2518         }
2519
2520         print_counters(ts, argc, argv);
2521         return 0;
2522 }
2523
2524 static
2525 int process_stat_config_event(struct perf_tool *tool,
2526                               union perf_event *event,
2527                               struct perf_session *session __maybe_unused)
2528 {
2529         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
2530
2531         perf_event__read_stat_config(&stat_config, &event->stat_config);
2532
2533         if (cpu_map__empty(st->cpus)) {
2534                 if (st->aggr_mode != AGGR_UNSET)
2535                         pr_warning("warning: processing task data, aggregation mode not set\n");
2536                 return 0;
2537         }
2538
2539         if (st->aggr_mode != AGGR_UNSET)
2540                 stat_config.aggr_mode = st->aggr_mode;
2541
2542         if (perf_stat.data.is_pipe)
2543                 perf_stat_init_aggr_mode();
2544         else
2545                 perf_stat_init_aggr_mode_file(st);
2546
2547         return 0;
2548 }
2549
2550 static int set_maps(struct perf_stat *st)
2551 {
2552         if (!st->cpus || !st->threads)
2553                 return 0;
2554
2555         if (WARN_ONCE(st->maps_allocated, "stats double allocation\n"))
2556                 return -EINVAL;
2557
2558         perf_evlist__set_maps(evsel_list, st->cpus, st->threads);
2559
2560         if (perf_evlist__alloc_stats(evsel_list, true))
2561                 return -ENOMEM;
2562
2563         st->maps_allocated = true;
2564         return 0;
2565 }
2566
2567 static
2568 int process_thread_map_event(struct perf_tool *tool,
2569                              union perf_event *event,
2570                              struct perf_session *session __maybe_unused)
2571 {
2572         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
2573
2574         if (st->threads) {
2575                 pr_warning("Extra thread map event, ignoring.\n");
2576                 return 0;
2577         }
2578
2579         st->threads = thread_map__new_event(&event->thread_map);
2580         if (!st->threads)
2581                 return -ENOMEM;
2582
2583         return set_maps(st);
2584 }
2585
2586 static
2587 int process_cpu_map_event(struct perf_tool *tool,
2588                           union perf_event *event,
2589                           struct perf_session *session __maybe_unused)
2590 {
2591         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
2592         struct cpu_map *cpus;
2593
2594         if (st->cpus) {
2595                 pr_warning("Extra cpu map event, ignoring.\n");
2596                 return 0;
2597         }
2598
2599         cpus = cpu_map__new_data(&event->cpu_map.data);
2600         if (!cpus)
2601                 return -ENOMEM;
2602
2603         st->cpus = cpus;
2604         return set_maps(st);
2605 }
2606
2607 static int runtime_stat_new(struct perf_stat_config *config, int nthreads)
2608 {
2609         int i;
2610
2611         config->stats = calloc(nthreads, sizeof(struct runtime_stat));
2612         if (!config->stats)
2613                 return -1;
2614
2615         config->stats_num = nthreads;
2616
2617         for (i = 0; i < nthreads; i++)
2618                 runtime_stat__init(&config->stats[i]);
2619
2620         return 0;
2621 }
2622
2623 static void runtime_stat_delete(struct perf_stat_config *config)
2624 {
2625         int i;
2626
2627         if (!config->stats)
2628                 return;
2629
2630         for (i = 0; i < config->stats_num; i++)
2631                 runtime_stat__exit(&config->stats[i]);
2632
2633         free(config->stats);
2634 }
2635
2636 static const char * const stat_report_usage[] = {
2637         "perf stat report [<options>]",
2638         NULL,
2639 };
2640
2641 static struct perf_stat perf_stat = {
2642         .tool = {
2643                 .attr           = perf_event__process_attr,
2644                 .event_update   = perf_event__process_event_update,
2645                 .thread_map     = process_thread_map_event,
2646                 .cpu_map        = process_cpu_map_event,
2647                 .stat_config    = process_stat_config_event,
2648                 .stat           = perf_event__process_stat_event,
2649                 .stat_round     = process_stat_round_event,
2650         },
2651         .aggr_mode = AGGR_UNSET,
2652 };
2653
2654 static int __cmd_report(int argc, const char **argv)
2655 {
2656         struct perf_session *session;
2657         const struct option options[] = {
2658         OPT_STRING('i', "input", &input_name, "file", "input file name"),
2659         OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode,
2660                      "aggregate counts per processor socket", AGGR_SOCKET),
2661         OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode,
2662                      "aggregate counts per physical processor core", AGGR_CORE),
2663         OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode,
2664                      "disable CPU count aggregation", AGGR_NONE),
2665         OPT_END()
2666         };
2667         struct stat st;
2668         int ret;
2669
2670         argc = parse_options(argc, argv, options, stat_report_usage, 0);
2671
2672         if (!input_name || !strlen(input_name)) {
2673                 if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
2674                         input_name = "-";
2675                 else
2676                         input_name = "perf.data";
2677         }
2678
2679         perf_stat.data.file.path = input_name;
2680         perf_stat.data.mode      = PERF_DATA_MODE_READ;
2681
2682         session = perf_session__new(&perf_stat.data, false, &perf_stat.tool);
2683         if (session == NULL)
2684                 return -1;
2685
2686         perf_stat.session  = session;
2687         stat_config.output = stderr;
2688         evsel_list         = session->evlist;
2689
2690         ret = perf_session__process_events(session);
2691         if (ret)
2692                 return ret;
2693
2694         perf_session__delete(session);
2695         return 0;
2696 }
2697
2698 static void setup_system_wide(int forks)
2699 {
2700         /*
2701          * Make system wide (-a) the default target if
2702          * no target was specified and one of following
2703          * conditions is met:
2704          *
2705          *   - there's no workload specified
2706          *   - there is workload specified but all requested
2707          *     events are system wide events
2708          */
2709         if (!target__none(&target))
2710                 return;
2711
2712         if (!forks)
2713                 target.system_wide = true;
2714         else {
2715                 struct perf_evsel *counter;
2716
2717                 evlist__for_each_entry(evsel_list, counter) {
2718                         if (!counter->system_wide)
2719                                 return;
2720                 }
2721
2722                 if (evsel_list->nr_entries)
2723                         target.system_wide = true;
2724         }
2725 }
2726
2727 int cmd_stat(int argc, const char **argv)
2728 {
2729         const char * const stat_usage[] = {
2730                 "perf stat [<options>] [<command>]",
2731                 NULL
2732         };
2733         int status = -EINVAL, run_idx;
2734         const char *mode;
2735         FILE *output = stderr;
2736         unsigned int interval, timeout;
2737         const char * const stat_subcommands[] = { "record", "report" };
2738
2739         setlocale(LC_ALL, "");
2740
2741         evsel_list = perf_evlist__new();
2742         if (evsel_list == NULL)
2743                 return -ENOMEM;
2744
2745         parse_events__shrink_config_terms();
2746         argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
2747                                         (const char **) stat_usage,
2748                                         PARSE_OPT_STOP_AT_NON_OPTION);
2749         perf_stat__collect_metric_expr(evsel_list);
2750         perf_stat__init_shadow_stats();
2751
2752         if (csv_sep) {
2753                 csv_output = true;
2754                 if (!strcmp(csv_sep, "\\t"))
2755                         csv_sep = "\t";
2756         } else
2757                 csv_sep = DEFAULT_SEPARATOR;
2758
2759         if (argc && !strncmp(argv[0], "rec", 3)) {
2760                 argc = __cmd_record(argc, argv);
2761                 if (argc < 0)
2762                         return -1;
2763         } else if (argc && !strncmp(argv[0], "rep", 3))
2764                 return __cmd_report(argc, argv);
2765
2766         interval = stat_config.interval;
2767         timeout = stat_config.timeout;
2768
2769         /*
2770          * For record command the -o is already taken care of.
2771          */
2772         if (!STAT_RECORD && output_name && strcmp(output_name, "-"))
2773                 output = NULL;
2774
2775         if (output_name && output_fd) {
2776                 fprintf(stderr, "cannot use both --output and --log-fd\n");
2777                 parse_options_usage(stat_usage, stat_options, "o", 1);
2778                 parse_options_usage(NULL, stat_options, "log-fd", 0);
2779                 goto out;
2780         }
2781
2782         if (metric_only && stat_config.aggr_mode == AGGR_THREAD) {
2783                 fprintf(stderr, "--metric-only is not supported with --per-thread\n");
2784                 goto out;
2785         }
2786
2787         if (metric_only && run_count > 1) {
2788                 fprintf(stderr, "--metric-only is not supported with -r\n");
2789                 goto out;
2790         }
2791
2792         if (walltime_run_table && run_count <= 1) {
2793                 fprintf(stderr, "--table is only supported with -r\n");
2794                 parse_options_usage(stat_usage, stat_options, "r", 1);
2795                 parse_options_usage(NULL, stat_options, "table", 0);
2796                 goto out;
2797         }
2798
2799         if (output_fd < 0) {
2800                 fprintf(stderr, "argument to --log-fd must be a > 0\n");
2801                 parse_options_usage(stat_usage, stat_options, "log-fd", 0);
2802                 goto out;
2803         }
2804
2805         if (!output) {
2806                 struct timespec tm;
2807                 mode = append_file ? "a" : "w";
2808
2809                 output = fopen(output_name, mode);
2810                 if (!output) {
2811                         perror("failed to create output file");
2812                         return -1;
2813                 }
2814                 clock_gettime(CLOCK_REALTIME, &tm);
2815                 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
2816         } else if (output_fd > 0) {
2817                 mode = append_file ? "a" : "w";
2818                 output = fdopen(output_fd, mode);
2819                 if (!output) {
2820                         perror("Failed opening logfd");
2821                         return -errno;
2822                 }
2823         }
2824
2825         stat_config.output = output;
2826
2827         /*
2828          * let the spreadsheet do the pretty-printing
2829          */
2830         if (csv_output) {
2831                 /* User explicitly passed -B? */
2832                 if (big_num_opt == 1) {
2833                         fprintf(stderr, "-B option not supported with -x\n");
2834                         parse_options_usage(stat_usage, stat_options, "B", 1);
2835                         parse_options_usage(NULL, stat_options, "x", 1);
2836                         goto out;
2837                 } else /* Nope, so disable big number formatting */
2838                         big_num = false;
2839         } else if (big_num_opt == 0) /* User passed --no-big-num */
2840                 big_num = false;
2841
2842         setup_system_wide(argc);
2843
2844         /*
2845          * Display user/system times only for single
2846          * run and when there's specified tracee.
2847          */
2848         if ((run_count == 1) && target__none(&target))
2849                 ru_display = true;
2850
2851         if (run_count < 0) {
2852                 pr_err("Run count must be a positive number\n");
2853                 parse_options_usage(stat_usage, stat_options, "r", 1);
2854                 goto out;
2855         } else if (run_count == 0) {
2856                 forever = true;
2857                 run_count = 1;
2858         }
2859
2860         if (walltime_run_table) {
2861                 walltime_run = zalloc(run_count * sizeof(walltime_run[0]));
2862                 if (!walltime_run) {
2863                         pr_err("failed to setup -r option");
2864                         goto out;
2865                 }
2866         }
2867
2868         if ((stat_config.aggr_mode == AGGR_THREAD) &&
2869                 !target__has_task(&target)) {
2870                 if (!target.system_wide || target.cpu_list) {
2871                         fprintf(stderr, "The --per-thread option is only "
2872                                 "available when monitoring via -p -t -a "
2873                                 "options or only --per-thread.\n");
2874                         parse_options_usage(NULL, stat_options, "p", 1);
2875                         parse_options_usage(NULL, stat_options, "t", 1);
2876                         goto out;
2877                 }
2878         }
2879
2880         /*
2881          * no_aggr, cgroup are for system-wide only
2882          * --per-thread is aggregated per thread, we dont mix it with cpu mode
2883          */
2884         if (((stat_config.aggr_mode != AGGR_GLOBAL &&
2885               stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
2886             !target__has_cpu(&target)) {
2887                 fprintf(stderr, "both cgroup and no-aggregation "
2888                         "modes only available in system-wide mode\n");
2889
2890                 parse_options_usage(stat_usage, stat_options, "G", 1);
2891                 parse_options_usage(NULL, stat_options, "A", 1);
2892                 parse_options_usage(NULL, stat_options, "a", 1);
2893                 goto out;
2894         }
2895
2896         if (add_default_attributes())
2897                 goto out;
2898
2899         target__validate(&target);
2900
2901         if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide))
2902                 target.per_thread = true;
2903
2904         if (perf_evlist__create_maps(evsel_list, &target) < 0) {
2905                 if (target__has_task(&target)) {
2906                         pr_err("Problems finding threads of monitor\n");
2907                         parse_options_usage(stat_usage, stat_options, "p", 1);
2908                         parse_options_usage(NULL, stat_options, "t", 1);
2909                 } else if (target__has_cpu(&target)) {
2910                         perror("failed to parse CPUs map");
2911                         parse_options_usage(stat_usage, stat_options, "C", 1);
2912                         parse_options_usage(NULL, stat_options, "a", 1);
2913                 }
2914                 goto out;
2915         }
2916
2917         /*
2918          * Initialize thread_map with comm names,
2919          * so we could print it out on output.
2920          */
2921         if (stat_config.aggr_mode == AGGR_THREAD) {
2922                 thread_map__read_comms(evsel_list->threads);
2923                 if (target.system_wide) {
2924                         if (runtime_stat_new(&stat_config,
2925                                 thread_map__nr(evsel_list->threads))) {
2926                                 goto out;
2927                         }
2928                 }
2929         }
2930
2931         if (stat_config.times && interval)
2932                 interval_count = true;
2933         else if (stat_config.times && !interval) {
2934                 pr_err("interval-count option should be used together with "
2935                                 "interval-print.\n");
2936                 parse_options_usage(stat_usage, stat_options, "interval-count", 0);
2937                 parse_options_usage(stat_usage, stat_options, "I", 1);
2938                 goto out;
2939         }
2940
2941         if (timeout && timeout < 100) {
2942                 if (timeout < 10) {
2943                         pr_err("timeout must be >= 10ms.\n");
2944                         parse_options_usage(stat_usage, stat_options, "timeout", 0);
2945                         goto out;
2946                 } else
2947                         pr_warning("timeout < 100ms. "
2948                                    "The overhead percentage could be high in some cases. "
2949                                    "Please proceed with caution.\n");
2950         }
2951         if (timeout && interval) {
2952                 pr_err("timeout option is not supported with interval-print.\n");
2953                 parse_options_usage(stat_usage, stat_options, "timeout", 0);
2954                 parse_options_usage(stat_usage, stat_options, "I", 1);
2955                 goto out;
2956         }
2957
2958         if (perf_evlist__alloc_stats(evsel_list, interval))
2959                 goto out;
2960
2961         if (perf_stat_init_aggr_mode())
2962                 goto out;
2963
2964         /*
2965          * Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless
2966          * while avoiding that older tools show confusing messages.
2967          *
2968          * However for pipe sessions we need to keep it zero,
2969          * because script's perf_evsel__check_attr is triggered
2970          * by attr->sample_type != 0, and we can't run it on
2971          * stat sessions.
2972          */
2973         stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe);
2974
2975         /*
2976          * We dont want to block the signals - that would cause
2977          * child tasks to inherit that and Ctrl-C would not work.
2978          * What we want is for Ctrl-C to work in the exec()-ed
2979          * task, but being ignored by perf stat itself:
2980          */
2981         atexit(sig_atexit);
2982         if (!forever)
2983                 signal(SIGINT,  skip_signal);
2984         signal(SIGCHLD, skip_signal);
2985         signal(SIGALRM, skip_signal);
2986         signal(SIGABRT, skip_signal);
2987
2988         status = 0;
2989         for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
2990                 if (run_count != 1 && verbose > 0)
2991                         fprintf(output, "[ perf stat: executing run #%d ... ]\n",
2992                                 run_idx + 1);
2993
2994                 status = run_perf_stat(argc, argv, run_idx);
2995                 if (forever && status != -1) {
2996                         print_counters(NULL, argc, argv);
2997                         perf_stat__reset_stats();
2998                 }
2999         }
3000
3001         if (!forever && status != -1 && !interval)
3002                 print_counters(NULL, argc, argv);
3003
3004         if (STAT_RECORD) {
3005                 /*
3006                  * We synthesize the kernel mmap record just so that older tools
3007                  * don't emit warnings about not being able to resolve symbols
3008                  * due to /proc/sys/kernel/kptr_restrict settings and instear provide
3009                  * a saner message about no samples being in the perf.data file.
3010                  *
3011                  * This also serves to suppress a warning about f_header.data.size == 0
3012                  * in header.c at the moment 'perf stat record' gets introduced, which
3013                  * is not really needed once we start adding the stat specific PERF_RECORD_
3014                  * records, but the need to suppress the kptr_restrict messages in older
3015                  * tools remain  -acme
3016                  */
3017                 int fd = perf_data__fd(&perf_stat.data);
3018                 int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat,
3019                                                              process_synthesized_event,
3020                                                              &perf_stat.session->machines.host);
3021                 if (err) {
3022                         pr_warning("Couldn't synthesize the kernel mmap record, harmless, "
3023                                    "older tools may produce warnings about this file\n.");
3024                 }
3025
3026                 if (!interval) {
3027                         if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL))
3028                                 pr_err("failed to write stat round event\n");
3029                 }
3030
3031                 if (!perf_stat.data.is_pipe) {
3032                         perf_stat.session->header.data_size += perf_stat.bytes_written;
3033                         perf_session__write_header(perf_stat.session, evsel_list, fd, true);
3034                 }
3035
3036                 perf_session__delete(perf_stat.session);
3037         }
3038
3039         perf_stat__exit_aggr_mode();
3040         perf_evlist__free_stats(evsel_list);
3041 out:
3042         free(walltime_run);
3043
3044         if (smi_cost && smi_reset)
3045                 sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
3046
3047         perf_evlist__delete(evsel_list);
3048
3049         runtime_stat_delete(&stat_config);
3050
3051         return status;
3052 }