]> asedeno.scripts.mit.edu Git - linux.git/blob - tools/perf/builtin-stat.c
5645a8361de6f494b1f9b56475dec3a5dd959d9d
[linux.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/color.h"
56 #include "util/stat.h"
57 #include "util/header.h"
58 #include "util/cpumap.h"
59 #include "util/thread.h"
60 #include "util/thread_map.h"
61 #include "util/counts.h"
62 #include "util/session.h"
63 #include "util/tool.h"
64 #include "asm/bug.h"
65
66 #include <stdlib.h>
67 #include <sys/prctl.h>
68 #include <locale.h>
69
70 #define DEFAULT_SEPARATOR       " "
71 #define CNTR_NOT_SUPPORTED      "<not supported>"
72 #define CNTR_NOT_COUNTED        "<not counted>"
73
74 static void print_counters(struct timespec *ts, int argc, const char **argv);
75
76 /* Default events used for perf stat -T */
77 static const char *transaction_attrs = {
78         "task-clock,"
79         "{"
80         "instructions,"
81         "cycles,"
82         "cpu/cycles-t/,"
83         "cpu/tx-start/,"
84         "cpu/el-start/,"
85         "cpu/cycles-ct/"
86         "}"
87 };
88
89 /* More limited version when the CPU does not have all events. */
90 static const char * transaction_limited_attrs = {
91         "task-clock,"
92         "{"
93         "instructions,"
94         "cycles,"
95         "cpu/cycles-t/,"
96         "cpu/tx-start/"
97         "}"
98 };
99
100 static struct perf_evlist       *evsel_list;
101
102 static struct target target = {
103         .uid    = UINT_MAX,
104 };
105
106 typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);
107
108 static int                      run_count                       =  1;
109 static bool                     no_inherit                      = false;
110 static volatile pid_t           child_pid                       = -1;
111 static bool                     null_run                        =  false;
112 static int                      detailed_run                    =  0;
113 static bool                     transaction_run;
114 static bool                     big_num                         =  true;
115 static int                      big_num_opt                     =  -1;
116 static const char               *csv_sep                        = NULL;
117 static bool                     csv_output                      = false;
118 static bool                     group                           = false;
119 static const char               *pre_cmd                        = NULL;
120 static const char               *post_cmd                       = NULL;
121 static bool                     sync_run                        = false;
122 static unsigned int             initial_delay                   = 0;
123 static unsigned int             unit_width                      = 4; /* strlen("unit") */
124 static bool                     forever                         = false;
125 static bool                     metric_only                     = false;
126 static struct timespec          ref_time;
127 static struct cpu_map           *aggr_map;
128 static aggr_get_id_t            aggr_get_id;
129 static bool                     append_file;
130 static const char               *output_name;
131 static int                      output_fd;
132
133 struct perf_stat {
134         bool                     record;
135         struct perf_data_file    file;
136         struct perf_session     *session;
137         u64                      bytes_written;
138         struct perf_tool         tool;
139         bool                     maps_allocated;
140         struct cpu_map          *cpus;
141         struct thread_map       *threads;
142         enum aggr_mode           aggr_mode;
143 };
144
145 static struct perf_stat         perf_stat;
146 #define STAT_RECORD             perf_stat.record
147
148 static volatile int done = 0;
149
150 static struct perf_stat_config stat_config = {
151         .aggr_mode      = AGGR_GLOBAL,
152         .scale          = true,
153 };
154
155 static inline void diff_timespec(struct timespec *r, struct timespec *a,
156                                  struct timespec *b)
157 {
158         r->tv_sec = a->tv_sec - b->tv_sec;
159         if (a->tv_nsec < b->tv_nsec) {
160                 r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec;
161                 r->tv_sec--;
162         } else {
163                 r->tv_nsec = a->tv_nsec - b->tv_nsec ;
164         }
165 }
166
167 static void perf_stat__reset_stats(void)
168 {
169         perf_evlist__reset_stats(evsel_list);
170         perf_stat__reset_shadow_stats();
171 }
172
173 static int create_perf_stat_counter(struct perf_evsel *evsel)
174 {
175         struct perf_event_attr *attr = &evsel->attr;
176
177         if (stat_config.scale)
178                 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
179                                     PERF_FORMAT_TOTAL_TIME_RUNNING;
180
181         attr->inherit = !no_inherit;
182
183         /*
184          * Some events get initialized with sample_(period/type) set,
185          * like tracepoints. Clear it up for counting.
186          */
187         attr->sample_period = 0;
188
189         /*
190          * But set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless
191          * while avoiding that older tools show confusing messages.
192          *
193          * However for pipe sessions we need to keep it zero,
194          * because script's perf_evsel__check_attr is triggered
195          * by attr->sample_type != 0, and we can't run it on
196          * stat sessions.
197          */
198         if (!(STAT_RECORD && perf_stat.file.is_pipe))
199                 attr->sample_type = PERF_SAMPLE_IDENTIFIER;
200
201         /*
202          * Disabling all counters initially, they will be enabled
203          * either manually by us or by kernel via enable_on_exec
204          * set later.
205          */
206         if (perf_evsel__is_group_leader(evsel)) {
207                 attr->disabled = 1;
208
209                 /*
210                  * In case of initial_delay we enable tracee
211                  * events manually.
212                  */
213                 if (target__none(&target) && !initial_delay)
214                         attr->enable_on_exec = 1;
215         }
216
217         if (target__has_cpu(&target))
218                 return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
219
220         return perf_evsel__open_per_thread(evsel, evsel_list->threads);
221 }
222
223 /*
224  * Does the counter have nsecs as a unit?
225  */
226 static inline int nsec_counter(struct perf_evsel *evsel)
227 {
228         if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
229             perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
230                 return 1;
231
232         return 0;
233 }
234
235 static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
236                                      union perf_event *event,
237                                      struct perf_sample *sample __maybe_unused,
238                                      struct machine *machine __maybe_unused)
239 {
240         if (perf_data_file__write(&perf_stat.file, event, event->header.size) < 0) {
241                 pr_err("failed to write perf data, error: %m\n");
242                 return -1;
243         }
244
245         perf_stat.bytes_written += event->header.size;
246         return 0;
247 }
248
249 static int write_stat_round_event(u64 tm, u64 type)
250 {
251         return perf_event__synthesize_stat_round(NULL, tm, type,
252                                                  process_synthesized_event,
253                                                  NULL);
254 }
255
256 #define WRITE_STAT_ROUND_EVENT(time, interval) \
257         write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
258
259 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
260
261 static int
262 perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread,
263                              struct perf_counts_values *count)
264 {
265         struct perf_sample_id *sid = SID(counter, cpu, thread);
266
267         return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
268                                            process_synthesized_event, NULL);
269 }
270
271 /*
272  * Read out the results of a single counter:
273  * do not aggregate counts across CPUs in system-wide mode
274  */
275 static int read_counter(struct perf_evsel *counter)
276 {
277         int nthreads = thread_map__nr(evsel_list->threads);
278         int ncpus = perf_evsel__nr_cpus(counter);
279         int cpu, thread;
280
281         if (!counter->supported)
282                 return -ENOENT;
283
284         if (counter->system_wide)
285                 nthreads = 1;
286
287         for (thread = 0; thread < nthreads; thread++) {
288                 for (cpu = 0; cpu < ncpus; cpu++) {
289                         struct perf_counts_values *count;
290
291                         count = perf_counts(counter->counts, cpu, thread);
292                         if (perf_evsel__read(counter, cpu, thread, count))
293                                 return -1;
294
295                         if (STAT_RECORD) {
296                                 if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
297                                         pr_err("failed to write stat event\n");
298                                         return -1;
299                                 }
300                         }
301
302                         if (verbose > 1) {
303                                 fprintf(stat_config.output,
304                                         "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
305                                                 perf_evsel__name(counter),
306                                                 cpu,
307                                                 count->val, count->ena, count->run);
308                         }
309                 }
310         }
311
312         return 0;
313 }
314
315 static void read_counters(bool close_counters)
316 {
317         struct perf_evsel *counter;
318
319         evlist__for_each(evsel_list, counter) {
320                 if (read_counter(counter))
321                         pr_debug("failed to read counter %s\n", counter->name);
322
323                 if (perf_stat_process_counter(&stat_config, counter))
324                         pr_warning("failed to process counter %s\n", counter->name);
325
326                 if (close_counters) {
327                         perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
328                                              thread_map__nr(evsel_list->threads));
329                 }
330         }
331 }
332
333 static void process_interval(void)
334 {
335         struct timespec ts, rs;
336
337         read_counters(false);
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 * NSECS_PER_SEC + rs.tv_nsec, INTERVAL))
344                         pr_err("failed to write stat round event\n");
345         }
346
347         print_counters(&rs, 0, NULL);
348 }
349
350 static void enable_counters(void)
351 {
352         if (initial_delay)
353                 usleep(initial_delay * 1000);
354
355         /*
356          * We need to enable counters only if:
357          * - we don't have tracee (attaching to task or cpu)
358          * - we have initial delay configured
359          */
360         if (!target__none(&target) || initial_delay)
361                 perf_evlist__enable(evsel_list);
362 }
363
364 static volatile int workload_exec_errno;
365
366 /*
367  * perf_evlist__prepare_workload will send a SIGUSR1
368  * if the fork fails, since we asked by setting its
369  * want_signal to true.
370  */
371 static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
372                                         void *ucontext __maybe_unused)
373 {
374         workload_exec_errno = info->si_value.sival_int;
375 }
376
377 static bool has_unit(struct perf_evsel *counter)
378 {
379         return counter->unit && *counter->unit;
380 }
381
382 static bool has_scale(struct perf_evsel *counter)
383 {
384         return counter->scale != 1;
385 }
386
387 static int perf_stat_synthesize_config(bool is_pipe)
388 {
389         struct perf_evsel *counter;
390         int err;
391
392         if (is_pipe) {
393                 err = perf_event__synthesize_attrs(NULL, perf_stat.session,
394                                                    process_synthesized_event);
395                 if (err < 0) {
396                         pr_err("Couldn't synthesize attrs.\n");
397                         return err;
398                 }
399         }
400
401         /*
402          * Synthesize other events stuff not carried within
403          * attr event - unit, scale, name
404          */
405         evlist__for_each(evsel_list, counter) {
406                 if (!counter->supported)
407                         continue;
408
409                 /*
410                  * Synthesize unit and scale only if it's defined.
411                  */
412                 if (has_unit(counter)) {
413                         err = perf_event__synthesize_event_update_unit(NULL, counter, process_synthesized_event);
414                         if (err < 0) {
415                                 pr_err("Couldn't synthesize evsel unit.\n");
416                                 return err;
417                         }
418                 }
419
420                 if (has_scale(counter)) {
421                         err = perf_event__synthesize_event_update_scale(NULL, counter, process_synthesized_event);
422                         if (err < 0) {
423                                 pr_err("Couldn't synthesize evsel scale.\n");
424                                 return err;
425                         }
426                 }
427
428                 if (counter->own_cpus) {
429                         err = perf_event__synthesize_event_update_cpus(NULL, counter, process_synthesized_event);
430                         if (err < 0) {
431                                 pr_err("Couldn't synthesize evsel scale.\n");
432                                 return err;
433                         }
434                 }
435
436                 /*
437                  * Name is needed only for pipe output,
438                  * perf.data carries event names.
439                  */
440                 if (is_pipe) {
441                         err = perf_event__synthesize_event_update_name(NULL, counter, process_synthesized_event);
442                         if (err < 0) {
443                                 pr_err("Couldn't synthesize evsel name.\n");
444                                 return err;
445                         }
446                 }
447         }
448
449         err = perf_event__synthesize_thread_map2(NULL, evsel_list->threads,
450                                                 process_synthesized_event,
451                                                 NULL);
452         if (err < 0) {
453                 pr_err("Couldn't synthesize thread map.\n");
454                 return err;
455         }
456
457         err = perf_event__synthesize_cpu_map(NULL, evsel_list->cpus,
458                                              process_synthesized_event, NULL);
459         if (err < 0) {
460                 pr_err("Couldn't synthesize thread map.\n");
461                 return err;
462         }
463
464         err = perf_event__synthesize_stat_config(NULL, &stat_config,
465                                                  process_synthesized_event, NULL);
466         if (err < 0) {
467                 pr_err("Couldn't synthesize config.\n");
468                 return err;
469         }
470
471         return 0;
472 }
473
474 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
475
476 static int __store_counter_ids(struct perf_evsel *counter,
477                                struct cpu_map *cpus,
478                                struct thread_map *threads)
479 {
480         int cpu, thread;
481
482         for (cpu = 0; cpu < cpus->nr; cpu++) {
483                 for (thread = 0; thread < threads->nr; thread++) {
484                         int fd = FD(counter, cpu, thread);
485
486                         if (perf_evlist__id_add_fd(evsel_list, counter,
487                                                    cpu, thread, fd) < 0)
488                                 return -1;
489                 }
490         }
491
492         return 0;
493 }
494
495 static int store_counter_ids(struct perf_evsel *counter)
496 {
497         struct cpu_map *cpus = counter->cpus;
498         struct thread_map *threads = counter->threads;
499
500         if (perf_evsel__alloc_id(counter, cpus->nr, threads->nr))
501                 return -ENOMEM;
502
503         return __store_counter_ids(counter, cpus, threads);
504 }
505
506 static int __run_perf_stat(int argc, const char **argv)
507 {
508         int interval = stat_config.interval;
509         char msg[512];
510         unsigned long long t0, t1;
511         struct perf_evsel *counter;
512         struct timespec ts;
513         size_t l;
514         int status = 0;
515         const bool forks = (argc > 0);
516         bool is_pipe = STAT_RECORD ? perf_stat.file.is_pipe : false;
517
518         if (interval) {
519                 ts.tv_sec  = interval / 1000;
520                 ts.tv_nsec = (interval % 1000) * 1000000;
521         } else {
522                 ts.tv_sec  = 1;
523                 ts.tv_nsec = 0;
524         }
525
526         if (forks) {
527                 if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe,
528                                                   workload_exec_failed_signal) < 0) {
529                         perror("failed to prepare workload");
530                         return -1;
531                 }
532                 child_pid = evsel_list->workload.pid;
533         }
534
535         if (group)
536                 perf_evlist__set_leader(evsel_list);
537
538         evlist__for_each(evsel_list, counter) {
539                 if (create_perf_stat_counter(counter) < 0) {
540                         /*
541                          * PPC returns ENXIO for HW counters until 2.6.37
542                          * (behavior changed with commit b0a873e).
543                          */
544                         if (errno == EINVAL || errno == ENOSYS ||
545                             errno == ENOENT || errno == EOPNOTSUPP ||
546                             errno == ENXIO) {
547                                 if (verbose)
548                                         ui__warning("%s event is not supported by the kernel.\n",
549                                                     perf_evsel__name(counter));
550                                 counter->supported = false;
551
552                                 if ((counter->leader != counter) ||
553                                     !(counter->leader->nr_members > 1))
554                                         continue;
555                         }
556
557                         perf_evsel__open_strerror(counter, &target,
558                                                   errno, msg, sizeof(msg));
559                         ui__error("%s\n", msg);
560
561                         if (child_pid != -1)
562                                 kill(child_pid, SIGTERM);
563
564                         return -1;
565                 }
566                 counter->supported = true;
567
568                 l = strlen(counter->unit);
569                 if (l > unit_width)
570                         unit_width = l;
571
572                 if (STAT_RECORD && store_counter_ids(counter))
573                         return -1;
574         }
575
576         if (perf_evlist__apply_filters(evsel_list, &counter)) {
577                 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
578                         counter->filter, perf_evsel__name(counter), errno,
579                         strerror_r(errno, msg, sizeof(msg)));
580                 return -1;
581         }
582
583         if (STAT_RECORD) {
584                 int err, fd = perf_data_file__fd(&perf_stat.file);
585
586                 if (is_pipe) {
587                         err = perf_header__write_pipe(perf_data_file__fd(&perf_stat.file));
588                 } else {
589                         err = perf_session__write_header(perf_stat.session, evsel_list,
590                                                          fd, false);
591                 }
592
593                 if (err < 0)
594                         return err;
595
596                 err = perf_stat_synthesize_config(is_pipe);
597                 if (err < 0)
598                         return err;
599         }
600
601         /*
602          * Enable counters and exec the command:
603          */
604         t0 = rdclock();
605         clock_gettime(CLOCK_MONOTONIC, &ref_time);
606
607         if (forks) {
608                 perf_evlist__start_workload(evsel_list);
609                 enable_counters();
610
611                 if (interval) {
612                         while (!waitpid(child_pid, &status, WNOHANG)) {
613                                 nanosleep(&ts, NULL);
614                                 process_interval();
615                         }
616                 }
617                 wait(&status);
618
619                 if (workload_exec_errno) {
620                         const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
621                         pr_err("Workload failed: %s\n", emsg);
622                         return -1;
623                 }
624
625                 if (WIFSIGNALED(status))
626                         psignal(WTERMSIG(status), argv[0]);
627         } else {
628                 enable_counters();
629                 while (!done) {
630                         nanosleep(&ts, NULL);
631                         if (interval)
632                                 process_interval();
633                 }
634         }
635
636         t1 = rdclock();
637
638         update_stats(&walltime_nsecs_stats, t1 - t0);
639
640         read_counters(true);
641
642         return WEXITSTATUS(status);
643 }
644
645 static int run_perf_stat(int argc, const char **argv)
646 {
647         int ret;
648
649         if (pre_cmd) {
650                 ret = system(pre_cmd);
651                 if (ret)
652                         return ret;
653         }
654
655         if (sync_run)
656                 sync();
657
658         ret = __run_perf_stat(argc, argv);
659         if (ret)
660                 return ret;
661
662         if (post_cmd) {
663                 ret = system(post_cmd);
664                 if (ret)
665                         return ret;
666         }
667
668         return ret;
669 }
670
671 static void print_running(u64 run, u64 ena)
672 {
673         if (csv_output) {
674                 fprintf(stat_config.output, "%s%" PRIu64 "%s%.2f",
675                                         csv_sep,
676                                         run,
677                                         csv_sep,
678                                         ena ? 100.0 * run / ena : 100.0);
679         } else if (run != ena) {
680                 fprintf(stat_config.output, "  (%.2f%%)", 100.0 * run / ena);
681         }
682 }
683
684 static void print_noise_pct(double total, double avg)
685 {
686         double pct = rel_stddev_stats(total, avg);
687
688         if (csv_output)
689                 fprintf(stat_config.output, "%s%.2f%%", csv_sep, pct);
690         else if (pct)
691                 fprintf(stat_config.output, "  ( +-%6.2f%% )", pct);
692 }
693
694 static void print_noise(struct perf_evsel *evsel, double avg)
695 {
696         struct perf_stat_evsel *ps;
697
698         if (run_count == 1)
699                 return;
700
701         ps = evsel->priv;
702         print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
703 }
704
705 static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
706 {
707         switch (stat_config.aggr_mode) {
708         case AGGR_CORE:
709                 fprintf(stat_config.output, "S%d-C%*d%s%*d%s",
710                         cpu_map__id_to_socket(id),
711                         csv_output ? 0 : -8,
712                         cpu_map__id_to_cpu(id),
713                         csv_sep,
714                         csv_output ? 0 : 4,
715                         nr,
716                         csv_sep);
717                 break;
718         case AGGR_SOCKET:
719                 fprintf(stat_config.output, "S%*d%s%*d%s",
720                         csv_output ? 0 : -5,
721                         id,
722                         csv_sep,
723                         csv_output ? 0 : 4,
724                         nr,
725                         csv_sep);
726                         break;
727         case AGGR_NONE:
728                 fprintf(stat_config.output, "CPU%*d%s",
729                         csv_output ? 0 : -4,
730                         perf_evsel__cpus(evsel)->map[id], csv_sep);
731                 break;
732         case AGGR_THREAD:
733                 fprintf(stat_config.output, "%*s-%*d%s",
734                         csv_output ? 0 : 16,
735                         thread_map__comm(evsel->threads, id),
736                         csv_output ? 0 : -8,
737                         thread_map__pid(evsel->threads, id),
738                         csv_sep);
739                 break;
740         case AGGR_GLOBAL:
741         case AGGR_UNSET:
742         default:
743                 break;
744         }
745 }
746
747 struct outstate {
748         FILE *fh;
749         bool newline;
750         const char *prefix;
751         int  nfields;
752         int  id, nr;
753         struct perf_evsel *evsel;
754 };
755
756 #define METRIC_LEN  35
757
758 static void new_line_std(void *ctx)
759 {
760         struct outstate *os = ctx;
761
762         os->newline = true;
763 }
764
765 static void do_new_line_std(struct outstate *os)
766 {
767         fputc('\n', os->fh);
768         fputs(os->prefix, os->fh);
769         aggr_printout(os->evsel, os->id, os->nr);
770         if (stat_config.aggr_mode == AGGR_NONE)
771                 fprintf(os->fh, "        ");
772         fprintf(os->fh, "                                                 ");
773 }
774
775 static void print_metric_std(void *ctx, const char *color, const char *fmt,
776                              const char *unit, double val)
777 {
778         struct outstate *os = ctx;
779         FILE *out = os->fh;
780         int n;
781         bool newline = os->newline;
782
783         os->newline = false;
784
785         if (unit == NULL || fmt == NULL) {
786                 fprintf(out, "%-*s", METRIC_LEN, "");
787                 return;
788         }
789
790         if (newline)
791                 do_new_line_std(os);
792
793         n = fprintf(out, " # ");
794         if (color)
795                 n += color_fprintf(out, color, fmt, val);
796         else
797                 n += fprintf(out, fmt, val);
798         fprintf(out, " %-*s", METRIC_LEN - n - 1, unit);
799 }
800
801 static void new_line_csv(void *ctx)
802 {
803         struct outstate *os = ctx;
804         int i;
805
806         fputc('\n', os->fh);
807         if (os->prefix)
808                 fprintf(os->fh, "%s%s", os->prefix, csv_sep);
809         aggr_printout(os->evsel, os->id, os->nr);
810         for (i = 0; i < os->nfields; i++)
811                 fputs(csv_sep, os->fh);
812 }
813
814 static void print_metric_csv(void *ctx,
815                              const char *color __maybe_unused,
816                              const char *fmt, const char *unit, double val)
817 {
818         struct outstate *os = ctx;
819         FILE *out = os->fh;
820         char buf[64], *vals, *ends;
821
822         if (unit == NULL || fmt == NULL) {
823                 fprintf(out, "%s%s%s%s", csv_sep, csv_sep, csv_sep, csv_sep);
824                 return;
825         }
826         snprintf(buf, sizeof(buf), fmt, val);
827         vals = buf;
828         while (isspace(*vals))
829                 vals++;
830         ends = vals;
831         while (isdigit(*ends) || *ends == '.')
832                 ends++;
833         *ends = 0;
834         while (isspace(*unit))
835                 unit++;
836         fprintf(out, "%s%s%s%s", csv_sep, vals, csv_sep, unit);
837 }
838
839 #define METRIC_ONLY_LEN 20
840
841 /* Filter out some columns that don't work well in metrics only mode */
842
843 static bool valid_only_metric(const char *unit)
844 {
845         if (!unit)
846                 return false;
847         if (strstr(unit, "/sec") ||
848             strstr(unit, "hz") ||
849             strstr(unit, "Hz") ||
850             strstr(unit, "CPUs utilized"))
851                 return false;
852         return true;
853 }
854
855 static const char *fixunit(char *buf, struct perf_evsel *evsel,
856                            const char *unit)
857 {
858         if (!strncmp(unit, "of all", 6)) {
859                 snprintf(buf, 1024, "%s %s", perf_evsel__name(evsel),
860                          unit);
861                 return buf;
862         }
863         return unit;
864 }
865
866 static void print_metric_only(void *ctx, const char *color, const char *fmt,
867                               const char *unit, double val)
868 {
869         struct outstate *os = ctx;
870         FILE *out = os->fh;
871         int n;
872         char buf[1024];
873         unsigned mlen = METRIC_ONLY_LEN;
874
875         if (!valid_only_metric(unit))
876                 return;
877         unit = fixunit(buf, os->evsel, unit);
878         if (color)
879                 n = color_fprintf(out, color, fmt, val);
880         else
881                 n = fprintf(out, fmt, val);
882         if (n > METRIC_ONLY_LEN)
883                 n = METRIC_ONLY_LEN;
884         if (mlen < strlen(unit))
885                 mlen = strlen(unit) + 1;
886         fprintf(out, "%*s", mlen - n, "");
887 }
888
889 static void print_metric_only_csv(void *ctx, const char *color __maybe_unused,
890                                   const char *fmt,
891                                   const char *unit, double val)
892 {
893         struct outstate *os = ctx;
894         FILE *out = os->fh;
895         char buf[64], *vals, *ends;
896         char tbuf[1024];
897
898         if (!valid_only_metric(unit))
899                 return;
900         unit = fixunit(tbuf, os->evsel, unit);
901         snprintf(buf, sizeof buf, fmt, val);
902         vals = buf;
903         while (isspace(*vals))
904                 vals++;
905         ends = vals;
906         while (isdigit(*ends) || *ends == '.')
907                 ends++;
908         *ends = 0;
909         fprintf(out, "%s%s", vals, csv_sep);
910 }
911
912 static void new_line_metric(void *ctx __maybe_unused)
913 {
914 }
915
916 static void print_metric_header(void *ctx, const char *color __maybe_unused,
917                                 const char *fmt __maybe_unused,
918                                 const char *unit, double val __maybe_unused)
919 {
920         struct outstate *os = ctx;
921         char tbuf[1024];
922
923         if (!valid_only_metric(unit))
924                 return;
925         unit = fixunit(tbuf, os->evsel, unit);
926         if (csv_output)
927                 fprintf(os->fh, "%s%s", unit, csv_sep);
928         else
929                 fprintf(os->fh, "%-*s ", METRIC_ONLY_LEN, unit);
930 }
931
932 static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
933 {
934         FILE *output = stat_config.output;
935         double msecs = avg / 1e6;
936         const char *fmt_v, *fmt_n;
937         char name[25];
938
939         fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
940         fmt_n = csv_output ? "%s" : "%-25s";
941
942         aggr_printout(evsel, id, nr);
943
944         scnprintf(name, sizeof(name), "%s%s",
945                   perf_evsel__name(evsel), csv_output ? "" : " (msec)");
946
947         fprintf(output, fmt_v, msecs, csv_sep);
948
949         if (csv_output)
950                 fprintf(output, "%s%s", evsel->unit, csv_sep);
951         else
952                 fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
953
954         fprintf(output, fmt_n, name);
955
956         if (evsel->cgrp)
957                 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
958 }
959
960 static int first_shadow_cpu(struct perf_evsel *evsel, int id)
961 {
962         int i;
963
964         if (!aggr_get_id)
965                 return 0;
966
967         if (stat_config.aggr_mode == AGGR_NONE)
968                 return id;
969
970         if (stat_config.aggr_mode == AGGR_GLOBAL)
971                 return 0;
972
973         for (i = 0; i < perf_evsel__nr_cpus(evsel); i++) {
974                 int cpu2 = perf_evsel__cpus(evsel)->map[i];
975
976                 if (aggr_get_id(evsel_list->cpus, cpu2) == id)
977                         return cpu2;
978         }
979         return 0;
980 }
981
982 static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
983 {
984         FILE *output = stat_config.output;
985         double sc =  evsel->scale;
986         const char *fmt;
987
988         if (csv_output) {
989                 fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
990         } else {
991                 if (big_num)
992                         fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
993                 else
994                         fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
995         }
996
997         aggr_printout(evsel, id, nr);
998
999         fprintf(output, fmt, avg, csv_sep);
1000
1001         if (evsel->unit)
1002                 fprintf(output, "%-*s%s",
1003                         csv_output ? 0 : unit_width,
1004                         evsel->unit, csv_sep);
1005
1006         fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
1007
1008         if (evsel->cgrp)
1009                 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
1010 }
1011
1012 static void printout(int id, int nr, struct perf_evsel *counter, double uval,
1013                      char *prefix, u64 run, u64 ena, double noise)
1014 {
1015         struct perf_stat_output_ctx out;
1016         struct outstate os = {
1017                 .fh = stat_config.output,
1018                 .prefix = prefix ? prefix : "",
1019                 .id = id,
1020                 .nr = nr,
1021                 .evsel = counter,
1022         };
1023         print_metric_t pm = print_metric_std;
1024         void (*nl)(void *);
1025
1026         if (metric_only) {
1027                 nl = new_line_metric;
1028                 if (csv_output)
1029                         pm = print_metric_only_csv;
1030                 else
1031                         pm = print_metric_only;
1032         } else
1033                 nl = new_line_std;
1034
1035         if (csv_output && !metric_only) {
1036                 static int aggr_fields[] = {
1037                         [AGGR_GLOBAL] = 0,
1038                         [AGGR_THREAD] = 1,
1039                         [AGGR_NONE] = 1,
1040                         [AGGR_SOCKET] = 2,
1041                         [AGGR_CORE] = 2,
1042                 };
1043
1044                 pm = print_metric_csv;
1045                 nl = new_line_csv;
1046                 os.nfields = 3;
1047                 os.nfields += aggr_fields[stat_config.aggr_mode];
1048                 if (counter->cgrp)
1049                         os.nfields++;
1050         }
1051         if (run == 0 || ena == 0 || counter->counts->scaled == -1) {
1052                 if (metric_only) {
1053                         pm(&os, NULL, "", "", 0);
1054                         return;
1055                 }
1056                 aggr_printout(counter, id, nr);
1057
1058                 fprintf(stat_config.output, "%*s%s",
1059                         csv_output ? 0 : 18,
1060                         counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
1061                         csv_sep);
1062
1063                 fprintf(stat_config.output, "%-*s%s",
1064                         csv_output ? 0 : unit_width,
1065                         counter->unit, csv_sep);
1066
1067                 fprintf(stat_config.output, "%*s",
1068                         csv_output ? 0 : -25,
1069                         perf_evsel__name(counter));
1070
1071                 if (counter->cgrp)
1072                         fprintf(stat_config.output, "%s%s",
1073                                 csv_sep, counter->cgrp->name);
1074
1075                 if (!csv_output)
1076                         pm(&os, NULL, NULL, "", 0);
1077                 print_noise(counter, noise);
1078                 print_running(run, ena);
1079                 if (csv_output)
1080                         pm(&os, NULL, NULL, "", 0);
1081                 return;
1082         }
1083
1084         if (metric_only)
1085                 /* nothing */;
1086         else if (nsec_counter(counter))
1087                 nsec_printout(id, nr, counter, uval);
1088         else
1089                 abs_printout(id, nr, counter, uval);
1090
1091         out.print_metric = pm;
1092         out.new_line = nl;
1093         out.ctx = &os;
1094
1095         if (csv_output && !metric_only) {
1096                 print_noise(counter, noise);
1097                 print_running(run, ena);
1098         }
1099
1100         perf_stat__print_shadow_stats(counter, uval,
1101                                 first_shadow_cpu(counter, id),
1102                                 &out);
1103         if (!csv_output && !metric_only) {
1104                 print_noise(counter, noise);
1105                 print_running(run, ena);
1106         }
1107 }
1108
1109 static void aggr_update_shadow(void)
1110 {
1111         int cpu, s2, id, s;
1112         u64 val;
1113         struct perf_evsel *counter;
1114
1115         for (s = 0; s < aggr_map->nr; s++) {
1116                 id = aggr_map->map[s];
1117                 evlist__for_each(evsel_list, counter) {
1118                         val = 0;
1119                         for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1120                                 s2 = aggr_get_id(evsel_list->cpus, cpu);
1121                                 if (s2 != id)
1122                                         continue;
1123                                 val += perf_counts(counter->counts, cpu, 0)->val;
1124                         }
1125                         val = val * counter->scale;
1126                         perf_stat__update_shadow_stats(counter, &val,
1127                                                        first_shadow_cpu(counter, id));
1128                 }
1129         }
1130 }
1131
1132 static void print_aggr(char *prefix)
1133 {
1134         FILE *output = stat_config.output;
1135         struct perf_evsel *counter;
1136         int cpu, s, s2, id, nr;
1137         double uval;
1138         u64 ena, run, val;
1139         bool first;
1140
1141         if (!(aggr_map || aggr_get_id))
1142                 return;
1143
1144         aggr_update_shadow();
1145
1146         /*
1147          * With metric_only everything is on a single line.
1148          * Without each counter has its own line.
1149          */
1150         for (s = 0; s < aggr_map->nr; s++) {
1151                 if (prefix && metric_only)
1152                         fprintf(output, "%s", prefix);
1153
1154                 id = aggr_map->map[s];
1155                 first = true;
1156                 evlist__for_each(evsel_list, counter) {
1157                         val = ena = run = 0;
1158                         nr = 0;
1159                         for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1160                                 s2 = aggr_get_id(perf_evsel__cpus(counter), cpu);
1161                                 if (s2 != id)
1162                                         continue;
1163                                 val += perf_counts(counter->counts, cpu, 0)->val;
1164                                 ena += perf_counts(counter->counts, cpu, 0)->ena;
1165                                 run += perf_counts(counter->counts, cpu, 0)->run;
1166                                 nr++;
1167                         }
1168                         if (first && metric_only) {
1169                                 first = false;
1170                                 aggr_printout(counter, id, nr);
1171                         }
1172                         if (prefix && !metric_only)
1173                                 fprintf(output, "%s", prefix);
1174
1175                         uval = val * counter->scale;
1176                         printout(id, nr, counter, uval, prefix, run, ena, 1.0);
1177                         if (!metric_only)
1178                                 fputc('\n', output);
1179                 }
1180                 if (metric_only)
1181                         fputc('\n', output);
1182         }
1183 }
1184
1185 static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
1186 {
1187         FILE *output = stat_config.output;
1188         int nthreads = thread_map__nr(counter->threads);
1189         int ncpus = cpu_map__nr(counter->cpus);
1190         int cpu, thread;
1191         double uval;
1192
1193         for (thread = 0; thread < nthreads; thread++) {
1194                 u64 ena = 0, run = 0, val = 0;
1195
1196                 for (cpu = 0; cpu < ncpus; cpu++) {
1197                         val += perf_counts(counter->counts, cpu, thread)->val;
1198                         ena += perf_counts(counter->counts, cpu, thread)->ena;
1199                         run += perf_counts(counter->counts, cpu, thread)->run;
1200                 }
1201
1202                 if (prefix)
1203                         fprintf(output, "%s", prefix);
1204
1205                 uval = val * counter->scale;
1206                 printout(thread, 0, counter, uval, prefix, run, ena, 1.0);
1207                 fputc('\n', output);
1208         }
1209 }
1210
1211 /*
1212  * Print out the results of a single counter:
1213  * aggregated counts in system-wide mode
1214  */
1215 static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
1216 {
1217         FILE *output = stat_config.output;
1218         struct perf_stat_evsel *ps = counter->priv;
1219         double avg = avg_stats(&ps->res_stats[0]);
1220         double uval;
1221         double avg_enabled, avg_running;
1222
1223         avg_enabled = avg_stats(&ps->res_stats[1]);
1224         avg_running = avg_stats(&ps->res_stats[2]);
1225
1226         if (prefix && !metric_only)
1227                 fprintf(output, "%s", prefix);
1228
1229         uval = avg * counter->scale;
1230         printout(-1, 0, counter, uval, prefix, avg_running, avg_enabled, avg);
1231         if (!metric_only)
1232                 fprintf(output, "\n");
1233 }
1234
1235 /*
1236  * Print out the results of a single counter:
1237  * does not use aggregated count in system-wide
1238  */
1239 static void print_counter(struct perf_evsel *counter, char *prefix)
1240 {
1241         FILE *output = stat_config.output;
1242         u64 ena, run, val;
1243         double uval;
1244         int cpu;
1245
1246         for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
1247                 val = perf_counts(counter->counts, cpu, 0)->val;
1248                 ena = perf_counts(counter->counts, cpu, 0)->ena;
1249                 run = perf_counts(counter->counts, cpu, 0)->run;
1250
1251                 if (prefix)
1252                         fprintf(output, "%s", prefix);
1253
1254                 uval = val * counter->scale;
1255                 printout(cpu, 0, counter, uval, prefix, run, ena, 1.0);
1256
1257                 fputc('\n', output);
1258         }
1259 }
1260
1261 static void print_no_aggr_metric(char *prefix)
1262 {
1263         int cpu;
1264         int nrcpus = 0;
1265         struct perf_evsel *counter;
1266         u64 ena, run, val;
1267         double uval;
1268
1269         nrcpus = evsel_list->cpus->nr;
1270         for (cpu = 0; cpu < nrcpus; cpu++) {
1271                 bool first = true;
1272
1273                 if (prefix)
1274                         fputs(prefix, stat_config.output);
1275                 evlist__for_each(evsel_list, counter) {
1276                         if (first) {
1277                                 aggr_printout(counter, cpu, 0);
1278                                 first = false;
1279                         }
1280                         val = perf_counts(counter->counts, cpu, 0)->val;
1281                         ena = perf_counts(counter->counts, cpu, 0)->ena;
1282                         run = perf_counts(counter->counts, cpu, 0)->run;
1283
1284                         uval = val * counter->scale;
1285                         printout(cpu, 0, counter, uval, prefix, run, ena, 1.0);
1286                 }
1287                 fputc('\n', stat_config.output);
1288         }
1289 }
1290
1291 static int aggr_header_lens[] = {
1292         [AGGR_CORE] = 18,
1293         [AGGR_SOCKET] = 12,
1294         [AGGR_NONE] = 6,
1295         [AGGR_THREAD] = 24,
1296         [AGGR_GLOBAL] = 0,
1297 };
1298
1299 static void print_metric_headers(char *prefix)
1300 {
1301         struct perf_stat_output_ctx out;
1302         struct perf_evsel *counter;
1303         struct outstate os = {
1304                 .fh = stat_config.output
1305         };
1306
1307         if (prefix)
1308                 fprintf(stat_config.output, "%s", prefix);
1309
1310         if (!csv_output)
1311                 fprintf(stat_config.output, "%*s",
1312                         aggr_header_lens[stat_config.aggr_mode], "");
1313
1314         /* Print metrics headers only */
1315         evlist__for_each(evsel_list, counter) {
1316                 os.evsel = counter;
1317                 out.ctx = &os;
1318                 out.print_metric = print_metric_header;
1319                 out.new_line = new_line_metric;
1320                 os.evsel = counter;
1321                 perf_stat__print_shadow_stats(counter, 0,
1322                                               0,
1323                                               &out);
1324         }
1325         fputc('\n', stat_config.output);
1326 }
1327
1328 static void print_interval(char *prefix, struct timespec *ts)
1329 {
1330         FILE *output = stat_config.output;
1331         static int num_print_interval;
1332
1333         sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
1334
1335         if (num_print_interval == 0 && !csv_output && !metric_only) {
1336                 switch (stat_config.aggr_mode) {
1337                 case AGGR_SOCKET:
1338                         fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
1339                         break;
1340                 case AGGR_CORE:
1341                         fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
1342                         break;
1343                 case AGGR_NONE:
1344                         fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
1345                         break;
1346                 case AGGR_THREAD:
1347                         fprintf(output, "#           time             comm-pid                  counts %*s events\n", unit_width, "unit");
1348                         break;
1349                 case AGGR_GLOBAL:
1350                 default:
1351                         fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
1352                 case AGGR_UNSET:
1353                         break;
1354                 }
1355         }
1356
1357         if (++num_print_interval == 25)
1358                 num_print_interval = 0;
1359 }
1360
1361 static void print_header(int argc, const char **argv)
1362 {
1363         FILE *output = stat_config.output;
1364         int i;
1365
1366         fflush(stdout);
1367
1368         if (!csv_output) {
1369                 fprintf(output, "\n");
1370                 fprintf(output, " Performance counter stats for ");
1371                 if (target.system_wide)
1372                         fprintf(output, "\'system wide");
1373                 else if (target.cpu_list)
1374                         fprintf(output, "\'CPU(s) %s", target.cpu_list);
1375                 else if (!target__has_task(&target)) {
1376                         fprintf(output, "\'%s", argv ? argv[0] : "pipe");
1377                         for (i = 1; argv && (i < argc); i++)
1378                                 fprintf(output, " %s", argv[i]);
1379                 } else if (target.pid)
1380                         fprintf(output, "process id \'%s", target.pid);
1381                 else
1382                         fprintf(output, "thread id \'%s", target.tid);
1383
1384                 fprintf(output, "\'");
1385                 if (run_count > 1)
1386                         fprintf(output, " (%d runs)", run_count);
1387                 fprintf(output, ":\n\n");
1388         }
1389 }
1390
1391 static void print_footer(void)
1392 {
1393         FILE *output = stat_config.output;
1394
1395         if (!null_run)
1396                 fprintf(output, "\n");
1397         fprintf(output, " %17.9f seconds time elapsed",
1398                         avg_stats(&walltime_nsecs_stats)/1e9);
1399         if (run_count > 1) {
1400                 fprintf(output, "                                        ");
1401                 print_noise_pct(stddev_stats(&walltime_nsecs_stats),
1402                                 avg_stats(&walltime_nsecs_stats));
1403         }
1404         fprintf(output, "\n\n");
1405 }
1406
1407 static void print_counters(struct timespec *ts, int argc, const char **argv)
1408 {
1409         int interval = stat_config.interval;
1410         struct perf_evsel *counter;
1411         char buf[64], *prefix = NULL;
1412
1413         /* Do not print anything if we record to the pipe. */
1414         if (STAT_RECORD && perf_stat.file.is_pipe)
1415                 return;
1416
1417         if (interval)
1418                 print_interval(prefix = buf, ts);
1419         else
1420                 print_header(argc, argv);
1421
1422         if (metric_only) {
1423                 static int num_print_iv;
1424
1425                 if (num_print_iv == 0)
1426                         print_metric_headers(prefix);
1427                 if (num_print_iv++ == 25)
1428                         num_print_iv = 0;
1429                 if (stat_config.aggr_mode == AGGR_GLOBAL && prefix)
1430                         fprintf(stat_config.output, "%s", prefix);
1431         }
1432
1433         switch (stat_config.aggr_mode) {
1434         case AGGR_CORE:
1435         case AGGR_SOCKET:
1436                 print_aggr(prefix);
1437                 break;
1438         case AGGR_THREAD:
1439                 evlist__for_each(evsel_list, counter)
1440                         print_aggr_thread(counter, prefix);
1441                 break;
1442         case AGGR_GLOBAL:
1443                 evlist__for_each(evsel_list, counter)
1444                         print_counter_aggr(counter, prefix);
1445                 if (metric_only)
1446                         fputc('\n', stat_config.output);
1447                 break;
1448         case AGGR_NONE:
1449                 if (metric_only)
1450                         print_no_aggr_metric(prefix);
1451                 else {
1452                         evlist__for_each(evsel_list, counter)
1453                                 print_counter(counter, prefix);
1454                 }
1455                 break;
1456         case AGGR_UNSET:
1457         default:
1458                 break;
1459         }
1460
1461         if (!interval && !csv_output)
1462                 print_footer();
1463
1464         fflush(stat_config.output);
1465 }
1466
1467 static volatile int signr = -1;
1468
1469 static void skip_signal(int signo)
1470 {
1471         if ((child_pid == -1) || stat_config.interval)
1472                 done = 1;
1473
1474         signr = signo;
1475         /*
1476          * render child_pid harmless
1477          * won't send SIGTERM to a random
1478          * process in case of race condition
1479          * and fast PID recycling
1480          */
1481         child_pid = -1;
1482 }
1483
1484 static void sig_atexit(void)
1485 {
1486         sigset_t set, oset;
1487
1488         /*
1489          * avoid race condition with SIGCHLD handler
1490          * in skip_signal() which is modifying child_pid
1491          * goal is to avoid send SIGTERM to a random
1492          * process
1493          */
1494         sigemptyset(&set);
1495         sigaddset(&set, SIGCHLD);
1496         sigprocmask(SIG_BLOCK, &set, &oset);
1497
1498         if (child_pid != -1)
1499                 kill(child_pid, SIGTERM);
1500
1501         sigprocmask(SIG_SETMASK, &oset, NULL);
1502
1503         if (signr == -1)
1504                 return;
1505
1506         signal(signr, SIG_DFL);
1507         kill(getpid(), signr);
1508 }
1509
1510 static int stat__set_big_num(const struct option *opt __maybe_unused,
1511                              const char *s __maybe_unused, int unset)
1512 {
1513         big_num_opt = unset ? 0 : 1;
1514         return 0;
1515 }
1516
1517 static const struct option stat_options[] = {
1518         OPT_BOOLEAN('T', "transaction", &transaction_run,
1519                     "hardware transaction statistics"),
1520         OPT_CALLBACK('e', "event", &evsel_list, "event",
1521                      "event selector. use 'perf list' to list available events",
1522                      parse_events_option),
1523         OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1524                      "event filter", parse_filter),
1525         OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1526                     "child tasks do not inherit counters"),
1527         OPT_STRING('p', "pid", &target.pid, "pid",
1528                    "stat events on existing process id"),
1529         OPT_STRING('t', "tid", &target.tid, "tid",
1530                    "stat events on existing thread id"),
1531         OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1532                     "system-wide collection from all CPUs"),
1533         OPT_BOOLEAN('g', "group", &group,
1534                     "put the counters into a counter group"),
1535         OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
1536         OPT_INCR('v', "verbose", &verbose,
1537                     "be more verbose (show counter open errors, etc)"),
1538         OPT_INTEGER('r', "repeat", &run_count,
1539                     "repeat command and print average + stddev (max: 100, forever: 0)"),
1540         OPT_BOOLEAN('n', "null", &null_run,
1541                     "null run - dont start any counters"),
1542         OPT_INCR('d', "detailed", &detailed_run,
1543                     "detailed run - start a lot of events"),
1544         OPT_BOOLEAN('S', "sync", &sync_run,
1545                     "call sync() before starting a run"),
1546         OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1547                            "print large numbers with thousands\' separators",
1548                            stat__set_big_num),
1549         OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1550                     "list of cpus to monitor in system-wide"),
1551         OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
1552                     "disable CPU count aggregation", AGGR_NONE),
1553         OPT_STRING('x', "field-separator", &csv_sep, "separator",
1554                    "print counts with custom separator"),
1555         OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1556                      "monitor event in cgroup name only", parse_cgroups),
1557         OPT_STRING('o', "output", &output_name, "file", "output file name"),
1558         OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1559         OPT_INTEGER(0, "log-fd", &output_fd,
1560                     "log output to fd, instead of stderr"),
1561         OPT_STRING(0, "pre", &pre_cmd, "command",
1562                         "command to run prior to the measured command"),
1563         OPT_STRING(0, "post", &post_cmd, "command",
1564                         "command to run after to the measured command"),
1565         OPT_UINTEGER('I', "interval-print", &stat_config.interval,
1566                     "print counts at regular interval in ms (>= 10)"),
1567         OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
1568                      "aggregate counts per processor socket", AGGR_SOCKET),
1569         OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
1570                      "aggregate counts per physical processor core", AGGR_CORE),
1571         OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
1572                      "aggregate counts per thread", AGGR_THREAD),
1573         OPT_UINTEGER('D', "delay", &initial_delay,
1574                      "ms to wait before starting measurement after program start"),
1575         OPT_BOOLEAN(0, "metric-only", &metric_only,
1576                         "Only print computed metrics. No raw values"),
1577         OPT_END()
1578 };
1579
1580 static int perf_stat__get_socket(struct cpu_map *map, int cpu)
1581 {
1582         return cpu_map__get_socket(map, cpu, NULL);
1583 }
1584
1585 static int perf_stat__get_core(struct cpu_map *map, int cpu)
1586 {
1587         return cpu_map__get_core(map, cpu, NULL);
1588 }
1589
1590 static int cpu_map__get_max(struct cpu_map *map)
1591 {
1592         int i, max = -1;
1593
1594         for (i = 0; i < map->nr; i++) {
1595                 if (map->map[i] > max)
1596                         max = map->map[i];
1597         }
1598
1599         return max;
1600 }
1601
1602 static struct cpu_map *cpus_aggr_map;
1603
1604 static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int idx)
1605 {
1606         int cpu;
1607
1608         if (idx >= map->nr)
1609                 return -1;
1610
1611         cpu = map->map[idx];
1612
1613         if (cpus_aggr_map->map[cpu] == -1)
1614                 cpus_aggr_map->map[cpu] = get_id(map, idx);
1615
1616         return cpus_aggr_map->map[cpu];
1617 }
1618
1619 static int perf_stat__get_socket_cached(struct cpu_map *map, int idx)
1620 {
1621         return perf_stat__get_aggr(perf_stat__get_socket, map, idx);
1622 }
1623
1624 static int perf_stat__get_core_cached(struct cpu_map *map, int idx)
1625 {
1626         return perf_stat__get_aggr(perf_stat__get_core, map, idx);
1627 }
1628
1629 static int perf_stat_init_aggr_mode(void)
1630 {
1631         int nr;
1632
1633         switch (stat_config.aggr_mode) {
1634         case AGGR_SOCKET:
1635                 if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
1636                         perror("cannot build socket map");
1637                         return -1;
1638                 }
1639                 aggr_get_id = perf_stat__get_socket_cached;
1640                 break;
1641         case AGGR_CORE:
1642                 if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
1643                         perror("cannot build core map");
1644                         return -1;
1645                 }
1646                 aggr_get_id = perf_stat__get_core_cached;
1647                 break;
1648         case AGGR_NONE:
1649         case AGGR_GLOBAL:
1650         case AGGR_THREAD:
1651         case AGGR_UNSET:
1652         default:
1653                 break;
1654         }
1655
1656         /*
1657          * The evsel_list->cpus is the base we operate on,
1658          * taking the highest cpu number to be the size of
1659          * the aggregation translate cpumap.
1660          */
1661         nr = cpu_map__get_max(evsel_list->cpus);
1662         cpus_aggr_map = cpu_map__empty_new(nr + 1);
1663         return cpus_aggr_map ? 0 : -ENOMEM;
1664 }
1665
1666 static void perf_stat__exit_aggr_mode(void)
1667 {
1668         cpu_map__put(aggr_map);
1669         cpu_map__put(cpus_aggr_map);
1670         aggr_map = NULL;
1671         cpus_aggr_map = NULL;
1672 }
1673
1674 static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, int idx)
1675 {
1676         int cpu;
1677
1678         if (idx > map->nr)
1679                 return -1;
1680
1681         cpu = map->map[idx];
1682
1683         if (cpu >= env->nr_cpus_online)
1684                 return -1;
1685
1686         return cpu;
1687 }
1688
1689 static int perf_env__get_socket(struct cpu_map *map, int idx, void *data)
1690 {
1691         struct perf_env *env = data;
1692         int cpu = perf_env__get_cpu(env, map, idx);
1693
1694         return cpu == -1 ? -1 : env->cpu[cpu].socket_id;
1695 }
1696
1697 static int perf_env__get_core(struct cpu_map *map, int idx, void *data)
1698 {
1699         struct perf_env *env = data;
1700         int core = -1, cpu = perf_env__get_cpu(env, map, idx);
1701
1702         if (cpu != -1) {
1703                 int socket_id = env->cpu[cpu].socket_id;
1704
1705                 /*
1706                  * Encode socket in upper 16 bits
1707                  * core_id is relative to socket, and
1708                  * we need a global id. So we combine
1709                  * socket + core id.
1710                  */
1711                 core = (socket_id << 16) | (env->cpu[cpu].core_id & 0xffff);
1712         }
1713
1714         return core;
1715 }
1716
1717 static int perf_env__build_socket_map(struct perf_env *env, struct cpu_map *cpus,
1718                                       struct cpu_map **sockp)
1719 {
1720         return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
1721 }
1722
1723 static int perf_env__build_core_map(struct perf_env *env, struct cpu_map *cpus,
1724                                     struct cpu_map **corep)
1725 {
1726         return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
1727 }
1728
1729 static int perf_stat__get_socket_file(struct cpu_map *map, int idx)
1730 {
1731         return perf_env__get_socket(map, idx, &perf_stat.session->header.env);
1732 }
1733
1734 static int perf_stat__get_core_file(struct cpu_map *map, int idx)
1735 {
1736         return perf_env__get_core(map, idx, &perf_stat.session->header.env);
1737 }
1738
1739 static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
1740 {
1741         struct perf_env *env = &st->session->header.env;
1742
1743         switch (stat_config.aggr_mode) {
1744         case AGGR_SOCKET:
1745                 if (perf_env__build_socket_map(env, evsel_list->cpus, &aggr_map)) {
1746                         perror("cannot build socket map");
1747                         return -1;
1748                 }
1749                 aggr_get_id = perf_stat__get_socket_file;
1750                 break;
1751         case AGGR_CORE:
1752                 if (perf_env__build_core_map(env, evsel_list->cpus, &aggr_map)) {
1753                         perror("cannot build core map");
1754                         return -1;
1755                 }
1756                 aggr_get_id = perf_stat__get_core_file;
1757                 break;
1758         case AGGR_NONE:
1759         case AGGR_GLOBAL:
1760         case AGGR_THREAD:
1761         case AGGR_UNSET:
1762         default:
1763                 break;
1764         }
1765
1766         return 0;
1767 }
1768
1769 /*
1770  * Add default attributes, if there were no attributes specified or
1771  * if -d/--detailed, -d -d or -d -d -d is used:
1772  */
1773 static int add_default_attributes(void)
1774 {
1775         struct perf_event_attr default_attrs0[] = {
1776
1777   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK              },
1778   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES        },
1779   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS          },
1780   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS             },
1781
1782   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES              },
1783 };
1784         struct perf_event_attr frontend_attrs[] = {
1785   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
1786 };
1787         struct perf_event_attr backend_attrs[] = {
1788   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND  },
1789 };
1790         struct perf_event_attr default_attrs1[] = {
1791   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS            },
1792   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS     },
1793   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES           },
1794
1795 };
1796
1797 /*
1798  * Detailed stats (-d), covering the L1 and last level data caches:
1799  */
1800         struct perf_event_attr detailed_attrs[] = {
1801
1802   { .type = PERF_TYPE_HW_CACHE,
1803     .config =
1804          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1805         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1806         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1807
1808   { .type = PERF_TYPE_HW_CACHE,
1809     .config =
1810          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1811         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1812         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1813
1814   { .type = PERF_TYPE_HW_CACHE,
1815     .config =
1816          PERF_COUNT_HW_CACHE_LL                 <<  0  |
1817         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1818         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1819
1820   { .type = PERF_TYPE_HW_CACHE,
1821     .config =
1822          PERF_COUNT_HW_CACHE_LL                 <<  0  |
1823         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1824         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1825 };
1826
1827 /*
1828  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1829  */
1830         struct perf_event_attr very_detailed_attrs[] = {
1831
1832   { .type = PERF_TYPE_HW_CACHE,
1833     .config =
1834          PERF_COUNT_HW_CACHE_L1I                <<  0  |
1835         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1836         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1837
1838   { .type = PERF_TYPE_HW_CACHE,
1839     .config =
1840          PERF_COUNT_HW_CACHE_L1I                <<  0  |
1841         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1842         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1843
1844   { .type = PERF_TYPE_HW_CACHE,
1845     .config =
1846          PERF_COUNT_HW_CACHE_DTLB               <<  0  |
1847         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1848         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1849
1850   { .type = PERF_TYPE_HW_CACHE,
1851     .config =
1852          PERF_COUNT_HW_CACHE_DTLB               <<  0  |
1853         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1854         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1855
1856   { .type = PERF_TYPE_HW_CACHE,
1857     .config =
1858          PERF_COUNT_HW_CACHE_ITLB               <<  0  |
1859         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1860         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1861
1862   { .type = PERF_TYPE_HW_CACHE,
1863     .config =
1864          PERF_COUNT_HW_CACHE_ITLB               <<  0  |
1865         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1866         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1867
1868 };
1869
1870 /*
1871  * Very, very detailed stats (-d -d -d), adding prefetch events:
1872  */
1873         struct perf_event_attr very_very_detailed_attrs[] = {
1874
1875   { .type = PERF_TYPE_HW_CACHE,
1876     .config =
1877          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1878         (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
1879         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1880
1881   { .type = PERF_TYPE_HW_CACHE,
1882     .config =
1883          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1884         (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
1885         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1886 };
1887
1888         /* Set attrs if no event is selected and !null_run: */
1889         if (null_run)
1890                 return 0;
1891
1892         if (transaction_run) {
1893                 int err;
1894                 if (pmu_have_event("cpu", "cycles-ct") &&
1895                     pmu_have_event("cpu", "el-start"))
1896                         err = parse_events(evsel_list, transaction_attrs, NULL);
1897                 else
1898                         err = parse_events(evsel_list, transaction_limited_attrs, NULL);
1899                 if (err) {
1900                         fprintf(stderr, "Cannot set up transaction events\n");
1901                         return -1;
1902                 }
1903                 return 0;
1904         }
1905
1906         if (!evsel_list->nr_entries) {
1907                 if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
1908                         return -1;
1909                 if (pmu_have_event("cpu", "stalled-cycles-frontend")) {
1910                         if (perf_evlist__add_default_attrs(evsel_list,
1911                                                 frontend_attrs) < 0)
1912                                 return -1;
1913                 }
1914                 if (pmu_have_event("cpu", "stalled-cycles-backend")) {
1915                         if (perf_evlist__add_default_attrs(evsel_list,
1916                                                 backend_attrs) < 0)
1917                                 return -1;
1918                 }
1919                 if (perf_evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
1920                         return -1;
1921         }
1922
1923         /* Detailed events get appended to the event list: */
1924
1925         if (detailed_run <  1)
1926                 return 0;
1927
1928         /* Append detailed run extra attributes: */
1929         if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
1930                 return -1;
1931
1932         if (detailed_run < 2)
1933                 return 0;
1934
1935         /* Append very detailed run extra attributes: */
1936         if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
1937                 return -1;
1938
1939         if (detailed_run < 3)
1940                 return 0;
1941
1942         /* Append very, very detailed run extra attributes: */
1943         return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
1944 }
1945
1946 static const char * const stat_record_usage[] = {
1947         "perf stat record [<options>]",
1948         NULL,
1949 };
1950
1951 static void init_features(struct perf_session *session)
1952 {
1953         int feat;
1954
1955         for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
1956                 perf_header__set_feat(&session->header, feat);
1957
1958         perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
1959         perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
1960         perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
1961         perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
1962 }
1963
1964 static int __cmd_record(int argc, const char **argv)
1965 {
1966         struct perf_session *session;
1967         struct perf_data_file *file = &perf_stat.file;
1968
1969         argc = parse_options(argc, argv, stat_options, stat_record_usage,
1970                              PARSE_OPT_STOP_AT_NON_OPTION);
1971
1972         if (output_name)
1973                 file->path = output_name;
1974
1975         if (run_count != 1 || forever) {
1976                 pr_err("Cannot use -r option with perf stat record.\n");
1977                 return -1;
1978         }
1979
1980         session = perf_session__new(file, false, NULL);
1981         if (session == NULL) {
1982                 pr_err("Perf session creation failed.\n");
1983                 return -1;
1984         }
1985
1986         init_features(session);
1987
1988         session->evlist   = evsel_list;
1989         perf_stat.session = session;
1990         perf_stat.record  = true;
1991         return argc;
1992 }
1993
1994 static int process_stat_round_event(struct perf_tool *tool __maybe_unused,
1995                                     union perf_event *event,
1996                                     struct perf_session *session)
1997 {
1998         struct stat_round_event *round = &event->stat_round;
1999         struct perf_evsel *counter;
2000         struct timespec tsh, *ts = NULL;
2001         const char **argv = session->header.env.cmdline_argv;
2002         int argc = session->header.env.nr_cmdline;
2003
2004         evlist__for_each(evsel_list, counter)
2005                 perf_stat_process_counter(&stat_config, counter);
2006
2007         if (round->type == PERF_STAT_ROUND_TYPE__FINAL)
2008                 update_stats(&walltime_nsecs_stats, round->time);
2009
2010         if (stat_config.interval && round->time) {
2011                 tsh.tv_sec  = round->time / NSECS_PER_SEC;
2012                 tsh.tv_nsec = round->time % NSECS_PER_SEC;
2013                 ts = &tsh;
2014         }
2015
2016         print_counters(ts, argc, argv);
2017         return 0;
2018 }
2019
2020 static
2021 int process_stat_config_event(struct perf_tool *tool __maybe_unused,
2022                               union perf_event *event,
2023                               struct perf_session *session __maybe_unused)
2024 {
2025         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
2026
2027         perf_event__read_stat_config(&stat_config, &event->stat_config);
2028
2029         if (cpu_map__empty(st->cpus)) {
2030                 if (st->aggr_mode != AGGR_UNSET)
2031                         pr_warning("warning: processing task data, aggregation mode not set\n");
2032                 return 0;
2033         }
2034
2035         if (st->aggr_mode != AGGR_UNSET)
2036                 stat_config.aggr_mode = st->aggr_mode;
2037
2038         if (perf_stat.file.is_pipe)
2039                 perf_stat_init_aggr_mode();
2040         else
2041                 perf_stat_init_aggr_mode_file(st);
2042
2043         return 0;
2044 }
2045
2046 static int set_maps(struct perf_stat *st)
2047 {
2048         if (!st->cpus || !st->threads)
2049                 return 0;
2050
2051         if (WARN_ONCE(st->maps_allocated, "stats double allocation\n"))
2052                 return -EINVAL;
2053
2054         perf_evlist__set_maps(evsel_list, st->cpus, st->threads);
2055
2056         if (perf_evlist__alloc_stats(evsel_list, true))
2057                 return -ENOMEM;
2058
2059         st->maps_allocated = true;
2060         return 0;
2061 }
2062
2063 static
2064 int process_thread_map_event(struct perf_tool *tool __maybe_unused,
2065                              union perf_event *event,
2066                              struct perf_session *session __maybe_unused)
2067 {
2068         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
2069
2070         if (st->threads) {
2071                 pr_warning("Extra thread map event, ignoring.\n");
2072                 return 0;
2073         }
2074
2075         st->threads = thread_map__new_event(&event->thread_map);
2076         if (!st->threads)
2077                 return -ENOMEM;
2078
2079         return set_maps(st);
2080 }
2081
2082 static
2083 int process_cpu_map_event(struct perf_tool *tool __maybe_unused,
2084                           union perf_event *event,
2085                           struct perf_session *session __maybe_unused)
2086 {
2087         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
2088         struct cpu_map *cpus;
2089
2090         if (st->cpus) {
2091                 pr_warning("Extra cpu map event, ignoring.\n");
2092                 return 0;
2093         }
2094
2095         cpus = cpu_map__new_data(&event->cpu_map.data);
2096         if (!cpus)
2097                 return -ENOMEM;
2098
2099         st->cpus = cpus;
2100         return set_maps(st);
2101 }
2102
2103 static const char * const stat_report_usage[] = {
2104         "perf stat report [<options>]",
2105         NULL,
2106 };
2107
2108 static struct perf_stat perf_stat = {
2109         .tool = {
2110                 .attr           = perf_event__process_attr,
2111                 .event_update   = perf_event__process_event_update,
2112                 .thread_map     = process_thread_map_event,
2113                 .cpu_map        = process_cpu_map_event,
2114                 .stat_config    = process_stat_config_event,
2115                 .stat           = perf_event__process_stat_event,
2116                 .stat_round     = process_stat_round_event,
2117         },
2118         .aggr_mode = AGGR_UNSET,
2119 };
2120
2121 static int __cmd_report(int argc, const char **argv)
2122 {
2123         struct perf_session *session;
2124         const struct option options[] = {
2125         OPT_STRING('i', "input", &input_name, "file", "input file name"),
2126         OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode,
2127                      "aggregate counts per processor socket", AGGR_SOCKET),
2128         OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode,
2129                      "aggregate counts per physical processor core", AGGR_CORE),
2130         OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode,
2131                      "disable CPU count aggregation", AGGR_NONE),
2132         OPT_END()
2133         };
2134         struct stat st;
2135         int ret;
2136
2137         argc = parse_options(argc, argv, options, stat_report_usage, 0);
2138
2139         if (!input_name || !strlen(input_name)) {
2140                 if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
2141                         input_name = "-";
2142                 else
2143                         input_name = "perf.data";
2144         }
2145
2146         perf_stat.file.path = input_name;
2147         perf_stat.file.mode = PERF_DATA_MODE_READ;
2148
2149         session = perf_session__new(&perf_stat.file, false, &perf_stat.tool);
2150         if (session == NULL)
2151                 return -1;
2152
2153         perf_stat.session  = session;
2154         stat_config.output = stderr;
2155         evsel_list         = session->evlist;
2156
2157         ret = perf_session__process_events(session);
2158         if (ret)
2159                 return ret;
2160
2161         perf_session__delete(session);
2162         return 0;
2163 }
2164
2165 int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
2166 {
2167         const char * const stat_usage[] = {
2168                 "perf stat [<options>] [<command>]",
2169                 NULL
2170         };
2171         int status = -EINVAL, run_idx;
2172         const char *mode;
2173         FILE *output = stderr;
2174         unsigned int interval;
2175         const char * const stat_subcommands[] = { "record", "report" };
2176
2177         setlocale(LC_ALL, "");
2178
2179         evsel_list = perf_evlist__new();
2180         if (evsel_list == NULL)
2181                 return -ENOMEM;
2182
2183         parse_events__shrink_config_terms();
2184         argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
2185                                         (const char **) stat_usage,
2186                                         PARSE_OPT_STOP_AT_NON_OPTION);
2187         perf_stat__init_shadow_stats();
2188
2189         if (csv_sep) {
2190                 csv_output = true;
2191                 if (!strcmp(csv_sep, "\\t"))
2192                         csv_sep = "\t";
2193         } else
2194                 csv_sep = DEFAULT_SEPARATOR;
2195
2196         if (argc && !strncmp(argv[0], "rec", 3)) {
2197                 argc = __cmd_record(argc, argv);
2198                 if (argc < 0)
2199                         return -1;
2200         } else if (argc && !strncmp(argv[0], "rep", 3))
2201                 return __cmd_report(argc, argv);
2202
2203         interval = stat_config.interval;
2204
2205         /*
2206          * For record command the -o is already taken care of.
2207          */
2208         if (!STAT_RECORD && output_name && strcmp(output_name, "-"))
2209                 output = NULL;
2210
2211         if (output_name && output_fd) {
2212                 fprintf(stderr, "cannot use both --output and --log-fd\n");
2213                 parse_options_usage(stat_usage, stat_options, "o", 1);
2214                 parse_options_usage(NULL, stat_options, "log-fd", 0);
2215                 goto out;
2216         }
2217
2218         if (metric_only && stat_config.aggr_mode == AGGR_THREAD) {
2219                 fprintf(stderr, "--metric-only is not supported with --per-thread\n");
2220                 goto out;
2221         }
2222
2223         if (metric_only && run_count > 1) {
2224                 fprintf(stderr, "--metric-only is not supported with -r\n");
2225                 goto out;
2226         }
2227
2228         if (output_fd < 0) {
2229                 fprintf(stderr, "argument to --log-fd must be a > 0\n");
2230                 parse_options_usage(stat_usage, stat_options, "log-fd", 0);
2231                 goto out;
2232         }
2233
2234         if (!output) {
2235                 struct timespec tm;
2236                 mode = append_file ? "a" : "w";
2237
2238                 output = fopen(output_name, mode);
2239                 if (!output) {
2240                         perror("failed to create output file");
2241                         return -1;
2242                 }
2243                 clock_gettime(CLOCK_REALTIME, &tm);
2244                 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
2245         } else if (output_fd > 0) {
2246                 mode = append_file ? "a" : "w";
2247                 output = fdopen(output_fd, mode);
2248                 if (!output) {
2249                         perror("Failed opening logfd");
2250                         return -errno;
2251                 }
2252         }
2253
2254         stat_config.output = output;
2255
2256         /*
2257          * let the spreadsheet do the pretty-printing
2258          */
2259         if (csv_output) {
2260                 /* User explicitly passed -B? */
2261                 if (big_num_opt == 1) {
2262                         fprintf(stderr, "-B option not supported with -x\n");
2263                         parse_options_usage(stat_usage, stat_options, "B", 1);
2264                         parse_options_usage(NULL, stat_options, "x", 1);
2265                         goto out;
2266                 } else /* Nope, so disable big number formatting */
2267                         big_num = false;
2268         } else if (big_num_opt == 0) /* User passed --no-big-num */
2269                 big_num = false;
2270
2271         if (!argc && target__none(&target))
2272                 usage_with_options(stat_usage, stat_options);
2273
2274         if (run_count < 0) {
2275                 pr_err("Run count must be a positive number\n");
2276                 parse_options_usage(stat_usage, stat_options, "r", 1);
2277                 goto out;
2278         } else if (run_count == 0) {
2279                 forever = true;
2280                 run_count = 1;
2281         }
2282
2283         if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) {
2284                 fprintf(stderr, "The --per-thread option is only available "
2285                         "when monitoring via -p -t options.\n");
2286                 parse_options_usage(NULL, stat_options, "p", 1);
2287                 parse_options_usage(NULL, stat_options, "t", 1);
2288                 goto out;
2289         }
2290
2291         /*
2292          * no_aggr, cgroup are for system-wide only
2293          * --per-thread is aggregated per thread, we dont mix it with cpu mode
2294          */
2295         if (((stat_config.aggr_mode != AGGR_GLOBAL &&
2296               stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
2297             !target__has_cpu(&target)) {
2298                 fprintf(stderr, "both cgroup and no-aggregation "
2299                         "modes only available in system-wide mode\n");
2300
2301                 parse_options_usage(stat_usage, stat_options, "G", 1);
2302                 parse_options_usage(NULL, stat_options, "A", 1);
2303                 parse_options_usage(NULL, stat_options, "a", 1);
2304                 goto out;
2305         }
2306
2307         if (add_default_attributes())
2308                 goto out;
2309
2310         target__validate(&target);
2311
2312         if (perf_evlist__create_maps(evsel_list, &target) < 0) {
2313                 if (target__has_task(&target)) {
2314                         pr_err("Problems finding threads of monitor\n");
2315                         parse_options_usage(stat_usage, stat_options, "p", 1);
2316                         parse_options_usage(NULL, stat_options, "t", 1);
2317                 } else if (target__has_cpu(&target)) {
2318                         perror("failed to parse CPUs map");
2319                         parse_options_usage(stat_usage, stat_options, "C", 1);
2320                         parse_options_usage(NULL, stat_options, "a", 1);
2321                 }
2322                 goto out;
2323         }
2324
2325         /*
2326          * Initialize thread_map with comm names,
2327          * so we could print it out on output.
2328          */
2329         if (stat_config.aggr_mode == AGGR_THREAD)
2330                 thread_map__read_comms(evsel_list->threads);
2331
2332         if (interval && interval < 100) {
2333                 if (interval < 10) {
2334                         pr_err("print interval must be >= 10ms\n");
2335                         parse_options_usage(stat_usage, stat_options, "I", 1);
2336                         goto out;
2337                 } else
2338                         pr_warning("print interval < 100ms. "
2339                                    "The overhead percentage could be high in some cases. "
2340                                    "Please proceed with caution.\n");
2341         }
2342
2343         if (perf_evlist__alloc_stats(evsel_list, interval))
2344                 goto out;
2345
2346         if (perf_stat_init_aggr_mode())
2347                 goto out;
2348
2349         /*
2350          * We dont want to block the signals - that would cause
2351          * child tasks to inherit that and Ctrl-C would not work.
2352          * What we want is for Ctrl-C to work in the exec()-ed
2353          * task, but being ignored by perf stat itself:
2354          */
2355         atexit(sig_atexit);
2356         if (!forever)
2357                 signal(SIGINT,  skip_signal);
2358         signal(SIGCHLD, skip_signal);
2359         signal(SIGALRM, skip_signal);
2360         signal(SIGABRT, skip_signal);
2361
2362         status = 0;
2363         for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
2364                 if (run_count != 1 && verbose)
2365                         fprintf(output, "[ perf stat: executing run #%d ... ]\n",
2366                                 run_idx + 1);
2367
2368                 status = run_perf_stat(argc, argv);
2369                 if (forever && status != -1) {
2370                         print_counters(NULL, argc, argv);
2371                         perf_stat__reset_stats();
2372                 }
2373         }
2374
2375         if (!forever && status != -1 && !interval)
2376                 print_counters(NULL, argc, argv);
2377
2378         if (STAT_RECORD) {
2379                 /*
2380                  * We synthesize the kernel mmap record just so that older tools
2381                  * don't emit warnings about not being able to resolve symbols
2382                  * due to /proc/sys/kernel/kptr_restrict settings and instear provide
2383                  * a saner message about no samples being in the perf.data file.
2384                  *
2385                  * This also serves to suppress a warning about f_header.data.size == 0
2386                  * in header.c at the moment 'perf stat record' gets introduced, which
2387                  * is not really needed once we start adding the stat specific PERF_RECORD_
2388                  * records, but the need to suppress the kptr_restrict messages in older
2389                  * tools remain  -acme
2390                  */
2391                 int fd = perf_data_file__fd(&perf_stat.file);
2392                 int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat,
2393                                                              process_synthesized_event,
2394                                                              &perf_stat.session->machines.host);
2395                 if (err) {
2396                         pr_warning("Couldn't synthesize the kernel mmap record, harmless, "
2397                                    "older tools may produce warnings about this file\n.");
2398                 }
2399
2400                 if (!interval) {
2401                         if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL))
2402                                 pr_err("failed to write stat round event\n");
2403                 }
2404
2405                 if (!perf_stat.file.is_pipe) {
2406                         perf_stat.session->header.data_size += perf_stat.bytes_written;
2407                         perf_session__write_header(perf_stat.session, evsel_list, fd, true);
2408                 }
2409
2410                 perf_session__delete(perf_stat.session);
2411         }
2412
2413         perf_stat__exit_aggr_mode();
2414         perf_evlist__free_stats(evsel_list);
2415 out:
2416         perf_evlist__delete(evsel_list);
2417         return status;
2418 }