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