Show inlined functions with bt-akaros.sh (kernel)
[akaros.git] / tools / dev-util / perf / perf.c
1 /* Copyright (c) 2015-2016 Google Inc
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * Davide Libenzi <dlibenzi@google.com>
4  * See LICENSE for details.
5  */
6
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <sys/wait.h>
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <fcntl.h>
16 #include <limits.h>
17 #include <errno.h>
18 #include <argp.h>
19 #include <time.h>
20 #include <parlib/parlib.h>
21 #include <parlib/timing.h>
22 #include <parlib/core_set.h>
23 #include "xlib.h"
24 #include "perfconv.h"
25 #include "perf_core.h"
26
27 /* Helpers */
28 static void run_process_and_wait(int argc, char *argv[],
29                                  const struct core_set *cores);
30
31 /* For communicating with perf_create_context() */
32 static struct perf_context_config perf_cfg = {
33         .perf_file = "#arch/perf",
34         .kpctl_file = "#kprof/kpctl",
35         .kpdata_file = "#kprof/kpdata",
36 };
37
38 static struct perfconv_context *cctx;
39 static struct perf_context *pctx;
40 extern char **environ;  /* POSIX envp */
41
42 struct perf_opts {
43         FILE                    *outfile;
44         const char              *events;
45         char                    **cmd_argv;
46         int                     cmd_argc;
47         struct core_set         cores;
48         bool                    got_cores;
49         bool                    verbose;
50         bool                    sampling;
51         bool                    stat_bignum;
52         bool                    record_quiet;
53         unsigned long           record_period;
54 };
55 static struct perf_opts opts;
56
57 struct perf_cmd {
58         char                    *name;
59         char                    *desc;
60         char                    *opts;
61         int (*func)(struct perf_cmd *, int, char **);
62 };
63
64 static int perf_help(struct perf_cmd *cmd, int argc, char *argv[]);
65 static int perf_list(struct perf_cmd *cmd, int argc, char *argv[]);
66 static int perf_record(struct perf_cmd *cmd, int argc, char *argv[]);
67 static int perf_stat(struct perf_cmd *cmd, int argc, char *argv[]);
68 static int perf_pmu_caps(struct perf_cmd *cmd, int argc, char *argv[]);
69
70 static struct perf_cmd perf_cmds[] = {
71         { .name = "help",
72           .desc = "Detailed help for commands",
73           .opts = "COMMAND",
74           .func = perf_help,
75         },
76         { .name = "list",
77           .desc = "Lists all available events",
78           .opts = "[REGEX]",
79           .func = perf_list,
80         },
81         { .name = "record",
82           .desc = "Samples events during command execution",
83           .opts = 0,
84           .func = perf_record,
85         },
86         { .name = "stat",
87           .desc = "Counts events during command execution",
88           .opts = 0,
89           .func = perf_stat,
90         },
91         { .name = "pmu_caps",
92           .desc = "Shows PMU capabilities",
93           .opts = "",
94           .func = perf_pmu_caps,
95         },
96 };
97
98 /**************************** perf help ****************************/
99
100 static int perf_help(struct perf_cmd *cmd, int argc, char *argv[])
101 {
102         char *sub_argv[2];
103
104         if (argc < 2) {
105                 fprintf(stderr, "perf %s %s\n", cmd->name, cmd->opts);
106                 return -1;
107         }
108         for (int i = 0; i < COUNT_OF(perf_cmds); i++) {
109                 if (!strcmp(perf_cmds[i].name, argv[1])) {
110                         if (perf_cmds[i].opts) {
111                                 fprintf(stdout, "perf %s %s\n",
112                                         perf_cmds[i].name, perf_cmds[i].opts);
113                                 fprintf(stdout, "\t%s\n", perf_cmds[i].desc);
114                         } else {
115                                 /* For argp subcommands, call their help
116                                  * directly. */
117                                 sub_argv[0] = xstrdup(perf_cmds[i].name);
118                                 sub_argv[1] = xstrdup("--help");
119                                 perf_cmds[i].func(&perf_cmds[i], 2, sub_argv);
120                                 free(sub_argv[0]);
121                                 free(sub_argv[1]);
122                         }
123                         return 0;
124                 }
125         }
126         fprintf(stderr, "Unknown perf command %s\n", argv[1]);
127         return -1;
128 }
129
130 /**************************** perf list ****************************/
131
132 static int perf_list(struct perf_cmd *cmd, int argc, char *argv[])
133 {
134         char *show_regex = NULL;
135
136         if (argc > 1)
137                 show_regex = argv[1];
138         perf_show_events(show_regex, stdout);
139         return 0;
140 }
141
142 /**************************** perf pmu_caps ************************/
143
144 static int perf_pmu_caps(struct perf_cmd *cmd, int argc, char *argv[])
145 {
146         const struct perf_arch_info *pai = perf_context_get_arch_info(pctx);
147
148         fprintf(stdout,
149                         "PERF.version             = %u\n"
150                         "PERF.proc_arch_events    = %u\n"
151                         "PERF.bits_x_counter      = %u\n"
152                         "PERF.counters_x_proc     = %u\n"
153                         "PERF.bits_x_fix_counter  = %u\n"
154                         "PERF.fix_counters_x_proc = %u\n",
155                         pai->perfmon_version, pai->proc_arch_events,
156                         pai->bits_x_counter, pai->counters_x_proc,
157                         pai->bits_x_fix_counter, pai->fix_counters_x_proc);
158         return 0;
159 }
160
161 /**************************** Common argp ************************/
162
163 /* Collection argument parsing.  These options are common to any function that
164  * will collect perf events, e.g. perf record and perf stat. */
165
166 static struct argp_option collect_opts[] = {
167         {"event", 'e', "EVENT", 0, "Event string, e.g. cycles:u:k"},
168         {"cores", 'C', "CORE_LIST", 0, "List of cores, e.g. 0.2.4:8-19"},
169         {"cpu", 'C', 0, OPTION_ALIAS},
170         {"all-cpus", 'a', 0, 0, "Collect events on all cores (on by default)"},
171         {"verbose", 'v', 0, 0, 0},
172         { 0 }
173 };
174
175 static const char *collect_args_doc = "COMMAND [ARGS]";
176
177 static error_t parse_collect_opt(int key, char *arg, struct argp_state *state)
178 {
179         struct perf_opts *p_opts = state->input;
180
181         /* argp doesn't pass input to the child parser(s) by default... */
182         state->child_inputs[0] = state->input;
183
184         switch (key) {
185         case 'a':
186                 /* Our default operation is to track all cores; we don't follow
187                  * processes yet. */
188                 break;
189         case 'C':
190                 parlib_parse_cores(arg, &p_opts->cores);
191                 p_opts->got_cores = TRUE;
192                 break;
193         case 'e':
194                 p_opts->events = arg;
195                 break;
196         case 'v':
197                 p_opts->verbose = TRUE;
198                 break;
199         case ARGP_KEY_ARG:
200                 p_opts->cmd_argc = state->argc - state->next + 1;
201                 p_opts->cmd_argv = xmalloc(sizeof(char*) *
202                                            (p_opts->cmd_argc + 1));
203                 p_opts->cmd_argv[0] = arg;
204                 memcpy(&p_opts->cmd_argv[1], &state->argv[state->next],
205                        sizeof(char*) * (p_opts->cmd_argc - 1));
206                 p_opts->cmd_argv[p_opts->cmd_argc] = NULL;
207                 state->next = state->argc;
208                 break;
209         case ARGP_KEY_END:
210                 if (!p_opts->cmd_argc)
211                         argp_usage(state);
212                 /* By default, we set all cores (different than linux) */
213                 if (!p_opts->got_cores)
214                         parlib_get_all_core_set(&p_opts->cores);
215                 break;
216         default:
217                 return ARGP_ERR_UNKNOWN;
218         }
219         return 0;
220 }
221
222 /* Helper, parses args using the collect_opts and the child parser for a given
223  * cmd. */
224 static void collect_argp(struct perf_cmd *cmd, int argc, char *argv[],
225                          struct argp_child *children, struct perf_opts *opts)
226 {
227         struct argp collect_opt = {collect_opts, parse_collect_opt,
228                                    collect_args_doc, cmd->desc, children};
229         char *cmd_name;
230         const char *fmt = "perf %s";
231         size_t cmd_sz = strlen(cmd->name) + strlen(fmt) + 1;
232
233         /* Rewrite the command name from foo to perf foo for the --help output*/
234         cmd_name = xmalloc(cmd_sz);
235         snprintf(cmd_name, cmd_sz, fmt, cmd->name);
236         cmd_name[cmd_sz - 1] = '\0';
237         argv[0] = cmd_name;
238         argp_parse(&collect_opt, argc, argv, ARGP_IN_ORDER, 0, opts);
239         /* It's possible that someone could still be using cmd_name */
240 }
241
242 /* Helper, submits the events in opts to the kernel for monitoring. */
243 static void submit_events(struct perf_opts *opts)
244 {
245         struct perf_eventsel *sel;
246         char *dup_evts, *tok, *tok_save = 0;
247
248         dup_evts = xstrdup(opts->events);
249         for (tok = strtok_r(dup_evts, ",", &tok_save);
250              tok;
251              tok = strtok_r(NULL, ",", &tok_save)) {
252
253                 sel = perf_parse_event(tok);
254                 PMEV_SET_INTEN(sel->ev.event, opts->sampling);
255                 sel->ev.trigger_count = opts->record_period;
256                 perf_context_event_submit(pctx, &opts->cores, sel);
257         }
258         free(dup_evts);
259 }
260
261 /**************************** perf record ************************/
262
263 static struct argp_option record_opts[] = {
264         {"count", 'c', "PERIOD", 0, "Sampling period"},
265         {"output", 'o', "FILE", 0, "Output file name (default perf.data)"},
266         {"freq", 'F', "FREQUENCY", 0, "Sampling frequency (assumes cycles)"},
267         {"call-graph", 'g', 0, 0, "Backtrace recording (always on!)"},
268         {"quiet", 'q', 0, 0, "No printing to stdio"},
269         { 0 }
270 };
271
272 /* In lieu of adaptively changing the period to maintain a set freq, we
273  * just assume they want cycles and that the TSC is close to that.
274  *
275  * (cycles/sec) / (samples/sec) = cycles / sample = period.
276  *
277  * TODO: this also assumes we're running the core at full speed. */
278 static unsigned long freq_to_period(unsigned long freq)
279 {
280         return get_tsc_freq() / freq;
281 }
282
283 static error_t parse_record_opt(int key, char *arg, struct argp_state *state)
284 {
285         struct perf_opts *p_opts = state->input;
286
287         switch (key) {
288         case 'c':
289                 if (p_opts->record_period)
290                         argp_error(state,
291                                 "Period set.  Only use at most one of -c -F");
292                 p_opts->record_period = atol(arg);
293                 break;
294         case 'F':
295                 if (p_opts->record_period)
296                         argp_error(state,
297                                 "Period set.  Only use at most one of -c -F");
298                 /* TODO: when we properly support freq, multiple events will
299                  * have the same freq but different, dynamic, periods. */
300                 p_opts->record_period = freq_to_period(atol(arg));
301                 break;
302         case 'g':
303                 /* Our default operation is to record backtraces. */
304                 break;
305         case 'o':
306                 p_opts->outfile = xfopen(arg, "wb");
307                 break;
308         case 'q':
309                 p_opts->record_quiet = TRUE;
310                 break;
311         case ARGP_KEY_END:
312                 if (!p_opts->events)
313                         p_opts->events = "cycles";
314                 if (!p_opts->outfile)
315                         p_opts->outfile = xfopen("perf.data", "wb");
316                 if (!p_opts->record_period)
317                         p_opts->record_period = freq_to_period(1000);
318                 break;
319         default:
320                 return ARGP_ERR_UNKNOWN;
321         }
322         return 0;
323 }
324
325 static int perf_record(struct perf_cmd *cmd, int argc, char *argv[])
326 {
327         struct argp argp_record = {record_opts, parse_record_opt};
328         struct argp_child children[] = { {&argp_record, 0, 0, 0}, {0} };
329
330         collect_argp(cmd, argc, argv, children, &opts);
331         opts.sampling = TRUE;
332
333         /* Once a perf event is submitted, it'll start counting and firing the
334          * IRQ.  However, we can control whether or not the samples are
335          * collected. */
336         submit_events(&opts);
337         perf_start_sampling(pctx);
338         run_process_and_wait(opts.cmd_argc, opts.cmd_argv,
339                              opts.got_cores ? &opts.cores : NULL);
340         perf_stop_sampling(pctx);
341         if (opts.verbose)
342                 perf_context_show_events(pctx, stdout);
343         /* The events are still counting and firing IRQs.  Let's be nice and
344          * turn them off to minimize our impact. */
345         perf_stop_events(pctx);
346         /* Generate the Linux perf file format with the traces which have been
347          * created during this operation. */
348         perf_convert_trace_data(cctx, perf_cfg.kpdata_file, opts.outfile);
349         fclose(opts.outfile);
350         return 0;
351 }
352
353 /**************************** perf stat  ************************/
354
355 static struct argp_option stat_opts[] = {
356         {"big-num", 'B', 0, 0, "Formatting option"},
357         {"output", 'o', "FILE", 0, "Print output to file (default stdout)"},
358         { 0 }
359 };
360
361 static error_t parse_stat_opt(int key, char *arg, struct argp_state *state)
362 {
363         struct perf_opts *p_opts = state->input;
364
365         switch (key) {
366         case 'B':
367                 p_opts->stat_bignum = TRUE;
368                 break;
369         case 'o':
370                 p_opts->outfile = xfopen(arg, "w");
371                 break;
372         case ARGP_KEY_END:
373                 if (!p_opts->events)
374                         p_opts->events = "cache-misses,cache-references,"
375                                 "branch-misses,branches,instructions,cycles";
376                 if (!p_opts->outfile)
377                         p_opts->outfile = stdout;
378                 break;
379         default:
380                 return ARGP_ERR_UNKNOWN;
381         }
382         return 0;
383 }
384
385 struct stat_val {
386         char                    *name;
387         uint64_t                count;
388 };
389
390 /* Helper, given a name, fetches its value as a float. */
391 static float get_count_for(char *name, struct stat_val *all_vals,
392                            size_t nr_vals)
393 {
394         for (int i = 0; i < nr_vals; i++) {
395                 if (!strcmp(name, all_vals[i].name))
396                         return (float)all_vals[i].count;
397         }
398         return 0.0;
399 }
400
401 /* Helper, gets the seconds count as a float */
402 static float get_seconds(struct stat_val *all_vals, size_t nr_vals)
403 {
404         float sec = get_count_for("nsec", all_vals, nr_vals) / 1000000000;
405
406         /* We should never have a time of 0, but in case something went wrong,
407          * don't hand back 0 (divide by 0 errors). */
408         return sec != 0.0 ? sec : 1.0;
409 }
410
411 /* Prints "X per second", scaling for K, M, or G. */
412 static void print_default_rate(FILE *out, struct stat_val *val,
413                                struct stat_val *all_vals, size_t nr_vals)
414 {
415         float rate = val->count / get_seconds(all_vals, nr_vals);
416         char scale = ' ';
417
418         if (rate > 1000000000) {
419                 rate /= 1000000000;
420                 scale = 'G';
421         } else if (rate > 1000000) {
422                 rate /= 1000000;
423                 scale = 'M';
424         } else if (rate > 1000) {
425                 rate /= 1000;
426                 scale = 'K';
427         }
428         fprintf(out, "%9.3f %c/sec\n", rate, scale);
429 }
430
431 /* Prints a line for the given stat val.  We pass all the vals since some stats
432  * will adjust their output based on *other* known values.  e.g. IPC. */
433 static void stat_print_val(FILE *out, struct stat_val *val,
434                            struct stat_val *all_vals, size_t nr_vals)
435 {
436         /* Everyone gets the same front part of the printout */
437         fprintf(out, "%18llu      %-25s #", val->count, val->name);
438
439         /* Based on the particular event and what other events we know, we may
440          * print something different to the summary bit after the #. */
441         if (!strcmp(val->name, "instructions")) {
442                 float cycles = get_count_for("cycles", all_vals, nr_vals);
443
444                 if (cycles != 0.0)
445                         fprintf(out, "%9.3f insns per cycle\n",
446                                 val->count / cycles);
447                 else
448                         print_default_rate(out, val, all_vals, nr_vals);
449         } else if (!strcmp(val->name, "cache-misses")) {
450                 float cache_ref = get_count_for("cache-references", all_vals,
451                                                 nr_vals);
452
453                 if (cache_ref != 0.0)
454                         fprintf(out, "%8.2f%% of all refs\n",
455                                 val->count * 100 / cache_ref);
456                 else
457                         print_default_rate(out, val, all_vals, nr_vals);
458         } else if (!strcmp(val->name, "branch-misses")) {
459                 float branches = get_count_for("branches", all_vals, nr_vals);
460
461                 if (branches != 0.0)
462                         fprintf(out, "%8.2f%% of all branches\n",
463                                 val->count * 100 / branches);
464                 else
465                         print_default_rate(out, val, all_vals, nr_vals);
466         } else {
467                 print_default_rate(out, val, all_vals, nr_vals);
468         }
469 }
470
471 static char *cmd_as_str(int argc, char *const argv[])
472 {
473         size_t len = 0;
474         char *str;
475
476         for (int i = 0; i < argc; i++)
477                 len += strlen(argv[i]) + 1;
478         str = xzmalloc(len);
479         for (int i = 0; i < argc; i++) {
480                 strlcat(str, argv[i], len);
481                 if (i != argc - 1)
482                         strlcat(str, " ", len);
483         }
484         return str;
485 }
486
487 static struct stat_val *collect_stats(struct perf_context *pctx,
488                                       struct timespec *diff)
489 {
490         struct stat_val *stat_vals;
491
492         /* the last stat is time (nsec). */
493         stat_vals = xzmalloc(sizeof(struct stat_val) * (pctx->event_count + 1));
494         for (int i = 0; i < pctx->event_count; i++) {
495                 stat_vals[i].count = perf_get_event_count(pctx, i);
496                 stat_vals[i].name = pctx->events[i].sel.fq_str;
497         }
498         stat_vals[pctx->event_count].name = "nsec";
499         stat_vals[pctx->event_count].count = diff->tv_sec * 1000000000 +
500                                              diff->tv_nsec;
501         return stat_vals;
502 }
503
504 static int perf_stat(struct perf_cmd *cmd, int argc, char *argv[])
505 {
506         struct argp argp_stat = {stat_opts, parse_stat_opt};
507         struct argp_child children[] = { {&argp_stat, 0, 0, 0}, {0} };
508         FILE *out;
509         struct timespec start, end, diff;
510         struct stat_val *stat_vals;
511         char *cmd_string;
512
513         collect_argp(cmd, argc, argv, children, &opts);
514         opts.sampling = FALSE;
515         out = opts.outfile;
516
517         /* As soon as we submit one event, that event is being tracked, meaning
518          * that the setup/teardown of perf events is also tracked.  Each event
519          * (including the clock measurement) will roughly account for either the
520          * start or stop of every other event. */
521         clock_gettime(CLOCK_REALTIME, &start);
522         submit_events(&opts);
523         run_process_and_wait(opts.cmd_argc, opts.cmd_argv,
524                              opts.got_cores ? &opts.cores : NULL);
525         clock_gettime(CLOCK_REALTIME, &end);
526         subtract_timespecs(&diff, &end, &start);
527         stat_vals = collect_stats(pctx, &diff);
528         perf_stop_events(pctx);
529         cmd_string = cmd_as_str(opts.cmd_argc, opts.cmd_argv);
530         fprintf(out, "\nPerformance counter stats for '%s':\n\n", cmd_string);
531         free(cmd_string);
532         for (int i = 0; i < pctx->event_count; i++)
533                 stat_print_val(out, &stat_vals[i], stat_vals,
534                                pctx->event_count + 1);
535         fprintf(out, "\n%8llu.%09llu seconds time elapsed\n\n", diff.tv_sec,
536                 diff.tv_nsec);
537         fclose(out);
538         free(stat_vals);
539         return 0;
540 }
541
542 static void run_process_and_wait(int argc, char *argv[],
543                                  const struct core_set *cores)
544 {
545         int pid, status;
546
547         pid = create_child_with_stdfds(argv[0], argc, argv, environ);
548         if (pid < 0) {
549                 perror("Unable to spawn child");
550                 fflush(stderr);
551                 exit(1);
552         }
553         if (cores) {
554                 if (provision_core_set(pid, cores)) {
555                         fprintf(stderr,
556                                         "Unable to provision all cores to PID %d: cmd='%s'\n",
557                                         pid, argv[0]);
558                         sys_proc_destroy(pid, -1);
559                         exit(1);
560                 }
561         }
562         sys_proc_run(pid);
563         waitpid(pid, &status, 0);
564 }
565
566 static void save_cmdline(int argc, char *argv[])
567 {
568         size_t len = 0;
569         char *p;
570
571         for (int i = 0; i < argc; i++)
572                 len += strlen(argv[i]) + 1;
573         cmd_line_save = xmalloc(len);
574         p = cmd_line_save;
575         for (int i = 0; i < argc; i++) {
576                 strcpy(p, argv[i]);
577                 p += strlen(argv[i]);
578                 if (!(i == argc - 1)) {
579                         *p = ' ';       /* overwrite \0 with ' ' */
580                         p++;
581                 }
582         }
583 }
584
585 static void global_usage(void)
586 {
587         fprintf(stderr, "  Usage: perf COMMAND [ARGS]\n");
588         fprintf(stderr, "\n  Available commands:\n\n");
589         for (int i = 0; i < COUNT_OF(perf_cmds); i++)
590                 fprintf(stderr, "  \t%s: %s\n", perf_cmds[i].name,
591                         perf_cmds[i].desc);
592         exit(-1);
593 }
594
595 int main(int argc, char *argv[])
596 {
597         int i, ret = -1;
598
599         save_cmdline(argc, argv);
600
601         /* Common inits.  Some functions don't need these, but it doesn't hurt.
602          */
603         perf_initialize();
604         pctx = perf_create_context(&perf_cfg);
605         cctx = perfconv_create_context(pctx);
606
607         if (argc < 2)
608                 global_usage();
609         for (i = 0; i < COUNT_OF(perf_cmds); i++) {
610                 if (!strcmp(perf_cmds[i].name, argv[1])) {
611                         ret = perf_cmds[i].func(&perf_cmds[i], argc - 1,
612                                                 argv + 1);
613                         break;
614                 }
615         }
616         if (i == COUNT_OF(perf_cmds))
617                 global_usage();
618         /* This cleanup is optional - they'll all be dealt with when the program
619          * exits.  This means its safe for us to exit(-1) at any point in the
620          * program. */
621         perf_free_context(pctx);
622         perfconv_free_context(cctx);
623         perf_finalize();
624         return ret;
625 }