linux/tools/perf/builtin-report.c
<<
>>
Prefs
   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/config.h"
  12
  13#include "util/annotate.h"
  14#include "util/color.h"
  15#include "util/dso.h"
  16#include <linux/list.h>
  17#include <linux/rbtree.h>
  18#include <linux/err.h>
  19#include <linux/zalloc.h>
  20#include "util/map.h"
  21#include "util/symbol.h"
  22#include "util/map_symbol.h"
  23#include "util/mem-events.h"
  24#include "util/branch.h"
  25#include "util/callchain.h"
  26#include "util/values.h"
  27
  28#include "perf.h"
  29#include "util/debug.h"
  30#include "util/evlist.h"
  31#include "util/evsel.h"
  32#include "util/evswitch.h"
  33#include "util/header.h"
  34#include "util/session.h"
  35#include "util/srcline.h"
  36#include "util/tool.h"
  37
  38#include <subcmd/parse-options.h>
  39#include <subcmd/exec-cmd.h>
  40#include "util/parse-events.h"
  41
  42#include "util/thread.h"
  43#include "util/sort.h"
  44#include "util/hist.h"
  45#include "util/data.h"
  46#include "arch/common.h"
  47#include "util/time-utils.h"
  48#include "util/auxtrace.h"
  49#include "util/units.h"
  50#include "util/util.h" // perf_tip()
  51#include "ui/ui.h"
  52#include "ui/progress.h"
  53#include "util/block-info.h"
  54
  55#include <dlfcn.h>
  56#include <errno.h>
  57#include <inttypes.h>
  58#include <regex.h>
  59#include <linux/ctype.h>
  60#include <signal.h>
  61#include <linux/bitmap.h>
  62#include <linux/string.h>
  63#include <linux/stringify.h>
  64#include <linux/time64.h>
  65#include <sys/types.h>
  66#include <sys/stat.h>
  67#include <unistd.h>
  68#include <linux/mman.h>
  69
  70struct report {
  71        struct perf_tool        tool;
  72        struct perf_session     *session;
  73        struct evswitch         evswitch;
  74        bool                    use_tui, use_gtk, use_stdio;
  75        bool                    show_full_info;
  76        bool                    show_threads;
  77        bool                    inverted_callchain;
  78        bool                    mem_mode;
  79        bool                    stats_mode;
  80        bool                    tasks_mode;
  81        bool                    mmaps_mode;
  82        bool                    header;
  83        bool                    header_only;
  84        bool                    nonany_branch_mode;
  85        bool                    group_set;
  86        bool                    stitch_lbr;
  87        int                     max_stack;
  88        struct perf_read_values show_threads_values;
  89        struct annotation_options annotation_opts;
  90        const char              *pretty_printing_style;
  91        const char              *cpu_list;
  92        const char              *symbol_filter_str;
  93        const char              *time_str;
  94        struct perf_time_interval *ptime_range;
  95        int                     range_size;
  96        int                     range_num;
  97        float                   min_percent;
  98        u64                     nr_entries;
  99        u64                     queue_size;
 100        u64                     total_cycles;
 101        int                     socket_filter;
 102        DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 103        struct branch_type_stat brtype_stat;
 104        bool                    symbol_ipc;
 105        bool                    total_cycles_mode;
 106        struct block_report     *block_reports;
 107        int                     nr_block_reports;
 108};
 109
 110static int report__config(const char *var, const char *value, void *cb)
 111{
 112        struct report *rep = cb;
 113
 114        if (!strcmp(var, "report.group")) {
 115                symbol_conf.event_group = perf_config_bool(var, value);
 116                return 0;
 117        }
 118        if (!strcmp(var, "report.percent-limit")) {
 119                double pcnt = strtof(value, NULL);
 120
 121                rep->min_percent = pcnt;
 122                callchain_param.min_percent = pcnt;
 123                return 0;
 124        }
 125        if (!strcmp(var, "report.children")) {
 126                symbol_conf.cumulate_callchain = perf_config_bool(var, value);
 127                return 0;
 128        }
 129        if (!strcmp(var, "report.queue-size"))
 130                return perf_config_u64(&rep->queue_size, var, value);
 131
 132        if (!strcmp(var, "report.sort_order")) {
 133                default_sort_order = strdup(value);
 134                return 0;
 135        }
 136
 137        return 0;
 138}
 139
 140static int hist_iter__report_callback(struct hist_entry_iter *iter,
 141                                      struct addr_location *al, bool single,
 142                                      void *arg)
 143{
 144        int err = 0;
 145        struct report *rep = arg;
 146        struct hist_entry *he = iter->he;
 147        struct evsel *evsel = iter->evsel;
 148        struct perf_sample *sample = iter->sample;
 149        struct mem_info *mi;
 150        struct branch_info *bi;
 151
 152        if (!ui__has_annotation() && !rep->symbol_ipc)
 153                return 0;
 154
 155        if (sort__mode == SORT_MODE__BRANCH) {
 156                bi = he->branch_info;
 157                err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
 158                if (err)
 159                        goto out;
 160
 161                err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
 162
 163        } else if (rep->mem_mode) {
 164                mi = he->mem_info;
 165                err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel);
 166                if (err)
 167                        goto out;
 168
 169                err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
 170
 171        } else if (symbol_conf.cumulate_callchain) {
 172                if (single)
 173                        err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
 174        } else {
 175                err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr);
 176        }
 177
 178out:
 179        return err;
 180}
 181
 182static int hist_iter__branch_callback(struct hist_entry_iter *iter,
 183                                      struct addr_location *al __maybe_unused,
 184                                      bool single __maybe_unused,
 185                                      void *arg)
 186{
 187        struct hist_entry *he = iter->he;
 188        struct report *rep = arg;
 189        struct branch_info *bi = he->branch_info;
 190        struct perf_sample *sample = iter->sample;
 191        struct evsel *evsel = iter->evsel;
 192        int err;
 193
 194        branch_type_count(&rep->brtype_stat, &bi->flags,
 195                          bi->from.addr, bi->to.addr);
 196
 197        if (!ui__has_annotation() && !rep->symbol_ipc)
 198                return 0;
 199
 200        err = addr_map_symbol__inc_samples(&bi->from, sample, evsel);
 201        if (err)
 202                goto out;
 203
 204        err = addr_map_symbol__inc_samples(&bi->to, sample, evsel);
 205
 206out:
 207        return err;
 208}
 209
 210static void setup_forced_leader(struct report *report,
 211                                struct evlist *evlist)
 212{
 213        if (report->group_set)
 214                perf_evlist__force_leader(evlist);
 215}
 216
 217static int process_feature_event(struct perf_session *session,
 218                                 union perf_event *event)
 219{
 220        struct report *rep = container_of(session->tool, struct report, tool);
 221
 222        if (event->feat.feat_id < HEADER_LAST_FEATURE)
 223                return perf_event__process_feature(session, event);
 224
 225        if (event->feat.feat_id != HEADER_LAST_FEATURE) {
 226                pr_err("failed: wrong feature ID: %" PRI_lu64 "\n",
 227                       event->feat.feat_id);
 228                return -1;
 229        }
 230
 231        /*
 232         * (feat_id = HEADER_LAST_FEATURE) is the end marker which
 233         * means all features are received, now we can force the
 234         * group if needed.
 235         */
 236        setup_forced_leader(rep, session->evlist);
 237        return 0;
 238}
 239
 240static int process_sample_event(struct perf_tool *tool,
 241                                union perf_event *event,
 242                                struct perf_sample *sample,
 243                                struct evsel *evsel,
 244                                struct machine *machine)
 245{
 246        struct report *rep = container_of(tool, struct report, tool);
 247        struct addr_location al;
 248        struct hist_entry_iter iter = {
 249                .evsel                  = evsel,
 250                .sample                 = sample,
 251                .hide_unresolved        = symbol_conf.hide_unresolved,
 252                .add_entry_cb           = hist_iter__report_callback,
 253        };
 254        int ret = 0;
 255
 256        if (perf_time__ranges_skip_sample(rep->ptime_range, rep->range_num,
 257                                          sample->time)) {
 258                return 0;
 259        }
 260
 261        if (evswitch__discard(&rep->evswitch, evsel))
 262                return 0;
 263
 264        if (machine__resolve(machine, &al, sample) < 0) {
 265                pr_debug("problem processing %d event, skipping it.\n",
 266                         event->header.type);
 267                return -1;
 268        }
 269
 270        if (rep->stitch_lbr)
 271                al.thread->lbr_stitch_enable = true;
 272
 273        if (symbol_conf.hide_unresolved && al.sym == NULL)
 274                goto out_put;
 275
 276        if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
 277                goto out_put;
 278
 279        if (sort__mode == SORT_MODE__BRANCH) {
 280                /*
 281                 * A non-synthesized event might not have a branch stack if
 282                 * branch stacks have been synthesized (using itrace options).
 283                 */
 284                if (!sample->branch_stack)
 285                        goto out_put;
 286
 287                iter.add_entry_cb = hist_iter__branch_callback;
 288                iter.ops = &hist_iter_branch;
 289        } else if (rep->mem_mode) {
 290                iter.ops = &hist_iter_mem;
 291        } else if (symbol_conf.cumulate_callchain) {
 292                iter.ops = &hist_iter_cumulative;
 293        } else {
 294                iter.ops = &hist_iter_normal;
 295        }
 296
 297        if (al.map != NULL)
 298                al.map->dso->hit = 1;
 299
 300        if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) {
 301                hist__account_cycles(sample->branch_stack, &al, sample,
 302                                     rep->nonany_branch_mode,
 303                                     &rep->total_cycles);
 304        }
 305
 306        ret = hist_entry_iter__add(&iter, &al, rep->max_stack, rep);
 307        if (ret < 0)
 308                pr_debug("problem adding hist entry, skipping event\n");
 309out_put:
 310        addr_location__put(&al);
 311        return ret;
 312}
 313
 314static int process_read_event(struct perf_tool *tool,
 315                              union perf_event *event,
 316                              struct perf_sample *sample __maybe_unused,
 317                              struct evsel *evsel,
 318                              struct machine *machine __maybe_unused)
 319{
 320        struct report *rep = container_of(tool, struct report, tool);
 321
 322        if (rep->show_threads) {
 323                const char *name = evsel__name(evsel);
 324                int err = perf_read_values_add_value(&rep->show_threads_values,
 325                                           event->read.pid, event->read.tid,
 326                                           evsel->idx,
 327                                           name,
 328                                           event->read.value);
 329
 330                if (err)
 331                        return err;
 332        }
 333
 334        return 0;
 335}
 336
 337/* For pipe mode, sample_type is not currently set */
 338static int report__setup_sample_type(struct report *rep)
 339{
 340        struct perf_session *session = rep->session;
 341        u64 sample_type = evlist__combined_sample_type(session->evlist);
 342        bool is_pipe = perf_data__is_pipe(session->data);
 343
 344        if (session->itrace_synth_opts->callchain ||
 345            session->itrace_synth_opts->add_callchain ||
 346            (!is_pipe &&
 347             perf_header__has_feat(&session->header, HEADER_AUXTRACE) &&
 348             !session->itrace_synth_opts->set))
 349                sample_type |= PERF_SAMPLE_CALLCHAIN;
 350
 351        if (session->itrace_synth_opts->last_branch ||
 352            session->itrace_synth_opts->add_last_branch)
 353                sample_type |= PERF_SAMPLE_BRANCH_STACK;
 354
 355        if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
 356                if (perf_hpp_list.parent) {
 357                        ui__error("Selected --sort parent, but no "
 358                                    "callchain data. Did you call "
 359                                    "'perf record' without -g?\n");
 360                        return -EINVAL;
 361                }
 362                if (symbol_conf.use_callchain &&
 363                        !symbol_conf.show_branchflag_count) {
 364                        ui__error("Selected -g or --branch-history.\n"
 365                                  "But no callchain or branch data.\n"
 366                                  "Did you call 'perf record' without -g or -b?\n");
 367                        return -1;
 368                }
 369        } else if (!callchain_param.enabled &&
 370                   callchain_param.mode != CHAIN_NONE &&
 371                   !symbol_conf.use_callchain) {
 372                        symbol_conf.use_callchain = true;
 373                        if (callchain_register_param(&callchain_param) < 0) {
 374                                ui__error("Can't register callchain params.\n");
 375                                return -EINVAL;
 376                        }
 377        }
 378
 379        if (symbol_conf.cumulate_callchain) {
 380                /* Silently ignore if callchain is missing */
 381                if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
 382                        symbol_conf.cumulate_callchain = false;
 383                        perf_hpp__cancel_cumulate();
 384                }
 385        }
 386
 387        if (sort__mode == SORT_MODE__BRANCH) {
 388                if (!is_pipe &&
 389                    !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
 390                        ui__error("Selected -b but no branch data. "
 391                                  "Did you call perf record without -b?\n");
 392                        return -1;
 393                }
 394        }
 395
 396        if (sort__mode == SORT_MODE__MEMORY) {
 397                if (!is_pipe && !(sample_type & PERF_SAMPLE_DATA_SRC)) {
 398                        ui__error("Selected --mem-mode but no mem data. "
 399                                  "Did you call perf record without -d?\n");
 400                        return -1;
 401                }
 402        }
 403
 404        callchain_param_setup(sample_type);
 405
 406        if (rep->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) {
 407                ui__warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
 408                            "Please apply --call-graph lbr when recording.\n");
 409                rep->stitch_lbr = false;
 410        }
 411
 412        /* ??? handle more cases than just ANY? */
 413        if (!(evlist__combined_branch_type(session->evlist) & PERF_SAMPLE_BRANCH_ANY))
 414                rep->nonany_branch_mode = true;
 415
 416#if !defined(HAVE_LIBUNWIND_SUPPORT) && !defined(HAVE_DWARF_SUPPORT)
 417        if (dwarf_callchain_users) {
 418                ui__warning("Please install libunwind or libdw "
 419                            "development packages during the perf build.\n");
 420        }
 421#endif
 422
 423        return 0;
 424}
 425
 426static void sig_handler(int sig __maybe_unused)
 427{
 428        session_done = 1;
 429}
 430
 431static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report *rep,
 432                                              const char *evname, FILE *fp)
 433{
 434        size_t ret;
 435        char unit;
 436        unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
 437        u64 nr_events = hists->stats.total_period;
 438        struct evsel *evsel = hists_to_evsel(hists);
 439        char buf[512];
 440        size_t size = sizeof(buf);
 441        int socked_id = hists->socket_filter;
 442
 443        if (quiet)
 444                return 0;
 445
 446        if (symbol_conf.filter_relative) {
 447                nr_samples = hists->stats.nr_non_filtered_samples;
 448                nr_events = hists->stats.total_non_filtered_period;
 449        }
 450
 451        if (evsel__is_group_event(evsel)) {
 452                struct evsel *pos;
 453
 454                evsel__group_desc(evsel, buf, size);
 455                evname = buf;
 456
 457                for_each_group_member(pos, evsel) {
 458                        const struct hists *pos_hists = evsel__hists(pos);
 459
 460                        if (symbol_conf.filter_relative) {
 461                                nr_samples += pos_hists->stats.nr_non_filtered_samples;
 462                                nr_events += pos_hists->stats.total_non_filtered_period;
 463                        } else {
 464                                nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
 465                                nr_events += pos_hists->stats.total_period;
 466                        }
 467                }
 468        }
 469
 470        nr_samples = convert_unit(nr_samples, &unit);
 471        ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
 472        if (evname != NULL) {
 473                ret += fprintf(fp, " of event%s '%s'",
 474                               evsel->core.nr_members > 1 ? "s" : "", evname);
 475        }
 476
 477        if (rep->time_str)
 478                ret += fprintf(fp, " (time slices: %s)", rep->time_str);
 479
 480        if (symbol_conf.show_ref_callgraph && evname && strstr(evname, "call-graph=no")) {
 481                ret += fprintf(fp, ", show reference callgraph");
 482        }
 483
 484        if (rep->mem_mode) {
 485                ret += fprintf(fp, "\n# Total weight : %" PRIu64, nr_events);
 486                ret += fprintf(fp, "\n# Sort order   : %s", sort_order ? : default_mem_sort_order);
 487        } else
 488                ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
 489
 490        if (socked_id > -1)
 491                ret += fprintf(fp, "\n# Processor Socket: %d", socked_id);
 492
 493        return ret + fprintf(fp, "\n#\n");
 494}
 495
 496static int perf_evlist__tui_block_hists_browse(struct evlist *evlist,
 497                                               struct report *rep)
 498{
 499        struct evsel *pos;
 500        int i = 0, ret;
 501
 502        evlist__for_each_entry(evlist, pos) {
 503                ret = report__browse_block_hists(&rep->block_reports[i++].hist,
 504                                                 rep->min_percent, pos,
 505                                                 &rep->session->header.env,
 506                                                 &rep->annotation_opts);
 507                if (ret != 0)
 508                        return ret;
 509        }
 510
 511        return 0;
 512}
 513
 514static int perf_evlist__tty_browse_hists(struct evlist *evlist,
 515                                         struct report *rep,
 516                                         const char *help)
 517{
 518        struct evsel *pos;
 519        int i = 0;
 520
 521        if (!quiet) {
 522                fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n",
 523                        evlist->stats.total_lost_samples);
 524        }
 525
 526        evlist__for_each_entry(evlist, pos) {
 527                struct hists *hists = evsel__hists(pos);
 528                const char *evname = evsel__name(pos);
 529
 530                if (symbol_conf.event_group && !evsel__is_group_leader(pos))
 531                        continue;
 532
 533                hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
 534
 535                if (rep->total_cycles_mode) {
 536                        report__browse_block_hists(&rep->block_reports[i++].hist,
 537                                                   rep->min_percent, pos,
 538                                                   NULL, NULL);
 539                        continue;
 540                }
 541
 542                hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
 543                               !(symbol_conf.use_callchain ||
 544                                 symbol_conf.show_branchflag_count));
 545                fprintf(stdout, "\n\n");
 546        }
 547
 548        if (!quiet)
 549                fprintf(stdout, "#\n# (%s)\n#\n", help);
 550
 551        if (rep->show_threads) {
 552                bool style = !strcmp(rep->pretty_printing_style, "raw");
 553                perf_read_values_display(stdout, &rep->show_threads_values,
 554                                         style);
 555                perf_read_values_destroy(&rep->show_threads_values);
 556        }
 557
 558        if (sort__mode == SORT_MODE__BRANCH)
 559                branch_type_stat_display(stdout, &rep->brtype_stat);
 560
 561        return 0;
 562}
 563
 564static void report__warn_kptr_restrict(const struct report *rep)
 565{
 566        struct map *kernel_map = machine__kernel_map(&rep->session->machines.host);
 567        struct kmap *kernel_kmap = kernel_map ? map__kmap(kernel_map) : NULL;
 568
 569        if (perf_evlist__exclude_kernel(rep->session->evlist))
 570                return;
 571
 572        if (kernel_map == NULL ||
 573            (kernel_map->dso->hit &&
 574             (kernel_kmap->ref_reloc_sym == NULL ||
 575              kernel_kmap->ref_reloc_sym->addr == 0))) {
 576                const char *desc =
 577                    "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
 578                    "can't be resolved.";
 579
 580                if (kernel_map && map__has_symbols(kernel_map)) {
 581                        desc = "If some relocation was applied (e.g. "
 582                               "kexec) symbols may be misresolved.";
 583                }
 584
 585                ui__warning(
 586"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
 587"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
 588"Samples in kernel modules can't be resolved as well.\n\n",
 589                desc);
 590        }
 591}
 592
 593static int report__gtk_browse_hists(struct report *rep, const char *help)
 594{
 595        int (*hist_browser)(struct evlist *evlist, const char *help,
 596                            struct hist_browser_timer *timer, float min_pcnt);
 597
 598        hist_browser = dlsym(perf_gtk_handle, "perf_evlist__gtk_browse_hists");
 599
 600        if (hist_browser == NULL) {
 601                ui__error("GTK browser not found!\n");
 602                return -1;
 603        }
 604
 605        return hist_browser(rep->session->evlist, help, NULL, rep->min_percent);
 606}
 607
 608static int report__browse_hists(struct report *rep)
 609{
 610        int ret;
 611        struct perf_session *session = rep->session;
 612        struct evlist *evlist = session->evlist;
 613        const char *help = perf_tip(system_path(TIPDIR));
 614
 615        if (help == NULL) {
 616                /* fallback for people who don't install perf ;-) */
 617                help = perf_tip(DOCDIR);
 618                if (help == NULL)
 619                        help = "Cannot load tips.txt file, please install perf!";
 620        }
 621
 622        switch (use_browser) {
 623        case 1:
 624                if (rep->total_cycles_mode) {
 625                        ret = perf_evlist__tui_block_hists_browse(evlist, rep);
 626                        break;
 627                }
 628
 629                ret = perf_evlist__tui_browse_hists(evlist, help, NULL,
 630                                                    rep->min_percent,
 631                                                    &session->header.env,
 632                                                    true, &rep->annotation_opts);
 633                /*
 634                 * Usually "ret" is the last pressed key, and we only
 635                 * care if the key notifies us to switch data file.
 636                 */
 637                if (ret != K_SWITCH_INPUT_DATA && ret != K_RELOAD)
 638                        ret = 0;
 639                break;
 640        case 2:
 641                ret = report__gtk_browse_hists(rep, help);
 642                break;
 643        default:
 644                ret = perf_evlist__tty_browse_hists(evlist, rep, help);
 645                break;
 646        }
 647
 648        return ret;
 649}
 650
 651static int report__collapse_hists(struct report *rep)
 652{
 653        struct ui_progress prog;
 654        struct evsel *pos;
 655        int ret = 0;
 656
 657        ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
 658
 659        evlist__for_each_entry(rep->session->evlist, pos) {
 660                struct hists *hists = evsel__hists(pos);
 661
 662                if (pos->idx == 0)
 663                        hists->symbol_filter_str = rep->symbol_filter_str;
 664
 665                hists->socket_filter = rep->socket_filter;
 666
 667                ret = hists__collapse_resort(hists, &prog);
 668                if (ret < 0)
 669                        break;
 670
 671                /* Non-group events are considered as leader */
 672                if (symbol_conf.event_group && !evsel__is_group_leader(pos)) {
 673                        struct hists *leader_hists = evsel__hists(pos->leader);
 674
 675                        hists__match(leader_hists, hists);
 676                        hists__link(leader_hists, hists);
 677                }
 678        }
 679
 680        ui_progress__finish();
 681        return ret;
 682}
 683
 684static int hists__resort_cb(struct hist_entry *he, void *arg)
 685{
 686        struct report *rep = arg;
 687        struct symbol *sym = he->ms.sym;
 688
 689        if (rep->symbol_ipc && sym && !sym->annotate2) {
 690                struct evsel *evsel = hists_to_evsel(he->hists);
 691
 692                symbol__annotate2(&he->ms, evsel,
 693                                  &annotation__default_options, NULL);
 694        }
 695
 696        return 0;
 697}
 698
 699static void report__output_resort(struct report *rep)
 700{
 701        struct ui_progress prog;
 702        struct evsel *pos;
 703
 704        ui_progress__init(&prog, rep->nr_entries, "Sorting events for output...");
 705
 706        evlist__for_each_entry(rep->session->evlist, pos) {
 707                evsel__output_resort_cb(pos, &prog, hists__resort_cb, rep);
 708        }
 709
 710        ui_progress__finish();
 711}
 712
 713static void stats_setup(struct report *rep)
 714{
 715        memset(&rep->tool, 0, sizeof(rep->tool));
 716        rep->tool.no_warn = true;
 717}
 718
 719static int stats_print(struct report *rep)
 720{
 721        struct perf_session *session = rep->session;
 722
 723        perf_session__fprintf_nr_events(session, stdout);
 724        return 0;
 725}
 726
 727static void tasks_setup(struct report *rep)
 728{
 729        memset(&rep->tool, 0, sizeof(rep->tool));
 730        rep->tool.ordered_events = true;
 731        if (rep->mmaps_mode) {
 732                rep->tool.mmap = perf_event__process_mmap;
 733                rep->tool.mmap2 = perf_event__process_mmap2;
 734        }
 735        rep->tool.comm = perf_event__process_comm;
 736        rep->tool.exit = perf_event__process_exit;
 737        rep->tool.fork = perf_event__process_fork;
 738        rep->tool.no_warn = true;
 739}
 740
 741struct task {
 742        struct thread           *thread;
 743        struct list_head         list;
 744        struct list_head         children;
 745};
 746
 747static struct task *tasks_list(struct task *task, struct machine *machine)
 748{
 749        struct thread *parent_thread, *thread = task->thread;
 750        struct task   *parent_task;
 751
 752        /* Already listed. */
 753        if (!list_empty(&task->list))
 754                return NULL;
 755
 756        /* Last one in the chain. */
 757        if (thread->ppid == -1)
 758                return task;
 759
 760        parent_thread = machine__find_thread(machine, -1, thread->ppid);
 761        if (!parent_thread)
 762                return ERR_PTR(-ENOENT);
 763
 764        parent_task = thread__priv(parent_thread);
 765        list_add_tail(&task->list, &parent_task->children);
 766        return tasks_list(parent_task, machine);
 767}
 768
 769static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
 770{
 771        size_t printed = 0;
 772        struct map *map;
 773
 774        maps__for_each_entry(maps, map) {
 775                printed += fprintf(fp, "%*s  %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
 776                                   indent, "", map->start, map->end,
 777                                   map->prot & PROT_READ ? 'r' : '-',
 778                                   map->prot & PROT_WRITE ? 'w' : '-',
 779                                   map->prot & PROT_EXEC ? 'x' : '-',
 780                                   map->flags & MAP_SHARED ? 's' : 'p',
 781                                   map->pgoff,
 782                                   map->dso->id.ino, map->dso->name);
 783        }
 784
 785        return printed;
 786}
 787
 788static void task__print_level(struct task *task, FILE *fp, int level)
 789{
 790        struct thread *thread = task->thread;
 791        struct task *child;
 792        int comm_indent = fprintf(fp, "  %8d %8d %8d |%*s",
 793                                  thread->pid_, thread->tid, thread->ppid,
 794                                  level, "");
 795
 796        fprintf(fp, "%s\n", thread__comm_str(thread));
 797
 798        maps__fprintf_task(thread->maps, comm_indent, fp);
 799
 800        if (!list_empty(&task->children)) {
 801                list_for_each_entry(child, &task->children, list)
 802                        task__print_level(child, fp, level + 1);
 803        }
 804}
 805
 806static int tasks_print(struct report *rep, FILE *fp)
 807{
 808        struct perf_session *session = rep->session;
 809        struct machine      *machine = &session->machines.host;
 810        struct task *tasks, *task;
 811        unsigned int nr = 0, itask = 0, i;
 812        struct rb_node *nd;
 813        LIST_HEAD(list);
 814
 815        /*
 816         * No locking needed while accessing machine->threads,
 817         * because --tasks is single threaded command.
 818         */
 819
 820        /* Count all the threads. */
 821        for (i = 0; i < THREADS__TABLE_SIZE; i++)
 822                nr += machine->threads[i].nr;
 823
 824        tasks = malloc(sizeof(*tasks) * nr);
 825        if (!tasks)
 826                return -ENOMEM;
 827
 828        for (i = 0; i < THREADS__TABLE_SIZE; i++) {
 829                struct threads *threads = &machine->threads[i];
 830
 831                for (nd = rb_first_cached(&threads->entries); nd;
 832                     nd = rb_next(nd)) {
 833                        task = tasks + itask++;
 834
 835                        task->thread = rb_entry(nd, struct thread, rb_node);
 836                        INIT_LIST_HEAD(&task->children);
 837                        INIT_LIST_HEAD(&task->list);
 838                        thread__set_priv(task->thread, task);
 839                }
 840        }
 841
 842        /*
 843         * Iterate every task down to the unprocessed parent
 844         * and link all in task children list. Task with no
 845         * parent is added into 'list'.
 846         */
 847        for (itask = 0; itask < nr; itask++) {
 848                task = tasks + itask;
 849
 850                if (!list_empty(&task->list))
 851                        continue;
 852
 853                task = tasks_list(task, machine);
 854                if (IS_ERR(task)) {
 855                        pr_err("Error: failed to process tasks\n");
 856                        free(tasks);
 857                        return PTR_ERR(task);
 858                }
 859
 860                if (task)
 861                        list_add_tail(&task->list, &list);
 862        }
 863
 864        fprintf(fp, "# %8s %8s %8s  %s\n", "pid", "tid", "ppid", "comm");
 865
 866        list_for_each_entry(task, &list, list)
 867                task__print_level(task, fp, 0);
 868
 869        free(tasks);
 870        return 0;
 871}
 872
 873static int __cmd_report(struct report *rep)
 874{
 875        int ret;
 876        struct perf_session *session = rep->session;
 877        struct evsel *pos;
 878        struct perf_data *data = session->data;
 879
 880        signal(SIGINT, sig_handler);
 881
 882        if (rep->cpu_list) {
 883                ret = perf_session__cpu_bitmap(session, rep->cpu_list,
 884                                               rep->cpu_bitmap);
 885                if (ret) {
 886                        ui__error("failed to set cpu bitmap\n");
 887                        return ret;
 888                }
 889                session->itrace_synth_opts->cpu_bitmap = rep->cpu_bitmap;
 890        }
 891
 892        if (rep->show_threads) {
 893                ret = perf_read_values_init(&rep->show_threads_values);
 894                if (ret)
 895                        return ret;
 896        }
 897
 898        ret = report__setup_sample_type(rep);
 899        if (ret) {
 900                /* report__setup_sample_type() already showed error message */
 901                return ret;
 902        }
 903
 904        if (rep->stats_mode)
 905                stats_setup(rep);
 906
 907        if (rep->tasks_mode)
 908                tasks_setup(rep);
 909
 910        ret = perf_session__process_events(session);
 911        if (ret) {
 912                ui__error("failed to process sample\n");
 913                return ret;
 914        }
 915
 916        if (rep->stats_mode)
 917                return stats_print(rep);
 918
 919        if (rep->tasks_mode)
 920                return tasks_print(rep, stdout);
 921
 922        report__warn_kptr_restrict(rep);
 923
 924        evlist__for_each_entry(session->evlist, pos)
 925                rep->nr_entries += evsel__hists(pos)->nr_entries;
 926
 927        if (use_browser == 0) {
 928                if (verbose > 3)
 929                        perf_session__fprintf(session, stdout);
 930
 931                if (verbose > 2)
 932                        perf_session__fprintf_dsos(session, stdout);
 933
 934                if (dump_trace) {
 935                        perf_session__fprintf_nr_events(session, stdout);
 936                        perf_evlist__fprintf_nr_events(session->evlist, stdout);
 937                        return 0;
 938                }
 939        }
 940
 941        ret = report__collapse_hists(rep);
 942        if (ret) {
 943                ui__error("failed to process hist entry\n");
 944                return ret;
 945        }
 946
 947        if (session_done())
 948                return 0;
 949
 950        /*
 951         * recalculate number of entries after collapsing since it
 952         * might be changed during the collapse phase.
 953         */
 954        rep->nr_entries = 0;
 955        evlist__for_each_entry(session->evlist, pos)
 956                rep->nr_entries += evsel__hists(pos)->nr_entries;
 957
 958        if (rep->nr_entries == 0) {
 959                ui__error("The %s data has no samples!\n", data->path);
 960                return 0;
 961        }
 962
 963        report__output_resort(rep);
 964
 965        if (rep->total_cycles_mode) {
 966                int block_hpps[6] = {
 967                        PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT,
 968                        PERF_HPP_REPORT__BLOCK_LBR_CYCLES,
 969                        PERF_HPP_REPORT__BLOCK_CYCLES_PCT,
 970                        PERF_HPP_REPORT__BLOCK_AVG_CYCLES,
 971                        PERF_HPP_REPORT__BLOCK_RANGE,
 972                        PERF_HPP_REPORT__BLOCK_DSO,
 973                };
 974
 975                rep->block_reports = block_info__create_report(session->evlist,
 976                                                               rep->total_cycles,
 977                                                               block_hpps, 6,
 978                                                               &rep->nr_block_reports);
 979                if (!rep->block_reports)
 980                        return -1;
 981        }
 982
 983        return report__browse_hists(rep);
 984}
 985
 986static int
 987report_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 988{
 989        struct callchain_param *callchain = opt->value;
 990
 991        callchain->enabled = !unset;
 992        /*
 993         * --no-call-graph
 994         */
 995        if (unset) {
 996                symbol_conf.use_callchain = false;
 997                callchain->mode = CHAIN_NONE;
 998                return 0;
 999        }
1000
1001        return parse_callchain_report_opt(arg);
1002}
1003
1004static int
1005parse_time_quantum(const struct option *opt, const char *arg,
1006                   int unset __maybe_unused)
1007{
1008        unsigned long *time_q = opt->value;
1009        char *end;
1010
1011        *time_q = strtoul(arg, &end, 0);
1012        if (end == arg)
1013                goto parse_err;
1014        if (*time_q == 0) {
1015                pr_err("time quantum cannot be 0");
1016                return -1;
1017        }
1018        end = skip_spaces(end);
1019        if (*end == 0)
1020                return 0;
1021        if (!strcmp(end, "s")) {
1022                *time_q *= NSEC_PER_SEC;
1023                return 0;
1024        }
1025        if (!strcmp(end, "ms")) {
1026                *time_q *= NSEC_PER_MSEC;
1027                return 0;
1028        }
1029        if (!strcmp(end, "us")) {
1030                *time_q *= NSEC_PER_USEC;
1031                return 0;
1032        }
1033        if (!strcmp(end, "ns"))
1034                return 0;
1035parse_err:
1036        pr_err("Cannot parse time quantum `%s'\n", arg);
1037        return -1;
1038}
1039
1040int
1041report_parse_ignore_callees_opt(const struct option *opt __maybe_unused,
1042                                const char *arg, int unset __maybe_unused)
1043{
1044        if (arg) {
1045                int err = regcomp(&ignore_callees_regex, arg, REG_EXTENDED);
1046                if (err) {
1047                        char buf[BUFSIZ];
1048                        regerror(err, &ignore_callees_regex, buf, sizeof(buf));
1049                        pr_err("Invalid --ignore-callees regex: %s\n%s", arg, buf);
1050                        return -1;
1051                }
1052                have_ignore_callees = 1;
1053        }
1054
1055        return 0;
1056}
1057
1058static int
1059parse_branch_mode(const struct option *opt,
1060                  const char *str __maybe_unused, int unset)
1061{
1062        int *branch_mode = opt->value;
1063
1064        *branch_mode = !unset;
1065        return 0;
1066}
1067
1068static int
1069parse_percent_limit(const struct option *opt, const char *str,
1070                    int unset __maybe_unused)
1071{
1072        struct report *rep = opt->value;
1073        double pcnt = strtof(str, NULL);
1074
1075        rep->min_percent = pcnt;
1076        callchain_param.min_percent = pcnt;
1077        return 0;
1078}
1079
1080static int process_attr(struct perf_tool *tool __maybe_unused,
1081                        union perf_event *event,
1082                        struct evlist **pevlist)
1083{
1084        u64 sample_type;
1085        int err;
1086
1087        err = perf_event__process_attr(tool, event, pevlist);
1088        if (err)
1089                return err;
1090
1091        /*
1092         * Check if we need to enable callchains based
1093         * on events sample_type.
1094         */
1095        sample_type = evlist__combined_sample_type(*pevlist);
1096        callchain_param_setup(sample_type);
1097        return 0;
1098}
1099
1100int cmd_report(int argc, const char **argv)
1101{
1102        struct perf_session *session;
1103        struct itrace_synth_opts itrace_synth_opts = { .set = 0, };
1104        struct stat st;
1105        bool has_br_stack = false;
1106        int branch_mode = -1;
1107        int last_key = 0;
1108        bool branch_call_mode = false;
1109#define CALLCHAIN_DEFAULT_OPT  "graph,0.5,caller,function,percent"
1110        static const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n"
1111                                                    CALLCHAIN_REPORT_HELP
1112                                                    "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT;
1113        char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT;
1114        const char * const report_usage[] = {
1115                "perf report [<options>]",
1116                NULL
1117        };
1118        struct report report = {
1119                .tool = {
1120                        .sample          = process_sample_event,
1121                        .mmap            = perf_event__process_mmap,
1122                        .mmap2           = perf_event__process_mmap2,
1123                        .comm            = perf_event__process_comm,
1124                        .namespaces      = perf_event__process_namespaces,
1125                        .cgroup          = perf_event__process_cgroup,
1126                        .exit            = perf_event__process_exit,
1127                        .fork            = perf_event__process_fork,
1128                        .lost            = perf_event__process_lost,
1129                        .read            = process_read_event,
1130                        .attr            = process_attr,
1131                        .tracing_data    = perf_event__process_tracing_data,
1132                        .build_id        = perf_event__process_build_id,
1133                        .id_index        = perf_event__process_id_index,
1134                        .auxtrace_info   = perf_event__process_auxtrace_info,
1135                        .auxtrace        = perf_event__process_auxtrace,
1136                        .event_update    = perf_event__process_event_update,
1137                        .feature         = process_feature_event,
1138                        .ordered_events  = true,
1139                        .ordering_requires_timestamps = true,
1140                },
1141                .max_stack               = PERF_MAX_STACK_DEPTH,
1142                .pretty_printing_style   = "normal",
1143                .socket_filter           = -1,
1144                .annotation_opts         = annotation__default_options,
1145        };
1146        const struct option options[] = {
1147        OPT_STRING('i', "input", &input_name, "file",
1148                    "input file name"),
1149        OPT_INCR('v', "verbose", &verbose,
1150                    "be more verbose (show symbol address, etc)"),
1151        OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"),
1152        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1153                    "dump raw trace in ASCII"),
1154        OPT_BOOLEAN(0, "stats", &report.stats_mode, "Display event stats"),
1155        OPT_BOOLEAN(0, "tasks", &report.tasks_mode, "Display recorded tasks"),
1156        OPT_BOOLEAN(0, "mmaps", &report.mmaps_mode, "Display recorded tasks memory maps"),
1157        OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
1158                   "file", "vmlinux pathname"),
1159        OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
1160                    "don't load vmlinux even if found"),
1161        OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
1162                   "file", "kallsyms pathname"),
1163        OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
1164        OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
1165                    "load module symbols - WARNING: use only with -k and LIVE kernel"),
1166        OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
1167                    "Show a column with the number of samples"),
1168        OPT_BOOLEAN('T', "threads", &report.show_threads,
1169                    "Show per-thread event counters"),
1170        OPT_STRING(0, "pretty", &report.pretty_printing_style, "key",
1171                   "pretty printing style key: normal raw"),
1172        OPT_BOOLEAN(0, "tui", &report.use_tui, "Use the TUI interface"),
1173        OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
1174        OPT_BOOLEAN(0, "stdio", &report.use_stdio,
1175                    "Use the stdio interface"),
1176        OPT_BOOLEAN(0, "header", &report.header, "Show data header."),
1177        OPT_BOOLEAN(0, "header-only", &report.header_only,
1178                    "Show only data header."),
1179        OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1180                   sort_help("sort by key(s):")),
1181        OPT_STRING('F', "fields", &field_order, "key[,keys...]",
1182                   sort_help("output field(s): overhead period sample ")),
1183        OPT_BOOLEAN(0, "show-cpu-utilization", &symbol_conf.show_cpu_utilization,
1184                    "Show sample percentage for different cpu modes"),
1185        OPT_BOOLEAN_FLAG(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
1186                    "Show sample percentage for different cpu modes", PARSE_OPT_HIDDEN),
1187        OPT_STRING('p', "parent", &parent_pattern, "regex",
1188                   "regex filter to identify parent, see: '--sort parent'"),
1189        OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
1190                    "Only display entries with parent-match"),
1191        OPT_CALLBACK_DEFAULT('g', "call-graph", &callchain_param,
1192                             "print_type,threshold[,print_limit],order,sort_key[,branch],value",
1193                             report_callchain_help, &report_parse_callchain_opt,
1194                             callchain_default_opt),
1195        OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
1196                    "Accumulate callchains of children and show total overhead as well. "
1197                    "Enabled by default, use --no-children to disable."),
1198        OPT_INTEGER(0, "max-stack", &report.max_stack,
1199                    "Set the maximum stack depth when parsing the callchain, "
1200                    "anything beyond the specified depth will be ignored. "
1201                    "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
1202        OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
1203                    "alias for inverted call graph"),
1204        OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
1205                   "ignore callees of these functions in call graphs",
1206                   report_parse_ignore_callees_opt),
1207        OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
1208                   "only consider symbols in these dsos"),
1209        OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1210                   "only consider symbols in these comms"),
1211        OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
1212                   "only consider symbols in these pids"),
1213        OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
1214                   "only consider symbols in these tids"),
1215        OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
1216                   "only consider these symbols"),
1217        OPT_STRING(0, "symbol-filter", &report.symbol_filter_str, "filter",
1218                   "only show symbols that (partially) match with this filter"),
1219        OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
1220                   "width[,width...]",
1221                   "don't try to adjust column width, use these fixed values"),
1222        OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
1223                   "separator for columns, no spaces will be added between "
1224                   "columns '.' is reserved."),
1225        OPT_BOOLEAN('U', "hide-unresolved", &symbol_conf.hide_unresolved,
1226                    "Only display entries resolved to a symbol"),
1227        OPT_CALLBACK(0, "symfs", NULL, "directory",
1228                     "Look for files with symbols relative to this directory",
1229                     symbol__config_symfs),
1230        OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
1231                   "list of cpus to profile"),
1232        OPT_BOOLEAN('I', "show-info", &report.show_full_info,
1233                    "Display extended information about perf.data file"),
1234        OPT_BOOLEAN(0, "source", &report.annotation_opts.annotate_src,
1235                    "Interleave source code with assembly code (default)"),
1236        OPT_BOOLEAN(0, "asm-raw", &report.annotation_opts.show_asm_raw,
1237                    "Display raw encoding of assembly instructions (default)"),
1238        OPT_STRING('M', "disassembler-style", &report.annotation_opts.disassembler_style, "disassembler style",
1239                   "Specify disassembler style (e.g. -M intel for intel syntax)"),
1240        OPT_STRING(0, "prefix", &report.annotation_opts.prefix, "prefix",
1241                    "Add prefix to source file path names in programs (with --prefix-strip)"),
1242        OPT_STRING(0, "prefix-strip", &report.annotation_opts.prefix_strip, "N",
1243                    "Strip first N entries of source file path name in programs (with --prefix)"),
1244        OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
1245                    "Show a column with the sum of periods"),
1246        OPT_BOOLEAN_SET(0, "group", &symbol_conf.event_group, &report.group_set,
1247                    "Show event group information together"),
1248        OPT_INTEGER(0, "group-sort-idx", &symbol_conf.group_sort_idx,
1249                    "Sort the output by the event at the index n in group. "
1250                    "If n is invalid, sort by the first event. "
1251                    "WARNING: should be used on grouped events."),
1252        OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
1253                    "use branch records for per branch histogram filling",
1254                    parse_branch_mode),
1255        OPT_BOOLEAN(0, "branch-history", &branch_call_mode,
1256                    "add last branch records to call history"),
1257        OPT_STRING(0, "objdump", &report.annotation_opts.objdump_path, "path",
1258                   "objdump binary to use for disassembly and annotations"),
1259        OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
1260                    "Disable symbol demangling"),
1261        OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
1262                    "Enable kernel symbol demangling"),
1263        OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
1264        OPT_INTEGER(0, "samples", &symbol_conf.res_sample,
1265                    "Number of samples to save per histogram entry for individual browsing"),
1266        OPT_CALLBACK(0, "percent-limit", &report, "percent",
1267                     "Don't show entries under that percent", parse_percent_limit),
1268        OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
1269                     "how to display percentage of filtered entries", parse_filter_percentage),
1270        OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
1271                            "Instruction Tracing options\n" ITRACE_HELP,
1272                            itrace_parse_synth_opts),
1273        OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
1274                        "Show full source file name path for source lines"),
1275        OPT_BOOLEAN(0, "show-ref-call-graph", &symbol_conf.show_ref_callgraph,
1276                    "Show callgraph from reference event"),
1277        OPT_BOOLEAN(0, "stitch-lbr", &report.stitch_lbr,
1278                    "Enable LBR callgraph stitching approach"),
1279        OPT_INTEGER(0, "socket-filter", &report.socket_filter,
1280                    "only show processor socket that match with this filter"),
1281        OPT_BOOLEAN(0, "raw-trace", &symbol_conf.raw_trace,
1282                    "Show raw trace event output (do not use print fmt or plugins)"),
1283        OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy,
1284                    "Show entries in a hierarchy"),
1285        OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode",
1286                             "'always' (default), 'never' or 'auto' only applicable to --stdio mode",
1287                             stdio__config_color, "always"),
1288        OPT_STRING(0, "time", &report.time_str, "str",
1289                   "Time span of interest (start,stop)"),
1290        OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
1291                    "Show inline function"),
1292        OPT_CALLBACK(0, "percent-type", &report.annotation_opts, "local-period",
1293                     "Set percent type local/global-period/hits",
1294                     annotate_parse_percent_type),
1295        OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs, "Show times in nanosecs"),
1296        OPT_CALLBACK(0, "time-quantum", &symbol_conf.time_quantum, "time (ms|us|ns|s)",
1297                     "Set time quantum for time sort key (default 100ms)",
1298                     parse_time_quantum),
1299        OPTS_EVSWITCH(&report.evswitch),
1300        OPT_BOOLEAN(0, "total-cycles", &report.total_cycles_mode,
1301                    "Sort all blocks by 'Sampled Cycles%'"),
1302        OPT_END()
1303        };
1304        struct perf_data data = {
1305                .mode  = PERF_DATA_MODE_READ,
1306        };
1307        int ret = hists__init();
1308        char sort_tmp[128];
1309
1310        if (ret < 0)
1311                return ret;
1312
1313        ret = perf_config(report__config, &report);
1314        if (ret)
1315                return ret;
1316
1317        argc = parse_options(argc, argv, options, report_usage, 0);
1318        if (argc) {
1319                /*
1320                 * Special case: if there's an argument left then assume that
1321                 * it's a symbol filter:
1322                 */
1323                if (argc > 1)
1324                        usage_with_options(report_usage, options);
1325
1326                report.symbol_filter_str = argv[0];
1327        }
1328
1329        if (annotate_check_args(&report.annotation_opts) < 0)
1330                return -EINVAL;
1331
1332        if (report.mmaps_mode)
1333                report.tasks_mode = true;
1334
1335        if (dump_trace)
1336                report.tool.ordered_events = false;
1337
1338        if (quiet)
1339                perf_quiet_option();
1340
1341        if (symbol_conf.vmlinux_name &&
1342            access(symbol_conf.vmlinux_name, R_OK)) {
1343                pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name);
1344                return -EINVAL;
1345        }
1346        if (symbol_conf.kallsyms_name &&
1347            access(symbol_conf.kallsyms_name, R_OK)) {
1348                pr_err("Invalid file: %s\n", symbol_conf.kallsyms_name);
1349                return -EINVAL;
1350        }
1351
1352        if (report.inverted_callchain)
1353                callchain_param.order = ORDER_CALLER;
1354        if (symbol_conf.cumulate_callchain && !callchain_param.order_set)
1355                callchain_param.order = ORDER_CALLER;
1356
1357        if ((itrace_synth_opts.callchain || itrace_synth_opts.add_callchain) &&
1358            (int)itrace_synth_opts.callchain_sz > report.max_stack)
1359                report.max_stack = itrace_synth_opts.callchain_sz;
1360
1361        if (!input_name || !strlen(input_name)) {
1362                if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
1363                        input_name = "-";
1364                else
1365                        input_name = "perf.data";
1366        }
1367
1368        data.path  = input_name;
1369        data.force = symbol_conf.force;
1370
1371repeat:
1372        session = perf_session__new(&data, false, &report.tool);
1373        if (IS_ERR(session))
1374                return PTR_ERR(session);
1375
1376        ret = evswitch__init(&report.evswitch, session->evlist, stderr);
1377        if (ret)
1378                return ret;
1379
1380        if (zstd_init(&(session->zstd_data), 0) < 0)
1381                pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
1382
1383        if (report.queue_size) {
1384                ordered_events__set_alloc_size(&session->ordered_events,
1385                                               report.queue_size);
1386        }
1387
1388        session->itrace_synth_opts = &itrace_synth_opts;
1389
1390        report.session = session;
1391
1392        has_br_stack = perf_header__has_feat(&session->header,
1393                                             HEADER_BRANCH_STACK);
1394        if (evlist__combined_sample_type(session->evlist) & PERF_SAMPLE_STACK_USER)
1395                has_br_stack = false;
1396
1397        setup_forced_leader(&report, session->evlist);
1398
1399        if (symbol_conf.group_sort_idx && !session->evlist->nr_groups) {
1400                parse_options_usage(NULL, options, "group-sort-idx", 0);
1401                ret = -EINVAL;
1402                goto error;
1403        }
1404
1405        if (itrace_synth_opts.last_branch || itrace_synth_opts.add_last_branch)
1406                has_br_stack = true;
1407
1408        if (has_br_stack && branch_call_mode)
1409                symbol_conf.show_branchflag_count = true;
1410
1411        memset(&report.brtype_stat, 0, sizeof(struct branch_type_stat));
1412
1413        /*
1414         * Branch mode is a tristate:
1415         * -1 means default, so decide based on the file having branch data.
1416         * 0/1 means the user chose a mode.
1417         */
1418        if (((branch_mode == -1 && has_br_stack) || branch_mode == 1) &&
1419            !branch_call_mode) {
1420                sort__mode = SORT_MODE__BRANCH;
1421                symbol_conf.cumulate_callchain = false;
1422        }
1423        if (branch_call_mode) {
1424                callchain_param.key = CCKEY_ADDRESS;
1425                callchain_param.branch_callstack = true;
1426                symbol_conf.use_callchain = true;
1427                callchain_register_param(&callchain_param);
1428                if (sort_order == NULL)
1429                        sort_order = "srcline,symbol,dso";
1430        }
1431
1432        if (report.mem_mode) {
1433                if (sort__mode == SORT_MODE__BRANCH) {
1434                        pr_err("branch and mem mode incompatible\n");
1435                        goto error;
1436                }
1437                sort__mode = SORT_MODE__MEMORY;
1438                symbol_conf.cumulate_callchain = false;
1439        }
1440
1441        if (symbol_conf.report_hierarchy) {
1442                /* disable incompatible options */
1443                symbol_conf.cumulate_callchain = false;
1444
1445                if (field_order) {
1446                        pr_err("Error: --hierarchy and --fields options cannot be used together\n");
1447                        parse_options_usage(report_usage, options, "F", 1);
1448                        parse_options_usage(NULL, options, "hierarchy", 0);
1449                        goto error;
1450                }
1451
1452                perf_hpp_list.need_collapse = true;
1453        }
1454
1455        if (report.use_stdio)
1456                use_browser = 0;
1457        else if (report.use_tui)
1458                use_browser = 1;
1459        else if (report.use_gtk)
1460                use_browser = 2;
1461
1462        /* Force tty output for header output and per-thread stat. */
1463        if (report.header || report.header_only || report.show_threads)
1464                use_browser = 0;
1465        if (report.header || report.header_only)
1466                report.tool.show_feat_hdr = SHOW_FEAT_HEADER;
1467        if (report.show_full_info)
1468                report.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
1469        if (report.stats_mode || report.tasks_mode)
1470                use_browser = 0;
1471        if (report.stats_mode && report.tasks_mode) {
1472                pr_err("Error: --tasks and --mmaps can't be used together with --stats\n");
1473                goto error;
1474        }
1475
1476        if (report.total_cycles_mode) {
1477                if (sort__mode != SORT_MODE__BRANCH)
1478                        report.total_cycles_mode = false;
1479                else
1480                        sort_order = NULL;
1481        }
1482
1483        if (strcmp(input_name, "-") != 0)
1484                setup_browser(true);
1485        else
1486                use_browser = 0;
1487
1488        if (sort_order && strstr(sort_order, "ipc")) {
1489                parse_options_usage(report_usage, options, "s", 1);
1490                goto error;
1491        }
1492
1493        if (sort_order && strstr(sort_order, "symbol")) {
1494                if (sort__mode == SORT_MODE__BRANCH) {
1495                        snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
1496                                 sort_order, "ipc_lbr");
1497                        report.symbol_ipc = true;
1498                } else {
1499                        snprintf(sort_tmp, sizeof(sort_tmp), "%s,%s",
1500                                 sort_order, "ipc_null");
1501                }
1502
1503                sort_order = sort_tmp;
1504        }
1505
1506        if ((last_key != K_SWITCH_INPUT_DATA && last_key != K_RELOAD) &&
1507            (setup_sorting(session->evlist) < 0)) {
1508                if (sort_order)
1509                        parse_options_usage(report_usage, options, "s", 1);
1510                if (field_order)
1511                        parse_options_usage(sort_order ? NULL : report_usage,
1512                                            options, "F", 1);
1513                goto error;
1514        }
1515
1516        if ((report.header || report.header_only) && !quiet) {
1517                perf_session__fprintf_info(session, stdout,
1518                                           report.show_full_info);
1519                if (report.header_only) {
1520                        ret = 0;
1521                        goto error;
1522                }
1523        } else if (use_browser == 0 && !quiet &&
1524                   !report.stats_mode && !report.tasks_mode) {
1525                fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
1526                      stdout);
1527        }
1528
1529        /*
1530         * Only in the TUI browser we are doing integrated annotation,
1531         * so don't allocate extra space that won't be used in the stdio
1532         * implementation.
1533         */
1534        if (ui__has_annotation() || report.symbol_ipc ||
1535            report.total_cycles_mode) {
1536                ret = symbol__annotation_init();
1537                if (ret < 0)
1538                        goto error;
1539                /*
1540                 * For searching by name on the "Browse map details".
1541                 * providing it only in verbose mode not to bloat too
1542                 * much struct symbol.
1543                 */
1544                if (verbose > 0) {
1545                        /*
1546                         * XXX: Need to provide a less kludgy way to ask for
1547                         * more space per symbol, the u32 is for the index on
1548                         * the ui browser.
1549                         * See symbol__browser_index.
1550                         */
1551                        symbol_conf.priv_size += sizeof(u32);
1552                        symbol_conf.sort_by_name = true;
1553                }
1554                annotation_config__init(&report.annotation_opts);
1555        }
1556
1557        if (symbol__init(&session->header.env) < 0)
1558                goto error;
1559
1560        if (report.time_str) {
1561                ret = perf_time__parse_for_ranges(report.time_str, session,
1562                                                  &report.ptime_range,
1563                                                  &report.range_size,
1564                                                  &report.range_num);
1565                if (ret < 0)
1566                        goto error;
1567
1568                itrace_synth_opts__set_time_range(&itrace_synth_opts,
1569                                                  report.ptime_range,
1570                                                  report.range_num);
1571        }
1572
1573        if (session->tevent.pevent &&
1574            tep_set_function_resolver(session->tevent.pevent,
1575                                      machine__resolve_kernel_addr,
1576                                      &session->machines.host) < 0) {
1577                pr_err("%s: failed to set libtraceevent function resolver\n",
1578                       __func__);
1579                return -1;
1580        }
1581
1582        sort__setup_elide(stdout);
1583
1584        ret = __cmd_report(&report);
1585        if (ret == K_SWITCH_INPUT_DATA || ret == K_RELOAD) {
1586                perf_session__delete(session);
1587                last_key = K_SWITCH_INPUT_DATA;
1588                goto repeat;
1589        } else
1590                ret = 0;
1591
1592error:
1593        if (report.ptime_range) {
1594                itrace_synth_opts__clear_time_range(&itrace_synth_opts);
1595                zfree(&report.ptime_range);
1596        }
1597
1598        if (report.block_reports) {
1599                block_info__free_report(report.block_reports,
1600                                        report.nr_block_reports);
1601                report.block_reports = NULL;
1602        }
1603
1604        zstd_fini(&(session->zstd_data));
1605        perf_session__delete(session);
1606        return ret;
1607}
1608