Merge tag 'for-linus-5.4-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / tools / perf / builtin-stat.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * builtin-stat.c
4  *
5  * Builtin stat command: Give a precise performance counters summary
6  * overview about any workload, CPU or specific PID.
7  *
8  * Sample output:
9
10    $ perf stat ./hackbench 10
11
12   Time: 0.118
13
14   Performance counter stats for './hackbench 10':
15
16        1708.761321 task-clock                #   11.037 CPUs utilized
17             41,190 context-switches          #    0.024 M/sec
18              6,735 CPU-migrations            #    0.004 M/sec
19             17,318 page-faults               #    0.010 M/sec
20      5,205,202,243 cycles                    #    3.046 GHz
21      3,856,436,920 stalled-cycles-frontend   #   74.09% frontend cycles idle
22      1,600,790,871 stalled-cycles-backend    #   30.75% backend  cycles idle
23      2,603,501,247 instructions              #    0.50  insns per cycle
24                                              #    1.48  stalled cycles per insn
25        484,357,498 branches                  #  283.455 M/sec
26          6,388,934 branch-misses             #    1.32% of all branches
27
28         0.154822978  seconds time elapsed
29
30  *
31  * Copyright (C) 2008-2011, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
32  *
33  * Improvements and fixes by:
34  *
35  *   Arjan van de Ven <arjan@linux.intel.com>
36  *   Yanmin Zhang <yanmin.zhang@intel.com>
37  *   Wu Fengguang <fengguang.wu@intel.com>
38  *   Mike Galbraith <efault@gmx.de>
39  *   Paul Mackerras <paulus@samba.org>
40  *   Jaswinder Singh Rajput <jaswinder@kernel.org>
41  */
42
43 #include "builtin.h"
44 #include "perf.h"
45 #include "util/cgroup.h"
46 #include <subcmd/parse-options.h>
47 #include "util/parse-events.h"
48 #include "util/pmu.h"
49 #include "util/event.h"
50 #include "util/evlist.h"
51 #include "util/evsel.h"
52 #include "util/debug.h"
53 #include "util/color.h"
54 #include "util/stat.h"
55 #include "util/header.h"
56 #include "util/cpumap.h"
57 #include "util/thread_map.h"
58 #include "util/counts.h"
59 #include "util/group.h"
60 #include "util/session.h"
61 #include "util/tool.h"
62 #include "util/string2.h"
63 #include "util/metricgroup.h"
64 #include "util/target.h"
65 #include "util/time-utils.h"
66 #include "util/top.h"
67 #include "asm/bug.h"
68
69 #include <linux/time64.h>
70 #include <linux/zalloc.h>
71 #include <api/fs/fs.h>
72 #include <errno.h>
73 #include <signal.h>
74 #include <stdlib.h>
75 #include <sys/prctl.h>
76 #include <inttypes.h>
77 #include <locale.h>
78 #include <math.h>
79 #include <sys/types.h>
80 #include <sys/stat.h>
81 #include <sys/wait.h>
82 #include <unistd.h>
83 #include <sys/time.h>
84 #include <sys/resource.h>
85
86 #include <linux/ctype.h>
87 #include <perf/evlist.h>
88
89 #define DEFAULT_SEPARATOR       " "
90 #define FREEZE_ON_SMI_PATH      "devices/cpu/freeze_on_smi"
91
92 static void print_counters(struct timespec *ts, int argc, const char **argv);
93
94 /* Default events used for perf stat -T */
95 static const char *transaction_attrs = {
96         "task-clock,"
97         "{"
98         "instructions,"
99         "cycles,"
100         "cpu/cycles-t/,"
101         "cpu/tx-start/,"
102         "cpu/el-start/,"
103         "cpu/cycles-ct/"
104         "}"
105 };
106
107 /* More limited version when the CPU does not have all events. */
108 static const char * transaction_limited_attrs = {
109         "task-clock,"
110         "{"
111         "instructions,"
112         "cycles,"
113         "cpu/cycles-t/,"
114         "cpu/tx-start/"
115         "}"
116 };
117
118 static const char * topdown_attrs[] = {
119         "topdown-total-slots",
120         "topdown-slots-retired",
121         "topdown-recovery-bubbles",
122         "topdown-fetch-bubbles",
123         "topdown-slots-issued",
124         NULL,
125 };
126
127 static const char *smi_cost_attrs = {
128         "{"
129         "msr/aperf/,"
130         "msr/smi/,"
131         "cycles"
132         "}"
133 };
134
135 static struct evlist    *evsel_list;
136
137 static struct target target = {
138         .uid    = UINT_MAX,
139 };
140
141 #define METRIC_ONLY_LEN 20
142
143 static volatile pid_t           child_pid                       = -1;
144 static int                      detailed_run                    =  0;
145 static bool                     transaction_run;
146 static bool                     topdown_run                     = false;
147 static bool                     smi_cost                        = false;
148 static bool                     smi_reset                       = false;
149 static int                      big_num_opt                     =  -1;
150 static bool                     group                           = false;
151 static const char               *pre_cmd                        = NULL;
152 static const char               *post_cmd                       = NULL;
153 static bool                     sync_run                        = false;
154 static bool                     forever                         = false;
155 static bool                     force_metric_only               = false;
156 static struct timespec          ref_time;
157 static bool                     append_file;
158 static bool                     interval_count;
159 static const char               *output_name;
160 static int                      output_fd;
161
162 struct perf_stat {
163         bool                     record;
164         struct perf_data         data;
165         struct perf_session     *session;
166         u64                      bytes_written;
167         struct perf_tool         tool;
168         bool                     maps_allocated;
169         struct perf_cpu_map     *cpus;
170         struct perf_thread_map *threads;
171         enum aggr_mode           aggr_mode;
172 };
173
174 static struct perf_stat         perf_stat;
175 #define STAT_RECORD             perf_stat.record
176
177 static volatile int done = 0;
178
179 static struct perf_stat_config stat_config = {
180         .aggr_mode              = AGGR_GLOBAL,
181         .scale                  = true,
182         .unit_width             = 4, /* strlen("unit") */
183         .run_count              = 1,
184         .metric_only_len        = METRIC_ONLY_LEN,
185         .walltime_nsecs_stats   = &walltime_nsecs_stats,
186         .big_num                = true,
187 };
188
189 static inline void diff_timespec(struct timespec *r, struct timespec *a,
190                                  struct timespec *b)
191 {
192         r->tv_sec = a->tv_sec - b->tv_sec;
193         if (a->tv_nsec < b->tv_nsec) {
194                 r->tv_nsec = a->tv_nsec + NSEC_PER_SEC - b->tv_nsec;
195                 r->tv_sec--;
196         } else {
197                 r->tv_nsec = a->tv_nsec - b->tv_nsec ;
198         }
199 }
200
201 static void perf_stat__reset_stats(void)
202 {
203         int i;
204
205         perf_evlist__reset_stats(evsel_list);
206         perf_stat__reset_shadow_stats();
207
208         for (i = 0; i < stat_config.stats_num; i++)
209                 perf_stat__reset_shadow_per_stat(&stat_config.stats[i]);
210 }
211
212 static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
213                                      union perf_event *event,
214                                      struct perf_sample *sample __maybe_unused,
215                                      struct machine *machine __maybe_unused)
216 {
217         if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) {
218                 pr_err("failed to write perf data, error: %m\n");
219                 return -1;
220         }
221
222         perf_stat.bytes_written += event->header.size;
223         return 0;
224 }
225
226 static int write_stat_round_event(u64 tm, u64 type)
227 {
228         return perf_event__synthesize_stat_round(NULL, tm, type,
229                                                  process_synthesized_event,
230                                                  NULL);
231 }
232
233 #define WRITE_STAT_ROUND_EVENT(time, interval) \
234         write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
235
236 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
237
238 static int
239 perf_evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread,
240                              struct perf_counts_values *count)
241 {
242         struct perf_sample_id *sid = SID(counter, cpu, thread);
243
244         return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
245                                            process_synthesized_event, NULL);
246 }
247
248 static int read_single_counter(struct evsel *counter, int cpu,
249                                int thread, struct timespec *rs)
250 {
251         if (counter->tool_event == PERF_TOOL_DURATION_TIME) {
252                 u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL;
253                 struct perf_counts_values *count =
254                         perf_counts(counter->counts, cpu, thread);
255                 count->ena = count->run = val;
256                 count->val = val;
257                 return 0;
258         }
259         return perf_evsel__read_counter(counter, cpu, thread);
260 }
261
262 /*
263  * Read out the results of a single counter:
264  * do not aggregate counts across CPUs in system-wide mode
265  */
266 static int read_counter(struct evsel *counter, struct timespec *rs)
267 {
268         int nthreads = perf_thread_map__nr(evsel_list->core.threads);
269         int ncpus, cpu, thread;
270
271         if (target__has_cpu(&target) && !target__has_per_thread(&target))
272                 ncpus = perf_evsel__nr_cpus(counter);
273         else
274                 ncpus = 1;
275
276         if (!counter->supported)
277                 return -ENOENT;
278
279         if (counter->system_wide)
280                 nthreads = 1;
281
282         for (thread = 0; thread < nthreads; thread++) {
283                 for (cpu = 0; cpu < ncpus; cpu++) {
284                         struct perf_counts_values *count;
285
286                         count = perf_counts(counter->counts, cpu, thread);
287
288                         /*
289                          * The leader's group read loads data into its group members
290                          * (via perf_evsel__read_counter) and sets threir count->loaded.
291                          */
292                         if (!perf_counts__is_loaded(counter->counts, cpu, thread) &&
293                             read_single_counter(counter, cpu, thread, rs)) {
294                                 counter->counts->scaled = -1;
295                                 perf_counts(counter->counts, cpu, thread)->ena = 0;
296                                 perf_counts(counter->counts, cpu, thread)->run = 0;
297                                 return -1;
298                         }
299
300                         perf_counts__set_loaded(counter->counts, cpu, thread, false);
301
302                         if (STAT_RECORD) {
303                                 if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
304                                         pr_err("failed to write stat event\n");
305                                         return -1;
306                                 }
307                         }
308
309                         if (verbose > 1) {
310                                 fprintf(stat_config.output,
311                                         "%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
312                                                 perf_evsel__name(counter),
313                                                 cpu,
314                                                 count->val, count->ena, count->run);
315                         }
316                 }
317         }
318
319         return 0;
320 }
321
322 static void read_counters(struct timespec *rs)
323 {
324         struct evsel *counter;
325         int ret;
326
327         evlist__for_each_entry(evsel_list, counter) {
328                 ret = read_counter(counter, rs);
329                 if (ret)
330                         pr_debug("failed to read counter %s\n", counter->name);
331
332                 if (ret == 0 && perf_stat_process_counter(&stat_config, counter))
333                         pr_warning("failed to process counter %s\n", counter->name);
334         }
335 }
336
337 static void process_interval(void)
338 {
339         struct timespec ts, rs;
340
341         clock_gettime(CLOCK_MONOTONIC, &ts);
342         diff_timespec(&rs, &ts, &ref_time);
343
344         read_counters(&rs);
345
346         if (STAT_RECORD) {
347                 if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSEC_PER_SEC + rs.tv_nsec, INTERVAL))
348                         pr_err("failed to write stat round event\n");
349         }
350
351         init_stats(&walltime_nsecs_stats);
352         update_stats(&walltime_nsecs_stats, stat_config.interval * 1000000);
353         print_counters(&rs, 0, NULL);
354 }
355
356 static void enable_counters(void)
357 {
358         if (stat_config.initial_delay)
359                 usleep(stat_config.initial_delay * USEC_PER_MSEC);
360
361         /*
362          * We need to enable counters only if:
363          * - we don't have tracee (attaching to task or cpu)
364          * - we have initial delay configured
365          */
366         if (!target__none(&target) || stat_config.initial_delay)
367                 evlist__enable(evsel_list);
368 }
369
370 static void disable_counters(void)
371 {
372         /*
373          * If we don't have tracee (attaching to task or cpu), counters may
374          * still be running. To get accurate group ratios, we must stop groups
375          * from counting before reading their constituent counters.
376          */
377         if (!target__none(&target))
378                 evlist__disable(evsel_list);
379 }
380
381 static volatile int workload_exec_errno;
382
383 /*
384  * perf_evlist__prepare_workload will send a SIGUSR1
385  * if the fork fails, since we asked by setting its
386  * want_signal to true.
387  */
388 static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info,
389                                         void *ucontext __maybe_unused)
390 {
391         workload_exec_errno = info->si_value.sival_int;
392 }
393
394 static bool perf_evsel__should_store_id(struct evsel *counter)
395 {
396         return STAT_RECORD || counter->core.attr.read_format & PERF_FORMAT_ID;
397 }
398
399 static bool is_target_alive(struct target *_target,
400                             struct perf_thread_map *threads)
401 {
402         struct stat st;
403         int i;
404
405         if (!target__has_task(_target))
406                 return true;
407
408         for (i = 0; i < threads->nr; i++) {
409                 char path[PATH_MAX];
410
411                 scnprintf(path, PATH_MAX, "%s/%d", procfs__mountpoint(),
412                           threads->map[i].pid);
413
414                 if (!stat(path, &st))
415                         return true;
416         }
417
418         return false;
419 }
420
421 static int __run_perf_stat(int argc, const char **argv, int run_idx)
422 {
423         int interval = stat_config.interval;
424         int times = stat_config.times;
425         int timeout = stat_config.timeout;
426         char msg[BUFSIZ];
427         unsigned long long t0, t1;
428         struct evsel *counter;
429         struct timespec ts;
430         size_t l;
431         int status = 0;
432         const bool forks = (argc > 0);
433         bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false;
434
435         if (interval) {
436                 ts.tv_sec  = interval / USEC_PER_MSEC;
437                 ts.tv_nsec = (interval % USEC_PER_MSEC) * NSEC_PER_MSEC;
438         } else if (timeout) {
439                 ts.tv_sec  = timeout / USEC_PER_MSEC;
440                 ts.tv_nsec = (timeout % USEC_PER_MSEC) * NSEC_PER_MSEC;
441         } else {
442                 ts.tv_sec  = 1;
443                 ts.tv_nsec = 0;
444         }
445
446         if (forks) {
447                 if (perf_evlist__prepare_workload(evsel_list, &target, argv, is_pipe,
448                                                   workload_exec_failed_signal) < 0) {
449                         perror("failed to prepare workload");
450                         return -1;
451                 }
452                 child_pid = evsel_list->workload.pid;
453         }
454
455         if (group)
456                 perf_evlist__set_leader(evsel_list);
457
458         evlist__for_each_entry(evsel_list, counter) {
459 try_again:
460                 if (create_perf_stat_counter(counter, &stat_config, &target) < 0) {
461
462                         /* Weak group failed. Reset the group. */
463                         if ((errno == EINVAL || errno == EBADF) &&
464                             counter->leader != counter &&
465                             counter->weak_group) {
466                                 counter = perf_evlist__reset_weak_group(evsel_list, counter);
467                                 goto try_again;
468                         }
469
470                         /*
471                          * PPC returns ENXIO for HW counters until 2.6.37
472                          * (behavior changed with commit b0a873e).
473                          */
474                         if (errno == EINVAL || errno == ENOSYS ||
475                             errno == ENOENT || errno == EOPNOTSUPP ||
476                             errno == ENXIO) {
477                                 if (verbose > 0)
478                                         ui__warning("%s event is not supported by the kernel.\n",
479                                                     perf_evsel__name(counter));
480                                 counter->supported = false;
481
482                                 if ((counter->leader != counter) ||
483                                     !(counter->leader->core.nr_members > 1))
484                                         continue;
485                         } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
486                                 if (verbose > 0)
487                                         ui__warning("%s\n", msg);
488                                 goto try_again;
489                         } else if (target__has_per_thread(&target) &&
490                                    evsel_list->core.threads &&
491                                    evsel_list->core.threads->err_thread != -1) {
492                                 /*
493                                  * For global --per-thread case, skip current
494                                  * error thread.
495                                  */
496                                 if (!thread_map__remove(evsel_list->core.threads,
497                                                         evsel_list->core.threads->err_thread)) {
498                                         evsel_list->core.threads->err_thread = -1;
499                                         goto try_again;
500                                 }
501                         }
502
503                         perf_evsel__open_strerror(counter, &target,
504                                                   errno, msg, sizeof(msg));
505                         ui__error("%s\n", msg);
506
507                         if (child_pid != -1)
508                                 kill(child_pid, SIGTERM);
509
510                         return -1;
511                 }
512                 counter->supported = true;
513
514                 l = strlen(counter->unit);
515                 if (l > stat_config.unit_width)
516                         stat_config.unit_width = l;
517
518                 if (perf_evsel__should_store_id(counter) &&
519                     perf_evsel__store_ids(counter, evsel_list))
520                         return -1;
521         }
522
523         if (perf_evlist__apply_filters(evsel_list, &counter)) {
524                 pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
525                         counter->filter, perf_evsel__name(counter), errno,
526                         str_error_r(errno, msg, sizeof(msg)));
527                 return -1;
528         }
529
530         if (STAT_RECORD) {
531                 int err, fd = perf_data__fd(&perf_stat.data);
532
533                 if (is_pipe) {
534                         err = perf_header__write_pipe(perf_data__fd(&perf_stat.data));
535                 } else {
536                         err = perf_session__write_header(perf_stat.session, evsel_list,
537                                                          fd, false);
538                 }
539
540                 if (err < 0)
541                         return err;
542
543                 err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list,
544                                                   process_synthesized_event, is_pipe);
545                 if (err < 0)
546                         return err;
547         }
548
549         /*
550          * Enable counters and exec the command:
551          */
552         t0 = rdclock();
553         clock_gettime(CLOCK_MONOTONIC, &ref_time);
554
555         if (forks) {
556                 perf_evlist__start_workload(evsel_list);
557                 enable_counters();
558
559                 if (interval || timeout) {
560                         while (!waitpid(child_pid, &status, WNOHANG)) {
561                                 nanosleep(&ts, NULL);
562                                 if (timeout)
563                                         break;
564                                 process_interval();
565                                 if (interval_count && !(--times))
566                                         break;
567                         }
568                 }
569                 if (child_pid != -1)
570                         wait4(child_pid, &status, 0, &stat_config.ru_data);
571
572                 if (workload_exec_errno) {
573                         const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg));
574                         pr_err("Workload failed: %s\n", emsg);
575                         return -1;
576                 }
577
578                 if (WIFSIGNALED(status))
579                         psignal(WTERMSIG(status), argv[0]);
580         } else {
581                 enable_counters();
582                 while (!done) {
583                         nanosleep(&ts, NULL);
584                         if (!is_target_alive(&target, evsel_list->core.threads))
585                                 break;
586                         if (timeout)
587                                 break;
588                         if (interval) {
589                                 process_interval();
590                                 if (interval_count && !(--times))
591                                         break;
592                         }
593                 }
594         }
595
596         disable_counters();
597
598         t1 = rdclock();
599
600         if (stat_config.walltime_run_table)
601                 stat_config.walltime_run[run_idx] = t1 - t0;
602
603         update_stats(&walltime_nsecs_stats, t1 - t0);
604
605         /*
606          * Closing a group leader splits the group, and as we only disable
607          * group leaders, results in remaining events becoming enabled. To
608          * avoid arbitrary skew, we must read all counters before closing any
609          * group leaders.
610          */
611         read_counters(&(struct timespec) { .tv_nsec = t1-t0 });
612
613         /*
614          * We need to keep evsel_list alive, because it's processed
615          * later the evsel_list will be closed after.
616          */
617         if (!STAT_RECORD)
618                 evlist__close(evsel_list);
619
620         return WEXITSTATUS(status);
621 }
622
623 static int run_perf_stat(int argc, const char **argv, int run_idx)
624 {
625         int ret;
626
627         if (pre_cmd) {
628                 ret = system(pre_cmd);
629                 if (ret)
630                         return ret;
631         }
632
633         if (sync_run)
634                 sync();
635
636         ret = __run_perf_stat(argc, argv, run_idx);
637         if (ret)
638                 return ret;
639
640         if (post_cmd) {
641                 ret = system(post_cmd);
642                 if (ret)
643                         return ret;
644         }
645
646         return ret;
647 }
648
649 static void print_counters(struct timespec *ts, int argc, const char **argv)
650 {
651         /* Do not print anything if we record to the pipe. */
652         if (STAT_RECORD && perf_stat.data.is_pipe)
653                 return;
654
655         perf_evlist__print_counters(evsel_list, &stat_config, &target,
656                                     ts, argc, argv);
657 }
658
659 static volatile int signr = -1;
660
661 static void skip_signal(int signo)
662 {
663         if ((child_pid == -1) || stat_config.interval)
664                 done = 1;
665
666         signr = signo;
667         /*
668          * render child_pid harmless
669          * won't send SIGTERM to a random
670          * process in case of race condition
671          * and fast PID recycling
672          */
673         child_pid = -1;
674 }
675
676 static void sig_atexit(void)
677 {
678         sigset_t set, oset;
679
680         /*
681          * avoid race condition with SIGCHLD handler
682          * in skip_signal() which is modifying child_pid
683          * goal is to avoid send SIGTERM to a random
684          * process
685          */
686         sigemptyset(&set);
687         sigaddset(&set, SIGCHLD);
688         sigprocmask(SIG_BLOCK, &set, &oset);
689
690         if (child_pid != -1)
691                 kill(child_pid, SIGTERM);
692
693         sigprocmask(SIG_SETMASK, &oset, NULL);
694
695         if (signr == -1)
696                 return;
697
698         signal(signr, SIG_DFL);
699         kill(getpid(), signr);
700 }
701
702 static int stat__set_big_num(const struct option *opt __maybe_unused,
703                              const char *s __maybe_unused, int unset)
704 {
705         big_num_opt = unset ? 0 : 1;
706         return 0;
707 }
708
709 static int enable_metric_only(const struct option *opt __maybe_unused,
710                               const char *s __maybe_unused, int unset)
711 {
712         force_metric_only = true;
713         stat_config.metric_only = !unset;
714         return 0;
715 }
716
717 static int parse_metric_groups(const struct option *opt,
718                                const char *str,
719                                int unset __maybe_unused)
720 {
721         return metricgroup__parse_groups(opt, str, &stat_config.metric_events);
722 }
723
724 static struct option stat_options[] = {
725         OPT_BOOLEAN('T', "transaction", &transaction_run,
726                     "hardware transaction statistics"),
727         OPT_CALLBACK('e', "event", &evsel_list, "event",
728                      "event selector. use 'perf list' to list available events",
729                      parse_events_option),
730         OPT_CALLBACK(0, "filter", &evsel_list, "filter",
731                      "event filter", parse_filter),
732         OPT_BOOLEAN('i', "no-inherit", &stat_config.no_inherit,
733                     "child tasks do not inherit counters"),
734         OPT_STRING('p', "pid", &target.pid, "pid",
735                    "stat events on existing process id"),
736         OPT_STRING('t', "tid", &target.tid, "tid",
737                    "stat events on existing thread id"),
738         OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
739                     "system-wide collection from all CPUs"),
740         OPT_BOOLEAN('g', "group", &group,
741                     "put the counters into a counter group"),
742         OPT_BOOLEAN(0, "scale", &stat_config.scale,
743                     "Use --no-scale to disable counter scaling for multiplexing"),
744         OPT_INCR('v', "verbose", &verbose,
745                     "be more verbose (show counter open errors, etc)"),
746         OPT_INTEGER('r', "repeat", &stat_config.run_count,
747                     "repeat command and print average + stddev (max: 100, forever: 0)"),
748         OPT_BOOLEAN(0, "table", &stat_config.walltime_run_table,
749                     "display details about each run (only with -r option)"),
750         OPT_BOOLEAN('n', "null", &stat_config.null_run,
751                     "null run - dont start any counters"),
752         OPT_INCR('d', "detailed", &detailed_run,
753                     "detailed run - start a lot of events"),
754         OPT_BOOLEAN('S', "sync", &sync_run,
755                     "call sync() before starting a run"),
756         OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
757                            "print large numbers with thousands\' separators",
758                            stat__set_big_num),
759         OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
760                     "list of cpus to monitor in system-wide"),
761         OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
762                     "disable CPU count aggregation", AGGR_NONE),
763         OPT_BOOLEAN(0, "no-merge", &stat_config.no_merge, "Do not merge identical named events"),
764         OPT_STRING('x', "field-separator", &stat_config.csv_sep, "separator",
765                    "print counts with custom separator"),
766         OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
767                      "monitor event in cgroup name only", parse_cgroups),
768         OPT_STRING('o', "output", &output_name, "file", "output file name"),
769         OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
770         OPT_INTEGER(0, "log-fd", &output_fd,
771                     "log output to fd, instead of stderr"),
772         OPT_STRING(0, "pre", &pre_cmd, "command",
773                         "command to run prior to the measured command"),
774         OPT_STRING(0, "post", &post_cmd, "command",
775                         "command to run after to the measured command"),
776         OPT_UINTEGER('I', "interval-print", &stat_config.interval,
777                     "print counts at regular interval in ms "
778                     "(overhead is possible for values <= 100ms)"),
779         OPT_INTEGER(0, "interval-count", &stat_config.times,
780                     "print counts for fixed number of times"),
781         OPT_BOOLEAN(0, "interval-clear", &stat_config.interval_clear,
782                     "clear screen in between new interval"),
783         OPT_UINTEGER(0, "timeout", &stat_config.timeout,
784                     "stop workload and print counts after a timeout period in ms (>= 10ms)"),
785         OPT_SET_UINT(0, "per-socket", &stat_config.aggr_mode,
786                      "aggregate counts per processor socket", AGGR_SOCKET),
787         OPT_SET_UINT(0, "per-die", &stat_config.aggr_mode,
788                      "aggregate counts per processor die", AGGR_DIE),
789         OPT_SET_UINT(0, "per-core", &stat_config.aggr_mode,
790                      "aggregate counts per physical processor core", AGGR_CORE),
791         OPT_SET_UINT(0, "per-thread", &stat_config.aggr_mode,
792                      "aggregate counts per thread", AGGR_THREAD),
793         OPT_UINTEGER('D', "delay", &stat_config.initial_delay,
794                      "ms to wait before starting measurement after program start"),
795         OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL,
796                         "Only print computed metrics. No raw values", enable_metric_only),
797         OPT_BOOLEAN(0, "topdown", &topdown_run,
798                         "measure topdown level 1 statistics"),
799         OPT_BOOLEAN(0, "smi-cost", &smi_cost,
800                         "measure SMI cost"),
801         OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list",
802                      "monitor specified metrics or metric groups (separated by ,)",
803                      parse_metric_groups),
804         OPT_END()
805 };
806
807 static int perf_stat__get_socket(struct perf_stat_config *config __maybe_unused,
808                                  struct perf_cpu_map *map, int cpu)
809 {
810         return cpu_map__get_socket(map, cpu, NULL);
811 }
812
813 static int perf_stat__get_die(struct perf_stat_config *config __maybe_unused,
814                               struct perf_cpu_map *map, int cpu)
815 {
816         return cpu_map__get_die(map, cpu, NULL);
817 }
818
819 static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
820                                struct perf_cpu_map *map, int cpu)
821 {
822         return cpu_map__get_core(map, cpu, NULL);
823 }
824
825 static int cpu_map__get_max(struct perf_cpu_map *map)
826 {
827         int i, max = -1;
828
829         for (i = 0; i < map->nr; i++) {
830                 if (map->map[i] > max)
831                         max = map->map[i];
832         }
833
834         return max;
835 }
836
837 static int perf_stat__get_aggr(struct perf_stat_config *config,
838                                aggr_get_id_t get_id, struct perf_cpu_map *map, int idx)
839 {
840         int cpu;
841
842         if (idx >= map->nr)
843                 return -1;
844
845         cpu = map->map[idx];
846
847         if (config->cpus_aggr_map->map[cpu] == -1)
848                 config->cpus_aggr_map->map[cpu] = get_id(config, map, idx);
849
850         return config->cpus_aggr_map->map[cpu];
851 }
852
853 static int perf_stat__get_socket_cached(struct perf_stat_config *config,
854                                         struct perf_cpu_map *map, int idx)
855 {
856         return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx);
857 }
858
859 static int perf_stat__get_die_cached(struct perf_stat_config *config,
860                                         struct perf_cpu_map *map, int idx)
861 {
862         return perf_stat__get_aggr(config, perf_stat__get_die, map, idx);
863 }
864
865 static int perf_stat__get_core_cached(struct perf_stat_config *config,
866                                       struct perf_cpu_map *map, int idx)
867 {
868         return perf_stat__get_aggr(config, perf_stat__get_core, map, idx);
869 }
870
871 static bool term_percore_set(void)
872 {
873         struct evsel *counter;
874
875         evlist__for_each_entry(evsel_list, counter) {
876                 if (counter->percore)
877                         return true;
878         }
879
880         return false;
881 }
882
883 static int perf_stat_init_aggr_mode(void)
884 {
885         int nr;
886
887         switch (stat_config.aggr_mode) {
888         case AGGR_SOCKET:
889                 if (cpu_map__build_socket_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
890                         perror("cannot build socket map");
891                         return -1;
892                 }
893                 stat_config.aggr_get_id = perf_stat__get_socket_cached;
894                 break;
895         case AGGR_DIE:
896                 if (cpu_map__build_die_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
897                         perror("cannot build die map");
898                         return -1;
899                 }
900                 stat_config.aggr_get_id = perf_stat__get_die_cached;
901                 break;
902         case AGGR_CORE:
903                 if (cpu_map__build_core_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
904                         perror("cannot build core map");
905                         return -1;
906                 }
907                 stat_config.aggr_get_id = perf_stat__get_core_cached;
908                 break;
909         case AGGR_NONE:
910                 if (term_percore_set()) {
911                         if (cpu_map__build_core_map(evsel_list->core.cpus,
912                                                     &stat_config.aggr_map)) {
913                                 perror("cannot build core map");
914                                 return -1;
915                         }
916                         stat_config.aggr_get_id = perf_stat__get_core_cached;
917                 }
918                 break;
919         case AGGR_GLOBAL:
920         case AGGR_THREAD:
921         case AGGR_UNSET:
922         default:
923                 break;
924         }
925
926         /*
927          * The evsel_list->cpus is the base we operate on,
928          * taking the highest cpu number to be the size of
929          * the aggregation translate cpumap.
930          */
931         nr = cpu_map__get_max(evsel_list->core.cpus);
932         stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1);
933         return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
934 }
935
936 static void perf_stat__exit_aggr_mode(void)
937 {
938         perf_cpu_map__put(stat_config.aggr_map);
939         perf_cpu_map__put(stat_config.cpus_aggr_map);
940         stat_config.aggr_map = NULL;
941         stat_config.cpus_aggr_map = NULL;
942 }
943
944 static inline int perf_env__get_cpu(struct perf_env *env, struct perf_cpu_map *map, int idx)
945 {
946         int cpu;
947
948         if (idx > map->nr)
949                 return -1;
950
951         cpu = map->map[idx];
952
953         if (cpu >= env->nr_cpus_avail)
954                 return -1;
955
956         return cpu;
957 }
958
959 static int perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data)
960 {
961         struct perf_env *env = data;
962         int cpu = perf_env__get_cpu(env, map, idx);
963
964         return cpu == -1 ? -1 : env->cpu[cpu].socket_id;
965 }
966
967 static int perf_env__get_die(struct perf_cpu_map *map, int idx, void *data)
968 {
969         struct perf_env *env = data;
970         int die_id = -1, cpu = perf_env__get_cpu(env, map, idx);
971
972         if (cpu != -1) {
973                 /*
974                  * Encode socket in bit range 15:8
975                  * die_id is relative to socket,
976                  * we need a global id. So we combine
977                  * socket + die id
978                  */
979                 if (WARN_ONCE(env->cpu[cpu].socket_id >> 8, "The socket id number is too big.\n"))
980                         return -1;
981
982                 if (WARN_ONCE(env->cpu[cpu].die_id >> 8, "The die id number is too big.\n"))
983                         return -1;
984
985                 die_id = (env->cpu[cpu].socket_id << 8) | (env->cpu[cpu].die_id & 0xff);
986         }
987
988         return die_id;
989 }
990
991 static int perf_env__get_core(struct perf_cpu_map *map, int idx, void *data)
992 {
993         struct perf_env *env = data;
994         int core = -1, cpu = perf_env__get_cpu(env, map, idx);
995
996         if (cpu != -1) {
997                 /*
998                  * Encode socket in bit range 31:24
999                  * encode die id in bit range 23:16
1000                  * core_id is relative to socket and die,
1001                  * we need a global id. So we combine
1002                  * socket + die id + core id
1003                  */
1004                 if (WARN_ONCE(env->cpu[cpu].socket_id >> 8, "The socket id number is too big.\n"))
1005                         return -1;
1006
1007                 if (WARN_ONCE(env->cpu[cpu].die_id >> 8, "The die id number is too big.\n"))
1008                         return -1;
1009
1010                 if (WARN_ONCE(env->cpu[cpu].core_id >> 16, "The core id number is too big.\n"))
1011                         return -1;
1012
1013                 core = (env->cpu[cpu].socket_id << 24) |
1014                        (env->cpu[cpu].die_id << 16) |
1015                        (env->cpu[cpu].core_id & 0xffff);
1016         }
1017
1018         return core;
1019 }
1020
1021 static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
1022                                       struct perf_cpu_map **sockp)
1023 {
1024         return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
1025 }
1026
1027 static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus,
1028                                    struct perf_cpu_map **diep)
1029 {
1030         return cpu_map__build_map(cpus, diep, perf_env__get_die, env);
1031 }
1032
1033 static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus,
1034                                     struct perf_cpu_map **corep)
1035 {
1036         return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
1037 }
1038
1039 static int perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
1040                                       struct perf_cpu_map *map, int idx)
1041 {
1042         return perf_env__get_socket(map, idx, &perf_stat.session->header.env);
1043 }
1044 static int perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused,
1045                                    struct perf_cpu_map *map, int idx)
1046 {
1047         return perf_env__get_die(map, idx, &perf_stat.session->header.env);
1048 }
1049
1050 static int perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused,
1051                                     struct perf_cpu_map *map, int idx)
1052 {
1053         return perf_env__get_core(map, idx, &perf_stat.session->header.env);
1054 }
1055
1056 static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
1057 {
1058         struct perf_env *env = &st->session->header.env;
1059
1060         switch (stat_config.aggr_mode) {
1061         case AGGR_SOCKET:
1062                 if (perf_env__build_socket_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
1063                         perror("cannot build socket map");
1064                         return -1;
1065                 }
1066                 stat_config.aggr_get_id = perf_stat__get_socket_file;
1067                 break;
1068         case AGGR_DIE:
1069                 if (perf_env__build_die_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
1070                         perror("cannot build die map");
1071                         return -1;
1072                 }
1073                 stat_config.aggr_get_id = perf_stat__get_die_file;
1074                 break;
1075         case AGGR_CORE:
1076                 if (perf_env__build_core_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
1077                         perror("cannot build core map");
1078                         return -1;
1079                 }
1080                 stat_config.aggr_get_id = perf_stat__get_core_file;
1081                 break;
1082         case AGGR_NONE:
1083         case AGGR_GLOBAL:
1084         case AGGR_THREAD:
1085         case AGGR_UNSET:
1086         default:
1087                 break;
1088         }
1089
1090         return 0;
1091 }
1092
1093 static int topdown_filter_events(const char **attr, char **str, bool use_group)
1094 {
1095         int off = 0;
1096         int i;
1097         int len = 0;
1098         char *s;
1099
1100         for (i = 0; attr[i]; i++) {
1101                 if (pmu_have_event("cpu", attr[i])) {
1102                         len += strlen(attr[i]) + 1;
1103                         attr[i - off] = attr[i];
1104                 } else
1105                         off++;
1106         }
1107         attr[i - off] = NULL;
1108
1109         *str = malloc(len + 1 + 2);
1110         if (!*str)
1111                 return -1;
1112         s = *str;
1113         if (i - off == 0) {
1114                 *s = 0;
1115                 return 0;
1116         }
1117         if (use_group)
1118                 *s++ = '{';
1119         for (i = 0; attr[i]; i++) {
1120                 strcpy(s, attr[i]);
1121                 s += strlen(s);
1122                 *s++ = ',';
1123         }
1124         if (use_group) {
1125                 s[-1] = '}';
1126                 *s = 0;
1127         } else
1128                 s[-1] = 0;
1129         return 0;
1130 }
1131
1132 __weak bool arch_topdown_check_group(bool *warn)
1133 {
1134         *warn = false;
1135         return false;
1136 }
1137
1138 __weak void arch_topdown_group_warn(void)
1139 {
1140 }
1141
1142 /*
1143  * Add default attributes, if there were no attributes specified or
1144  * if -d/--detailed, -d -d or -d -d -d is used:
1145  */
1146 static int add_default_attributes(void)
1147 {
1148         int err;
1149         struct perf_event_attr default_attrs0[] = {
1150
1151   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK              },
1152   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES        },
1153   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS          },
1154   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS             },
1155
1156   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES              },
1157 };
1158         struct perf_event_attr frontend_attrs[] = {
1159   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
1160 };
1161         struct perf_event_attr backend_attrs[] = {
1162   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND  },
1163 };
1164         struct perf_event_attr default_attrs1[] = {
1165   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS            },
1166   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS     },
1167   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES           },
1168
1169 };
1170
1171 /*
1172  * Detailed stats (-d), covering the L1 and last level data caches:
1173  */
1174         struct perf_event_attr detailed_attrs[] = {
1175
1176   { .type = PERF_TYPE_HW_CACHE,
1177     .config =
1178          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1179         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1180         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1181
1182   { .type = PERF_TYPE_HW_CACHE,
1183     .config =
1184          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1185         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1186         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1187
1188   { .type = PERF_TYPE_HW_CACHE,
1189     .config =
1190          PERF_COUNT_HW_CACHE_LL                 <<  0  |
1191         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1192         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1193
1194   { .type = PERF_TYPE_HW_CACHE,
1195     .config =
1196          PERF_COUNT_HW_CACHE_LL                 <<  0  |
1197         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1198         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1199 };
1200
1201 /*
1202  * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
1203  */
1204         struct perf_event_attr very_detailed_attrs[] = {
1205
1206   { .type = PERF_TYPE_HW_CACHE,
1207     .config =
1208          PERF_COUNT_HW_CACHE_L1I                <<  0  |
1209         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1210         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1211
1212   { .type = PERF_TYPE_HW_CACHE,
1213     .config =
1214          PERF_COUNT_HW_CACHE_L1I                <<  0  |
1215         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1216         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1217
1218   { .type = PERF_TYPE_HW_CACHE,
1219     .config =
1220          PERF_COUNT_HW_CACHE_DTLB               <<  0  |
1221         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1222         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1223
1224   { .type = PERF_TYPE_HW_CACHE,
1225     .config =
1226          PERF_COUNT_HW_CACHE_DTLB               <<  0  |
1227         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1228         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1229
1230   { .type = PERF_TYPE_HW_CACHE,
1231     .config =
1232          PERF_COUNT_HW_CACHE_ITLB               <<  0  |
1233         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1234         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1235
1236   { .type = PERF_TYPE_HW_CACHE,
1237     .config =
1238          PERF_COUNT_HW_CACHE_ITLB               <<  0  |
1239         (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
1240         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1241
1242 };
1243
1244 /*
1245  * Very, very detailed stats (-d -d -d), adding prefetch events:
1246  */
1247         struct perf_event_attr very_very_detailed_attrs[] = {
1248
1249   { .type = PERF_TYPE_HW_CACHE,
1250     .config =
1251          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1252         (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
1253         (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)                          },
1254
1255   { .type = PERF_TYPE_HW_CACHE,
1256     .config =
1257          PERF_COUNT_HW_CACHE_L1D                <<  0  |
1258         (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
1259         (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)                          },
1260 };
1261         struct parse_events_error errinfo;
1262
1263         /* Set attrs if no event is selected and !null_run: */
1264         if (stat_config.null_run)
1265                 return 0;
1266
1267         if (transaction_run) {
1268                 /* Handle -T as -M transaction. Once platform specific metrics
1269                  * support has been added to the json files, all archictures
1270                  * will use this approach. To determine transaction support
1271                  * on an architecture test for such a metric name.
1272                  */
1273                 if (metricgroup__has_metric("transaction")) {
1274                         struct option opt = { .value = &evsel_list };
1275
1276                         return metricgroup__parse_groups(&opt, "transaction",
1277                                                          &stat_config.metric_events);
1278                 }
1279
1280                 if (pmu_have_event("cpu", "cycles-ct") &&
1281                     pmu_have_event("cpu", "el-start"))
1282                         err = parse_events(evsel_list, transaction_attrs,
1283                                            &errinfo);
1284                 else
1285                         err = parse_events(evsel_list,
1286                                            transaction_limited_attrs,
1287                                            &errinfo);
1288                 if (err) {
1289                         fprintf(stderr, "Cannot set up transaction events\n");
1290                         parse_events_print_error(&errinfo, transaction_attrs);
1291                         return -1;
1292                 }
1293                 return 0;
1294         }
1295
1296         if (smi_cost) {
1297                 int smi;
1298
1299                 if (sysfs__read_int(FREEZE_ON_SMI_PATH, &smi) < 0) {
1300                         fprintf(stderr, "freeze_on_smi is not supported.\n");
1301                         return -1;
1302                 }
1303
1304                 if (!smi) {
1305                         if (sysfs__write_int(FREEZE_ON_SMI_PATH, 1) < 0) {
1306                                 fprintf(stderr, "Failed to set freeze_on_smi.\n");
1307                                 return -1;
1308                         }
1309                         smi_reset = true;
1310                 }
1311
1312                 if (pmu_have_event("msr", "aperf") &&
1313                     pmu_have_event("msr", "smi")) {
1314                         if (!force_metric_only)
1315                                 stat_config.metric_only = true;
1316                         err = parse_events(evsel_list, smi_cost_attrs, &errinfo);
1317                 } else {
1318                         fprintf(stderr, "To measure SMI cost, it needs "
1319                                 "msr/aperf/, msr/smi/ and cpu/cycles/ support\n");
1320                         parse_events_print_error(&errinfo, smi_cost_attrs);
1321                         return -1;
1322                 }
1323                 if (err) {
1324                         fprintf(stderr, "Cannot set up SMI cost events\n");
1325                         return -1;
1326                 }
1327                 return 0;
1328         }
1329
1330         if (topdown_run) {
1331                 char *str = NULL;
1332                 bool warn = false;
1333
1334                 if (stat_config.aggr_mode != AGGR_GLOBAL &&
1335                     stat_config.aggr_mode != AGGR_CORE) {
1336                         pr_err("top down event configuration requires --per-core mode\n");
1337                         return -1;
1338                 }
1339                 stat_config.aggr_mode = AGGR_CORE;
1340                 if (nr_cgroups || !target__has_cpu(&target)) {
1341                         pr_err("top down event configuration requires system-wide mode (-a)\n");
1342                         return -1;
1343                 }
1344
1345                 if (!force_metric_only)
1346                         stat_config.metric_only = true;
1347                 if (topdown_filter_events(topdown_attrs, &str,
1348                                 arch_topdown_check_group(&warn)) < 0) {
1349                         pr_err("Out of memory\n");
1350                         return -1;
1351                 }
1352                 if (topdown_attrs[0] && str) {
1353                         if (warn)
1354                                 arch_topdown_group_warn();
1355                         err = parse_events(evsel_list, str, &errinfo);
1356                         if (err) {
1357                                 fprintf(stderr,
1358                                         "Cannot set up top down events %s: %d\n",
1359                                         str, err);
1360                                 parse_events_print_error(&errinfo, str);
1361                                 free(str);
1362                                 return -1;
1363                         }
1364                 } else {
1365                         fprintf(stderr, "System does not support topdown\n");
1366                         return -1;
1367                 }
1368                 free(str);
1369         }
1370
1371         if (!evsel_list->core.nr_entries) {
1372                 if (target__has_cpu(&target))
1373                         default_attrs0[0].config = PERF_COUNT_SW_CPU_CLOCK;
1374
1375                 if (perf_evlist__add_default_attrs(evsel_list, default_attrs0) < 0)
1376                         return -1;
1377                 if (pmu_have_event("cpu", "stalled-cycles-frontend")) {
1378                         if (perf_evlist__add_default_attrs(evsel_list,
1379                                                 frontend_attrs) < 0)
1380                                 return -1;
1381                 }
1382                 if (pmu_have_event("cpu", "stalled-cycles-backend")) {
1383                         if (perf_evlist__add_default_attrs(evsel_list,
1384                                                 backend_attrs) < 0)
1385                                 return -1;
1386                 }
1387                 if (perf_evlist__add_default_attrs(evsel_list, default_attrs1) < 0)
1388                         return -1;
1389         }
1390
1391         /* Detailed events get appended to the event list: */
1392
1393         if (detailed_run <  1)
1394                 return 0;
1395
1396         /* Append detailed run extra attributes: */
1397         if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0)
1398                 return -1;
1399
1400         if (detailed_run < 2)
1401                 return 0;
1402
1403         /* Append very detailed run extra attributes: */
1404         if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0)
1405                 return -1;
1406
1407         if (detailed_run < 3)
1408                 return 0;
1409
1410         /* Append very, very detailed run extra attributes: */
1411         return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs);
1412 }
1413
1414 static const char * const stat_record_usage[] = {
1415         "perf stat record [<options>]",
1416         NULL,
1417 };
1418
1419 static void init_features(struct perf_session *session)
1420 {
1421         int feat;
1422
1423         for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
1424                 perf_header__set_feat(&session->header, feat);
1425
1426         perf_header__clear_feat(&session->header, HEADER_DIR_FORMAT);
1427         perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
1428         perf_header__clear_feat(&session->header, HEADER_TRACING_DATA);
1429         perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
1430         perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
1431 }
1432
1433 static int __cmd_record(int argc, const char **argv)
1434 {
1435         struct perf_session *session;
1436         struct perf_data *data = &perf_stat.data;
1437
1438         argc = parse_options(argc, argv, stat_options, stat_record_usage,
1439                              PARSE_OPT_STOP_AT_NON_OPTION);
1440
1441         if (output_name)
1442                 data->path = output_name;
1443
1444         if (stat_config.run_count != 1 || forever) {
1445                 pr_err("Cannot use -r option with perf stat record.\n");
1446                 return -1;
1447         }
1448
1449         session = perf_session__new(data, false, NULL);
1450         if (session == NULL) {
1451                 pr_err("Perf session creation failed.\n");
1452                 return -1;
1453         }
1454
1455         init_features(session);
1456
1457         session->evlist   = evsel_list;
1458         perf_stat.session = session;
1459         perf_stat.record  = true;
1460         return argc;
1461 }
1462
1463 static int process_stat_round_event(struct perf_session *session,
1464                                     union perf_event *event)
1465 {
1466         struct perf_record_stat_round *stat_round = &event->stat_round;
1467         struct evsel *counter;
1468         struct timespec tsh, *ts = NULL;
1469         const char **argv = session->header.env.cmdline_argv;
1470         int argc = session->header.env.nr_cmdline;
1471
1472         evlist__for_each_entry(evsel_list, counter)
1473                 perf_stat_process_counter(&stat_config, counter);
1474
1475         if (stat_round->type == PERF_STAT_ROUND_TYPE__FINAL)
1476                 update_stats(&walltime_nsecs_stats, stat_round->time);
1477
1478         if (stat_config.interval && stat_round->time) {
1479                 tsh.tv_sec  = stat_round->time / NSEC_PER_SEC;
1480                 tsh.tv_nsec = stat_round->time % NSEC_PER_SEC;
1481                 ts = &tsh;
1482         }
1483
1484         print_counters(ts, argc, argv);
1485         return 0;
1486 }
1487
1488 static
1489 int process_stat_config_event(struct perf_session *session,
1490                               union perf_event *event)
1491 {
1492         struct perf_tool *tool = session->tool;
1493         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
1494
1495         perf_event__read_stat_config(&stat_config, &event->stat_config);
1496
1497         if (perf_cpu_map__empty(st->cpus)) {
1498                 if (st->aggr_mode != AGGR_UNSET)
1499                         pr_warning("warning: processing task data, aggregation mode not set\n");
1500                 return 0;
1501         }
1502
1503         if (st->aggr_mode != AGGR_UNSET)
1504                 stat_config.aggr_mode = st->aggr_mode;
1505
1506         if (perf_stat.data.is_pipe)
1507                 perf_stat_init_aggr_mode();
1508         else
1509                 perf_stat_init_aggr_mode_file(st);
1510
1511         return 0;
1512 }
1513
1514 static int set_maps(struct perf_stat *st)
1515 {
1516         if (!st->cpus || !st->threads)
1517                 return 0;
1518
1519         if (WARN_ONCE(st->maps_allocated, "stats double allocation\n"))
1520                 return -EINVAL;
1521
1522         perf_evlist__set_maps(&evsel_list->core, st->cpus, st->threads);
1523
1524         if (perf_evlist__alloc_stats(evsel_list, true))
1525                 return -ENOMEM;
1526
1527         st->maps_allocated = true;
1528         return 0;
1529 }
1530
1531 static
1532 int process_thread_map_event(struct perf_session *session,
1533                              union perf_event *event)
1534 {
1535         struct perf_tool *tool = session->tool;
1536         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
1537
1538         if (st->threads) {
1539                 pr_warning("Extra thread map event, ignoring.\n");
1540                 return 0;
1541         }
1542
1543         st->threads = thread_map__new_event(&event->thread_map);
1544         if (!st->threads)
1545                 return -ENOMEM;
1546
1547         return set_maps(st);
1548 }
1549
1550 static
1551 int process_cpu_map_event(struct perf_session *session,
1552                           union perf_event *event)
1553 {
1554         struct perf_tool *tool = session->tool;
1555         struct perf_stat *st = container_of(tool, struct perf_stat, tool);
1556         struct perf_cpu_map *cpus;
1557
1558         if (st->cpus) {
1559                 pr_warning("Extra cpu map event, ignoring.\n");
1560                 return 0;
1561         }
1562
1563         cpus = cpu_map__new_data(&event->cpu_map.data);
1564         if (!cpus)
1565                 return -ENOMEM;
1566
1567         st->cpus = cpus;
1568         return set_maps(st);
1569 }
1570
1571 static int runtime_stat_new(struct perf_stat_config *config, int nthreads)
1572 {
1573         int i;
1574
1575         config->stats = calloc(nthreads, sizeof(struct runtime_stat));
1576         if (!config->stats)
1577                 return -1;
1578
1579         config->stats_num = nthreads;
1580
1581         for (i = 0; i < nthreads; i++)
1582                 runtime_stat__init(&config->stats[i]);
1583
1584         return 0;
1585 }
1586
1587 static void runtime_stat_delete(struct perf_stat_config *config)
1588 {
1589         int i;
1590
1591         if (!config->stats)
1592                 return;
1593
1594         for (i = 0; i < config->stats_num; i++)
1595                 runtime_stat__exit(&config->stats[i]);
1596
1597         zfree(&config->stats);
1598 }
1599
1600 static const char * const stat_report_usage[] = {
1601         "perf stat report [<options>]",
1602         NULL,
1603 };
1604
1605 static struct perf_stat perf_stat = {
1606         .tool = {
1607                 .attr           = perf_event__process_attr,
1608                 .event_update   = perf_event__process_event_update,
1609                 .thread_map     = process_thread_map_event,
1610                 .cpu_map        = process_cpu_map_event,
1611                 .stat_config    = process_stat_config_event,
1612                 .stat           = perf_event__process_stat_event,
1613                 .stat_round     = process_stat_round_event,
1614         },
1615         .aggr_mode = AGGR_UNSET,
1616 };
1617
1618 static int __cmd_report(int argc, const char **argv)
1619 {
1620         struct perf_session *session;
1621         const struct option options[] = {
1622         OPT_STRING('i', "input", &input_name, "file", "input file name"),
1623         OPT_SET_UINT(0, "per-socket", &perf_stat.aggr_mode,
1624                      "aggregate counts per processor socket", AGGR_SOCKET),
1625         OPT_SET_UINT(0, "per-die", &perf_stat.aggr_mode,
1626                      "aggregate counts per processor die", AGGR_DIE),
1627         OPT_SET_UINT(0, "per-core", &perf_stat.aggr_mode,
1628                      "aggregate counts per physical processor core", AGGR_CORE),
1629         OPT_SET_UINT('A', "no-aggr", &perf_stat.aggr_mode,
1630                      "disable CPU count aggregation", AGGR_NONE),
1631         OPT_END()
1632         };
1633         struct stat st;
1634         int ret;
1635
1636         argc = parse_options(argc, argv, options, stat_report_usage, 0);
1637
1638         if (!input_name || !strlen(input_name)) {
1639                 if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
1640                         input_name = "-";
1641                 else
1642                         input_name = "perf.data";
1643         }
1644
1645         perf_stat.data.path = input_name;
1646         perf_stat.data.mode = PERF_DATA_MODE_READ;
1647
1648         session = perf_session__new(&perf_stat.data, false, &perf_stat.tool);
1649         if (session == NULL)
1650                 return -1;
1651
1652         perf_stat.session  = session;
1653         stat_config.output = stderr;
1654         evsel_list         = session->evlist;
1655
1656         ret = perf_session__process_events(session);
1657         if (ret)
1658                 return ret;
1659
1660         perf_session__delete(session);
1661         return 0;
1662 }
1663
1664 static void setup_system_wide(int forks)
1665 {
1666         /*
1667          * Make system wide (-a) the default target if
1668          * no target was specified and one of following
1669          * conditions is met:
1670          *
1671          *   - there's no workload specified
1672          *   - there is workload specified but all requested
1673          *     events are system wide events
1674          */
1675         if (!target__none(&target))
1676                 return;
1677
1678         if (!forks)
1679                 target.system_wide = true;
1680         else {
1681                 struct evsel *counter;
1682
1683                 evlist__for_each_entry(evsel_list, counter) {
1684                         if (!counter->system_wide)
1685                                 return;
1686                 }
1687
1688                 if (evsel_list->core.nr_entries)
1689                         target.system_wide = true;
1690         }
1691 }
1692
1693 int cmd_stat(int argc, const char **argv)
1694 {
1695         const char * const stat_usage[] = {
1696                 "perf stat [<options>] [<command>]",
1697                 NULL
1698         };
1699         int status = -EINVAL, run_idx;
1700         const char *mode;
1701         FILE *output = stderr;
1702         unsigned int interval, timeout;
1703         const char * const stat_subcommands[] = { "record", "report" };
1704
1705         setlocale(LC_ALL, "");
1706
1707         evsel_list = evlist__new();
1708         if (evsel_list == NULL)
1709                 return -ENOMEM;
1710
1711         parse_events__shrink_config_terms();
1712
1713         /* String-parsing callback-based options would segfault when negated */
1714         set_option_flag(stat_options, 'e', "event", PARSE_OPT_NONEG);
1715         set_option_flag(stat_options, 'M', "metrics", PARSE_OPT_NONEG);
1716         set_option_flag(stat_options, 'G', "cgroup", PARSE_OPT_NONEG);
1717
1718         argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
1719                                         (const char **) stat_usage,
1720                                         PARSE_OPT_STOP_AT_NON_OPTION);
1721         perf_stat__collect_metric_expr(evsel_list);
1722         perf_stat__init_shadow_stats();
1723
1724         if (stat_config.csv_sep) {
1725                 stat_config.csv_output = true;
1726                 if (!strcmp(stat_config.csv_sep, "\\t"))
1727                         stat_config.csv_sep = "\t";
1728         } else
1729                 stat_config.csv_sep = DEFAULT_SEPARATOR;
1730
1731         if (argc && !strncmp(argv[0], "rec", 3)) {
1732                 argc = __cmd_record(argc, argv);
1733                 if (argc < 0)
1734                         return -1;
1735         } else if (argc && !strncmp(argv[0], "rep", 3))
1736                 return __cmd_report(argc, argv);
1737
1738         interval = stat_config.interval;
1739         timeout = stat_config.timeout;
1740
1741         /*
1742          * For record command the -o is already taken care of.
1743          */
1744         if (!STAT_RECORD && output_name && strcmp(output_name, "-"))
1745                 output = NULL;
1746
1747         if (output_name && output_fd) {
1748                 fprintf(stderr, "cannot use both --output and --log-fd\n");
1749                 parse_options_usage(stat_usage, stat_options, "o", 1);
1750                 parse_options_usage(NULL, stat_options, "log-fd", 0);
1751                 goto out;
1752         }
1753
1754         if (stat_config.metric_only && stat_config.aggr_mode == AGGR_THREAD) {
1755                 fprintf(stderr, "--metric-only is not supported with --per-thread\n");
1756                 goto out;
1757         }
1758
1759         if (stat_config.metric_only && stat_config.run_count > 1) {
1760                 fprintf(stderr, "--metric-only is not supported with -r\n");
1761                 goto out;
1762         }
1763
1764         if (stat_config.walltime_run_table && stat_config.run_count <= 1) {
1765                 fprintf(stderr, "--table is only supported with -r\n");
1766                 parse_options_usage(stat_usage, stat_options, "r", 1);
1767                 parse_options_usage(NULL, stat_options, "table", 0);
1768                 goto out;
1769         }
1770
1771         if (output_fd < 0) {
1772                 fprintf(stderr, "argument to --log-fd must be a > 0\n");
1773                 parse_options_usage(stat_usage, stat_options, "log-fd", 0);
1774                 goto out;
1775         }
1776
1777         if (!output) {
1778                 struct timespec tm;
1779                 mode = append_file ? "a" : "w";
1780
1781                 output = fopen(output_name, mode);
1782                 if (!output) {
1783                         perror("failed to create output file");
1784                         return -1;
1785                 }
1786                 clock_gettime(CLOCK_REALTIME, &tm);
1787                 fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
1788         } else if (output_fd > 0) {
1789                 mode = append_file ? "a" : "w";
1790                 output = fdopen(output_fd, mode);
1791                 if (!output) {
1792                         perror("Failed opening logfd");
1793                         return -errno;
1794                 }
1795         }
1796
1797         stat_config.output = output;
1798
1799         /*
1800          * let the spreadsheet do the pretty-printing
1801          */
1802         if (stat_config.csv_output) {
1803                 /* User explicitly passed -B? */
1804                 if (big_num_opt == 1) {
1805                         fprintf(stderr, "-B option not supported with -x\n");
1806                         parse_options_usage(stat_usage, stat_options, "B", 1);
1807                         parse_options_usage(NULL, stat_options, "x", 1);
1808                         goto out;
1809                 } else /* Nope, so disable big number formatting */
1810                         stat_config.big_num = false;
1811         } else if (big_num_opt == 0) /* User passed --no-big-num */
1812                 stat_config.big_num = false;
1813
1814         setup_system_wide(argc);
1815
1816         /*
1817          * Display user/system times only for single
1818          * run and when there's specified tracee.
1819          */
1820         if ((stat_config.run_count == 1) && target__none(&target))
1821                 stat_config.ru_display = true;
1822
1823         if (stat_config.run_count < 0) {
1824                 pr_err("Run count must be a positive number\n");
1825                 parse_options_usage(stat_usage, stat_options, "r", 1);
1826                 goto out;
1827         } else if (stat_config.run_count == 0) {
1828                 forever = true;
1829                 stat_config.run_count = 1;
1830         }
1831
1832         if (stat_config.walltime_run_table) {
1833                 stat_config.walltime_run = zalloc(stat_config.run_count * sizeof(stat_config.walltime_run[0]));
1834                 if (!stat_config.walltime_run) {
1835                         pr_err("failed to setup -r option");
1836                         goto out;
1837                 }
1838         }
1839
1840         if ((stat_config.aggr_mode == AGGR_THREAD) &&
1841                 !target__has_task(&target)) {
1842                 if (!target.system_wide || target.cpu_list) {
1843                         fprintf(stderr, "The --per-thread option is only "
1844                                 "available when monitoring via -p -t -a "
1845                                 "options or only --per-thread.\n");
1846                         parse_options_usage(NULL, stat_options, "p", 1);
1847                         parse_options_usage(NULL, stat_options, "t", 1);
1848                         goto out;
1849                 }
1850         }
1851
1852         /*
1853          * no_aggr, cgroup are for system-wide only
1854          * --per-thread is aggregated per thread, we dont mix it with cpu mode
1855          */
1856         if (((stat_config.aggr_mode != AGGR_GLOBAL &&
1857               stat_config.aggr_mode != AGGR_THREAD) || nr_cgroups) &&
1858             !target__has_cpu(&target)) {
1859                 fprintf(stderr, "both cgroup and no-aggregation "
1860                         "modes only available in system-wide mode\n");
1861
1862                 parse_options_usage(stat_usage, stat_options, "G", 1);
1863                 parse_options_usage(NULL, stat_options, "A", 1);
1864                 parse_options_usage(NULL, stat_options, "a", 1);
1865                 goto out;
1866         }
1867
1868         if (add_default_attributes())
1869                 goto out;
1870
1871         target__validate(&target);
1872
1873         if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide))
1874                 target.per_thread = true;
1875
1876         if (perf_evlist__create_maps(evsel_list, &target) < 0) {
1877                 if (target__has_task(&target)) {
1878                         pr_err("Problems finding threads of monitor\n");
1879                         parse_options_usage(stat_usage, stat_options, "p", 1);
1880                         parse_options_usage(NULL, stat_options, "t", 1);
1881                 } else if (target__has_cpu(&target)) {
1882                         perror("failed to parse CPUs map");
1883                         parse_options_usage(stat_usage, stat_options, "C", 1);
1884                         parse_options_usage(NULL, stat_options, "a", 1);
1885                 }
1886                 goto out;
1887         }
1888
1889         /*
1890          * Initialize thread_map with comm names,
1891          * so we could print it out on output.
1892          */
1893         if (stat_config.aggr_mode == AGGR_THREAD) {
1894                 thread_map__read_comms(evsel_list->core.threads);
1895                 if (target.system_wide) {
1896                         if (runtime_stat_new(&stat_config,
1897                                 perf_thread_map__nr(evsel_list->core.threads))) {
1898                                 goto out;
1899                         }
1900                 }
1901         }
1902
1903         if (stat_config.times && interval)
1904                 interval_count = true;
1905         else if (stat_config.times && !interval) {
1906                 pr_err("interval-count option should be used together with "
1907                                 "interval-print.\n");
1908                 parse_options_usage(stat_usage, stat_options, "interval-count", 0);
1909                 parse_options_usage(stat_usage, stat_options, "I", 1);
1910                 goto out;
1911         }
1912
1913         if (timeout && timeout < 100) {
1914                 if (timeout < 10) {
1915                         pr_err("timeout must be >= 10ms.\n");
1916                         parse_options_usage(stat_usage, stat_options, "timeout", 0);
1917                         goto out;
1918                 } else
1919                         pr_warning("timeout < 100ms. "
1920                                    "The overhead percentage could be high in some cases. "
1921                                    "Please proceed with caution.\n");
1922         }
1923         if (timeout && interval) {
1924                 pr_err("timeout option is not supported with interval-print.\n");
1925                 parse_options_usage(stat_usage, stat_options, "timeout", 0);
1926                 parse_options_usage(stat_usage, stat_options, "I", 1);
1927                 goto out;
1928         }
1929
1930         if (perf_evlist__alloc_stats(evsel_list, interval))
1931                 goto out;
1932
1933         if (perf_stat_init_aggr_mode())
1934                 goto out;
1935
1936         /*
1937          * Set sample_type to PERF_SAMPLE_IDENTIFIER, which should be harmless
1938          * while avoiding that older tools show confusing messages.
1939          *
1940          * However for pipe sessions we need to keep it zero,
1941          * because script's perf_evsel__check_attr is triggered
1942          * by attr->sample_type != 0, and we can't run it on
1943          * stat sessions.
1944          */
1945         stat_config.identifier = !(STAT_RECORD && perf_stat.data.is_pipe);
1946
1947         /*
1948          * We dont want to block the signals - that would cause
1949          * child tasks to inherit that and Ctrl-C would not work.
1950          * What we want is for Ctrl-C to work in the exec()-ed
1951          * task, but being ignored by perf stat itself:
1952          */
1953         atexit(sig_atexit);
1954         if (!forever)
1955                 signal(SIGINT,  skip_signal);
1956         signal(SIGCHLD, skip_signal);
1957         signal(SIGALRM, skip_signal);
1958         signal(SIGABRT, skip_signal);
1959
1960         status = 0;
1961         for (run_idx = 0; forever || run_idx < stat_config.run_count; run_idx++) {
1962                 if (stat_config.run_count != 1 && verbose > 0)
1963                         fprintf(output, "[ perf stat: executing run #%d ... ]\n",
1964                                 run_idx + 1);
1965
1966                 status = run_perf_stat(argc, argv, run_idx);
1967                 if (forever && status != -1) {
1968                         print_counters(NULL, argc, argv);
1969                         perf_stat__reset_stats();
1970                 }
1971         }
1972
1973         if (!forever && status != -1 && !interval)
1974                 print_counters(NULL, argc, argv);
1975
1976         if (STAT_RECORD) {
1977                 /*
1978                  * We synthesize the kernel mmap record just so that older tools
1979                  * don't emit warnings about not being able to resolve symbols
1980                  * due to /proc/sys/kernel/kptr_restrict settings and instear provide
1981                  * a saner message about no samples being in the perf.data file.
1982                  *
1983                  * This also serves to suppress a warning about f_header.data.size == 0
1984                  * in header.c at the moment 'perf stat record' gets introduced, which
1985                  * is not really needed once we start adding the stat specific PERF_RECORD_
1986                  * records, but the need to suppress the kptr_restrict messages in older
1987                  * tools remain  -acme
1988                  */
1989                 int fd = perf_data__fd(&perf_stat.data);
1990                 int err = perf_event__synthesize_kernel_mmap((void *)&perf_stat,
1991                                                              process_synthesized_event,
1992                                                              &perf_stat.session->machines.host);
1993                 if (err) {
1994                         pr_warning("Couldn't synthesize the kernel mmap record, harmless, "
1995                                    "older tools may produce warnings about this file\n.");
1996                 }
1997
1998                 if (!interval) {
1999                         if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL))
2000                                 pr_err("failed to write stat round event\n");
2001                 }
2002
2003                 if (!perf_stat.data.is_pipe) {
2004                         perf_stat.session->header.data_size += perf_stat.bytes_written;
2005                         perf_session__write_header(perf_stat.session, evsel_list, fd, true);
2006                 }
2007
2008                 evlist__close(evsel_list);
2009                 perf_session__delete(perf_stat.session);
2010         }
2011
2012         perf_stat__exit_aggr_mode();
2013         perf_evlist__free_stats(evsel_list);
2014 out:
2015         zfree(&stat_config.walltime_run);
2016
2017         if (smi_cost && smi_reset)
2018                 sysfs__write_int(FREEZE_ON_SMI_PATH, 0);
2019
2020         evlist__delete(evsel_list);
2021
2022         runtime_stat_delete(&stat_config);
2023
2024         return status;
2025 }