Linux Perf
builtin-report.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * builtin-report.c
4  *
5  * Builtin report command: Analyze the perf.data input file,
6  * look up and read DSOs and symbol information and display
7  * a histogram of results, along various sorting keys.
8  */
9 #include "builtin.h"
10 
11 #include "util/util.h"
12 #include "util/config.h"
13 
14 #include "util/annotate.h"
15 #include "util/color.h"
16 #include <linux/list.h>
17 #include <linux/rbtree.h>
18 #include <linux/err.h>
19 #include "util/symbol.h"
20 #include "util/callchain.h"
21 #include "util/values.h"
22 
23 #include "perf.h"
24 #include "util/debug.h"
25 #include "util/evlist.h"
26 #include "util/evsel.h"
27 #include "util/header.h"
28 #include "util/session.h"
29 #include "util/tool.h"
30 
31 #include <subcmd/parse-options.h>
32 #include <subcmd/exec-cmd.h>
33 #include "util/parse-events.h"
34 
35 #include "util/thread.h"
36 #include "util/sort.h"
37 #include "util/hist.h"
38 #include "util/data.h"
39 #include "arch/common.h"
40 #include "util/time-utils.h"
41 #include "util/auxtrace.h"
42 #include "util/units.h"
43 #include "util/branch.h"
44 
45 #include <dlfcn.h>
46 #include <errno.h>
47 #include <inttypes.h>
48 #include <regex.h>
49 #include <signal.h>
50 #include <linux/bitmap.h>
51 #include <linux/stringify.h>
52 #include <sys/types.h>
53 #include <sys/stat.h>
54 #include <unistd.h>
55 #include <linux/mman.h>
56 
57 struct report {
58  struct perf_tool tool;
64  bool mem_mode;
65  bool stats_mode;
66  bool tasks_mode;
67  bool mmaps_mode;
68  bool header;
71  bool group_set;
72  int max_stack;
75  const char *pretty_printing_style;
76  const char *cpu_list;
77  const char *symbol_filter_str;
78  const char *time_str;
81  int range_num;
82  float min_percent;
86  DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
88 };
89 
90 static int report__config(const char *var, const char *value, void *cb)
91 {
92  struct report *rep = cb;
93 
94  if (!strcmp(var, "report.group")) {
96  return 0;
97  }
98  if (!strcmp(var, "report.percent-limit")) {
99  double pcnt = strtof(value, NULL);
100 
101  rep->min_percent = pcnt;
103  return 0;
104  }
105  if (!strcmp(var, "report.children")) {
107  return 0;
108  }
109  if (!strcmp(var, "report.queue-size"))
110  return perf_config_u64(&rep->queue_size, var, value);
111 
112  if (!strcmp(var, "report.sort_order")) {
113  default_sort_order = strdup(value);
114  return 0;
115  }
116 
117  return 0;
118 }
119 
121  struct addr_location *al, bool single,
122  void *arg)
123 {
124  int err = 0;
125  struct report *rep = arg;
126  struct hist_entry *he = iter->he;
127  struct perf_evsel *evsel = iter->evsel;
128  struct perf_sample *sample = iter->sample;
129  struct mem_info *mi;
130  struct branch_info *bi;
131 
132  if (!ui__has_annotation())
133  return 0;
134 
135  hist__account_cycles(sample->branch_stack, al, sample,
136  rep->nonany_branch_mode);
137 
138  if (sort__mode == SORT_MODE__BRANCH) {
139  bi = he->branch_info;
140  err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
141  if (err)
142  goto out;
143 
144  err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
145 
146  } else if (rep->mem_mode) {
147  mi = he->mem_info;
148  err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel);
149  if (err)
150  goto out;
151 
152  err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
153 
154  } else if (symbol_conf.cumulate_callchain) {
155  if (single)
156  err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
157  } else {
158  err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
159  }
160 
161 out:
162  return err;
163 }
164 
166  struct addr_location *al __maybe_unused,
167  bool single __maybe_unused,
168  void *arg)
169 {
170  struct hist_entry *he = iter->he;
171  struct report *rep = arg;
172  struct branch_info *bi;
173  struct perf_sample *sample = iter->sample;
174  struct perf_evsel *evsel = iter->evsel;
175  int err;
176 
177  if (!ui__has_annotation())
178  return 0;
179 
180  hist__account_cycles(sample->branch_stack, al, sample,
181  rep->nonany_branch_mode);
182 
183  bi = he->branch_info;
184  err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
185  if (err)
186  goto out;
187 
188  err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
189 
190  branch_type_count(&rep->brtype_stat, &bi->flags,
191  bi->from.addr, bi->to.addr);
192 
193 out:
194  return err;
195 }
196 
197 static void setup_forced_leader(struct report *report,
198  struct perf_evlist *evlist)
199 {
200  if (report->group_set)
202 }
203 
205  union perf_event *event,
206  struct perf_session *session __maybe_unused)
207 {
208  struct report *rep = container_of(tool, struct report, tool);
209 
210  if (event->feat.feat_id < HEADER_LAST_FEATURE)
211  return perf_event__process_feature(tool, event, session);
212 
213  if (event->feat.feat_id != HEADER_LAST_FEATURE) {
214  pr_err("failed: wrong feature ID: %" PRIu64 "\n",
215  event->feat.feat_id);
216  return -1;
217  }
218 
219  /*
220  * All features are received, we can force the
221  * group if needed.
222  */
224  return 0;
225 }
226 
228  union perf_event *event,
229  struct perf_sample *sample,
230  struct perf_evsel *evsel,
231  struct machine *machine)
232 {
233  struct report *rep = container_of(tool, struct report, tool);
234  struct addr_location al;
235  struct hist_entry_iter iter = {
236  .evsel = evsel,
237  .sample = sample,
238  .hide_unresolved = symbol_conf.hide_unresolved,
239  .add_entry_cb = hist_iter__report_callback,
240  };
241  int ret = 0;
242 
244  sample->time)) {
245  return 0;
246  }
247 
248  if (machine__resolve(machine, &al, sample) < 0) {
249  pr_debug("problem processing %d event, skipping it.\n",
250  event->header.type);
251  return -1;
252  }
253 
254  if (symbol_conf.hide_unresolved && al.sym == NULL)
255  goto out_put;
256 
257  if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
258  goto out_put;
259 
260  if (sort__mode == SORT_MODE__BRANCH) {
261  /*
262  * A non-synthesized event might not have a branch stack if
263  * branch stacks have been synthesized (using itrace options).
264  */
265  if (!sample->branch_stack)
266  goto out_put;
267 
269  iter.ops = &hist_iter_branch;
270  } else if (rep->mem_mode) {
271  iter.ops = &hist_iter_mem;
272  } else if (symbol_conf.cumulate_callchain) {
273  iter.ops = &hist_iter_cumulative;
274  } else {
275  iter.ops = &hist_iter_normal;
276  }
277 
278  if (al.map != NULL)
279  al.map->dso->hit = 1;
280 
281  ret = hist_entry_iter__add(&iter, &al, rep->max_stack, rep);
282  if (ret < 0)
283  pr_debug("problem adding hist entry, skipping event\n");
284 out_put:
285  addr_location__put(&al);
286  return ret;
287 }
288 
289 static int process_read_event(struct perf_tool *tool,
290  union perf_event *event,
291  struct perf_sample *sample __maybe_unused,
292  struct perf_evsel *evsel,
293  struct machine *machine __maybe_unused)
294 {
295  struct report *rep = container_of(tool, struct report, tool);
296 
297  if (rep->show_threads) {
298  const char *name = evsel ? perf_evsel__name(evsel) : "unknown";
300  event->read.pid, event->read.tid,
301  evsel->idx,
302  name,
303  event->read.value);
304 
305  if (err)
306  return err;
307  }
308 
309  return 0;
310 }
311 
312 /* For pipe mode, sample_type is not currently set */
313 static int report__setup_sample_type(struct report *rep)
314 {
315  struct perf_session *session = rep->session;
316  u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
317  bool is_pipe = perf_data__is_pipe(session->data);
318 
319  if (session->itrace_synth_opts->callchain ||
320  (!is_pipe &&
322  !session->itrace_synth_opts->set))
323  sample_type |= PERF_SAMPLE_CALLCHAIN;
324 
325  if (session->itrace_synth_opts->last_branch)
326  sample_type |= PERF_SAMPLE_BRANCH_STACK;
327 
328  if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
329  if (perf_hpp_list.parent) {
330  ui__error("Selected --sort parent, but no "
331  "callchain data. Did you call "
332  "'perf record' without -g?\n");
333  return -EINVAL;
334  }
337  ui__error("Selected -g or --branch-history.\n"
338  "But no callchain or branch data.\n"
339  "Did you call 'perf record' without -g or -b?\n");
340  return -1;
341  }
342  } else if (!callchain_param.enabled &&
345  symbol_conf.use_callchain = true;
347  ui__error("Can't register callchain params.\n");
348  return -EINVAL;
349  }
350  }
351 
353  /* Silently ignore if callchain is missing */
354  if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
357  }
358  }
359 
360  if (sort__mode == SORT_MODE__BRANCH) {
361  if (!is_pipe &&
362  !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
363  ui__error("Selected -b but no branch data. "
364  "Did you call perf record without -b?\n");
365  return -1;
366  }
367  }
368 
370  if ((sample_type & PERF_SAMPLE_REGS_USER) &&
371  (sample_type & PERF_SAMPLE_STACK_USER)) {
373  dwarf_callchain_users = true;
374  } else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
376  else
378  }
379 
380  /* ??? handle more cases than just ANY? */
381  if (!(perf_evlist__combined_branch_type(session->evlist) &
382  PERF_SAMPLE_BRANCH_ANY))
383  rep->nonany_branch_mode = true;
384 
385  return 0;
386 }
387 
388 static void sig_handler(int sig __maybe_unused)
389 {
390  session_done = 1;
391 }
392 
393 static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep,
394  const char *evname, FILE *fp)
395 {
396  size_t ret;
397  char unit;
398  unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
399  u64 nr_events = hists->stats.total_period;
400  struct perf_evsel *evsel = hists_to_evsel(hists);
401  char buf[512];
402  size_t size = sizeof(buf);
403  int socked_id = hists->socket_filter;
404 
405  if (quiet)
406  return 0;
407 
409  nr_samples = hists->stats.nr_non_filtered_samples;
410  nr_events = hists->stats.total_non_filtered_period;
411  }
412 
413  if (perf_evsel__is_group_event(evsel)) {
414  struct perf_evsel *pos;
415 
416  perf_evsel__group_desc(evsel, buf, size);
417  evname = buf;
418 
419  for_each_group_member(pos, evsel) {
420  const struct hists *pos_hists = evsel__hists(pos);
421 
423  nr_samples += pos_hists->stats.nr_non_filtered_samples;
424  nr_events += pos_hists->stats.total_non_filtered_period;
425  } else {
426  nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
427  nr_events += pos_hists->stats.total_period;
428  }
429  }
430  }
431 
432  nr_samples = convert_unit(nr_samples, &unit);
433  ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
434  if (evname != NULL) {
435  ret += fprintf(fp, " of event%s '%s'",
436  evsel->nr_members > 1 ? "s" : "", evname);
437  }
438 
439  if (rep->time_str)
440  ret += fprintf(fp, " (time slices: %s)", rep->time_str);
441 
443  strstr(evname, "call-graph=no")) {
444  ret += fprintf(fp, ", show reference callgraph");
445  }
446 
447  if (rep->mem_mode) {
448  ret += fprintf(fp, "\n# Total weight : %" PRIu64, nr_events);
449  ret += fprintf(fp, "\n# Sort order : %s", sort_order ? : default_mem_sort_order);
450  } else
451  ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
452 
453  if (socked_id > -1)
454  ret += fprintf(fp, "\n# Processor Socket: %d", socked_id);
455 
456  return ret + fprintf(fp, "\n#\n");
457 }
458 
459 static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
460  struct report *rep,
461  const char *help)
462 {
463  struct perf_evsel *pos;
464 
465  if (!quiet) {
466  fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n",
467  evlist->stats.total_lost_samples);
468  }
469 
470  evlist__for_each_entry(evlist, pos) {
471  struct hists *hists = evsel__hists(pos);
472  const char *evname = perf_evsel__name(pos);
473 
474  if (symbol_conf.event_group &&
476  continue;
477 
478  hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
479  hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
482  fprintf(stdout, "\n\n");
483  }
484 
485  if (!quiet)
486  fprintf(stdout, "#\n# (%s)\n#\n", help);
487 
488  if (rep->show_threads) {
489  bool style = !strcmp(rep->pretty_printing_style, "raw");
491  style);
493  }
494 
496  branch_type_stat_display(stdout, &rep->brtype_stat);
497 
498  return 0;
499 }
500 
501 static void report__warn_kptr_restrict(const struct report *rep)
502 {
503  struct map *kernel_map = machine__kernel_map(&rep->session->machines.host);
504  struct kmap *kernel_kmap = kernel_map ? map__kmap(kernel_map) : NULL;
505 
507  return;
508 
509  if (kernel_map == NULL ||
510  (kernel_map->dso->hit &&
511  (kernel_kmap->ref_reloc_sym == NULL ||
512  kernel_kmap->ref_reloc_sym->addr == 0))) {
513  const char *desc =
514  "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
515  "can't be resolved.";
516 
517  if (kernel_map && map__has_symbols(kernel_map)) {
518  desc = "If some relocation was applied (e.g. "
519  "kexec) symbols may be misresolved.";
520  }
521 
522  ui__warning(
523 "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
524 "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
525 "Samples in kernel modules can't be resolved as well.\n\n",
526  desc);
527  }
528 }
529 
530 static int report__gtk_browse_hists(struct report *rep, const char *help)
531 {
532  int (*hist_browser)(struct perf_evlist *evlist, const char *help,
533  struct hist_browser_timer *timer, float min_pcnt);
534 
535  hist_browser = dlsym(perf_gtk_handle, "perf_evlist__gtk_browse_hists");
536 
537  if (hist_browser == NULL) {
538  ui__error("GTK browser not found!\n");
539  return -1;
540  }
541 
542  return hist_browser(rep->session->evlist, help, NULL, rep->min_percent);
543 }
544 
545 static int report__browse_hists(struct report *rep)
546 {
547  int ret;
548  struct perf_session *session = rep->session;
549  struct perf_evlist *evlist = session->evlist;
550  const char *help = perf_tip(system_path(TIPDIR));
551 
552  if (help == NULL) {
553  /* fallback for people who don't install perf ;-) */
554  help = perf_tip(DOCDIR);
555  if (help == NULL)
556  help = "Cannot load tips.txt file, please install perf!";
557  }
558 
559  switch (use_browser) {
560  case 1:
561  ret = perf_evlist__tui_browse_hists(evlist, help, NULL,
562  rep->min_percent,
563  &session->header.env,
564  true, &rep->annotation_opts);
565  /*
566  * Usually "ret" is the last pressed key, and we only
567  * care if the key notifies us to switch data file.
568  */
569  if (ret != K_SWITCH_INPUT_DATA)
570  ret = 0;
571  break;
572  case 2:
573  ret = report__gtk_browse_hists(rep, help);
574  break;
575  default:
576  ret = perf_evlist__tty_browse_hists(evlist, rep, help);
577  break;
578  }
579 
580  return ret;
581 }
582 
583 static int report__collapse_hists(struct report *rep)
584 {
585  struct ui_progress prog;
586  struct perf_evsel *pos;
587  int ret = 0;
588 
589  ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
590 
592  struct hists *hists = evsel__hists(pos);
593 
594  if (pos->idx == 0)
595  hists->symbol_filter_str = rep->symbol_filter_str;
596 
597  hists->socket_filter = rep->socket_filter;
598 
599  ret = hists__collapse_resort(hists, &prog);
600  if (ret < 0)
601  break;
602 
603  /* Non-group events are considered as leader */
604  if (symbol_conf.event_group &&
606  struct hists *leader_hists = evsel__hists(pos->leader);
607 
608  hists__match(leader_hists, hists);
609  hists__link(leader_hists, hists);
610  }
611  }
612 
614  return ret;
615 }
616 
617 static void report__output_resort(struct report *rep)
618 {
619  struct ui_progress prog;
620  struct perf_evsel *pos;
621 
622  ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");
623 
625  perf_evsel__output_resort(pos, &prog);
626 
628 }
629 
630 static void stats_setup(struct report *rep)
631 {
632  memset(&rep->tool, 0, sizeof(rep->tool));
633  rep->tool.no_warn = true;
634 }
635 
636 static int stats_print(struct report *rep)
637 {
638  struct perf_session *session = rep->session;
639 
640  perf_session__fprintf_nr_events(session, stdout);
641  return 0;
642 }
643 
644 static void tasks_setup(struct report *rep)
645 {
646  memset(&rep->tool, 0, sizeof(rep->tool));
647  rep->tool.ordered_events = true;
648  if (rep->mmaps_mode) {
651  }
655  rep->tool.no_warn = true;
656 }
657 
658 struct task {
659  struct thread *thread;
660  struct list_head list;
661  struct list_head children;
662 };
663 
664 static struct task *tasks_list(struct task *task, struct machine *machine)
665 {
666  struct thread *parent_thread, *thread = task->thread;
667  struct task *parent_task;
668 
669  /* Already listed. */
670  if (!list_empty(&task->list))
671  return NULL;
672 
673  /* Last one in the chain. */
674  if (thread->ppid == -1)
675  return task;
676 
677  parent_thread = machine__find_thread(machine, -1, thread->ppid);
678  if (!parent_thread)
679  return ERR_PTR(-ENOENT);
680 
681  parent_task = thread__priv(parent_thread);
682  list_add_tail(&task->list, &parent_task->children);
683  return tasks_list(parent_task, machine);
684 }
685 
686 static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
687 {
688  size_t printed = 0;
689  struct rb_node *nd;
690 
691  for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
692  struct map *map = rb_entry(nd, struct map, rb_node);
693 
694  printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
695  indent, "", map->start, map->end,
696  map->prot & PROT_READ ? 'r' : '-',
697  map->prot & PROT_WRITE ? 'w' : '-',
698  map->prot & PROT_EXEC ? 'x' : '-',
699  map->flags & MAP_SHARED ? 's' : 'p',
700  map->pgoff,
701  map->ino, map->dso->name);
702  }
703 
704  return printed;
705 }
706 
707 static int map_groups__fprintf_task(struct map_groups *mg, int indent, FILE *fp)
708 {
709  return maps__fprintf_task(&mg->maps, indent, fp);
710 }
711 
712 static void task__print_level(struct task *task, FILE *fp, int level)
713 {
714  struct thread *thread = task->thread;
715  struct task *child;
716  int comm_indent = fprintf(fp, " %8d %8d %8d |%*s",
717  thread->pid_, thread->tid, thread->ppid,
718  level, "");
719 
720  fprintf(fp, "%s\n", thread__comm_str(thread));
721 
722  map_groups__fprintf_task(thread->mg, comm_indent, fp);
723 
724  if (!list_empty(&task->children)) {
725  list_for_each_entry(child, &task->children, list)
726  task__print_level(child, fp, level + 1);
727  }
728 }
729 
730 static int tasks_print(struct report *rep, FILE *fp)
731 {
732  struct perf_session *session = rep->session;
733  struct machine *machine = &session->machines.host;
734  struct task *tasks, *task;
735  unsigned int nr = 0, itask = 0, i;
736  struct rb_node *nd;
737  LIST_HEAD(list);
738 
739  /*
740  * No locking needed while accessing machine->threads,
741  * because --tasks is single threaded command.
742  */
743 
744  /* Count all the threads. */
745  for (i = 0; i < THREADS__TABLE_SIZE; i++)
746  nr += machine->threads[i].nr;
747 
748  tasks = malloc(sizeof(*tasks) * nr);
749  if (!tasks)
750  return -ENOMEM;
751 
752  for (i = 0; i < THREADS__TABLE_SIZE; i++) {
753  struct threads *threads = &machine->threads[i];
754 
755  for (nd = rb_first(&threads->entries); nd; nd = rb_next(nd)) {
756  task = tasks + itask++;
757 
758  task->thread = rb_entry(nd, struct thread, rb_node);
759  INIT_LIST_HEAD(&task->children);
760  INIT_LIST_HEAD(&task->list);
761  thread__set_priv(task->thread, task);
762  }
763  }
764 
765  /*
766  * Iterate every task down to the unprocessed parent
767  * and link all in task children list. Task with no
768  * parent is added into 'list'.
769  */
770  for (itask = 0; itask < nr; itask++) {
771  task = tasks + itask;
772 
773  if (!list_empty(&task->list))
774  continue;
775 
776  task = tasks_list(task, machine);
777  if (IS_ERR(task)) {
778  pr_err("Error: failed to process tasks\n");
779  free(tasks);
780  return PTR_ERR(task);
781  }
782 
783  if (task)
784  list_add_tail(&task->list, &list);
785  }
786 
787  fprintf(fp, "# %8s %8s %8s %s\n", "pid", "tid", "ppid", "comm");
788 
789  list_for_each_entry(task, &list, list)
790  task__print_level(task, fp, 0);
791 
792  free(tasks);
793  return 0;
794 }
795 
796 static int __cmd_report(struct report *rep)
797 {
798  int ret;
799  struct perf_session *session = rep->session;
800  struct perf_evsel *pos;
801  struct perf_data *data = session->data;
802 
803  signal(SIGINT, sig_handler);
804 
805  if (rep->cpu_list) {
806  ret = perf_session__cpu_bitmap(session, rep->cpu_list,
807  rep->cpu_bitmap);
808  if (ret) {
809  ui__error("failed to set cpu bitmap\n");
810  return ret;
811  }
812  session->itrace_synth_opts->cpu_bitmap = rep->cpu_bitmap;
813  }
814 
815  if (rep->show_threads) {
817  if (ret)
818  return ret;
819  }
820 
821  ret = report__setup_sample_type(rep);
822  if (ret) {
823  /* report__setup_sample_type() already showed error message */
824  return ret;
825  }
826 
827  if (rep->stats_mode)
828  stats_setup(rep);
829 
830  if (rep->tasks_mode)
831  tasks_setup(rep);
832 
833  ret = perf_session__process_events(session);
834  if (ret) {
835  ui__error("failed to process sample\n");
836  return ret;
837  }
838 
839  if (rep->stats_mode)
840  return stats_print(rep);
841 
842  if (rep->tasks_mode)
843  return tasks_print(rep, stdout);
844 
846 
847  evlist__for_each_entry(session->evlist, pos)
848  rep->nr_entries += evsel__hists(pos)->nr_entries;
849 
850  if (use_browser == 0) {
851  if (verbose > 3)
852  perf_session__fprintf(session, stdout);
853 
854  if (verbose > 2)
855  perf_session__fprintf_dsos(session, stdout);
856 
857  if (dump_trace) {
858  perf_session__fprintf_nr_events(session, stdout);
859  perf_evlist__fprintf_nr_events(session->evlist, stdout);
860  return 0;
861  }
862  }
863 
864  ret = report__collapse_hists(rep);
865  if (ret) {
866  ui__error("failed to process hist entry\n");
867  return ret;
868  }
869 
870  if (session_done())
871  return 0;
872 
873  /*
874  * recalculate number of entries after collapsing since it
875  * might be changed during the collapse phase.
876  */
877  rep->nr_entries = 0;
878  evlist__for_each_entry(session->evlist, pos)
879  rep->nr_entries += evsel__hists(pos)->nr_entries;
880 
881  if (rep->nr_entries == 0) {
882  ui__error("The %s file has no samples!\n", data->file.path);
883  return 0;
884  }
885 
887 
888  return report__browse_hists(rep);
889 }
890 
891 static int
892 report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
893 {
894  struct callchain_param *callchain = opt->value;
895 
896  callchain->enabled = !unset;
897  /*
898  * --no-call-graph
899  */
900  if (unset) {
901  symbol_conf.use_callchain = false;
902  callchain->mode = CHAIN_NONE;
903  return 0;
904  }
905 
906  return parse_callchain_report_opt(arg);
907 }
908 
909 int
910 report_parse_ignore_callees_opt(const struct option *opt __maybe_unused,
911  const char *arg, int unset __maybe_unused)
912 {
913  if (arg) {
914  int err = regcomp(&ignore_callees_regex, arg, REG_EXTENDED);
915  if (err) {
916  char buf[BUFSIZ];
917  regerror(err, &ignore_callees_regex, buf, sizeof(buf));
918  pr_err("Invalid --ignore-callees regex: %s\n%s", arg, buf);
919  return -1;
920  }
922  }
923 
924  return 0;
925 }
926 
927 static int
928 parse_branch_mode(const struct option *opt,
929  const char *str __maybe_unused, int unset)
930 {
931  int *branch_mode = opt->value;
932 
933  *branch_mode = !unset;
934  return 0;
935 }
936 
937 static int
938 parse_percent_limit(const struct option *opt, const char *str,
939  int unset __maybe_unused)
940 {
941  struct report *rep = opt->value;
942  double pcnt = strtof(str, NULL);
943 
944  rep->min_percent = pcnt;
946  return 0;
947 }
948 
949 int cmd_report(int argc, const char **argv)
950 {
951  struct perf_session *session;
952  struct itrace_synth_opts itrace_synth_opts = { .set = 0, };
953  struct stat st;
954  bool has_br_stack = false;
955  int branch_mode = -1;
956  bool branch_call_mode = false;
957 #define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function,percent"
958  const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n"
960  "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT;
961  char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT;
962  const char * const report_usage[] = {
963  "perf report [<options>]",
964  NULL
965  };
966  struct report report = {
967  .tool = {
969  .mmap = perf_event__process_mmap,
970  .mmap2 = perf_event__process_mmap2,
971  .comm = perf_event__process_comm,
972  .namespaces = perf_event__process_namespaces,
973  .exit = perf_event__process_exit,
974  .fork = perf_event__process_fork,
975  .lost = perf_event__process_lost,
976  .read = process_read_event,
977  .attr = perf_event__process_attr,
978  .tracing_data = perf_event__process_tracing_data,
979  .build_id = perf_event__process_build_id,
980  .id_index = perf_event__process_id_index,
981  .auxtrace_info = perf_event__process_auxtrace_info,
982  .auxtrace = perf_event__process_auxtrace,
983  .feature = process_feature_event,
984  .ordered_events = true,
985  .ordering_requires_timestamps = true,
986  },
987  .max_stack = PERF_MAX_STACK_DEPTH,
988  .pretty_printing_style = "normal",
989  .socket_filter = -1,
990  .annotation_opts = annotation__default_options,
991  };
992  const struct option options[] = {
993  OPT_STRING('i', "input", &input_name, "file",
994  "input file name"),
995  OPT_INCR('v', "verbose", &verbose,
996  "be more verbose (show symbol address, etc)"),
997  OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"),
998  OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
999  "dump raw trace in ASCII"),
1000  OPT_BOOLEAN(0, "stats", &report.stats_mode, "Display event stats"),
1001  OPT_BOOLEAN(0, "tasks", &report.tasks_mode, "Display recorded tasks"),
1002  OPT_BOOLEAN(0, "mmaps", &report.mmaps_mode, "Display recorded tasks memory maps"),
1003  OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1004  "file", "vmlinux pathname"),
1005  OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
1006  "don't load vmlinux even if found"),
1007  OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
1008  "file", "kallsyms pathname"),
1009  OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
1010  OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
1011  "load module symbols - WARNING: use only with -k and LIVE kernel"),
1012  OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
1013  "Show a column with the number of samples"),
1014  OPT_BOOLEAN('T', "threads", &report.show_threads,
1015  "Show per-thread event counters"),
1016  OPT_STRING(0, "pretty", &report.pretty_printing_style, "key",
1017  "pretty printing style key: normal raw"),
1018  OPT_BOOLEAN(0, "tui", &report.use_tui, "Use the TUI interface"),
1019  OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
1020  OPT_BOOLEAN(0, "stdio", &report.use_stdio,
1021  "Use the stdio interface"),
1022  OPT_BOOLEAN(0, "header", &report.header, "Show data header."),
1023  OPT_BOOLEAN(0, "header-only", &report.header_only,
1024  "Show only data header."),
1025  OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1026  "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
1027  " Please refer the man page for the complete list."),
1028  OPT_STRING('F', "fields", &field_order, "key[,keys...]",
1029  "output field(s): overhead, period, sample plus all of sort keys"),
1030  OPT_BOOLEAN(0, "show-cpu-utilization", &symbol_conf.show_cpu_utilization,
1031  "Show sample percentage for different cpu modes"),
1032  OPT_BOOLEAN_FLAG(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
1033  "Show sample percentage for different cpu modes", PARSE_OPT_HIDDEN),
1034  OPT_STRING('p', "parent", &parent_pattern, "regex",
1035  "regex filter to identify parent, see: '--sort parent'"),
1036  OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
1037  "Only display entries with parent-match"),
1038  OPT_CALLBACK_DEFAULT('g', "call-graph", &callchain_param,
1039  "print_type,threshold[,print_limit],order,sort_key[,branch],value",
1040  report_callchain_help, &report_parse_callchain_opt,
1041  callchain_default_opt),
1042  OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
1043  "Accumulate callchains of children and show total overhead as well"),
1044  OPT_INTEGER(0, "max-stack", &report.max_stack,
1045  "Set the maximum stack depth when parsing the callchain, "
1046  "anything beyond the specified depth will be ignored. "
1047  "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
1048  OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
1049  "alias for inverted call graph"),
1050  OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
1051  "ignore callees of these functions in call graphs",
1053  OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
1054  "only consider symbols in these dsos"),
1055  OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1056  "only consider symbols in these comms"),
1057  OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
1058  "only consider symbols in these pids"),
1059  OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
1060  "only consider symbols in these tids"),
1061  OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
1062  "only consider these symbols"),
1063  OPT_STRING(0, "symbol-filter", &report.symbol_filter_str, "filter",
1064  "only show symbols that (partially) match with this filter"),
1065  OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
1066  "width[,width...]",
1067  "don't try to adjust column width, use these fixed values"),
1068  OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
1069  "separator for columns, no spaces will be added between "
1070  "columns '.' is reserved."),
1071  OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved,
1072  "Only display entries resolved to a symbol"),
1073  OPT_CALLBACK(0, "symfs", NULL, "directory",
1074  "Look for files with symbols relative to this directory",
1076  OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
1077  "list of cpus to profile"),
1078  OPT_BOOLEAN('I', "show-info", &report.show_full_info,
1079  "Display extended information about perf.data file"),
1080  OPT_BOOLEAN(0, "source", &report.annotation_opts.annotate_src,
1081  "Interleave source code with assembly code (default)"),
1082  OPT_BOOLEAN(0, "asm-raw", &report.annotation_opts.show_asm_raw,
1083  "Display raw encoding of assembly instructions (default)"),
1084  OPT_STRING('M', "disassembler-style", &report.annotation_opts.disassembler_style, "disassembler style",
1085  "Specify disassembler style (e.g. -M intel for intel syntax)"),
1086  OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
1087  "Show a column with the sum of periods"),
1088  OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group, &report.group_set,
1089  "Show event group information together"),
1090  OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
1091  "use branch records for per branch histogram filling",
1093  OPT_BOOLEAN(0, "branch-history", &branch_call_mode,
1094  "add last branch records to call history"),
1095  OPT_STRING(0, "objdump", &report.annotation_opts.objdump_path, "path",
1096  "objdump binary to use for disassembly and annotations"),
1097  OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
1098  "Disable symbol demangling"),
1099  OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
1100  "Enable kernel symbol demangling"),
1101  OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
1102  OPT_CALLBACK(0, "percent-limit", &report, "percent",
1103  "Don't show entries under that percent", parse_percent_limit),
1104  OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
1105  "how to display percentage of filtered entries", parse_filter_percentage),
1106  OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
1107  "Instruction Tracing options",
1109  OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
1110  "Show full source file name path for source lines"),
1111  OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
1112  "Show callgraph from reference event"),
1113  OPT_INTEGER(0, "socket-filter", &report.socket_filter,
1114  "only show processor socket that match with this filter"),
1115  OPT_BOOLEAN(0, "raw-trace", &symbol_conf.raw_trace,
1116  "Show raw trace event output (do not use print fmt or plugins)"),
1117  OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy,
1118  "Show entries in a hierarchy"),
1119  OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
1120  "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
1121  stdio__config_color, "always"),
1122  OPT_STRING(0, "time", &report.time_str, "str",
1123  "Time span of interest (start,stop)"),
1124  OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
1125  "Show inline function"),
1126  OPT_END()
1127  };
1128  struct perf_data data = {
1130  };
1131  int ret = hists__init();
1132 
1133  if (ret < 0)
1134  return ret;
1135 
1136  ret = perf_config(report__config, &report);
1137  if (ret)
1138  return ret;
1139 
1140  argc = parse_options(argc, argv, options, report_usage, 0);
1141  if (argc) {
1142  /*
1143  * Special case: if there's an argument left then assume that
1144  * it's a symbol filter:
1145  */
1146  if (argc > 1)
1147  usage_with_options(report_usage, options);
1148 
1149  report.symbol_filter_str = argv[0];
1150  }
1151 
1152  if (report.mmaps_mode)
1153  report.tasks_mode = true;
1154 
1155  if (quiet)
1157 
1158  if (symbol_conf.vmlinux_name &&
1159  access(symbol_conf.vmlinux_name, R_OK)) {
1160  pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name);
1161  return -EINVAL;
1162  }
1163  if (symbol_conf.kallsyms_name &&
1164  access(symbol_conf.kallsyms_name, R_OK)) {
1165  pr_err("Invalid file: %s\n", symbol_conf.kallsyms_name);
1166  return -EINVAL;
1167  }
1168 
1169  if (report.inverted_callchain)
1173 
1174  if (itrace_synth_opts.callchain &&
1175  (int)itrace_synth_opts.callchain_sz > report.max_stack)
1176  report.max_stack = itrace_synth_opts.callchain_sz;
1177 
1178  if (!input_name || !strlen(input_name)) {
1179  if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
1180  input_name = "-";
1181  else
1182  input_name = "perf.data";
1183  }
1184 
1185  data.file.path = input_name;
1186  data.force = symbol_conf.force;
1187 
1188 repeat:
1189  session = perf_session__new(&data, false, &report.tool);
1190  if (session == NULL)
1191  return -1;
1192 
1193  if (report.queue_size) {
1195  report.queue_size);
1196  }
1197 
1198  session->itrace_synth_opts = &itrace_synth_opts;
1199 
1200  report.session = session;
1201 
1202  has_br_stack = perf_header__has_feat(&session->header,
1204 
1205  setup_forced_leader(&report, session->evlist);
1206 
1207  if (itrace_synth_opts.last_branch)
1208  has_br_stack = true;
1209 
1210  if (has_br_stack && branch_call_mode)
1212 
1213  memset(&report.brtype_stat, 0, sizeof(struct branch_type_stat));
1214 
1215  /*
1216  * Branch mode is a tristate:
1217  * -1 means default, so decide based on the file having branch data.
1218  * 0/1 means the user chose a mode.
1219  */
1220  if (((branch_mode == -1 && has_br_stack) || branch_mode == 1) &&
1221  !branch_call_mode) {
1224  }
1225  if (branch_call_mode) {
1228  symbol_conf.use_callchain = true;
1230  if (sort_order == NULL)
1231  sort_order = "srcline,symbol,dso";
1232  }
1233 
1234  if (report.mem_mode) {
1235  if (sort__mode == SORT_MODE__BRANCH) {
1236  pr_err("branch and mem mode incompatible\n");
1237  goto error;
1238  }
1241  }
1242 
1244  /* disable incompatible options */
1246 
1247  if (field_order) {
1248  pr_err("Error: --hierarchy and --fields options cannot be used together\n");
1249  parse_options_usage(report_usage, options, "F", 1);
1250  parse_options_usage(NULL, options, "hierarchy", 0);
1251  goto error;
1252  }
1253 
1255  }
1256 
1257  if (report.use_stdio)
1258  use_browser = 0;
1259  else if (report.use_tui)
1260  use_browser = 1;
1261  else if (report.use_gtk)
1262  use_browser = 2;
1263 
1264  /* Force tty output for header output and per-thread stat. */
1265  if (report.header || report.header_only || report.show_threads)
1266  use_browser = 0;
1267  if (report.header || report.header_only)
1269  if (report.show_full_info)
1271  if (report.stats_mode || report.tasks_mode)
1272  use_browser = 0;
1273  if (report.stats_mode && report.tasks_mode) {
1274  pr_err("Error: --tasks and --mmaps can't be used together with --stats\n");
1275  goto error;
1276  }
1277 
1278  if (strcmp(input_name, "-") != 0)
1279  setup_browser(true);
1280  else
1281  use_browser = 0;
1282 
1283  if (setup_sorting(session->evlist) < 0) {
1284  if (sort_order)
1285  parse_options_usage(report_usage, options, "s", 1);
1286  if (field_order)
1287  parse_options_usage(sort_order ? NULL : report_usage,
1288  options, "F", 1);
1289  goto error;
1290  }
1291 
1292  if ((report.header || report.header_only) && !quiet) {
1293  perf_session__fprintf_info(session, stdout,
1294  report.show_full_info);
1295  if (report.header_only) {
1296  ret = 0;
1297  goto error;
1298  }
1299  } else if (use_browser == 0 && !quiet &&
1300  !report.stats_mode && !report.tasks_mode) {
1301  fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
1302  stdout);
1303  }
1304 
1305  /*
1306  * Only in the TUI browser we are doing integrated annotation,
1307  * so don't allocate extra space that won't be used in the stdio
1308  * implementation.
1309  */
1310  if (ui__has_annotation()) {
1311  ret = symbol__annotation_init();
1312  if (ret < 0)
1313  goto error;
1314  /*
1315  * For searching by name on the "Browse map details".
1316  * providing it only in verbose mode not to bloat too
1317  * much struct symbol.
1318  */
1319  if (verbose > 0) {
1320  /*
1321  * XXX: Need to provide a less kludgy way to ask for
1322  * more space per symbol, the u32 is for the index on
1323  * the ui browser.
1324  * See symbol__browser_index.
1325  */
1326  symbol_conf.priv_size += sizeof(u32);
1327  symbol_conf.sort_by_name = true;
1328  }
1330  }
1331 
1332  if (symbol__init(&session->header.env) < 0)
1333  goto error;
1334 
1336  &report.range_size);
1337  if (!report.ptime_range) {
1338  ret = -ENOMEM;
1339  goto error;
1340  }
1341 
1342  if (perf_time__parse_str(report.ptime_range, report.time_str) != 0) {
1343  if (session->evlist->first_sample_time == 0 &&
1344  session->evlist->last_sample_time == 0) {
1345  pr_err("HINT: no first/last sample time found in perf data.\n"
1346  "Please use latest perf binary to execute 'perf record'\n"
1347  "(if '--buildid-all' is enabled, please set '--timestamp-boundary').\n");
1348  ret = -EINVAL;
1349  goto error;
1350  }
1351 
1353  report.ptime_range, report.range_size,
1354  report.time_str,
1355  session->evlist->first_sample_time,
1356  session->evlist->last_sample_time);
1357 
1358  if (report.range_num < 0) {
1359  pr_err("Invalid time string\n");
1360  ret = -EINVAL;
1361  goto error;
1362  }
1363  } else {
1364  report.range_num = 1;
1365  }
1366 
1367  if (session->tevent.pevent &&
1368  pevent_set_function_resolver(session->tevent.pevent,
1370  &session->machines.host) < 0) {
1371  pr_err("%s: failed to set libtraceevent function resolver\n",
1372  __func__);
1373  return -1;
1374  }
1375 
1376  sort__setup_elide(stdout);
1377 
1378  ret = __cmd_report(&report);
1379  if (ret == K_SWITCH_INPUT_DATA) {
1380  perf_session__delete(session);
1381  goto repeat;
1382  } else
1383  ret = 0;
1384 
1385 error:
1386  zfree(&report.ptime_range);
1387 
1388  perf_session__delete(session);
1389  return ret;
1390 }
int perf_read_values_add_value(struct perf_read_values *values, u32 pid, u32 tid, u64 rawid, const char *name, u64 value)
Definition: values.c:183
static void setup_sorting(struct perf_sched *sched, const struct option *options, const char *const usage_msg[])
static int report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
bool event_group
Definition: symbol.h:93
static void setup_forced_leader(struct report *report, struct perf_evlist *evlist)
int(* add_entry_cb)(struct hist_entry_iter *iter, struct addr_location *al, bool single, void *arg)
Definition: hist.h:120
struct maps maps
Definition: map.h:64
struct map_groups * mg
Definition: thread.h:23
static int report__browse_hists(struct report *rep)
int perf_event__process_attr(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_evlist **pevlist)
Definition: header.c:3721
event_op mmap2
Definition: tool.h:47
const char * comm_list_str
Definition: symbol.h:131
int cmd_report(int argc, const char **argv)
const char * col_width_list_str
Definition: symbol.h:131
struct perf_sample * sample
Definition: hist.h:113
bool exclude_other
Definition: symbol.h:93
enum perf_data_mode mode
Definition: data.h:22
int value
Definition: python.c:1143
void perf_hpp__cancel_cumulate(void)
Definition: hist.c:539
static void ordered_events__set_alloc_size(struct ordered_events *oe, u64 size)
struct perf_evlist * evlist
Definition: session.h:25
static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine)
struct perf_data * data
Definition: session.h:36
struct branch_type_stat brtype_stat
int stdio__config_color(const struct option *opt __maybe_unused, const char *mode, int unset __maybe_unused)
Definition: setup.c:69
enum show_feature_header show_feat_hdr
Definition: tool.h:80
int machine__resolve(struct machine *machine, struct addr_location *al, struct perf_sample *sample)
Definition: event.c:1601
bool mmaps_mode
size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
Definition: session.c:2016
struct ordered_events ordered_events
Definition: session.h:35
const char * vmlinux_name
Definition: symbol.h:123
static void stats_setup(struct report *rep)
const char * perf_tip(const char *dirpath)
Definition: util.c:482
u32 flags
Definition: map.h:33
bool show_full_info
u64 pgoff
Definition: map.h:34
pid_t pid_
Definition: thread.h:24
struct kmap * map__kmap(struct map *map)
Definition: map.c:881
struct thread * thread
static LIST_HEAD(page_alloc_sort_input)
bool cumulate_callchain
Definition: symbol.h:93
enum sort_mode sort__mode
Definition: sort.c:31
size_t size
Definition: evsel.c:60
int ui__error(const char *format,...)
Definition: util.c:32
#define CALLCHAIN_REPORT_HELP
Definition: callchain.h:25
int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, struct perf_evsel *evsel, u64 ip)
Definition: annotate.c:1022
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, struct hist_browser_timer *hbt, float min_pcnt, struct perf_env *env, bool warn_lost_event, struct annotation_options *annotation_opts)
Definition: hists.c:3266
void * perf_gtk_handle
Definition: setup.c:11
static int stats_print(struct report *rep)
struct machine host
Definition: machine.h:136
int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1385
int hists__link(struct hists *leader, struct hists *other)
Definition: hist.c:2374
u64 feat_id
Definition: event.h:619
struct feature_event feat
Definition: event.h:653
pid_t ppid
Definition: thread.h:26
Definition: hist.h:106
unsigned int callchain_sz
Definition: auxtrace.h:96
Definition: map.h:52
dictionary data
Definition: stat-cpi.py:4
int ui__warning(const char *format,...)
Definition: util.c:44
u64 last_sample_time
Definition: evlist.h:53
static int report__gtk_browse_hists(struct report *rep, const char *help)
int int err
Definition: 5sec.c:44
int hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
Definition: hist.c:1464
int perf_event__process_feature(struct perf_tool *tool, union perf_event *event, struct perf_session *session __maybe_unused)
Definition: header.c:3446
int perf_config_bool(const char *name, const char *value)
Definition: config.c:389
struct perf_time_interval * perf_time__range_alloc(const char *ostr, int *size)
Definition: time-utils.c:328
u32 pid
Definition: event.h:73
static void report__warn_kptr_restrict(const struct report *rep)
bool perf_evlist__exclude_kernel(struct perf_evlist *evlist)
Definition: evlist.c:1787
struct list_head list
struct itrace_synth_opts * itrace_synth_opts
Definition: session.h:27
struct perf_data_file file
Definition: data.h:18
const char * tid_list_str
Definition: symbol.h:131
struct list_head children
enum perf_call_graph_mode record_mode
Definition: callchain.h:96
enum chain_value value
Definition: callchain.h:107
struct annotation_options annotation_opts
struct perf_env env
Definition: header.h:82
static int hist_iter__report_callback(struct hist_entry_iter *iter, struct addr_location *al, bool single, void *arg)
size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp)
Definition: session.c:2005
size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
Definition: session.c:2030
struct addr_map_symbol daddr
Definition: symbol.h:202
int perf_event__process_comm(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1273
struct rb_root entries
Definition: machine.h:32
int perf_event__process_exit(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1416
static struct hists * evsel__hists(struct perf_evsel *evsel)
Definition: hist.h:217
static int report__setup_sample_type(struct report *rep)
struct branch_flags flags
Definition: symbol.h:195
int perf_event__process_fork(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1408
bool use_modules
Definition: symbol.h:93
u8 hit
Definition: dso.h:162
bool filter_relative
Definition: symbol.h:93
int idx
Definition: evsel.h:100
bool force
Definition: symbol.h:93
bool group_set
int perf_event__process_build_id(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: header.c:3922
bool srcline_full_filename
Definition: srcline.c:17
bool nonany_branch_mode
bool use_gtk
static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
#define pr_err(fmt,...)
Definition: json.h:21
bool perf_time__ranges_skip_sample(struct perf_time_interval *ptime_buf, int num, u64 timestamp)
Definition: time-utils.c:371
static void tasks_setup(struct report *rep)
struct hist_entry * he
Definition: hist.h:114
void perf_session__delete(struct perf_session *session)
Definition: session.c:187
int use_browser
Definition: setup.c:12
#define session_done()
Definition: session.h:117
Definition: sort.h:89
u64 start
Definition: map.h:28
struct rb_root entries
Definition: map.h:59
bool branch_callstack
Definition: callchain.h:106
struct trace_event tevent
Definition: session.h:29
int perf_quiet_option(void)
Definition: debug.c:225
enum chain_mode mode
Definition: callchain.h:98
void * malloc(YYSIZE_T)
bool show_nr_samples
Definition: symbol.h:93
u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist)
Definition: evlist.c:1260
struct perf_time_interval * ptime_range
static struct map * machine__kernel_map(struct machine *machine)
Definition: machine.h:72
struct thread * machine__find_thread(struct machine *machine, pid_t pid, pid_t tid)
Definition: machine.c:504
static void report__output_resort(struct report *rep)
void addr_location__put(struct addr_location *al)
Definition: event.c:1661
int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
Definition: evsel.c:635
struct map * map
Definition: symbol.h:210
int max_stack
Definition: thread.h:18
void setup_browser(bool fallback_to_pager)
Definition: setup.c:76
int symbol__config_symfs(const struct option *opt __maybe_unused, const char *dir, int unset __maybe_unused)
Definition: symbol.c:2205
const char * name
const char * field_order
Definition: sort.c:28
bool dwarf_callchain_users
Definition: callchain.c:47
const char * objdump_path
Definition: annotate.h:83
const char * thread__comm_str(const struct thread *thread)
Definition: thread.c:258
char name[0]
Definition: dso.h:197
static struct perf_evsel * hists_to_evsel(struct hists *hists)
Definition: hist.h:211
struct perf_evlist * evlist
Definition: evsel.h:92
int parse_callchain_report_opt(const char *arg)
Definition: callchain.c:233
bool header_only
unsigned short priv_size
Definition: symbol.h:92
#define pr_debug(fmt,...)
Definition: json.h:27
Definition: tool.h:44
bool header
static int tasks_print(struct report *rep, FILE *fp)
int range_num
u64 nr_entries
Definition: hist.h:76
bool mem_mode
#define evlist__for_each_entry(evlist, evsel)
Definition: evlist.h:247
struct perf_read_values show_threads_values
void sort__setup_elide(FILE *output)
Definition: sort.c:2812
struct perf_session * session
struct threads threads[THREADS__TABLE_SIZE]
Definition: machine.h:47
struct read_event read
Definition: event.h:632
const char * default_sort_order
Definition: sort.c:21
u32 nr_non_filtered_samples
Definition: event.h:408
u64 queue_size
float min_percent
struct dso * dso
Definition: map.h:45
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS)
u64 total_lost_samples
Definition: event.h:403
u64 value
Definition: event.h:74
u64 total_period
Definition: event.h:400
struct perf_tool tool
event_op exit
Definition: tool.h:47
bool tasks_mode
int itrace_parse_synth_opts(const struct option *opt, const char *str, int unset)
Definition: auxtrace.c:981
const char * parent_pattern
Definition: sort.c:20
unsigned long convert_unit(unsigned long value, char *unit)
Definition: units.c:36
pid_t tid
Definition: thread.h:25
static int str(yyscan_t scanner, int token)
int perf_config_u64(u64 *dest, const char *name, const char *value)
Definition: config.c:348
int symbol__annotation_init(void)
Definition: symbol.c:2097
bool hide_unresolved
Definition: symbol.h:93
const char * input_name
Definition: perf.c:40
static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep, const char *evname, FILE *fp)
unsigned int nr
Definition: machine.h:34
bool stats_mode
int need_collapse
Definition: hist.h:274
int range_size
void perf_read_values_display(FILE *fp, struct perf_read_values *values, int raw)
Definition: values.c:298
static void task__print_level(struct task *task, FILE *fp, int level)
bool ordered_events
Definition: tool.h:76
const char default_mem_sort_order[]
Definition: sort.c:23
struct symbol * sym
Definition: symbol.h:211
Definition: map.h:58
const char * pid_list_str
Definition: symbol.h:131
const char * cpu_list
#define ui_progress__init(p, total, title)
Definition: progress.h:18
int parent
Definition: hist.h:275
#define event
s64 perf_event__process_auxtrace(struct perf_tool *tool, union perf_event *event, struct perf_session *session)
Definition: auxtrace.c:929
const char * symbol_filter_str
Definition: hist.h:83
int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: auxtrace.c:905
struct branch_stack * branch_stack
Definition: event.h:212
const char * field_sep
Definition: symbol.h:123
void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
Definition: branch.c:62
u32 cpu
Definition: event.h:201
Definition: map.h:63
const char * pretty_printing_style
struct ref_reloc_sym * ref_reloc_sym
Definition: map.h:53
Definition: data.h:17
const char * disassembler_style
Definition: annotate.h:84
int hists__init(void)
Definition: hist.c:2629
bool inline_name
Definition: symbol.h:93
int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: header.c:3854
bool map__has_symbols(const struct map *map)
Definition: map.c:262
u32 tid
Definition: event.h:73
bool show_ref_callgraph
Definition: symbol.h:93
const char * dso_list_str
Definition: symbol.h:131
bool no_warn
Definition: tool.h:79
bool show_threads
int report_parse_ignore_callees_opt(const struct option *opt __maybe_unused, const char *arg, int unset __maybe_unused)
static int process_read_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample __maybe_unused, struct perf_evsel *evsel, struct machine *machine __maybe_unused)
static struct task * tasks_list(struct task *task, struct machine *machine)
#define zfree(ptr)
Definition: util.h:25
const char * perf_evsel__name(struct perf_evsel *evsel)
Definition: evsel.c:577
double min_percent
Definition: callchain.h:101
static int report__config(const char *var, const char *value, void *cb)
void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags, u64 from, u64 to)
Definition: branch.c:19
bool ui__has_annotation(void)
Definition: annotate.c:2438
const struct hist_iter_ops hist_iter_mem
Definition: hist.c:1004
struct perf_event_header header
Definition: event.h:624
static int hist_iter__branch_callback(struct hist_entry_iter *iter, struct addr_location *al __maybe_unused, bool single __maybe_unused, void *arg)
struct rb_node rb_node
Definition: map.h:25
int perf_read_values_init(struct perf_read_values *values)
Definition: values.c:11
#define CALLCHAIN_DEFAULT_OPT
static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
void ui_progress__finish(void)
Definition: progress.c:44
const struct hist_iter_ops hist_iter_normal
Definition: hist.c:1020
const char * desc
Definition: clang.c:10
static int perf_data__is_pipe(struct perf_data *data)
Definition: data.h:35
struct branch_info * branch_info
Definition: sort.h:134
void hist__account_cycles(struct branch_stack *bs, struct addr_location *al, struct perf_sample *sample, bool nonany_branch_mode)
Definition: hist.c:2406
struct perf_session * perf_session__new(struct perf_data *data, bool repipe, struct perf_tool *tool)
Definition: session.c:116
struct mem_info * mem_info
Definition: sort.h:136
int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1393
const char * kallsyms_name
Definition: symbol.h:123
void perf_evlist__force_leader(struct perf_evlist *evlist)
Definition: evlist.c:1804
#define for_each_group_member(_evsel, _leader)
Definition: evsel.h:452
struct annotation_options annotation__default_options
Definition: annotate.c:47
bool perf_header__has_feat(const struct perf_header *header, int feat)
Definition: header.c:86
int perf_time__percent_parse_str(struct perf_time_interval *ptime_buf, int num, const char *ostr, u64 start, u64 end)
Definition: time-utils.c:295
Definition: jevents.c:228
bool use_callchain
Definition: symbol.h:93
unsigned long * cpu_bitmap
Definition: auxtrace.h:101
int socket_filter
Definition: hist.h:88
int perf_config(config_fn_t fn, void *data)
Definition: config.c:718
int perf_session__process_events(struct perf_session *session)
Definition: session.c:1945
void hists__match(struct hists *leader, struct hists *other)
Definition: hist.c:2299
bool inverted_callchain
bool demangle
Definition: symbol.h:93
struct perf_evsel * leader
Definition: evsel.h:136
bool sort_by_name
Definition: symbol.h:93
regex_t ignore_callees_regex
Definition: sort.c:29
enum chain_order order
Definition: callchain.h:103
u64 time
Definition: event.h:194
bool show_branchflag_count
Definition: symbol.h:93
struct events_stats stats
Definition: evlist.h:50
struct perf_evsel * evsel
Definition: hist.h:112
u64 perf_evlist__combined_branch_type(struct perf_evlist *evlist)
Definition: evlist.c:1266
bool ignore_vmlinux
Definition: symbol.h:93
bool raw_trace
Definition: symbol.h:93
struct perf_header header
Definition: session.h:23
size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp)
Definition: hist.c:2440
static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, struct report *rep, const char *help)
event_op comm
Definition: tool.h:47
bool dump_trace
Definition: debug.c:27
int symbol__init(struct perf_env *env)
Definition: symbol.c:2112
bool use_stdio
const struct hist_iter_ops hist_iter_cumulative
Definition: hist.c:1028
void free(void *)
int perf_event__process_id_index(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_session *session)
Definition: session.c:2136
const char * sym_list_str
Definition: symbol.h:131
struct pevent * pevent
Definition: trace-event.h:16
struct addr_map_symbol to
Definition: symbol.h:194
int nr_members
Definition: evsel.h:133
#define THREADS__TABLE_SIZE
Definition: machine.h:29
struct addr_map_symbol from
Definition: symbol.h:193
struct events_stats stats
Definition: hist.h:85
const struct hist_iter_ops hist_iter_branch
Definition: hist.c:1012
u32 nr_events[PERF_RECORD_HEADER_MAX]
Definition: event.h:407
static bool perf_evsel__is_group_event(struct perf_evsel *evsel)
Definition: evsel.h:393
static bool perf_evsel__is_group_leader(const struct perf_evsel *evsel)
Definition: evsel.h:380
#define MAX_NR_CPUS
Definition: perf.h:27
bool use_tui
bool demangle_kernel
Definition: symbol.h:93
static void thread__set_priv(struct thread *thread, void *p)
Definition: thread.h:109
int perf_event__process_lost(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1289
void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog)
Definition: hist.c:1756
int verbose
Definition: jevents.c:53
void annotation_config__init(void)
Definition: annotate.c:2788
const struct hist_iter_ops * ops
Definition: hist.h:118
static int parse_branch_mode(const struct option *opt, const char *str __maybe_unused, int unset)
#define K_SWITCH_INPUT_DATA
Definition: keysyms.h:27
u64 first_sample_time
Definition: evlist.h:52
u64 nr_entries
static void sig_handler(int sig __maybe_unused)
int parse_filter_percentage(const struct option *opt __maybe_unused, const char *arg, int unset __maybe_unused)
Definition: hist.c:2539
char * machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp)
Definition: machine.c:2501
static int map_groups__fprintf_task(struct map_groups *mg, int indent, FILE *fp)
int have_ignore_callees
Definition: sort.c:30
int perf_session__cpu_bitmap(struct perf_session *session, const char *cpu_list, unsigned long *cpu_bitmap)
Definition: session.c:2051
static int report__collapse_hists(struct report *rep)
event_op fork
Definition: tool.h:47
Definition: hist.h:71
u32 prot
Definition: map.h:32
u64 total_non_filtered_period
Definition: event.h:401
void perf_session__fprintf_info(struct perf_session *session, FILE *fp, bool full)
Definition: session.c:2096
bool force
Definition: data.h:20
u64 ino
Definition: map.h:37
int socket_filter
event_op mmap
Definition: tool.h:47
const char * sort_order
Definition: sort.c:27
int perf_event__process_namespaces(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
Definition: event.c:1281
const char * symbol_filter_str
int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, struct perf_evsel *evsel)
Definition: annotate.c:1016
size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, int max_cols, float min_pcnt, FILE *fp, bool use_callchain)
Definition: hist.c:756
bool show_total_period
Definition: symbol.h:93
int callchain_register_param(struct callchain_param *param)
Definition: callchain.c:494
u64 end
Definition: map.h:29
const char * time_str
void(* timer)(void *arg)
Definition: hist.h:423
const char * path
Definition: data.h:13
struct machines machines
Definition: session.h:24
int perf_time__parse_str(struct perf_time_interval *ptime, const char *ostr)
Definition: time-utils.c:91
void perf_read_values_destroy(struct perf_read_values *values)
Definition: values.c:46
bool report_hierarchy
Definition: symbol.h:93
bool show_cpu_utilization
Definition: symbol.h:93
static int process_feature_event(struct perf_tool *tool, union perf_event *event, struct perf_session *session __maybe_unused)
enum chain_key key
Definition: callchain.h:105
int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, int max_stack_depth, void *arg)
Definition: hist.c:1036
event_sample sample
Definition: tool.h:45
static void * thread__priv(struct thread *thread)
Definition: thread.h:104
static int __cmd_report(struct report *rep)
bool quiet
Definition: builtin-probe.c:54