]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - tools/perf/builtin-stat.c
Merge branch 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-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 "util/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
63 #include <stdlib.h>
64 #include <sys/prctl.h>
65 #include <locale.h>
66
67 #define DEFAULT_SEPARATOR       " "
68 #define CNTR_NOT_SUPPORTED      "<not supported>"
69 #define CNTR_NOT_COUNTED        "<not counted>"
70
71 static void print_counters(struct timespec *ts, int argc, const char **argv);
72
73 /* Default events used for perf stat -T */
74 static const char *transaction_attrs = {
75         "task-clock,"
76         "{"
77         "instructions,"
78         "cycles,"
79         "cpu/cycles-t/,"
80         "cpu/tx-start/,"
81         "cpu/el-start/,"
82         "cpu/cycles-ct/"
83         "}"
84 };
85
86 /* More limited version when the CPU does not have all events. */
87 static const char * transaction_limited_attrs = {
88         "task-clock,"
89         "{"
90         "instructions,"
91         "cycles,"
92         "cpu/cycles-t/,"
93         "cpu/tx-start/"
94         "}"
95 };
96
97 static struct perf_evlist       *evsel_list;
98
99 static struct target target = {
100         .uid    = UINT_MAX,
101 };
102
103 typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);
104
105 static int                      run_count                       =  1;
106 static bool                     no_inherit                      = false;
107 static volatile pid_t           child_pid                       = -1;
108 static bool                     null_run                        =  false;
109 static int                      detailed_run                    =  0;
110 static bool                     transaction_run;
111 static bool                     big_num                         =  true;
112 static int                      big_num_opt                     =  -1;
113 static const char               *csv_sep                        = NULL;
114 static bool                     csv_output                      = false;
115 static bool                     group                           = false;
116 static const char               *pre_cmd                        = NULL;
117 static const char               *post_cmd                       = NULL;
118 static bool                     sync_run                        = false;
119 static unsigned int             initial_delay                   = 0;
120 static unsigned int             unit_width                      = 4; /* strlen("unit") */
121 static bool                     forever                         = false;
122 static struct timespec          ref_time;
123 static struct cpu_map           *aggr_map;
124 static aggr_get_id_t            aggr_get_id;
125
126 static volatile int done = 0;
127
128 static struct perf_stat_config stat_config = {
129         .aggr_mode      = AGGR_GLOBAL,
130         .scale          = true,
131 };
132
133 static inline void diff_timespec(struct timespec *r, struct timespec *a,
134                                  struct timespec *b)
135 {
136         r->tv_sec = a->tv_sec - b->tv_sec;
137         if (a->tv_nsec < b->tv_nsec) {
138                 r->tv_nsec = a->tv_nsec + 1000000000L - b->tv_nsec;
139                 r->tv_sec--;
140         } else {
141                 r->tv_nsec = a->tv_nsec - b->tv_nsec ;
142         }
143 }
144
145 static void perf_stat__reset_stats(void)
146 {
147         perf_evlist__reset_stats(evsel_list);
148         perf_stat__reset_shadow_stats();
149 }
150
151 static int create_perf_stat_counter(struct perf_evsel *evsel)
152 {
153         struct perf_event_attr *attr = &evsel->attr;
154
155         if (stat_config.scale)
156                 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
157                                     PERF_FORMAT_TOTAL_TIME_RUNNING;
158
159         attr->inherit = !no_inherit;
160
161         if (target__has_cpu(&target))
162                 return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
163
164         if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) {
165                 attr->disabled = 1;
166                 if (!initial_delay)
167                         attr->enable_on_exec = 1;
168         }
169
170         return perf_evsel__open_per_thread(evsel, evsel_list->threads);
171 }
172
173 /*
174  * Does the counter have nsecs as a unit?
175  */
176 static inline int nsec_counter(struct perf_evsel *evsel)
177 {
178         if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
179             perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
180                 return 1;
181
182         return 0;
183 }
184
185 /*
186  * Read out the results of a single counter:
187  * do not aggregate counts across CPUs in system-wide mode
188  */
189 static int read_counter(struct perf_evsel *counter)
190 {
191         int nthreads = thread_map__nr(evsel_list->threads);
192         int ncpus = perf_evsel__nr_cpus(counter);
193         int cpu, thread;
194
195         if (!counter->supported)
196                 return -ENOENT;
197
198         if (counter->system_wide)
199                 nthreads = 1;
200
201         for (thread = 0; thread < nthreads; thread++) {
202                 for (cpu = 0; cpu < ncpus; cpu++) {
203                         struct perf_counts_values *count;
204
205                         count = perf_counts(counter->counts, cpu, thread);
206                         if (perf_evsel__read(counter, cpu, thread, count))
207                                 return -1;
208                 }
209         }
210
211         return 0;
212 }
213
214 static void read_counters(bool close_counters)
215 {
216         struct perf_evsel *counter;
217
218         evlist__for_each(evsel_list, counter) {
219                 if (read_counter(counter))
220                         pr_debug("failed to read counter %s\n", counter->name);
221
222                 if (perf_stat_process_counter(&stat_config, counter))
223                         pr_warning("failed to process counter %s\n", counter->name);
224
225                 if (close_counters) {
226                         perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
227                                              thread_map__nr(evsel_list->threads));
228                 }
229         }
230 }
231
232 static void process_interval(void)
233 {
234         struct timespec ts, rs;
235
236         read_counters(false);
237
238         clock_gettime(CLOCK_MONOTONIC, &ts);
239         diff_timespec(&rs, &ts, &ref_time);
240
241         print_counters(&rs, 0, NULL);
242 }
243
244 static void handle_initial_delay(void)
245 {
246         struct perf_evsel *counter;
247
248         if (initial_delay) {
249                 const int ncpus = cpu_map__nr(evsel_list->cpus),
250                         nthreads = thread_map__nr(evsel_list->threads);
251
252                 usleep(initial_delay * 1000);
253                 evlist__for_each(evsel_list, counter)
254                         perf_evsel__enable(counter, ncpus, nthreads);
255         }
256 }
257
258 static volatile int workload_exec_errno;
259
260 /*
261  * perf_evlist__prepare_workload will send a SIGUSR1
262  * if the fork fails, since we asked by setting its
263  * want_signal to true.
264  */
265 static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
266                                         void *ucontext __maybe_unused)
267 {
268         workload_exec_errno = info->si_value.sival_int;
269 }
270
271 static int __run_perf_stat(int argc, const char **argv)
272 {
273         int interval = stat_config.interval;
274         char msg[512];
275         unsigned long long t0, t1;
276         struct perf_evsel *counter;
277         struct timespec ts;
278         size_t l;
279         int status = 0;
280         const bool forks = (argc > 0);
281
282         if (interval) {
283                 ts.tv_sec  = interval / 1000;
284                 ts.tv_nsec = (interval % 1000) * 1000000;
285         } else {
286                 ts.tv_sec  = 1;
287                 ts.tv_nsec = 0;
288         }
289
290         if (forks) {
291                 if (perf_evlist__prepare_workload(evsel_list, &target, argv, false,
292                                                   workload_exec_failed_signal) < 0) {
293                         perror("failed to prepare workload");
294                         return -1;
295                 }
296                 child_pid = evsel_list->workload.pid;
297         }
298
299         if (group)
300                 perf_evlist__set_leader(evsel_list);
301
302         evlist__for_each(evsel_list, counter) {
303                 if (create_perf_stat_counter(counter) < 0) {
304                         /*
305                          * PPC returns ENXIO for HW counters until 2.6.37
306                          * (behavior changed with commit b0a873e).
307                          */
308                         if (errno == EINVAL || errno == ENOSYS ||
309                             errno == ENOENT || errno == EOPNOTSUPP ||
310                             errno == ENXIO) {
311                                 if (verbose)
312                                         ui__warning("%s event is not supported by the kernel.\n",
313                                                     perf_evsel__name(counter));
314                                 counter->supported = false;
315
316                                 if ((counter->leader != counter) ||
317                                     !(counter->leader->nr_members > 1))
318                                         continue;
319                         }
320
321                         perf_evsel__open_strerror(counter, &target,
322                                                   errno, msg, sizeof(msg));
323                         ui__error("%s\n", msg);
324
325                         if (child_pid != -1)
326                                 kill(child_pid, SIGTERM);
327
328                         return -1;
329                 }
330                 counter->supported = true;
331
332                 l = strlen(counter->unit);
333                 if (l > unit_width)
334                         unit_width = l;
335         }
336
337         if (perf_evlist__apply_filters(evsel_list, &counter)) {
338                 error("failed to set filter \"%s\" on event %s with %d (%s)\n",
339                         counter->filter, perf_evsel__name(counter), errno,
340                         strerror_r(errno, msg, sizeof(msg)));
341                 return -1;
342         }
343
344         /*
345          * Enable counters and exec the command:
346          */
347         t0 = rdclock();
348         clock_gettime(CLOCK_MONOTONIC, &ref_time);
349
350         if (forks) {
351                 perf_evlist__start_workload(evsel_list);
352                 handle_initial_delay();
353
354                 if (interval) {
355                         while (!waitpid(child_pid, &status, WNOHANG)) {
356                                 nanosleep(&ts, NULL);
357                                 process_interval();
358                         }
359                 }
360                 wait(&status);
361
362                 if (workload_exec_errno) {
363                         const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg));
364                         pr_err("Workload failed: %s\n", emsg);
365                         return -1;
366                 }
367
368                 if (WIFSIGNALED(status))
369                         psignal(WTERMSIG(status), argv[0]);
370         } else {
371                 handle_initial_delay();
372                 while (!done) {
373                         nanosleep(&ts, NULL);
374                         if (interval)
375                                 process_interval();
376                 }
377         }
378
379         t1 = rdclock();
380
381         update_stats(&walltime_nsecs_stats, t1 - t0);
382
383         read_counters(true);
384
385         return WEXITSTATUS(status);
386 }
387
388 static int run_perf_stat(int argc, const char **argv)
389 {
390         int ret;
391
392         if (pre_cmd) {
393                 ret = system(pre_cmd);
394                 if (ret)
395                         return ret;
396         }
397
398         if (sync_run)
399                 sync();
400
401         ret = __run_perf_stat(argc, argv);
402         if (ret)
403                 return ret;
404
405         if (post_cmd) {
406                 ret = system(post_cmd);
407                 if (ret)
408                         return ret;
409         }
410
411         return ret;
412 }
413
414 static void print_running(u64 run, u64 ena)
415 {
416         if (csv_output) {
417                 fprintf(stat_config.output, "%s%" PRIu64 "%s%.2f",
418                                         csv_sep,
419                                         run,
420                                         csv_sep,
421                                         ena ? 100.0 * run / ena : 100.0);
422         } else if (run != ena) {
423                 fprintf(stat_config.output, "  (%.2f%%)", 100.0 * run / ena);
424         }
425 }
426
427 static void print_noise_pct(double total, double avg)
428 {
429         double pct = rel_stddev_stats(total, avg);
430
431         if (csv_output)
432                 fprintf(stat_config.output, "%s%.2f%%", csv_sep, pct);
433         else if (pct)
434                 fprintf(stat_config.output, "  ( +-%6.2f%% )", pct);
435 }
436
437 static void print_noise(struct perf_evsel *evsel, double avg)
438 {
439         struct perf_stat_evsel *ps;
440
441         if (run_count == 1)
442                 return;
443
444         ps = evsel->priv;
445         print_noise_pct(stddev_stats(&ps->res_stats[0]), avg);
446 }
447
448 static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
449 {
450         switch (stat_config.aggr_mode) {
451         case AGGR_CORE:
452                 fprintf(stat_config.output, "S%d-C%*d%s%*d%s",
453                         cpu_map__id_to_socket(id),
454                         csv_output ? 0 : -8,
455                         cpu_map__id_to_cpu(id),
456                         csv_sep,
457                         csv_output ? 0 : 4,
458                         nr,
459                         csv_sep);
460                 break;
461         case AGGR_SOCKET:
462                 fprintf(stat_config.output, "S%*d%s%*d%s",
463                         csv_output ? 0 : -5,
464                         id,
465                         csv_sep,
466                         csv_output ? 0 : 4,
467                         nr,
468                         csv_sep);
469                         break;
470         case AGGR_NONE:
471                 fprintf(stat_config.output, "CPU%*d%s",
472                         csv_output ? 0 : -4,
473                         perf_evsel__cpus(evsel)->map[id], csv_sep);
474                 break;
475         case AGGR_THREAD:
476                 fprintf(stat_config.output, "%*s-%*d%s",
477                         csv_output ? 0 : 16,
478                         thread_map__comm(evsel->threads, id),
479                         csv_output ? 0 : -8,
480                         thread_map__pid(evsel->threads, id),
481                         csv_sep);
482                 break;
483         case AGGR_GLOBAL:
484         case AGGR_UNSET:
485         default:
486                 break;
487         }
488 }
489
490 static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg)
491 {
492         FILE *output = stat_config.output;
493         double msecs = avg / 1e6;
494         const char *fmt_v, *fmt_n;
495         char name[25];
496
497         fmt_v = csv_output ? "%.6f%s" : "%18.6f%s";
498         fmt_n = csv_output ? "%s" : "%-25s";
499
500         aggr_printout(evsel, id, nr);
501
502         scnprintf(name, sizeof(name), "%s%s",
503                   perf_evsel__name(evsel), csv_output ? "" : " (msec)");
504
505         fprintf(output, fmt_v, msecs, csv_sep);
506
507         if (csv_output)
508                 fprintf(output, "%s%s", evsel->unit, csv_sep);
509         else
510                 fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep);
511
512         fprintf(output, fmt_n, name);
513
514         if (evsel->cgrp)
515                 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
516
517         if (csv_output || stat_config.interval)
518                 return;
519
520         if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
521                 fprintf(output, " # %8.3f CPUs utilized          ",
522                         avg / avg_stats(&walltime_nsecs_stats));
523         else
524                 fprintf(output, "                                   ");
525 }
526
527 static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
528 {
529         FILE *output = stat_config.output;
530         double sc =  evsel->scale;
531         const char *fmt;
532         int cpu = cpu_map__id_to_cpu(id);
533
534         if (csv_output) {
535                 fmt = sc != 1.0 ?  "%.2f%s" : "%.0f%s";
536         } else {
537                 if (big_num)
538                         fmt = sc != 1.0 ? "%'18.2f%s" : "%'18.0f%s";
539                 else
540                         fmt = sc != 1.0 ? "%18.2f%s" : "%18.0f%s";
541         }
542
543         aggr_printout(evsel, id, nr);
544
545         if (stat_config.aggr_mode == AGGR_GLOBAL)
546                 cpu = 0;
547
548         fprintf(output, fmt, avg, csv_sep);
549
550         if (evsel->unit)
551                 fprintf(output, "%-*s%s",
552                         csv_output ? 0 : unit_width,
553                         evsel->unit, csv_sep);
554
555         fprintf(output, "%-*s", csv_output ? 0 : 25, perf_evsel__name(evsel));
556
557         if (evsel->cgrp)
558                 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
559
560         if (csv_output || stat_config.interval)
561                 return;
562
563         perf_stat__print_shadow_stats(output, evsel, avg, cpu,
564                                       stat_config.aggr_mode);
565 }
566
567 static void print_aggr(char *prefix)
568 {
569         FILE *output = stat_config.output;
570         struct perf_evsel *counter;
571         int cpu, s, s2, id, nr;
572         double uval;
573         u64 ena, run, val;
574
575         if (!(aggr_map || aggr_get_id))
576                 return;
577
578         for (s = 0; s < aggr_map->nr; s++) {
579                 id = aggr_map->map[s];
580                 evlist__for_each(evsel_list, counter) {
581                         val = ena = run = 0;
582                         nr = 0;
583                         for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
584                                 s2 = aggr_get_id(perf_evsel__cpus(counter), cpu);
585                                 if (s2 != id)
586                                         continue;
587                                 val += perf_counts(counter->counts, cpu, 0)->val;
588                                 ena += perf_counts(counter->counts, cpu, 0)->ena;
589                                 run += perf_counts(counter->counts, cpu, 0)->run;
590                                 nr++;
591                         }
592                         if (prefix)
593                                 fprintf(output, "%s", prefix);
594
595                         if (run == 0 || ena == 0) {
596                                 aggr_printout(counter, id, nr);
597
598                                 fprintf(output, "%*s%s",
599                                         csv_output ? 0 : 18,
600                                         counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
601                                         csv_sep);
602
603                                 fprintf(output, "%-*s%s",
604                                         csv_output ? 0 : unit_width,
605                                         counter->unit, csv_sep);
606
607                                 fprintf(output, "%*s",
608                                         csv_output ? 0 : -25,
609                                         perf_evsel__name(counter));
610
611                                 if (counter->cgrp)
612                                         fprintf(output, "%s%s",
613                                                 csv_sep, counter->cgrp->name);
614
615                                 print_running(run, ena);
616                                 fputc('\n', output);
617                                 continue;
618                         }
619                         uval = val * counter->scale;
620
621                         if (nsec_counter(counter))
622                                 nsec_printout(id, nr, counter, uval);
623                         else
624                                 abs_printout(id, nr, counter, uval);
625
626                         if (!csv_output)
627                                 print_noise(counter, 1.0);
628
629                         print_running(run, ena);
630                         fputc('\n', output);
631                 }
632         }
633 }
634
635 static void print_aggr_thread(struct perf_evsel *counter, char *prefix)
636 {
637         FILE *output = stat_config.output;
638         int nthreads = thread_map__nr(counter->threads);
639         int ncpus = cpu_map__nr(counter->cpus);
640         int cpu, thread;
641         double uval;
642
643         for (thread = 0; thread < nthreads; thread++) {
644                 u64 ena = 0, run = 0, val = 0;
645
646                 for (cpu = 0; cpu < ncpus; cpu++) {
647                         val += perf_counts(counter->counts, cpu, thread)->val;
648                         ena += perf_counts(counter->counts, cpu, thread)->ena;
649                         run += perf_counts(counter->counts, cpu, thread)->run;
650                 }
651
652                 if (prefix)
653                         fprintf(output, "%s", prefix);
654
655                 uval = val * counter->scale;
656
657                 if (nsec_counter(counter))
658                         nsec_printout(thread, 0, counter, uval);
659                 else
660                         abs_printout(thread, 0, counter, uval);
661
662                 if (!csv_output)
663                         print_noise(counter, 1.0);
664
665                 print_running(run, ena);
666                 fputc('\n', output);
667         }
668 }
669
670 /*
671  * Print out the results of a single counter:
672  * aggregated counts in system-wide mode
673  */
674 static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
675 {
676         FILE *output = stat_config.output;
677         struct perf_stat_evsel *ps = counter->priv;
678         double avg = avg_stats(&ps->res_stats[0]);
679         int scaled = counter->counts->scaled;
680         double uval;
681         double avg_enabled, avg_running;
682
683         avg_enabled = avg_stats(&ps->res_stats[1]);
684         avg_running = avg_stats(&ps->res_stats[2]);
685
686         if (prefix)
687                 fprintf(output, "%s", prefix);
688
689         if (scaled == -1 || !counter->supported) {
690                 fprintf(output, "%*s%s",
691                         csv_output ? 0 : 18,
692                         counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
693                         csv_sep);
694                 fprintf(output, "%-*s%s",
695                         csv_output ? 0 : unit_width,
696                         counter->unit, csv_sep);
697                 fprintf(output, "%*s",
698                         csv_output ? 0 : -25,
699                         perf_evsel__name(counter));
700
701                 if (counter->cgrp)
702                         fprintf(output, "%s%s", csv_sep, counter->cgrp->name);
703
704                 print_running(avg_running, avg_enabled);
705                 fputc('\n', output);
706                 return;
707         }
708
709         uval = avg * counter->scale;
710
711         if (nsec_counter(counter))
712                 nsec_printout(-1, 0, counter, uval);
713         else
714                 abs_printout(-1, 0, counter, uval);
715
716         print_noise(counter, avg);
717
718         print_running(avg_running, avg_enabled);
719         fprintf(output, "\n");
720 }
721
722 /*
723  * Print out the results of a single counter:
724  * does not use aggregated count in system-wide
725  */
726 static void print_counter(struct perf_evsel *counter, char *prefix)
727 {
728         FILE *output = stat_config.output;
729         u64 ena, run, val;
730         double uval;
731         int cpu;
732
733         for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
734                 val = perf_counts(counter->counts, cpu, 0)->val;
735                 ena = perf_counts(counter->counts, cpu, 0)->ena;
736                 run = perf_counts(counter->counts, cpu, 0)->run;
737
738                 if (prefix)
739                         fprintf(output, "%s", prefix);
740
741                 if (run == 0 || ena == 0) {
742                         fprintf(output, "CPU%*d%s%*s%s",
743                                 csv_output ? 0 : -4,
744                                 perf_evsel__cpus(counter)->map[cpu], csv_sep,
745                                 csv_output ? 0 : 18,
746                                 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
747                                 csv_sep);
748
749                                 fprintf(output, "%-*s%s",
750                                         csv_output ? 0 : unit_width,
751                                         counter->unit, csv_sep);
752
753                                 fprintf(output, "%*s",
754                                         csv_output ? 0 : -25,
755                                         perf_evsel__name(counter));
756
757                         if (counter->cgrp)
758                                 fprintf(output, "%s%s",
759                                         csv_sep, counter->cgrp->name);
760
761                         print_running(run, ena);
762                         fputc('\n', output);
763                         continue;
764                 }
765
766                 uval = val * counter->scale;
767
768                 if (nsec_counter(counter))
769                         nsec_printout(cpu, 0, counter, uval);
770                 else
771                         abs_printout(cpu, 0, counter, uval);
772
773                 if (!csv_output)
774                         print_noise(counter, 1.0);
775                 print_running(run, ena);
776
777                 fputc('\n', output);
778         }
779 }
780
781 static void print_interval(char *prefix, struct timespec *ts)
782 {
783         FILE *output = stat_config.output;
784         static int num_print_interval;
785
786         sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
787
788         if (num_print_interval == 0 && !csv_output) {
789                 switch (stat_config.aggr_mode) {
790                 case AGGR_SOCKET:
791                         fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
792                         break;
793                 case AGGR_CORE:
794                         fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
795                         break;
796                 case AGGR_NONE:
797                         fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
798                         break;
799                 case AGGR_THREAD:
800                         fprintf(output, "#           time             comm-pid                  counts %*s events\n", unit_width, "unit");
801                         break;
802                 case AGGR_GLOBAL:
803                 default:
804                         fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
805                 case AGGR_UNSET:
806                         break;
807                 }
808         }
809
810         if (++num_print_interval == 25)
811                 num_print_interval = 0;
812 }
813
814 static void print_header(int argc, const char **argv)
815 {
816         FILE *output = stat_config.output;
817         int i;
818
819         fflush(stdout);
820
821         if (!csv_output) {
822                 fprintf(output, "\n");
823                 fprintf(output, " Performance counter stats for ");
824                 if (target.system_wide)
825                         fprintf(output, "\'system wide");
826                 else if (target.cpu_list)
827                         fprintf(output, "\'CPU(s) %s", target.cpu_list);
828                 else if (!target__has_task(&target)) {
829                         fprintf(output, "\'%s", argv[0]);
830                         for (i = 1; i < argc; i++)
831                                 fprintf(output, " %s", argv[i]);
832                 } else if (target.pid)
833                         fprintf(output, "process id \'%s", target.pid);
834                 else
835                         fprintf(output, "thread id \'%s", target.tid);
836
837                 fprintf(output, "\'");
838                 if (run_count > 1)
839                         fprintf(output, " (%d runs)", run_count);
840                 fprintf(output, ":\n\n");
841         }
842 }
843
844 static void print_footer(void)
845 {
846         FILE *output = stat_config.output;
847
848         if (!null_run)
849                 fprintf(output, "\n");
850         fprintf(output, " %17.9f seconds time elapsed",
851                         avg_stats(&walltime_nsecs_stats)/1e9);
852         if (run_count > 1) {
853                 fprintf(output, "                                        ");
854                 print_noise_pct(stddev_stats(&walltime_nsecs_stats),
855                                 avg_stats(&walltime_nsecs_stats));
856         }
857         fprintf(output, "\n\n");
858 }
859
860 static void print_counters(struct timespec *ts, int argc, const char **argv)
861 {
862         int interval = stat_config.interval;
863         struct perf_evsel *counter;
864         char buf[64], *prefix = NULL;
865
866         if (interval)
867                 print_interval(prefix = buf, ts);
868         else
869                 print_header(argc, argv);
870
871         switch (stat_config.aggr_mode) {
872         case AGGR_CORE:
873         case AGGR_SOCKET:
874                 print_aggr(prefix);
875                 break;
876         case AGGR_THREAD:
877                 evlist__for_each(evsel_list, counter)
878                         print_aggr_thread(counter, prefix);
879                 break;
880         case AGGR_GLOBAL:
881                 evlist__for_each(evsel_list, counter)
882                         print_counter_aggr(counter, prefix);
883                 break;
884         case AGGR_NONE:
885                 evlist__for_each(evsel_list, counter)
886                         print_counter(counter, prefix);
887                 break;
888         case AGGR_UNSET:
889         default:
890                 break;
891         }
892
893         if (!interval && !csv_output)
894                 print_footer();
895
896         fflush(stat_config.output);
897 }
898
899 static volatile int signr = -1;
900
901 static void skip_signal(int signo)
902 {
903         if ((child_pid == -1) || stat_config.interval)
904                 done = 1;
905
906         signr = signo;
907         /*
908          * render child_pid harmless
909          * won't send SIGTERM to a random
910          * process in case of race condition
911          * and fast PID recycling
912          */
913         child_pid = -1;
914 }
915
916 static void sig_atexit(void)
917 {
918         sigset_t set, oset;
919
920         /*
921          * avoid race condition with SIGCHLD handler
922          * in skip_signal() which is modifying child_pid
923          * goal is to avoid send SIGTERM to a random
924          * process
925          */
926         sigemptyset(&set);
927         sigaddset(&set, SIGCHLD);
928         sigprocmask(SIG_BLOCK, &set, &oset);
929
930         if (child_pid != -1)
931                 kill(child_pid, SIGTERM);
932
933         sigprocmask(SIG_SETMASK, &oset, NULL);
934
935         if (signr == -1)
936                 return;
937
938         signal(signr, SIG_DFL);
939         kill(getpid(), signr);
940 }
941
942 static int stat__set_big_num(const struct option *opt __maybe_unused,
943                              const char *s __maybe_unused, int unset)
944 {
945         big_num_opt = unset ? 0 : 1;
946         return 0;
947 }
948
949 static int perf_stat__get_socket(struct cpu_map *map, int cpu)
950 {
951         return cpu_map__get_socket(map, cpu, NULL);
952 }
953
954 static int perf_stat__get_core(struct cpu_map *map, int cpu)
955 {
956         return cpu_map__get_core(map, cpu, NULL);
957 }
958
959 static int cpu_map__get_max(struct cpu_map *map)
960 {
961         int i, max = -1;
962
963         for (i = 0; i < map->nr; i++) {
964                 if (map->map[i] > max)
965                         max = map->map[i];
966         }
967
968         return max;
969 }
970
971 static struct cpu_map *cpus_aggr_map;
972
973 static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int idx)
974 {
975         int cpu;
976
977         if (idx >= map->nr)
978                 return -1;
979
980         cpu = map->map[idx];
981
982         if (cpus_aggr_map->map[cpu] == -1)
983                 cpus_aggr_map->map[cpu] = get_id(map, idx);
984
985         return cpus_aggr_map->map[cpu];
986 }
987
988 static int perf_stat__get_socket_cached(struct cpu_map *map, int idx)
989 {
990         return perf_stat__get_aggr(perf_stat__get_socket, map, idx);
991 }
992
993 static int perf_stat__get_core_cached(struct cpu_map *map, int idx)
994 {
995         return perf_stat__get_aggr(perf_stat__get_core, map, idx);
996 }
997
998 static int perf_stat_init_aggr_mode(void)
999 {
1000         int nr;
1001
1002         switch (stat_config.aggr_mode) {
1003         case AGGR_SOCKET:
1004                 if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
1005                         perror("cannot build socket map");
1006                         return -1;
1007                 }
1008                 aggr_get_id = perf_stat__get_socket_cached;
1009                 break;
1010         case AGGR_CORE:
1011                 if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
1012                         perror("cannot build core map");
1013                         return -1;
1014                 }
1015                 aggr_get_id = perf_stat__get_core_cached;
1016                 break;
1017         case AGGR_NONE:
1018         case AGGR_GLOBAL:
1019         case AGGR_THREAD:
1020         case AGGR_UNSET:
1021         default:
1022                 break;
1023         }
1024
1025         /*
1026          * The evsel_list->cpus is the base we operate on,
1027          * taking the highest cpu number to be the size of
1028          * the aggregation translate cpumap.
1029          */
1030         nr = cpu_map__get_max(evsel_list->cpus);
1031         cpus_aggr_map = cpu_map__empty_new(nr + 1);
1032         return cpus_aggr_map ? 0 : -ENOMEM;
1033 }
1034
1035 /*
1036  * Add default attributes, if there were no attributes specified or
1037  * if -d/--detailed, -d -d or -d -d -d is used:
1038  */
1039 static int add_default_attributes(void)
1040 {
1041         struct perf_event_attr default_attrs[] = {
1042
1043   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK              },
1044   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES        },
1045   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS          },
1046   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS             },
1047
1048   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES              },
1049   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
1050   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND  },
1051   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS            },
1052   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS     },
1053   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES           },
1054
1055 };
1056
1057 /*
1058  * Detailed stats (-d), covering the L1 and last level data caches:
1059  */
1060         struct perf_event_attr detailed_attrs[] = {
1061
1062   { .type = PERF_TYPE_HW_CACHE,
1063     .config =
1064          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1065         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1066         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1067
1068   { .type = PERF_TYPE_HW_CACHE,
1069     .config =
1070          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1071         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1072         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1073
1074   { .type = PERF_TYPE_HW_CACHE,
1075     .config =
1076          PERF_COUNT_HW_CACHE_LL                 <<  0  |
1077         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1078         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1079
1080   { .type = PERF_TYPE_HW_CACHE,
1081     .config =
1082          PERF_COUNT_HW_CACHE_LL                 <<  0  |
1083         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1084         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1085 };
1086
1087 /*
1088  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1089  */
1090         struct perf_event_attr very_detailed_attrs[] = {
1091
1092   { .type = PERF_TYPE_HW_CACHE,
1093     .config =
1094          PERF_COUNT_HW_CACHE_L1I                <<  0  |
1095         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1096         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1097
1098   { .type = PERF_TYPE_HW_CACHE,
1099     .config =
1100          PERF_COUNT_HW_CACHE_L1I                <<  0  |
1101         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1102         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1103
1104   { .type = PERF_TYPE_HW_CACHE,
1105     .config =
1106          PERF_COUNT_HW_CACHE_DTLB               <<  0  |
1107         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1108         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1109
1110   { .type = PERF_TYPE_HW_CACHE,
1111     .config =
1112          PERF_COUNT_HW_CACHE_DTLB               <<  0  |
1113         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1114         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1115
1116   { .type = PERF_TYPE_HW_CACHE,
1117     .config =
1118          PERF_COUNT_HW_CACHE_ITLB               <<  0  |
1119         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1120         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1121
1122   { .type = PERF_TYPE_HW_CACHE,
1123     .config =
1124          PERF_COUNT_HW_CACHE_ITLB               <<  0  |
1125         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1126         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1127
1128 };
1129
1130 /*
1131  * Very, very detailed stats (-d -d -d), adding prefetch events:
1132  */
1133         struct perf_event_attr very_very_detailed_attrs[] = {
1134
1135   { .type = PERF_TYPE_HW_CACHE,
1136     .config =
1137          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1138         (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
1139         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1140
1141   { .type = PERF_TYPE_HW_CACHE,
1142     .config =
1143          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1144         (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
1145         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1146 };
1147
1148         /* Set attrs if no event is selected and !null_run: */
1149         if (null_run)
1150                 return 0;
1151
1152         if (transaction_run) {
1153                 int err;
1154                 if (pmu_have_event("cpu", "cycles-ct") &&
1155                     pmu_have_event("cpu", "el-start"))
1156                         err = parse_events(evsel_list, transaction_attrs, NULL);
1157                 else
1158                         err = parse_events(evsel_list, transaction_limited_attrs, NULL);
1159                 if (err) {
1160                         fprintf(stderr, "Cannot set up transaction events\n");
1161                         return -1;
1162                 }
1163                 return 0;
1164         }
1165
1166         if (!evsel_list->nr_entries) {
1167                 if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0)
1168                         return -1;
1169         }
1170
1171         /* Detailed events get appended to the event list: */
1172
1173         if (detailed_run <  1)
1174                 return 0;
1175
1176         /* Append detailed run extra attributes: */
1177         if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
1178                 return -1;
1179
1180         if (detailed_run < 2)
1181                 return 0;
1182
1183         /* Append very detailed run extra attributes: */
1184         if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
1185                 return -1;
1186
1187         if (detailed_run < 3)
1188                 return 0;
1189
1190         /* Append very, very detailed run extra attributes: */
1191         return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
1192 }
1193
1194 int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1195 {
1196         bool append_file = false;
1197         int output_fd = 0;
1198         const char *output_name = NULL;
1199         const struct option options[] = {
1200         OPT_BOOLEAN('T', "transaction", &transaction_run,
1201                     "hardware transaction statistics"),
1202         OPT_CALLBACK('e', "event", &evsel_list, "event",
1203                      "event selector. use 'perf list' to list available events",
1204                      parse_events_option),
1205         OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1206                      "event filter", parse_filter),
1207         OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1208                     "child tasks do not inherit counters"),
1209         OPT_STRING('p', "pid", &target.pid, "pid",
1210                    "stat events on existing process id"),
1211         OPT_STRING('t', "tid", &target.tid, "tid",
1212                    "stat events on existing thread id"),
1213         OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1214                     "system-wide collection from all CPUs"),
1215         OPT_BOOLEAN('g', "group", &group,
1216                     "put the counters into a counter group"),
1217         OPT_BOOLEAN('c', "scale", &stat_config.scale, "scale/normalize counters"),
1218         OPT_INCR('v', "verbose", &verbose,
1219                     "be more verbose (show counter open errors, etc)"),
1220         OPT_INTEGER('r', "repeat", &run_count,
1221                     "repeat command and print average + stddev (max: 100, forever: 0)"),
1222         OPT_BOOLEAN('n', "null", &null_run,
1223                     "null run - dont start any counters"),
1224         OPT_INCR('d', "detailed", &detailed_run,
1225                     "detailed run - start a lot of events"),
1226         OPT_BOOLEAN('S', "sync", &sync_run,
1227                     "call sync() before starting a run"),
1228         OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1229                            "print large numbers with thousands\' separators",
1230                            stat__set_big_num),
1231         OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1232                     "list of cpus to monitor in system-wide"),
1233         OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
1234                     "disable CPU count aggregation", AGGR_NONE),
1235         OPT_STRING('x', "field-separator", &csv_sep, "separator",
1236                    "print counts with custom separator"),
1237         OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1238                      "monitor event in cgroup name only", parse_cgroups),
1239         OPT_STRING('o', "output", &output_name, "file", "output file name"),
1240         OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1241         OPT_INTEGER(0, "log-fd", &output_fd,
1242                     "log output to fd, instead of stderr"),
1243         OPT_STRING(0, "pre", &pre_cmd, "command",
1244                         "command to run prior to the measured command"),
1245         OPT_STRING(0, "post", &post_cmd, "command",
1246                         "command to run after to the measured command"),
1247         OPT_UINTEGER('I', "interval-print", &stat_config.interval,
1248                     "print counts at regular interval in ms (>= 10)"),
1249         OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
1250                      "aggregate counts per processor socket", AGGR_SOCKET),
1251         OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
1252                      "aggregate counts per physical processor core", AGGR_CORE),
1253         OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
1254                      "aggregate counts per thread", AGGR_THREAD),
1255         OPT_UINTEGER('D', "delay", &initial_delay,
1256                      "ms to wait before starting measurement after program start"),
1257         OPT_END()
1258         };
1259         const char * const stat_usage[] = {
1260                 "perf stat [<options>] [<command>]",
1261                 NULL
1262         };
1263         int status = -EINVAL, run_idx;
1264         const char *mode;
1265         FILE *output = stderr;
1266         unsigned int interval;
1267
1268         setlocale(LC_ALL, "");
1269
1270         evsel_list = perf_evlist__new();
1271         if (evsel_list == NULL)
1272                 return -ENOMEM;
1273
1274         argc = parse_options(argc, argv, options, stat_usage,
1275                 PARSE_OPT_STOP_AT_NON_OPTION);
1276
1277         interval = stat_config.interval;
1278
1279         if (output_name && strcmp(output_name, "-"))
1280                 output = NULL;
1281
1282         if (output_name && output_fd) {
1283                 fprintf(stderr, "cannot use both --output and --log-fd\n");
1284                 parse_options_usage(stat_usage, options, "o", 1);
1285                 parse_options_usage(NULL, options, "log-fd", 0);
1286                 goto out;
1287         }
1288
1289         if (output_fd < 0) {
1290                 fprintf(stderr, "argument to --log-fd must be a > 0\n");
1291                 parse_options_usage(stat_usage, options, "log-fd", 0);
1292                 goto out;
1293         }
1294
1295         if (!output) {
1296                 struct timespec tm;
1297                 mode = append_file ? "a" : "w";
1298
1299                 output = fopen(output_name, mode);
1300                 if (!output) {
1301                         perror("failed to create output file");
1302                         return -1;
1303                 }
1304                 clock_gettime(CLOCK_REALTIME, &tm);
1305                 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1306         } else if (output_fd > 0) {
1307                 mode = append_file ? "a" : "w";
1308                 output = fdopen(output_fd, mode);
1309                 if (!output) {
1310                         perror("Failed opening logfd");
1311                         return -errno;
1312                 }
1313         }
1314
1315         stat_config.output = output;
1316
1317         if (csv_sep) {
1318                 csv_output = true;
1319                 if (!strcmp(csv_sep, "\\t"))
1320                         csv_sep = "\t";
1321         } else
1322                 csv_sep = DEFAULT_SEPARATOR;
1323
1324         /*
1325          * let the spreadsheet do the pretty-printing
1326          */
1327         if (csv_output) {
1328                 /* User explicitly passed -B? */
1329                 if (big_num_opt == 1) {
1330                         fprintf(stderr, "-B option not supported with -x\n");
1331                         parse_options_usage(stat_usage, options, "B", 1);
1332                         parse_options_usage(NULL, options, "x", 1);
1333                         goto out;
1334                 } else /* Nope, so disable big number formatting */
1335                         big_num = false;
1336         } else if (big_num_opt == 0) /* User passed --no-big-num */
1337                 big_num = false;
1338
1339         if (!argc && target__none(&target))
1340                 usage_with_options(stat_usage, options);
1341
1342         if (run_count < 0) {
1343                 pr_err("Run count must be a positive number\n");
1344                 parse_options_usage(stat_usage, options, "r", 1);
1345                 goto out;
1346         } else if (run_count == 0) {
1347                 forever = true;
1348                 run_count = 1;
1349         }
1350
1351         if ((stat_config.aggr_mode == AGGR_THREAD) && !target__has_task(&target)) {
1352                 fprintf(stderr, "The --per-thread option is only available "
1353                         "when monitoring via -p -t options.\n");
1354                 parse_options_usage(NULL, options, "p", 1);
1355                 parse_options_usage(NULL, options, "t", 1);
1356                 goto out;
1357         }
1358
1359         /*
1360          * no_aggr, cgroup are for system-wide only
1361          * --per-thread is aggregated per thread, we dont mix it with cpu mode
1362          */
1363         if (((stat_config.aggr_mode != AGGR_GLOBAL &&
1364               stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
1365             !target__has_cpu(&target)) {
1366                 fprintf(stderr, "both cgroup and no-aggregation "
1367                         "modes only available in system-wide mode\n");
1368
1369                 parse_options_usage(stat_usage, options, "G", 1);
1370                 parse_options_usage(NULL, options, "A", 1);
1371                 parse_options_usage(NULL, options, "a", 1);
1372                 goto out;
1373         }
1374
1375         if (add_default_attributes())
1376                 goto out;
1377
1378         target__validate(&target);
1379
1380         if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1381                 if (target__has_task(&target)) {
1382                         pr_err("Problems finding threads of monitor\n");
1383                         parse_options_usage(stat_usage, options, "p", 1);
1384                         parse_options_usage(NULL, options, "t", 1);
1385                 } else if (target__has_cpu(&target)) {
1386                         perror("failed to parse CPUs map");
1387                         parse_options_usage(stat_usage, options, "C", 1);
1388                         parse_options_usage(NULL, options, "a", 1);
1389                 }
1390                 goto out;
1391         }
1392
1393         /*
1394          * Initialize thread_map with comm names,
1395          * so we could print it out on output.
1396          */
1397         if (stat_config.aggr_mode == AGGR_THREAD)
1398                 thread_map__read_comms(evsel_list->threads);
1399
1400         if (interval && interval < 100) {
1401                 if (interval < 10) {
1402                         pr_err("print interval must be >= 10ms\n");
1403                         parse_options_usage(stat_usage, options, "I", 1);
1404                         goto out;
1405                 } else
1406                         pr_warning("print interval < 100ms. "
1407                                    "The overhead percentage could be high in some cases. "
1408                                    "Please proceed with caution.\n");
1409         }
1410
1411         if (perf_evlist__alloc_stats(evsel_list, interval))
1412                 goto out;
1413
1414         if (perf_stat_init_aggr_mode())
1415                 goto out;
1416
1417         /*
1418          * We dont want to block the signals - that would cause
1419          * child tasks to inherit that and Ctrl-C would not work.
1420          * What we want is for Ctrl-C to work in the exec()-ed
1421          * task, but being ignored by perf stat itself:
1422          */
1423         atexit(sig_atexit);
1424         if (!forever)
1425                 signal(SIGINT,  skip_signal);
1426         signal(SIGCHLD, skip_signal);
1427         signal(SIGALRM, skip_signal);
1428         signal(SIGABRT, skip_signal);
1429
1430         status = 0;
1431         for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
1432                 if (run_count != 1 && verbose)
1433                         fprintf(output, "[ perf stat: executing run #%d ... ]\n",
1434                                 run_idx + 1);
1435
1436                 status = run_perf_stat(argc, argv);
1437                 if (forever && status != -1) {
1438                         print_counters(NULL, argc, argv);
1439                         perf_stat__reset_stats();
1440                 }
1441         }
1442
1443         if (!forever && status != -1 && !interval)
1444                 print_counters(NULL, argc, argv);
1445
1446         perf_evlist__free_stats(evsel_list);
1447 out:
1448         perf_evlist__delete(evsel_list);
1449         return status;
1450 }