linux/tools/perf/util/hist.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include "util.h"
   3#include "build-id.h"
   4#include "hist.h"
   5#include "map.h"
   6#include "session.h"
   7#include "namespaces.h"
   8#include "sort.h"
   9#include "units.h"
  10#include "evlist.h"
  11#include "evsel.h"
  12#include "annotate.h"
  13#include "srcline.h"
  14#include "thread.h"
  15#include "ui/progress.h"
  16#include <errno.h>
  17#include <math.h>
  18#include <inttypes.h>
  19#include <sys/param.h>
  20
  21static bool hists__filter_entry_by_dso(struct hists *hists,
  22                                       struct hist_entry *he);
  23static bool hists__filter_entry_by_thread(struct hists *hists,
  24                                          struct hist_entry *he);
  25static bool hists__filter_entry_by_symbol(struct hists *hists,
  26                                          struct hist_entry *he);
  27static bool hists__filter_entry_by_socket(struct hists *hists,
  28                                          struct hist_entry *he);
  29
  30u16 hists__col_len(struct hists *hists, enum hist_column col)
  31{
  32        return hists->col_len[col];
  33}
  34
  35void hists__set_col_len(struct hists *hists, enum hist_column col, u16 len)
  36{
  37        hists->col_len[col] = len;
  38}
  39
  40bool hists__new_col_len(struct hists *hists, enum hist_column col, u16 len)
  41{
  42        if (len > hists__col_len(hists, col)) {
  43                hists__set_col_len(hists, col, len);
  44                return true;
  45        }
  46        return false;
  47}
  48
  49void hists__reset_col_len(struct hists *hists)
  50{
  51        enum hist_column col;
  52
  53        for (col = 0; col < HISTC_NR_COLS; ++col)
  54                hists__set_col_len(hists, col, 0);
  55}
  56
  57static void hists__set_unres_dso_col_len(struct hists *hists, int dso)
  58{
  59        const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
  60
  61        if (hists__col_len(hists, dso) < unresolved_col_width &&
  62            !symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
  63            !symbol_conf.dso_list)
  64                hists__set_col_len(hists, dso, unresolved_col_width);
  65}
  66
  67void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
  68{
  69        const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
  70        int symlen;
  71        u16 len;
  72
  73        /*
  74         * +4 accounts for '[x] ' priv level info
  75         * +2 accounts for 0x prefix on raw addresses
  76         * +3 accounts for ' y ' symtab origin info
  77         */
  78        if (h->ms.sym) {
  79                symlen = h->ms.sym->namelen + 4;
  80                if (verbose > 0)
  81                        symlen += BITS_PER_LONG / 4 + 2 + 3;
  82                hists__new_col_len(hists, HISTC_SYMBOL, symlen);
  83        } else {
  84                symlen = unresolved_col_width + 4 + 2;
  85                hists__new_col_len(hists, HISTC_SYMBOL, symlen);
  86                hists__set_unres_dso_col_len(hists, HISTC_DSO);
  87        }
  88
  89        len = thread__comm_len(h->thread);
  90        if (hists__new_col_len(hists, HISTC_COMM, len))
  91                hists__set_col_len(hists, HISTC_THREAD, len + 8);
  92
  93        if (h->ms.map) {
  94                len = dso__name_len(h->ms.map->dso);
  95                hists__new_col_len(hists, HISTC_DSO, len);
  96        }
  97
  98        if (h->parent)
  99                hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
 100
 101        if (h->branch_info) {
 102                if (h->branch_info->from.sym) {
 103                        symlen = (int)h->branch_info->from.sym->namelen + 4;
 104                        if (verbose > 0)
 105                                symlen += BITS_PER_LONG / 4 + 2 + 3;
 106                        hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
 107
 108                        symlen = dso__name_len(h->branch_info->from.map->dso);
 109                        hists__new_col_len(hists, HISTC_DSO_FROM, symlen);
 110                } else {
 111                        symlen = unresolved_col_width + 4 + 2;
 112                        hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
 113                        hists__set_unres_dso_col_len(hists, HISTC_DSO_FROM);
 114                }
 115
 116                if (h->branch_info->to.sym) {
 117                        symlen = (int)h->branch_info->to.sym->namelen + 4;
 118                        if (verbose > 0)
 119                                symlen += BITS_PER_LONG / 4 + 2 + 3;
 120                        hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
 121
 122                        symlen = dso__name_len(h->branch_info->to.map->dso);
 123                        hists__new_col_len(hists, HISTC_DSO_TO, symlen);
 124                } else {
 125                        symlen = unresolved_col_width + 4 + 2;
 126                        hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
 127                        hists__set_unres_dso_col_len(hists, HISTC_DSO_TO);
 128                }
 129
 130                if (h->branch_info->srcline_from)
 131                        hists__new_col_len(hists, HISTC_SRCLINE_FROM,
 132                                        strlen(h->branch_info->srcline_from));
 133                if (h->branch_info->srcline_to)
 134                        hists__new_col_len(hists, HISTC_SRCLINE_TO,
 135                                        strlen(h->branch_info->srcline_to));
 136        }
 137
 138        if (h->mem_info) {
 139                if (h->mem_info->daddr.sym) {
 140                        symlen = (int)h->mem_info->daddr.sym->namelen + 4
 141                               + unresolved_col_width + 2;
 142                        hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
 143                                           symlen);
 144                        hists__new_col_len(hists, HISTC_MEM_DCACHELINE,
 145                                           symlen + 1);
 146                } else {
 147                        symlen = unresolved_col_width + 4 + 2;
 148                        hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
 149                                           symlen);
 150                        hists__new_col_len(hists, HISTC_MEM_DCACHELINE,
 151                                           symlen);
 152                }
 153
 154                if (h->mem_info->iaddr.sym) {
 155                        symlen = (int)h->mem_info->iaddr.sym->namelen + 4
 156                               + unresolved_col_width + 2;
 157                        hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL,
 158                                           symlen);
 159                } else {
 160                        symlen = unresolved_col_width + 4 + 2;
 161                        hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL,
 162                                           symlen);
 163                }
 164
 165                if (h->mem_info->daddr.map) {
 166                        symlen = dso__name_len(h->mem_info->daddr.map->dso);
 167                        hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
 168                                           symlen);
 169                } else {
 170                        symlen = unresolved_col_width + 4 + 2;
 171                        hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
 172                }
 173
 174                hists__new_col_len(hists, HISTC_MEM_PHYS_DADDR,
 175                                   unresolved_col_width + 4 + 2);
 176
 177        } else {
 178                symlen = unresolved_col_width + 4 + 2;
 179                hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen);
 180                hists__new_col_len(hists, HISTC_MEM_IADDR_SYMBOL, symlen);
 181                hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
 182        }
 183
 184        hists__new_col_len(hists, HISTC_CGROUP_ID, 20);
 185        hists__new_col_len(hists, HISTC_CPU, 3);
 186        hists__new_col_len(hists, HISTC_SOCKET, 6);
 187        hists__new_col_len(hists, HISTC_MEM_LOCKED, 6);
 188        hists__new_col_len(hists, HISTC_MEM_TLB, 22);
 189        hists__new_col_len(hists, HISTC_MEM_SNOOP, 12);
 190        hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3);
 191        hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12);
 192        hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
 193
 194        if (h->srcline) {
 195                len = MAX(strlen(h->srcline), strlen(sort_srcline.se_header));
 196                hists__new_col_len(hists, HISTC_SRCLINE, len);
 197        }
 198
 199        if (h->srcfile)
 200                hists__new_col_len(hists, HISTC_SRCFILE, strlen(h->srcfile));
 201
 202        if (h->transaction)
 203                hists__new_col_len(hists, HISTC_TRANSACTION,
 204                                   hist_entry__transaction_len());
 205
 206        if (h->trace_output)
 207                hists__new_col_len(hists, HISTC_TRACE, strlen(h->trace_output));
 208}
 209
 210void hists__output_recalc_col_len(struct hists *hists, int max_rows)
 211{
 212        struct rb_node *next = rb_first(&hists->entries);
 213        struct hist_entry *n;
 214        int row = 0;
 215
 216        hists__reset_col_len(hists);
 217
 218        while (next && row++ < max_rows) {
 219                n = rb_entry(next, struct hist_entry, rb_node);
 220                if (!n->filtered)
 221                        hists__calc_col_len(hists, n);
 222                next = rb_next(&n->rb_node);
 223        }
 224}
 225
 226static void he_stat__add_cpumode_period(struct he_stat *he_stat,
 227                                        unsigned int cpumode, u64 period)
 228{
 229        switch (cpumode) {
 230        case PERF_RECORD_MISC_KERNEL:
 231                he_stat->period_sys += period;
 232                break;
 233        case PERF_RECORD_MISC_USER:
 234                he_stat->period_us += period;
 235                break;
 236        case PERF_RECORD_MISC_GUEST_KERNEL:
 237                he_stat->period_guest_sys += period;
 238                break;
 239        case PERF_RECORD_MISC_GUEST_USER:
 240                he_stat->period_guest_us += period;
 241                break;
 242        default:
 243                break;
 244        }
 245}
 246
 247static void he_stat__add_period(struct he_stat *he_stat, u64 period,
 248                                u64 weight)
 249{
 250
 251        he_stat->period         += period;
 252        he_stat->weight         += weight;
 253        he_stat->nr_events      += 1;
 254}
 255
 256static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
 257{
 258        dest->period            += src->period;
 259        dest->period_sys        += src->period_sys;
 260        dest->period_us         += src->period_us;
 261        dest->period_guest_sys  += src->period_guest_sys;
 262        dest->period_guest_us   += src->period_guest_us;
 263        dest->nr_events         += src->nr_events;
 264        dest->weight            += src->weight;
 265}
 266
 267static void he_stat__decay(struct he_stat *he_stat)
 268{
 269        he_stat->period = (he_stat->period * 7) / 8;
 270        he_stat->nr_events = (he_stat->nr_events * 7) / 8;
 271        /* XXX need decay for weight too? */
 272}
 273
 274static void hists__delete_entry(struct hists *hists, struct hist_entry *he);
 275
 276static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
 277{
 278        u64 prev_period = he->stat.period;
 279        u64 diff;
 280
 281        if (prev_period == 0)
 282                return true;
 283
 284        he_stat__decay(&he->stat);
 285        if (symbol_conf.cumulate_callchain)
 286                he_stat__decay(he->stat_acc);
 287        decay_callchain(he->callchain);
 288
 289        diff = prev_period - he->stat.period;
 290
 291        if (!he->depth) {
 292                hists->stats.total_period -= diff;
 293                if (!he->filtered)
 294                        hists->stats.total_non_filtered_period -= diff;
 295        }
 296
 297        if (!he->leaf) {
 298                struct hist_entry *child;
 299                struct rb_node *node = rb_first(&he->hroot_out);
 300                while (node) {
 301                        child = rb_entry(node, struct hist_entry, rb_node);
 302                        node = rb_next(node);
 303
 304                        if (hists__decay_entry(hists, child))
 305                                hists__delete_entry(hists, child);
 306                }
 307        }
 308
 309        return he->stat.period == 0;
 310}
 311
 312static void hists__delete_entry(struct hists *hists, struct hist_entry *he)
 313{
 314        struct rb_root *root_in;
 315        struct rb_root *root_out;
 316
 317        if (he->parent_he) {
 318                root_in  = &he->parent_he->hroot_in;
 319                root_out = &he->parent_he->hroot_out;
 320        } else {
 321                if (hists__has(hists, need_collapse))
 322                        root_in = &hists->entries_collapsed;
 323                else
 324                        root_in = hists->entries_in;
 325                root_out = &hists->entries;
 326        }
 327
 328        rb_erase(&he->rb_node_in, root_in);
 329        rb_erase(&he->rb_node, root_out);
 330
 331        --hists->nr_entries;
 332        if (!he->filtered)
 333                --hists->nr_non_filtered_entries;
 334
 335        hist_entry__delete(he);
 336}
 337
 338void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
 339{
 340        struct rb_node *next = rb_first(&hists->entries);
 341        struct hist_entry *n;
 342
 343        while (next) {
 344                n = rb_entry(next, struct hist_entry, rb_node);
 345                next = rb_next(&n->rb_node);
 346                if (((zap_user && n->level == '.') ||
 347                     (zap_kernel && n->level != '.') ||
 348                     hists__decay_entry(hists, n))) {
 349                        hists__delete_entry(hists, n);
 350                }
 351        }
 352}
 353
 354void hists__delete_entries(struct hists *hists)
 355{
 356        struct rb_node *next = rb_first(&hists->entries);
 357        struct hist_entry *n;
 358
 359        while (next) {
 360                n = rb_entry(next, struct hist_entry, rb_node);
 361                next = rb_next(&n->rb_node);
 362
 363                hists__delete_entry(hists, n);
 364        }
 365}
 366
 367/*
 368 * histogram, sorted on item, collects periods
 369 */
 370
 371static int hist_entry__init(struct hist_entry *he,
 372                            struct hist_entry *template,
 373                            bool sample_self,
 374                            size_t callchain_size)
 375{
 376        *he = *template;
 377        he->callchain_size = callchain_size;
 378
 379        if (symbol_conf.cumulate_callchain) {
 380                he->stat_acc = malloc(sizeof(he->stat));
 381                if (he->stat_acc == NULL)
 382                        return -ENOMEM;
 383                memcpy(he->stat_acc, &he->stat, sizeof(he->stat));
 384                if (!sample_self)
 385                        memset(&he->stat, 0, sizeof(he->stat));
 386        }
 387
 388        map__get(he->ms.map);
 389
 390        if (he->branch_info) {
 391                /*
 392                 * This branch info is (a part of) allocated from
 393                 * sample__resolve_bstack() and will be freed after
 394                 * adding new entries.  So we need to save a copy.
 395                 */
 396                he->branch_info = malloc(sizeof(*he->branch_info));
 397                if (he->branch_info == NULL) {
 398                        map__zput(he->ms.map);
 399                        free(he->stat_acc);
 400                        return -ENOMEM;
 401                }
 402
 403                memcpy(he->branch_info, template->branch_info,
 404                       sizeof(*he->branch_info));
 405
 406                map__get(he->branch_info->from.map);
 407                map__get(he->branch_info->to.map);
 408        }
 409
 410        if (he->mem_info) {
 411                map__get(he->mem_info->iaddr.map);
 412                map__get(he->mem_info->daddr.map);
 413        }
 414
 415        if (hist_entry__has_callchains(he) && symbol_conf.use_callchain)
 416                callchain_init(he->callchain);
 417
 418        if (he->raw_data) {
 419                he->raw_data = memdup(he->raw_data, he->raw_size);
 420
 421                if (he->raw_data == NULL) {
 422                        map__put(he->ms.map);
 423                        if (he->branch_info) {
 424                                map__put(he->branch_info->from.map);
 425                                map__put(he->branch_info->to.map);
 426                                free(he->branch_info);
 427                        }
 428                        if (he->mem_info) {
 429                                map__put(he->mem_info->iaddr.map);
 430                                map__put(he->mem_info->daddr.map);
 431                        }
 432                        free(he->stat_acc);
 433                        return -ENOMEM;
 434                }
 435        }
 436        INIT_LIST_HEAD(&he->pairs.node);
 437        thread__get(he->thread);
 438        he->hroot_in  = RB_ROOT;
 439        he->hroot_out = RB_ROOT;
 440
 441        if (!symbol_conf.report_hierarchy)
 442                he->leaf = true;
 443
 444        return 0;
 445}
 446
 447static void *hist_entry__zalloc(size_t size)
 448{
 449        return zalloc(size + sizeof(struct hist_entry));
 450}
 451
 452static void hist_entry__free(void *ptr)
 453{
 454        free(ptr);
 455}
 456
 457static struct hist_entry_ops default_ops = {
 458        .new    = hist_entry__zalloc,
 459        .free   = hist_entry__free,
 460};
 461
 462static struct hist_entry *hist_entry__new(struct hist_entry *template,
 463                                          bool sample_self)
 464{
 465        struct hist_entry_ops *ops = template->ops;
 466        size_t callchain_size = 0;
 467        struct hist_entry *he;
 468        int err = 0;
 469
 470        if (!ops)
 471                ops = template->ops = &default_ops;
 472
 473        if (symbol_conf.use_callchain)
 474                callchain_size = sizeof(struct callchain_root);
 475
 476        he = ops->new(callchain_size);
 477        if (he) {
 478                err = hist_entry__init(he, template, sample_self, callchain_size);
 479                if (err) {
 480                        ops->free(he);
 481                        he = NULL;
 482                }
 483        }
 484
 485        return he;
 486}
 487
 488static u8 symbol__parent_filter(const struct symbol *parent)
 489{
 490        if (symbol_conf.exclude_other && parent == NULL)
 491                return 1 << HIST_FILTER__PARENT;
 492        return 0;
 493}
 494
 495static void hist_entry__add_callchain_period(struct hist_entry *he, u64 period)
 496{
 497        if (!hist_entry__has_callchains(he) || !symbol_conf.use_callchain)
 498                return;
 499
 500        he->hists->callchain_period += period;
 501        if (!he->filtered)
 502                he->hists->callchain_non_filtered_period += period;
 503}
 504
 505static struct hist_entry *hists__findnew_entry(struct hists *hists,
 506                                               struct hist_entry *entry,
 507                                               struct addr_location *al,
 508                                               bool sample_self)
 509{
 510        struct rb_node **p;
 511        struct rb_node *parent = NULL;
 512        struct hist_entry *he;
 513        int64_t cmp;
 514        u64 period = entry->stat.period;
 515        u64 weight = entry->stat.weight;
 516
 517        p = &hists->entries_in->rb_node;
 518
 519        while (*p != NULL) {
 520                parent = *p;
 521                he = rb_entry(parent, struct hist_entry, rb_node_in);
 522
 523                /*
 524                 * Make sure that it receives arguments in a same order as
 525                 * hist_entry__collapse() so that we can use an appropriate
 526                 * function when searching an entry regardless which sort
 527                 * keys were used.
 528                 */
 529                cmp = hist_entry__cmp(he, entry);
 530
 531                if (!cmp) {
 532                        if (sample_self) {
 533                                he_stat__add_period(&he->stat, period, weight);
 534                                hist_entry__add_callchain_period(he, period);
 535                        }
 536                        if (symbol_conf.cumulate_callchain)
 537                                he_stat__add_period(he->stat_acc, period, weight);
 538
 539                        /*
 540                         * This mem info was allocated from sample__resolve_mem
 541                         * and will not be used anymore.
 542                         */
 543                        mem_info__zput(entry->mem_info);
 544
 545                        /* If the map of an existing hist_entry has
 546                         * become out-of-date due to an exec() or
 547                         * similar, update it.  Otherwise we will
 548                         * mis-adjust symbol addresses when computing
 549                         * the history counter to increment.
 550                         */
 551                        if (he->ms.map != entry->ms.map) {
 552                                map__put(he->ms.map);
 553                                he->ms.map = map__get(entry->ms.map);
 554                        }
 555                        goto out;
 556                }
 557
 558                if (cmp < 0)
 559                        p = &(*p)->rb_left;
 560                else
 561                        p = &(*p)->rb_right;
 562        }
 563
 564        he = hist_entry__new(entry, sample_self);
 565        if (!he)
 566                return NULL;
 567
 568        if (sample_self)
 569                hist_entry__add_callchain_period(he, period);
 570        hists->nr_entries++;
 571
 572        rb_link_node(&he->rb_node_in, parent, p);
 573        rb_insert_color(&he->rb_node_in, hists->entries_in);
 574out:
 575        if (sample_self)
 576                he_stat__add_cpumode_period(&he->stat, al->cpumode, period);
 577        if (symbol_conf.cumulate_callchain)
 578                he_stat__add_cpumode_period(he->stat_acc, al->cpumode, period);
 579        return he;
 580}
 581
 582static struct hist_entry*
 583__hists__add_entry(struct hists *hists,
 584                   struct addr_location *al,
 585                   struct symbol *sym_parent,
 586                   struct branch_info *bi,
 587                   struct mem_info *mi,
 588                   struct perf_sample *sample,
 589                   bool sample_self,
 590                   struct hist_entry_ops *ops)
 591{
 592        struct namespaces *ns = thread__namespaces(al->thread);
 593        struct hist_entry entry = {
 594                .thread = al->thread,
 595                .comm = thread__comm(al->thread),
 596                .cgroup_id = {
 597                        .dev = ns ? ns->link_info[CGROUP_NS_INDEX].dev : 0,
 598                        .ino = ns ? ns->link_info[CGROUP_NS_INDEX].ino : 0,
 599                },
 600                .ms = {
 601                        .map    = al->map,
 602                        .sym    = al->sym,
 603                },
 604                .srcline = al->srcline ? strdup(al->srcline) : NULL,
 605                .socket  = al->socket,
 606                .cpu     = al->cpu,
 607                .cpumode = al->cpumode,
 608                .ip      = al->addr,
 609                .level   = al->level,
 610                .stat = {
 611                        .nr_events = 1,
 612                        .period = sample->period,
 613                        .weight = sample->weight,
 614                },
 615                .parent = sym_parent,
 616                .filtered = symbol__parent_filter(sym_parent) | al->filtered,
 617                .hists  = hists,
 618                .branch_info = bi,
 619                .mem_info = mi,
 620                .transaction = sample->transaction,
 621                .raw_data = sample->raw_data,
 622                .raw_size = sample->raw_size,
 623                .ops = ops,
 624        }, *he = hists__findnew_entry(hists, &entry, al, sample_self);
 625
 626        if (!hists->has_callchains && he && he->callchain_size != 0)
 627                hists->has_callchains = true;
 628        return he;
 629}
 630
 631struct hist_entry *hists__add_entry(struct hists *hists,
 632                                    struct addr_location *al,
 633                                    struct symbol *sym_parent,
 634                                    struct branch_info *bi,
 635                                    struct mem_info *mi,
 636                                    struct perf_sample *sample,
 637                                    bool sample_self)
 638{
 639        return __hists__add_entry(hists, al, sym_parent, bi, mi,
 640                                  sample, sample_self, NULL);
 641}
 642
 643struct hist_entry *hists__add_entry_ops(struct hists *hists,
 644                                        struct hist_entry_ops *ops,
 645                                        struct addr_location *al,
 646                                        struct symbol *sym_parent,
 647                                        struct branch_info *bi,
 648                                        struct mem_info *mi,
 649                                        struct perf_sample *sample,
 650                                        bool sample_self)
 651{
 652        return __hists__add_entry(hists, al, sym_parent, bi, mi,
 653                                  sample, sample_self, ops);
 654}
 655
 656static int
 657iter_next_nop_entry(struct hist_entry_iter *iter __maybe_unused,
 658                    struct addr_location *al __maybe_unused)
 659{
 660        return 0;
 661}
 662
 663static int
 664iter_add_next_nop_entry(struct hist_entry_iter *iter __maybe_unused,
 665                        struct addr_location *al __maybe_unused)
 666{
 667        return 0;
 668}
 669
 670static int
 671iter_prepare_mem_entry(struct hist_entry_iter *iter, struct addr_location *al)
 672{
 673        struct perf_sample *sample = iter->sample;
 674        struct mem_info *mi;
 675
 676        mi = sample__resolve_mem(sample, al);
 677        if (mi == NULL)
 678                return -ENOMEM;
 679
 680        iter->priv = mi;
 681        return 0;
 682}
 683
 684static int
 685iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al)
 686{
 687        u64 cost;
 688        struct mem_info *mi = iter->priv;
 689        struct hists *hists = evsel__hists(iter->evsel);
 690        struct perf_sample *sample = iter->sample;
 691        struct hist_entry *he;
 692
 693        if (mi == NULL)
 694                return -EINVAL;
 695
 696        cost = sample->weight;
 697        if (!cost)
 698                cost = 1;
 699
 700        /*
 701         * must pass period=weight in order to get the correct
 702         * sorting from hists__collapse_resort() which is solely
 703         * based on periods. We want sorting be done on nr_events * weight
 704         * and this is indirectly achieved by passing period=weight here
 705         * and the he_stat__add_period() function.
 706         */
 707        sample->period = cost;
 708
 709        he = hists__add_entry(hists, al, iter->parent, NULL, mi,
 710                              sample, true);
 711        if (!he)
 712                return -ENOMEM;
 713
 714        iter->he = he;
 715        return 0;
 716}
 717
 718static int
 719iter_finish_mem_entry(struct hist_entry_iter *iter,
 720                      struct addr_location *al __maybe_unused)
 721{
 722        struct perf_evsel *evsel = iter->evsel;
 723        struct hists *hists = evsel__hists(evsel);
 724        struct hist_entry *he = iter->he;
 725        int err = -EINVAL;
 726
 727        if (he == NULL)
 728                goto out;
 729
 730        hists__inc_nr_samples(hists, he->filtered);
 731
 732        err = hist_entry__append_callchain(he, iter->sample);
 733
 734out:
 735        /*
 736         * We don't need to free iter->priv (mem_info) here since the mem info
 737         * was either already freed in hists__findnew_entry() or passed to a
 738         * new hist entry by hist_entry__new().
 739         */
 740        iter->priv = NULL;
 741
 742        iter->he = NULL;
 743        return err;
 744}
 745
 746static int
 747iter_prepare_branch_entry(struct hist_entry_iter *iter, struct addr_location *al)
 748{
 749        struct branch_info *bi;
 750        struct perf_sample *sample = iter->sample;
 751
 752        bi = sample__resolve_bstack(sample, al);
 753        if (!bi)
 754                return -ENOMEM;
 755
 756        iter->curr = 0;
 757        iter->total = sample->branch_stack->nr;
 758
 759        iter->priv = bi;
 760        return 0;
 761}
 762
 763static int
 764iter_add_single_branch_entry(struct hist_entry_iter *iter __maybe_unused,
 765                             struct addr_location *al __maybe_unused)
 766{
 767        return 0;
 768}
 769
 770static int
 771iter_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *al)
 772{
 773        struct branch_info *bi = iter->priv;
 774        int i = iter->curr;
 775
 776        if (bi == NULL)
 777                return 0;
 778
 779        if (iter->curr >= iter->total)
 780                return 0;
 781
 782        al->map = bi[i].to.map;
 783        al->sym = bi[i].to.sym;
 784        al->addr = bi[i].to.addr;
 785        return 1;
 786}
 787
 788static int
 789iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *al)
 790{
 791        struct branch_info *bi;
 792        struct perf_evsel *evsel = iter->evsel;
 793        struct hists *hists = evsel__hists(evsel);
 794        struct perf_sample *sample = iter->sample;
 795        struct hist_entry *he = NULL;
 796        int i = iter->curr;
 797        int err = 0;
 798
 799        bi = iter->priv;
 800
 801        if (iter->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym))
 802                goto out;
 803
 804        /*
 805         * The report shows the percentage of total branches captured
 806         * and not events sampled. Thus we use a pseudo period of 1.
 807         */
 808        sample->period = 1;
 809        sample->weight = bi->flags.cycles ? bi->flags.cycles : 1;
 810
 811        he = hists__add_entry(hists, al, iter->parent, &bi[i], NULL,
 812                              sample, true);
 813        if (he == NULL)
 814                return -ENOMEM;
 815
 816        hists__inc_nr_samples(hists, he->filtered);
 817
 818out:
 819        iter->he = he;
 820        iter->curr++;
 821        return err;
 822}
 823
 824static int
 825iter_finish_branch_entry(struct hist_entry_iter *iter,
 826                         struct addr_location *al __maybe_unused)
 827{
 828        zfree(&iter->priv);
 829        iter->he = NULL;
 830
 831        return iter->curr >= iter->total ? 0 : -1;
 832}
 833
 834static int
 835iter_prepare_normal_entry(struct hist_entry_iter *iter __maybe_unused,
 836                          struct addr_location *al __maybe_unused)
 837{
 838        return 0;
 839}
 840
 841static int
 842iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location *al)
 843{
 844        struct perf_evsel *evsel = iter->evsel;
 845        struct perf_sample *sample = iter->sample;
 846        struct hist_entry *he;
 847
 848        he = hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL,
 849                              sample, true);
 850        if (he == NULL)
 851                return -ENOMEM;
 852
 853        iter->he = he;
 854        return 0;
 855}
 856
 857static int
 858iter_finish_normal_entry(struct hist_entry_iter *iter,
 859                         struct addr_location *al __maybe_unused)
 860{
 861        struct hist_entry *he = iter->he;
 862        struct perf_evsel *evsel = iter->evsel;
 863        struct perf_sample *sample = iter->sample;
 864
 865        if (he == NULL)
 866                return 0;
 867
 868        iter->he = NULL;
 869
 870        hists__inc_nr_samples(evsel__hists(evsel), he->filtered);
 871
 872        return hist_entry__append_callchain(he, sample);
 873}
 874
 875static int
 876iter_prepare_cumulative_entry(struct hist_entry_iter *iter,
 877                              struct addr_location *al __maybe_unused)
 878{
 879        struct hist_entry **he_cache;
 880
 881        callchain_cursor_commit(&callchain_cursor);
 882
 883        /*
 884         * This is for detecting cycles or recursions so that they're
 885         * cumulated only one time to prevent entries more than 100%
 886         * overhead.
 887         */
 888        he_cache = malloc(sizeof(*he_cache) * (callchain_cursor.nr + 1));
 889        if (he_cache == NULL)
 890                return -ENOMEM;
 891
 892        iter->priv = he_cache;
 893        iter->curr = 0;
 894
 895        return 0;
 896}
 897
 898static int
 899iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
 900                                 struct addr_location *al)
 901{
 902        struct perf_evsel *evsel = iter->evsel;
 903        struct hists *hists = evsel__hists(evsel);
 904        struct perf_sample *sample = iter->sample;
 905        struct hist_entry **he_cache = iter->priv;
 906        struct hist_entry *he;
 907        int err = 0;
 908
 909        he = hists__add_entry(hists, al, iter->parent, NULL, NULL,
 910                              sample, true);
 911        if (he == NULL)
 912                return -ENOMEM;
 913
 914        iter->he = he;
 915        he_cache[iter->curr++] = he;
 916
 917        hist_entry__append_callchain(he, sample);
 918
 919        /*
 920         * We need to re-initialize the cursor since callchain_append()
 921         * advanced the cursor to the end.
 922         */
 923        callchain_cursor_commit(&callchain_cursor);
 924
 925        hists__inc_nr_samples(hists, he->filtered);
 926
 927        return err;
 928}
 929
 930static int
 931iter_next_cumulative_entry(struct hist_entry_iter *iter,
 932                           struct addr_location *al)
 933{
 934        struct callchain_cursor_node *node;
 935
 936        node = callchain_cursor_current(&callchain_cursor);
 937        if (node == NULL)
 938                return 0;
 939
 940        return fill_callchain_info(al, node, iter->hide_unresolved);
 941}
 942
 943static int
 944iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
 945                               struct addr_location *al)
 946{
 947        struct perf_evsel *evsel = iter->evsel;
 948        struct perf_sample *sample = iter->sample;
 949        struct hist_entry **he_cache = iter->priv;
 950        struct hist_entry *he;
 951        struct hist_entry he_tmp = {
 952                .hists = evsel__hists(evsel),
 953                .cpu = al->cpu,
 954                .thread = al->thread,
 955                .comm = thread__comm(al->thread),
 956                .ip = al->addr,
 957                .ms = {
 958                        .map = al->map,
 959                        .sym = al->sym,
 960                },
 961                .srcline = al->srcline ? strdup(al->srcline) : NULL,
 962                .parent = iter->parent,
 963                .raw_data = sample->raw_data,
 964                .raw_size = sample->raw_size,
 965        };
 966        int i;
 967        struct callchain_cursor cursor;
 968
 969        callchain_cursor_snapshot(&cursor, &callchain_cursor);
 970
 971        callchain_cursor_advance(&callchain_cursor);
 972
 973        /*
 974         * Check if there's duplicate entries in the callchain.
 975         * It's possible that it has cycles or recursive calls.
 976         */
 977        for (i = 0; i < iter->curr; i++) {
 978                if (hist_entry__cmp(he_cache[i], &he_tmp) == 0) {
 979                        /* to avoid calling callback function */
 980                        iter->he = NULL;
 981                        return 0;
 982                }
 983        }
 984
 985        he = hists__add_entry(evsel__hists(evsel), al, iter->parent, NULL, NULL,
 986                              sample, false);
 987        if (he == NULL)
 988                return -ENOMEM;
 989
 990        iter->he = he;
 991        he_cache[iter->curr++] = he;
 992
 993        if (hist_entry__has_callchains(he) && symbol_conf.use_callchain)
 994                callchain_append(he->callchain, &cursor, sample->period);
 995        return 0;
 996}
 997
 998static int
 999iter_finish_cumulative_entry(struct hist_entry_iter *iter,
1000                             struct addr_location *al __maybe_unused)
1001{
1002        zfree(&iter->priv);
1003        iter->he = NULL;
1004
1005        return 0;
1006}
1007
1008const struct hist_iter_ops hist_iter_mem = {
1009        .prepare_entry          = iter_prepare_mem_entry,
1010        .add_single_entry       = iter_add_single_mem_entry,
1011        .next_entry             = iter_next_nop_entry,
1012        .add_next_entry         = iter_add_next_nop_entry,
1013        .finish_entry           = iter_finish_mem_entry,
1014};
1015
1016const struct hist_iter_ops hist_iter_branch = {
1017        .prepare_entry          = iter_prepare_branch_entry,
1018        .add_single_entry       = iter_add_single_branch_entry,
1019        .next_entry             = iter_next_branch_entry,
1020        .add_next_entry         = iter_add_next_branch_entry,
1021        .finish_entry           = iter_finish_branch_entry,
1022};
1023
1024const struct hist_iter_ops hist_iter_normal = {
1025        .prepare_entry          = iter_prepare_normal_entry,
1026        .add_single_entry       = iter_add_single_normal_entry,
1027        .next_entry             = iter_next_nop_entry,
1028        .add_next_entry         = iter_add_next_nop_entry,
1029        .finish_entry           = iter_finish_normal_entry,
1030};
1031
1032const struct hist_iter_ops hist_iter_cumulative = {
1033        .prepare_entry          = iter_prepare_cumulative_entry,
1034        .add_single_entry       = iter_add_single_cumulative_entry,
1035        .next_entry             = iter_next_cumulative_entry,
1036        .add_next_entry         = iter_add_next_cumulative_entry,
1037        .finish_entry           = iter_finish_cumulative_entry,
1038};
1039
1040int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
1041                         int max_stack_depth, void *arg)
1042{
1043        int err, err2;
1044        struct map *alm = NULL;
1045
1046        if (al)
1047                alm = map__get(al->map);
1048
1049        err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
1050                                        iter->evsel, al, max_stack_depth);
1051        if (err)
1052                return err;
1053
1054        err = iter->ops->prepare_entry(iter, al);
1055        if (err)
1056                goto out;
1057
1058        err = iter->ops->add_single_entry(iter, al);
1059        if (err)
1060                goto out;
1061
1062        if (iter->he && iter->add_entry_cb) {
1063                err = iter->add_entry_cb(iter, al, true, arg);
1064                if (err)
1065                        goto out;
1066        }
1067
1068        while (iter->ops->next_entry(iter, al)) {
1069                err = iter->ops->add_next_entry(iter, al);
1070                if (err)
1071                        break;
1072
1073                if (iter->he && iter->add_entry_cb) {
1074                        err = iter->add_entry_cb(iter, al, false, arg);
1075                        if (err)
1076                                goto out;
1077                }
1078        }
1079
1080out:
1081        err2 = iter->ops->finish_entry(iter, al);
1082        if (!err)
1083                err = err2;
1084
1085        map__put(alm);
1086
1087        return err;
1088}
1089
1090int64_t
1091hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
1092{
1093        struct hists *hists = left->hists;
1094        struct perf_hpp_fmt *fmt;
1095        int64_t cmp = 0;
1096
1097        hists__for_each_sort_list(hists, fmt) {
1098                if (perf_hpp__is_dynamic_entry(fmt) &&
1099                    !perf_hpp__defined_dynamic_entry(fmt, hists))
1100                        continue;
1101
1102                cmp = fmt->cmp(fmt, left, right);
1103                if (cmp)
1104                        break;
1105        }
1106
1107        return cmp;
1108}
1109
1110int64_t
1111hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
1112{
1113        struct hists *hists = left->hists;
1114        struct perf_hpp_fmt *fmt;
1115        int64_t cmp = 0;
1116
1117        hists__for_each_sort_list(hists, fmt) {
1118                if (perf_hpp__is_dynamic_entry(fmt) &&
1119                    !perf_hpp__defined_dynamic_entry(fmt, hists))
1120                        continue;
1121
1122                cmp = fmt->collapse(fmt, left, right);
1123                if (cmp)
1124                        break;
1125        }
1126
1127        return cmp;
1128}
1129
1130void hist_entry__delete(struct hist_entry *he)
1131{
1132        struct hist_entry_ops *ops = he->ops;
1133
1134        thread__zput(he->thread);
1135        map__zput(he->ms.map);
1136
1137        if (he->branch_info) {
1138                map__zput(he->branch_info->from.map);
1139                map__zput(he->branch_info->to.map);
1140                free_srcline(he->branch_info->srcline_from);
1141                free_srcline(he->branch_info->srcline_to);
1142                zfree(&he->branch_info);
1143        }
1144
1145        if (he->mem_info) {
1146                map__zput(he->mem_info->iaddr.map);
1147                map__zput(he->mem_info->daddr.map);
1148                mem_info__zput(he->mem_info);
1149        }
1150
1151        zfree(&he->stat_acc);
1152        free_srcline(he->srcline);
1153        if (he->srcfile && he->srcfile[0])
1154                free(he->srcfile);
1155        free_callchain(he->callchain);
1156        free(he->trace_output);
1157        free(he->raw_data);
1158        ops->free(he);
1159}
1160
1161/*
1162 * If this is not the last column, then we need to pad it according to the
1163 * pre-calculated max lenght for this column, otherwise don't bother adding
1164 * spaces because that would break viewing this with, for instance, 'less',
1165 * that would show tons of trailing spaces when a long C++ demangled method
1166 * names is sampled.
1167*/
1168int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp,
1169                                   struct perf_hpp_fmt *fmt, int printed)
1170{
1171        if (!list_is_last(&fmt->list, &he->hists->hpp_list->fields)) {
1172                const int width = fmt->width(fmt, hpp, he->hists);
1173                if (printed < width) {
1174                        advance_hpp(hpp, printed);
1175                        printed = scnprintf(hpp->buf, hpp->size, "%-*s", width - printed, " ");
1176                }
1177        }
1178
1179        return printed;
1180}
1181
1182/*
1183 * collapse the histogram
1184 */
1185
1186static void hists__apply_filters(struct hists *hists, struct hist_entry *he);
1187static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *he,
1188                                       enum hist_filter type);
1189
1190typedef bool (*fmt_chk_fn)(struct perf_hpp_fmt *fmt);
1191
1192static bool check_thread_entry(struct perf_hpp_fmt *fmt)
1193{
1194        return perf_hpp__is_thread_entry(fmt) || perf_hpp__is_comm_entry(fmt);
1195}
1196
1197static void hist_entry__check_and_remove_filter(struct hist_entry *he,
1198                                                enum hist_filter type,
1199                                                fmt_chk_fn check)
1200{
1201        struct perf_hpp_fmt *fmt;
1202        bool type_match = false;
1203        struct hist_entry *parent = he->parent_he;
1204
1205        switch (type) {
1206        case HIST_FILTER__THREAD:
1207                if (symbol_conf.comm_list == NULL &&
1208                    symbol_conf.pid_list == NULL &&
1209                    symbol_conf.tid_list == NULL)
1210                        return;
1211                break;
1212        case HIST_FILTER__DSO:
1213                if (symbol_conf.dso_list == NULL)
1214                        return;
1215                break;
1216        case HIST_FILTER__SYMBOL:
1217                if (symbol_conf.sym_list == NULL)
1218                        return;
1219                break;
1220        case HIST_FILTER__PARENT:
1221        case HIST_FILTER__GUEST:
1222        case HIST_FILTER__HOST:
1223        case HIST_FILTER__SOCKET:
1224        case HIST_FILTER__C2C:
1225        default:
1226                return;
1227        }
1228
1229        /* if it's filtered by own fmt, it has to have filter bits */
1230        perf_hpp_list__for_each_format(he->hpp_list, fmt) {
1231                if (check(fmt)) {
1232                        type_match = true;
1233                        break;
1234                }
1235        }
1236
1237        if (type_match) {
1238                /*
1239                 * If the filter is for current level entry, propagate
1240                 * filter marker to parents.  The marker bit was
1241                 * already set by default so it only needs to clear
1242                 * non-filtered entries.
1243                 */
1244                if (!(he->filtered & (1 << type))) {
1245                        while (parent) {
1246                                parent->filtered &= ~(1 << type);
1247                                parent = parent->parent_he;
1248                        }
1249                }
1250        } else {
1251                /*
1252                 * If current entry doesn't have matching formats, set
1253                 * filter marker for upper level entries.  it will be
1254                 * cleared if its lower level entries is not filtered.
1255                 *
1256                 * For lower-level entries, it inherits parent's
1257                 * filter bit so that lower level entries of a
1258                 * non-filtered entry won't set the filter marker.
1259                 */
1260                if (parent == NULL)
1261                        he->filtered |= (1 << type);
1262                else
1263                        he->filtered |= (parent->filtered & (1 << type));
1264        }
1265}
1266
1267static void hist_entry__apply_hierarchy_filters(struct hist_entry *he)
1268{
1269        hist_entry__check_and_remove_filter(he, HIST_FILTER__THREAD,
1270                                            check_thread_entry);
1271
1272        hist_entry__check_and_remove_filter(he, HIST_FILTER__DSO,
1273                                            perf_hpp__is_dso_entry);
1274
1275        hist_entry__check_and_remove_filter(he, HIST_FILTER__SYMBOL,
1276                                            perf_hpp__is_sym_entry);
1277
1278        hists__apply_filters(he->hists, he);
1279}
1280
1281static struct hist_entry *hierarchy_insert_entry(struct hists *hists,
1282                                                 struct rb_root *root,
1283                                                 struct hist_entry *he,
1284                                                 struct hist_entry *parent_he,
1285                                                 struct perf_hpp_list *hpp_list)
1286{
1287        struct rb_node **p = &root->rb_node;
1288        struct rb_node *parent = NULL;
1289        struct hist_entry *iter, *new;
1290        struct perf_hpp_fmt *fmt;
1291        int64_t cmp;
1292
1293        while (*p != NULL) {
1294                parent = *p;
1295                iter = rb_entry(parent, struct hist_entry, rb_node_in);
1296
1297                cmp = 0;
1298                perf_hpp_list__for_each_sort_list(hpp_list, fmt) {
1299                        cmp = fmt->collapse(fmt, iter, he);
1300                        if (cmp)
1301                                break;
1302                }
1303
1304                if (!cmp) {
1305                        he_stat__add_stat(&iter->stat, &he->stat);
1306                        return iter;
1307                }
1308
1309                if (cmp < 0)
1310                        p = &parent->rb_left;
1311                else
1312                        p = &parent->rb_right;
1313        }
1314
1315        new = hist_entry__new(he, true);
1316        if (new == NULL)
1317                return NULL;
1318
1319        hists->nr_entries++;
1320
1321        /* save related format list for output */
1322        new->hpp_list = hpp_list;
1323        new->parent_he = parent_he;
1324
1325        hist_entry__apply_hierarchy_filters(new);
1326
1327        /* some fields are now passed to 'new' */
1328        perf_hpp_list__for_each_sort_list(hpp_list, fmt) {
1329                if (perf_hpp__is_trace_entry(fmt) || perf_hpp__is_dynamic_entry(fmt))
1330                        he->trace_output = NULL;
1331                else
1332                        new->trace_output = NULL;
1333
1334                if (perf_hpp__is_srcline_entry(fmt))
1335                        he->srcline = NULL;
1336                else
1337                        new->srcline = NULL;
1338
1339                if (perf_hpp__is_srcfile_entry(fmt))
1340                        he->srcfile = NULL;
1341                else
1342                        new->srcfile = NULL;
1343        }
1344
1345        rb_link_node(&new->rb_node_in, parent, p);
1346        rb_insert_color(&new->rb_node_in, root);
1347        return new;
1348}
1349
1350static int hists__hierarchy_insert_entry(struct hists *hists,
1351                                         struct rb_root *root,
1352                                         struct hist_entry *he)
1353{
1354        struct perf_hpp_list_node *node;
1355        struct hist_entry *new_he = NULL;
1356        struct hist_entry *parent = NULL;
1357        int depth = 0;
1358        int ret = 0;
1359
1360        list_for_each_entry(node, &hists->hpp_formats, list) {
1361                /* skip period (overhead) and elided columns */
1362                if (node->level == 0 || node->skip)
1363                        continue;
1364
1365                /* insert copy of 'he' for each fmt into the hierarchy */
1366                new_he = hierarchy_insert_entry(hists, root, he, parent, &node->hpp);
1367                if (new_he == NULL) {
1368                        ret = -1;
1369                        break;
1370                }
1371
1372                root = &new_he->hroot_in;
1373                new_he->depth = depth++;
1374                parent = new_he;
1375        }
1376
1377        if (new_he) {
1378                new_he->leaf = true;
1379
1380                if (hist_entry__has_callchains(new_he) &&
1381                    symbol_conf.use_callchain) {
1382                        callchain_cursor_reset(&callchain_cursor);
1383                        if (callchain_merge(&callchain_cursor,
1384                                            new_he->callchain,
1385                                            he->callchain) < 0)
1386                                ret = -1;
1387                }
1388        }
1389
1390        /* 'he' is no longer used */
1391        hist_entry__delete(he);
1392
1393        /* return 0 (or -1) since it already applied filters */
1394        return ret;
1395}
1396
1397static int hists__collapse_insert_entry(struct hists *hists,
1398                                        struct rb_root *root,
1399                                        struct hist_entry *he)
1400{
1401        struct rb_node **p = &root->rb_node;
1402        struct rb_node *parent = NULL;
1403        struct hist_entry *iter;
1404        int64_t cmp;
1405
1406        if (symbol_conf.report_hierarchy)
1407                return hists__hierarchy_insert_entry(hists, root, he);
1408
1409        while (*p != NULL) {
1410                parent = *p;
1411                iter = rb_entry(parent, struct hist_entry, rb_node_in);
1412
1413                cmp = hist_entry__collapse(iter, he);
1414
1415                if (!cmp) {
1416                        int ret = 0;
1417
1418                        he_stat__add_stat(&iter->stat, &he->stat);
1419                        if (symbol_conf.cumulate_callchain)
1420                                he_stat__add_stat(iter->stat_acc, he->stat_acc);
1421
1422                        if (hist_entry__has_callchains(he) && symbol_conf.use_callchain) {
1423                                callchain_cursor_reset(&callchain_cursor);
1424                                if (callchain_merge(&callchain_cursor,
1425                                                    iter->callchain,
1426                                                    he->callchain) < 0)
1427                                        ret = -1;
1428                        }
1429                        hist_entry__delete(he);
1430                        return ret;
1431                }
1432
1433                if (cmp < 0)
1434                        p = &(*p)->rb_left;
1435                else
1436                        p = &(*p)->rb_right;
1437        }
1438        hists->nr_entries++;
1439
1440        rb_link_node(&he->rb_node_in, parent, p);
1441        rb_insert_color(&he->rb_node_in, root);
1442        return 1;
1443}
1444
1445struct rb_root *hists__get_rotate_entries_in(struct hists *hists)
1446{
1447        struct rb_root *root;
1448
1449        pthread_mutex_lock(&hists->lock);
1450
1451        root = hists->entries_in;
1452        if (++hists->entries_in > &hists->entries_in_array[1])
1453                hists->entries_in = &hists->entries_in_array[0];
1454
1455        pthread_mutex_unlock(&hists->lock);
1456
1457        return root;
1458}
1459
1460static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
1461{
1462        hists__filter_entry_by_dso(hists, he);
1463        hists__filter_entry_by_thread(hists, he);
1464        hists__filter_entry_by_symbol(hists, he);
1465        hists__filter_entry_by_socket(hists, he);
1466}
1467
1468int hists__collapse_resort(struct hists *hists, struct ui_progress *prog)
1469{
1470        struct rb_root *root;
1471        struct rb_node *next;
1472        struct hist_entry *n;
1473        int ret;
1474
1475        if (!hists__has(hists, need_collapse))
1476                return 0;
1477
1478        hists->nr_entries = 0;
1479
1480        root = hists__get_rotate_entries_in(hists);
1481
1482        next = rb_first(root);
1483
1484        while (next) {
1485                if (session_done())
1486                        break;
1487                n = rb_entry(next, struct hist_entry, rb_node_in);
1488                next = rb_next(&n->rb_node_in);
1489
1490                rb_erase(&n->rb_node_in, root);
1491                ret = hists__collapse_insert_entry(hists, &hists->entries_collapsed, n);
1492                if (ret < 0)
1493                        return -1;
1494
1495                if (ret) {
1496                        /*
1497                         * If it wasn't combined with one of the entries already
1498                         * collapsed, we need to apply the filters that may have
1499                         * been set by, say, the hist_browser.
1500                         */
1501                        hists__apply_filters(hists, n);
1502                }
1503                if (prog)
1504                        ui_progress__update(prog, 1);
1505        }
1506        return 0;
1507}
1508
1509static int hist_entry__sort(struct hist_entry *a, struct hist_entry *b)
1510{
1511        struct hists *hists = a->hists;
1512        struct perf_hpp_fmt *fmt;
1513        int64_t cmp = 0;
1514
1515        hists__for_each_sort_list(hists, fmt) {
1516                if (perf_hpp__should_skip(fmt, a->hists))
1517                        continue;
1518
1519                cmp = fmt->sort(fmt, a, b);
1520                if (cmp)
1521                        break;
1522        }
1523
1524        return cmp;
1525}
1526
1527static void hists__reset_filter_stats(struct hists *hists)
1528{
1529        hists->nr_non_filtered_entries = 0;
1530        hists->stats.total_non_filtered_period = 0;
1531}
1532
1533void hists__reset_stats(struct hists *hists)
1534{
1535        hists->nr_entries = 0;
1536        hists->stats.total_period = 0;
1537
1538        hists__reset_filter_stats(hists);
1539}
1540
1541static void hists__inc_filter_stats(struct hists *hists, struct hist_entry *h)
1542{
1543        hists->nr_non_filtered_entries++;
1544        hists->stats.total_non_filtered_period += h->stat.period;
1545}
1546
1547void hists__inc_stats(struct hists *hists, struct hist_entry *h)
1548{
1549        if (!h->filtered)
1550                hists__inc_filter_stats(hists, h);
1551
1552        hists->nr_entries++;
1553        hists->stats.total_period += h->stat.period;
1554}
1555
1556static void hierarchy_recalc_total_periods(struct hists *hists)
1557{
1558        struct rb_node *node;
1559        struct hist_entry *he;
1560
1561        node = rb_first(&hists->entries);
1562
1563        hists->stats.total_period = 0;
1564        hists->stats.total_non_filtered_period = 0;
1565
1566        /*
1567         * recalculate total period using top-level entries only
1568         * since lower level entries only see non-filtered entries
1569         * but upper level entries have sum of both entries.
1570         */
1571        while (node) {
1572                he = rb_entry(node, struct hist_entry, rb_node);
1573                node = rb_next(node);
1574
1575                hists->stats.total_period += he->stat.period;
1576                if (!he->filtered)
1577                        hists->stats.total_non_filtered_period += he->stat.period;
1578        }
1579}
1580
1581static void hierarchy_insert_output_entry(struct rb_root *root,
1582                                          struct hist_entry *he)
1583{
1584        struct rb_node **p = &root->rb_node;
1585        struct rb_node *parent = NULL;
1586        struct hist_entry *iter;
1587        struct perf_hpp_fmt *fmt;
1588
1589        while (*p != NULL) {
1590                parent = *p;
1591                iter = rb_entry(parent, struct hist_entry, rb_node);
1592
1593                if (hist_entry__sort(he, iter) > 0)
1594                        p = &parent->rb_left;
1595                else
1596                        p = &parent->rb_right;
1597        }
1598
1599        rb_link_node(&he->rb_node, parent, p);
1600        rb_insert_color(&he->rb_node, root);
1601
1602        /* update column width of dynamic entry */
1603        perf_hpp_list__for_each_sort_list(he->hpp_list, fmt) {
1604                if (perf_hpp__is_dynamic_entry(fmt))
1605                        fmt->sort(fmt, he, NULL);
1606        }
1607}
1608
1609static void hists__hierarchy_output_resort(struct hists *hists,
1610                                           struct ui_progress *prog,
1611                                           struct rb_root *root_in,
1612                                           struct rb_root *root_out,
1613                                           u64 min_callchain_hits,
1614                                           bool use_callchain)
1615{
1616        struct rb_node *node;
1617        struct hist_entry *he;
1618
1619        *root_out = RB_ROOT;
1620        node = rb_first(root_in);
1621
1622        while (node) {
1623                he = rb_entry(node, struct hist_entry, rb_node_in);
1624                node = rb_next(node);
1625
1626                hierarchy_insert_output_entry(root_out, he);
1627
1628                if (prog)
1629                        ui_progress__update(prog, 1);
1630
1631                hists->nr_entries++;
1632                if (!he->filtered) {
1633                        hists->nr_non_filtered_entries++;
1634                        hists__calc_col_len(hists, he);
1635                }
1636
1637                if (!he->leaf) {
1638                        hists__hierarchy_output_resort(hists, prog,
1639                                                       &he->hroot_in,
1640                                                       &he->hroot_out,
1641                                                       min_callchain_hits,
1642                                                       use_callchain);
1643                        continue;
1644                }
1645
1646                if (!use_callchain)
1647                        continue;
1648
1649                if (callchain_param.mode == CHAIN_GRAPH_REL) {
1650                        u64 total = he->stat.period;
1651
1652                        if (symbol_conf.cumulate_callchain)
1653                                total = he->stat_acc->period;
1654
1655                        min_callchain_hits = total * (callchain_param.min_percent / 100);
1656                }
1657
1658                callchain_param.sort(&he->sorted_chain, he->callchain,
1659                                     min_callchain_hits, &callchain_param);
1660        }
1661}
1662
1663static void __hists__insert_output_entry(struct rb_root *entries,
1664                                         struct hist_entry *he,
1665                                         u64 min_callchain_hits,
1666                                         bool use_callchain)
1667{
1668        struct rb_node **p = &entries->rb_node;
1669        struct rb_node *parent = NULL;
1670        struct hist_entry *iter;
1671        struct perf_hpp_fmt *fmt;
1672
1673        if (use_callchain) {
1674                if (callchain_param.mode == CHAIN_GRAPH_REL) {
1675                        u64 total = he->stat.period;
1676
1677                        if (symbol_conf.cumulate_callchain)
1678                                total = he->stat_acc->period;
1679
1680                        min_callchain_hits = total * (callchain_param.min_percent / 100);
1681                }
1682                callchain_param.sort(&he->sorted_chain, he->callchain,
1683                                      min_callchain_hits, &callchain_param);
1684        }
1685
1686        while (*p != NULL) {
1687                parent = *p;
1688                iter = rb_entry(parent, struct hist_entry, rb_node);
1689
1690                if (hist_entry__sort(he, iter) > 0)
1691                        p = &(*p)->rb_left;
1692                else
1693                        p = &(*p)->rb_right;
1694        }
1695
1696        rb_link_node(&he->rb_node, parent, p);
1697        rb_insert_color(&he->rb_node, entries);
1698
1699        perf_hpp_list__for_each_sort_list(&perf_hpp_list, fmt) {
1700                if (perf_hpp__is_dynamic_entry(fmt) &&
1701                    perf_hpp__defined_dynamic_entry(fmt, he->hists))
1702                        fmt->sort(fmt, he, NULL);  /* update column width */
1703        }
1704}
1705
1706static void output_resort(struct hists *hists, struct ui_progress *prog,
1707                          bool use_callchain, hists__resort_cb_t cb)
1708{
1709        struct rb_root *root;
1710        struct rb_node *next;
1711        struct hist_entry *n;
1712        u64 callchain_total;
1713        u64 min_callchain_hits;
1714
1715        callchain_total = hists->callchain_period;
1716        if (symbol_conf.filter_relative)
1717                callchain_total = hists->callchain_non_filtered_period;
1718
1719        min_callchain_hits = callchain_total * (callchain_param.min_percent / 100);
1720
1721        hists__reset_stats(hists);
1722        hists__reset_col_len(hists);
1723
1724        if (symbol_conf.report_hierarchy) {
1725                hists__hierarchy_output_resort(hists, prog,
1726                                               &hists->entries_collapsed,
1727                                               &hists->entries,
1728                                               min_callchain_hits,
1729                                               use_callchain);
1730                hierarchy_recalc_total_periods(hists);
1731                return;
1732        }
1733
1734        if (hists__has(hists, need_collapse))
1735                root = &hists->entries_collapsed;
1736        else
1737                root = hists->entries_in;
1738
1739        next = rb_first(root);
1740        hists->entries = RB_ROOT;
1741
1742        while (next) {
1743                n = rb_entry(next, struct hist_entry, rb_node_in);
1744                next = rb_next(&n->rb_node_in);
1745
1746                if (cb && cb(n))
1747                        continue;
1748
1749                __hists__insert_output_entry(&hists->entries, n, min_callchain_hits, use_callchain);
1750                hists__inc_stats(hists, n);
1751
1752                if (!n->filtered)
1753                        hists__calc_col_len(hists, n);
1754
1755                if (prog)
1756                        ui_progress__update(prog, 1);
1757        }
1758}
1759
1760void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *prog)
1761{
1762        bool use_callchain;
1763
1764        if (evsel && symbol_conf.use_callchain && !symbol_conf.show_ref_callgraph)
1765                use_callchain = evsel__has_callchain(evsel);
1766        else
1767                use_callchain = symbol_conf.use_callchain;
1768
1769        use_callchain |= symbol_conf.show_branchflag_count;
1770
1771        output_resort(evsel__hists(evsel), prog, use_callchain, NULL);
1772}
1773
1774void hists__output_resort(struct hists *hists, struct ui_progress *prog)
1775{
1776        output_resort(hists, prog, symbol_conf.use_callchain, NULL);
1777}
1778
1779void hists__output_resort_cb(struct hists *hists, struct ui_progress *prog,
1780                             hists__resort_cb_t cb)
1781{
1782        output_resort(hists, prog, symbol_conf.use_callchain, cb);
1783}
1784
1785static bool can_goto_child(struct hist_entry *he, enum hierarchy_move_dir hmd)
1786{
1787        if (he->leaf || hmd == HMD_FORCE_SIBLING)
1788                return false;
1789
1790        if (he->unfolded || hmd == HMD_FORCE_CHILD)
1791                return true;
1792
1793        return false;
1794}
1795
1796struct rb_node *rb_hierarchy_last(struct rb_node *node)
1797{
1798        struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
1799
1800        while (can_goto_child(he, HMD_NORMAL)) {
1801                node = rb_last(&he->hroot_out);
1802                he = rb_entry(node, struct hist_entry, rb_node);
1803        }
1804        return node;
1805}
1806
1807struct rb_node *__rb_hierarchy_next(struct rb_node *node, enum hierarchy_move_dir hmd)
1808{
1809        struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
1810
1811        if (can_goto_child(he, hmd))
1812                node = rb_first(&he->hroot_out);
1813        else
1814                node = rb_next(node);
1815
1816        while (node == NULL) {
1817                he = he->parent_he;
1818                if (he == NULL)
1819                        break;
1820
1821                node = rb_next(&he->rb_node);
1822        }
1823        return node;
1824}
1825
1826struct rb_node *rb_hierarchy_prev(struct rb_node *node)
1827{
1828        struct hist_entry *he = rb_entry(node, struct hist_entry, rb_node);
1829
1830        node = rb_prev(node);
1831        if (node)
1832                return rb_hierarchy_last(node);
1833
1834        he = he->parent_he;
1835        if (he == NULL)
1836                return NULL;
1837
1838        return &he->rb_node;
1839}
1840
1841bool hist_entry__has_hierarchy_children(struct hist_entry *he, float limit)
1842{
1843        struct rb_node *node;
1844        struct hist_entry *child;
1845        float percent;
1846
1847        if (he->leaf)
1848                return false;
1849
1850        node = rb_first(&he->hroot_out);
1851        child = rb_entry(node, struct hist_entry, rb_node);
1852
1853        while (node && child->filtered) {
1854                node = rb_next(node);
1855                child = rb_entry(node, struct hist_entry, rb_node);
1856        }
1857
1858        if (node)
1859                percent = hist_entry__get_percent_limit(child);
1860        else
1861                percent = 0;
1862
1863        return node && percent >= limit;
1864}
1865
1866static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
1867                                       enum hist_filter filter)
1868{
1869        h->filtered &= ~(1 << filter);
1870
1871        if (symbol_conf.report_hierarchy) {
1872                struct hist_entry *parent = h->parent_he;
1873
1874                while (parent) {
1875                        he_stat__add_stat(&parent->stat, &h->stat);
1876
1877                        parent->filtered &= ~(1 << filter);
1878
1879                        if (parent->filtered)
1880                                goto next;
1881
1882                        /* force fold unfiltered entry for simplicity */
1883                        parent->unfolded = false;
1884                        parent->has_no_entry = false;
1885                        parent->row_offset = 0;
1886                        parent->nr_rows = 0;
1887next:
1888                        parent = parent->parent_he;
1889                }
1890        }
1891
1892        if (h->filtered)
1893                return;
1894
1895        /* force fold unfiltered entry for simplicity */
1896        h->unfolded = false;
1897        h->has_no_entry = false;
1898        h->row_offset = 0;
1899        h->nr_rows = 0;
1900
1901        hists->stats.nr_non_filtered_samples += h->stat.nr_events;
1902
1903        hists__inc_filter_stats(hists, h);
1904        hists__calc_col_len(hists, h);
1905}
1906
1907
1908static bool hists__filter_entry_by_dso(struct hists *hists,
1909                                       struct hist_entry *he)
1910{
1911        if (hists->dso_filter != NULL &&
1912            (he->ms.map == NULL || he->ms.map->dso != hists->dso_filter)) {
1913                he->filtered |= (1 << HIST_FILTER__DSO);
1914                return true;
1915        }
1916
1917        return false;
1918}
1919
1920static bool hists__filter_entry_by_thread(struct hists *hists,
1921                                          struct hist_entry *he)
1922{
1923        if (hists->thread_filter != NULL &&
1924            he->thread != hists->thread_filter) {
1925                he->filtered |= (1 << HIST_FILTER__THREAD);
1926                return true;
1927        }
1928
1929        return false;
1930}
1931
1932static bool hists__filter_entry_by_symbol(struct hists *hists,
1933                                          struct hist_entry *he)
1934{
1935        if (hists->symbol_filter_str != NULL &&
1936            (!he->ms.sym || strstr(he->ms.sym->name,
1937                                   hists->symbol_filter_str) == NULL)) {
1938                he->filtered |= (1 << HIST_FILTER__SYMBOL);
1939                return true;
1940        }
1941
1942        return false;
1943}
1944
1945static bool hists__filter_entry_by_socket(struct hists *hists,
1946                                          struct hist_entry *he)
1947{
1948        if ((hists->socket_filter > -1) &&
1949            (he->socket != hists->socket_filter)) {
1950                he->filtered |= (1 << HIST_FILTER__SOCKET);
1951                return true;
1952        }
1953
1954        return false;
1955}
1956
1957typedef bool (*filter_fn_t)(struct hists *hists, struct hist_entry *he);
1958
1959static void hists__filter_by_type(struct hists *hists, int type, filter_fn_t filter)
1960{
1961        struct rb_node *nd;
1962
1963        hists->stats.nr_non_filtered_samples = 0;
1964
1965        hists__reset_filter_stats(hists);
1966        hists__reset_col_len(hists);
1967
1968        for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
1969                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
1970
1971                if (filter(hists, h))
1972                        continue;
1973
1974                hists__remove_entry_filter(hists, h, type);
1975        }
1976}
1977
1978static void resort_filtered_entry(struct rb_root *root, struct hist_entry *he)
1979{
1980        struct rb_node **p = &root->rb_node;
1981        struct rb_node *parent = NULL;
1982        struct hist_entry *iter;
1983        struct rb_root new_root = RB_ROOT;
1984        struct rb_node *nd;
1985
1986        while (*p != NULL) {
1987                parent = *p;
1988                iter = rb_entry(parent, struct hist_entry, rb_node);
1989
1990                if (hist_entry__sort(he, iter) > 0)
1991                        p = &(*p)->rb_left;
1992                else
1993                        p = &(*p)->rb_right;
1994        }
1995
1996        rb_link_node(&he->rb_node, parent, p);
1997        rb_insert_color(&he->rb_node, root);
1998
1999        if (he->leaf || he->filtered)
2000                return;
2001
2002        nd = rb_first(&he->hroot_out);
2003        while (nd) {
2004                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
2005
2006                nd = rb_next(nd);
2007                rb_erase(&h->rb_node, &he->hroot_out);
2008
2009                resort_filtered_entry(&new_root, h);
2010        }
2011
2012        he->hroot_out = new_root;
2013}
2014
2015static void hists__filter_hierarchy(struct hists *hists, int type, const void *arg)
2016{
2017        struct rb_node *nd;
2018        struct rb_root new_root = RB_ROOT;
2019
2020        hists->stats.nr_non_filtered_samples = 0;
2021
2022        hists__reset_filter_stats(hists);
2023        hists__reset_col_len(hists);
2024
2025        nd = rb_first(&hists->entries);
2026        while (nd) {
2027                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
2028                int ret;
2029
2030                ret = hist_entry__filter(h, type, arg);
2031
2032                /*
2033                 * case 1. non-matching type
2034                 * zero out the period, set filter marker and move to child
2035                 */
2036                if (ret < 0) {
2037                        memset(&h->stat, 0, sizeof(h->stat));
2038                        h->filtered |= (1 << type);
2039
2040                        nd = __rb_hierarchy_next(&h->rb_node, HMD_FORCE_CHILD);
2041                }
2042                /*
2043                 * case 2. matched type (filter out)
2044                 * set filter marker and move to next
2045                 */
2046                else if (ret == 1) {
2047                        h->filtered |= (1 << type);
2048
2049                        nd = __rb_hierarchy_next(&h->rb_node, HMD_FORCE_SIBLING);
2050                }
2051                /*
2052                 * case 3. ok (not filtered)
2053                 * add period to hists and parents, erase the filter marker
2054                 * and move to next sibling
2055                 */
2056                else {
2057                        hists__remove_entry_filter(hists, h, type);
2058
2059                        nd = __rb_hierarchy_next(&h->rb_node, HMD_FORCE_SIBLING);
2060                }
2061        }
2062
2063        hierarchy_recalc_total_periods(hists);
2064
2065        /*
2066         * resort output after applying a new filter since filter in a lower
2067         * hierarchy can change periods in a upper hierarchy.
2068         */
2069        nd = rb_first(&hists->entries);
2070        while (nd) {
2071                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
2072
2073                nd = rb_next(nd);
2074                rb_erase(&h->rb_node, &hists->entries);
2075
2076                resort_filtered_entry(&new_root, h);
2077        }
2078
2079        hists->entries = new_root;
2080}
2081
2082void hists__filter_by_thread(struct hists *hists)
2083{
2084        if (symbol_conf.report_hierarchy)
2085                hists__filter_hierarchy(hists, HIST_FILTER__THREAD,
2086                                        hists->thread_filter);
2087        else
2088                hists__filter_by_type(hists, HIST_FILTER__THREAD,
2089                                      hists__filter_entry_by_thread);
2090}
2091
2092void hists__filter_by_dso(struct hists *hists)
2093{
2094        if (symbol_conf.report_hierarchy)
2095                hists__filter_hierarchy(hists, HIST_FILTER__DSO,
2096                                        hists->dso_filter);
2097        else
2098                hists__filter_by_type(hists, HIST_FILTER__DSO,
2099                                      hists__filter_entry_by_dso);
2100}
2101
2102void hists__filter_by_symbol(struct hists *hists)
2103{
2104        if (symbol_conf.report_hierarchy)
2105                hists__filter_hierarchy(hists, HIST_FILTER__SYMBOL,
2106                                        hists->symbol_filter_str);
2107        else
2108                hists__filter_by_type(hists, HIST_FILTER__SYMBOL,
2109                                      hists__filter_entry_by_symbol);
2110}
2111
2112void hists__filter_by_socket(struct hists *hists)
2113{
2114        if (symbol_conf.report_hierarchy)
2115                hists__filter_hierarchy(hists, HIST_FILTER__SOCKET,
2116                                        &hists->socket_filter);
2117        else
2118                hists__filter_by_type(hists, HIST_FILTER__SOCKET,
2119                                      hists__filter_entry_by_socket);
2120}
2121
2122void events_stats__inc(struct events_stats *stats, u32 type)
2123{
2124        ++stats->nr_events[0];
2125        ++stats->nr_events[type];
2126}
2127
2128void hists__inc_nr_events(struct hists *hists, u32 type)
2129{
2130        events_stats__inc(&hists->stats, type);
2131}
2132
2133void hists__inc_nr_samples(struct hists *hists, bool filtered)
2134{
2135        events_stats__inc(&hists->stats, PERF_RECORD_SAMPLE);
2136        if (!filtered)
2137                hists->stats.nr_non_filtered_samples++;
2138}
2139
2140static struct hist_entry *hists__add_dummy_entry(struct hists *hists,
2141                                                 struct hist_entry *pair)
2142{
2143        struct rb_root *root;
2144        struct rb_node **p;
2145        struct rb_node *parent = NULL;
2146        struct hist_entry *he;
2147        int64_t cmp;
2148
2149        if (hists__has(hists, need_collapse))
2150                root = &hists->entries_collapsed;
2151        else
2152                root = hists->entries_in;
2153
2154        p = &root->rb_node;
2155
2156        while (*p != NULL) {
2157                parent = *p;
2158                he = rb_entry(parent, struct hist_entry, rb_node_in);
2159
2160                cmp = hist_entry__collapse(he, pair);
2161
2162                if (!cmp)
2163                        goto out;
2164
2165                if (cmp < 0)
2166                        p = &(*p)->rb_left;
2167                else
2168                        p = &(*p)->rb_right;
2169        }
2170
2171        he = hist_entry__new(pair, true);
2172        if (he) {
2173                memset(&he->stat, 0, sizeof(he->stat));
2174                he->hists = hists;
2175                if (symbol_conf.cumulate_callchain)
2176                        memset(he->stat_acc, 0, sizeof(he->stat));
2177                rb_link_node(&he->rb_node_in, parent, p);
2178                rb_insert_color(&he->rb_node_in, root);
2179                hists__inc_stats(hists, he);
2180                he->dummy = true;
2181        }
2182out:
2183        return he;
2184}
2185
2186static struct hist_entry *add_dummy_hierarchy_entry(struct hists *hists,
2187                                                    struct rb_root *root,
2188                                                    struct hist_entry *pair)
2189{
2190        struct rb_node **p;
2191        struct rb_node *parent = NULL;
2192        struct hist_entry *he;
2193        struct perf_hpp_fmt *fmt;
2194
2195        p = &root->rb_node;
2196        while (*p != NULL) {
2197                int64_t cmp = 0;
2198
2199                parent = *p;
2200                he = rb_entry(parent, struct hist_entry, rb_node_in);
2201
2202                perf_hpp_list__for_each_sort_list(he->hpp_list, fmt) {
2203                        cmp = fmt->collapse(fmt, he, pair);
2204                        if (cmp)
2205                                break;
2206                }
2207                if (!cmp)
2208                        goto out;
2209
2210                if (cmp < 0)
2211                        p = &parent->rb_left;
2212                else
2213                        p = &parent->rb_right;
2214        }
2215
2216        he = hist_entry__new(pair, true);
2217        if (he) {
2218                rb_link_node(&he->rb_node_in, parent, p);
2219                rb_insert_color(&he->rb_node_in, root);
2220
2221                he->dummy = true;
2222                he->hists = hists;
2223                memset(&he->stat, 0, sizeof(he->stat));
2224                hists__inc_stats(hists, he);
2225        }
2226out:
2227        return he;
2228}
2229
2230static struct hist_entry *hists__find_entry(struct hists *hists,
2231                                            struct hist_entry *he)
2232{
2233        struct rb_node *n;
2234
2235        if (hists__has(hists, need_collapse))
2236                n = hists->entries_collapsed.rb_node;
2237        else
2238                n = hists->entries_in->rb_node;
2239
2240        while (n) {
2241                struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node_in);
2242                int64_t cmp = hist_entry__collapse(iter, he);
2243
2244                if (cmp < 0)
2245                        n = n->rb_left;
2246                else if (cmp > 0)
2247                        n = n->rb_right;
2248                else
2249                        return iter;
2250        }
2251
2252        return NULL;
2253}
2254
2255static struct hist_entry *hists__find_hierarchy_entry(struct rb_root *root,
2256                                                      struct hist_entry *he)
2257{
2258        struct rb_node *n = root->rb_node;
2259
2260        while (n) {
2261                struct hist_entry *iter;
2262                struct perf_hpp_fmt *fmt;
2263                int64_t cmp = 0;
2264
2265                iter = rb_entry(n, struct hist_entry, rb_node_in);
2266                perf_hpp_list__for_each_sort_list(he->hpp_list, fmt) {
2267                        cmp = fmt->collapse(fmt, iter, he);
2268                        if (cmp)
2269                                break;
2270                }
2271
2272                if (cmp < 0)
2273                        n = n->rb_left;
2274                else if (cmp > 0)
2275                        n = n->rb_right;
2276                else
2277                        return iter;
2278        }
2279
2280        return NULL;
2281}
2282
2283static void hists__match_hierarchy(struct rb_root *leader_root,
2284                                   struct rb_root *other_root)
2285{
2286        struct rb_node *nd;
2287        struct hist_entry *pos, *pair;
2288
2289        for (nd = rb_first(leader_root); nd; nd = rb_next(nd)) {
2290                pos  = rb_entry(nd, struct hist_entry, rb_node_in);
2291                pair = hists__find_hierarchy_entry(other_root, pos);
2292
2293                if (pair) {
2294                        hist_entry__add_pair(pair, pos);
2295                        hists__match_hierarchy(&pos->hroot_in, &pair->hroot_in);
2296                }
2297        }
2298}
2299
2300/*
2301 * Look for pairs to link to the leader buckets (hist_entries):
2302 */
2303void hists__match(struct hists *leader, struct hists *other)
2304{
2305        struct rb_root *root;
2306        struct rb_node *nd;
2307        struct hist_entry *pos, *pair;
2308
2309        if (symbol_conf.report_hierarchy) {
2310                /* hierarchy report always collapses entries */
2311                return hists__match_hierarchy(&leader->entries_collapsed,
2312                                              &other->entries_collapsed);
2313        }
2314
2315        if (hists__has(leader, need_collapse))
2316                root = &leader->entries_collapsed;
2317        else
2318                root = leader->entries_in;
2319
2320        for (nd = rb_first(root); nd; nd = rb_next(nd)) {
2321                pos  = rb_entry(nd, struct hist_entry, rb_node_in);
2322                pair = hists__find_entry(other, pos);
2323
2324                if (pair)
2325                        hist_entry__add_pair(pair, pos);
2326        }
2327}
2328
2329static int hists__link_hierarchy(struct hists *leader_hists,
2330                                 struct hist_entry *parent,
2331                                 struct rb_root *leader_root,
2332                                 struct rb_root *other_root)
2333{
2334        struct rb_node *nd;
2335        struct hist_entry *pos, *leader;
2336
2337        for (nd = rb_first(other_root); nd; nd = rb_next(nd)) {
2338                pos = rb_entry(nd, struct hist_entry, rb_node_in);
2339
2340                if (hist_entry__has_pairs(pos)) {
2341                        bool found = false;
2342
2343                        list_for_each_entry(leader, &pos->pairs.head, pairs.node) {
2344                                if (leader->hists == leader_hists) {
2345                                        found = true;
2346                                        break;
2347                                }
2348                        }
2349                        if (!found)
2350                                return -1;
2351                } else {
2352                        leader = add_dummy_hierarchy_entry(leader_hists,
2353                                                           leader_root, pos);
2354                        if (leader == NULL)
2355                                return -1;
2356
2357                        /* do not point parent in the pos */
2358                        leader->parent_he = parent;
2359
2360                        hist_entry__add_pair(pos, leader);
2361                }
2362
2363                if (!pos->leaf) {
2364                        if (hists__link_hierarchy(leader_hists, leader,
2365                                                  &leader->hroot_in,
2366                                                  &pos->hroot_in) < 0)
2367                                return -1;
2368                }
2369        }
2370        return 0;
2371}
2372
2373/*
2374 * Look for entries in the other hists that are not present in the leader, if
2375 * we find them, just add a dummy entry on the leader hists, with period=0,
2376 * nr_events=0, to serve as the list header.
2377 */
2378int hists__link(struct hists *leader, struct hists *other)
2379{
2380        struct rb_root *root;
2381        struct rb_node *nd;
2382        struct hist_entry *pos, *pair;
2383
2384        if (symbol_conf.report_hierarchy) {
2385                /* hierarchy report always collapses entries */
2386                return hists__link_hierarchy(leader, NULL,
2387                                             &leader->entries_collapsed,
2388                                             &other->entries_collapsed);
2389        }
2390
2391        if (hists__has(other, need_collapse))
2392                root = &other->entries_collapsed;
2393        else
2394                root = other->entries_in;
2395
2396        for (nd = rb_first(root); nd; nd = rb_next(nd)) {
2397                pos = rb_entry(nd, struct hist_entry, rb_node_in);
2398
2399                if (!hist_entry__has_pairs(pos)) {
2400                        pair = hists__add_dummy_entry(leader, pos);
2401                        if (pair == NULL)
2402                                return -1;
2403                        hist_entry__add_pair(pos, pair);
2404                }
2405        }
2406
2407        return 0;
2408}
2409
2410void hist__account_cycles(struct branch_stack *bs, struct addr_location *al,
2411                          struct perf_sample *sample, bool nonany_branch_mode)
2412{
2413        struct branch_info *bi;
2414
2415        /* If we have branch cycles always annotate them. */
2416        if (bs && bs->nr && bs->entries[0].flags.cycles) {
2417                int i;
2418
2419                bi = sample__resolve_bstack(sample, al);
2420                if (bi) {
2421                        struct addr_map_symbol *prev = NULL;
2422
2423                        /*
2424                         * Ignore errors, still want to process the
2425                         * other entries.
2426                         *
2427                         * For non standard branch modes always
2428                         * force no IPC (prev == NULL)
2429                         *
2430                         * Note that perf stores branches reversed from
2431                         * program order!
2432                         */
2433                        for (i = bs->nr - 1; i >= 0; i--) {
2434                                addr_map_symbol__account_cycles(&bi[i].from,
2435                                        nonany_branch_mode ? NULL : prev,
2436                                        bi[i].flags.cycles);
2437                                prev = &bi[i].to;
2438                        }
2439                        free(bi);
2440                }
2441        }
2442}
2443
2444size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp)
2445{
2446        struct perf_evsel *pos;
2447        size_t ret = 0;
2448
2449        evlist__for_each_entry(evlist, pos) {
2450                ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos));
2451                ret += events_stats__fprintf(&evsel__hists(pos)->stats, fp);
2452        }
2453
2454        return ret;
2455}
2456
2457
2458u64 hists__total_period(struct hists *hists)
2459{
2460        return symbol_conf.filter_relative ? hists->stats.total_non_filtered_period :
2461                hists->stats.total_period;
2462}
2463
2464int __hists__scnprintf_title(struct hists *hists, char *bf, size_t size, bool show_freq)
2465{
2466        char unit;
2467        int printed;
2468        const struct dso *dso = hists->dso_filter;
2469        const struct thread *thread = hists->thread_filter;
2470        int socket_id = hists->socket_filter;
2471        unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
2472        u64 nr_events = hists->stats.total_period;
2473        struct perf_evsel *evsel = hists_to_evsel(hists);
2474        const char *ev_name = perf_evsel__name(evsel);
2475        char buf[512], sample_freq_str[64] = "";
2476        size_t buflen = sizeof(buf);
2477        char ref[30] = " show reference callgraph, ";
2478        bool enable_ref = false;
2479
2480        if (symbol_conf.filter_relative) {
2481                nr_samples = hists->stats.nr_non_filtered_samples;
2482                nr_events = hists->stats.total_non_filtered_period;
2483        }
2484
2485        if (perf_evsel__is_group_event(evsel)) {
2486                struct perf_evsel *pos;
2487
2488                perf_evsel__group_desc(evsel, buf, buflen);
2489                ev_name = buf;
2490
2491                for_each_group_member(pos, evsel) {
2492                        struct hists *pos_hists = evsel__hists(pos);
2493
2494                        if (symbol_conf.filter_relative) {
2495                                nr_samples += pos_hists->stats.nr_non_filtered_samples;
2496                                nr_events += pos_hists->stats.total_non_filtered_period;
2497                        } else {
2498                                nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE];
2499                                nr_events += pos_hists->stats.total_period;
2500                        }
2501                }
2502        }
2503
2504        if (symbol_conf.show_ref_callgraph &&
2505            strstr(ev_name, "call-graph=no"))
2506                enable_ref = true;
2507
2508        if (show_freq)
2509                scnprintf(sample_freq_str, sizeof(sample_freq_str), " %d Hz,", evsel->attr.sample_freq);
2510
2511        nr_samples = convert_unit(nr_samples, &unit);
2512        printed = scnprintf(bf, size,
2513                           "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
2514                           nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
2515                           ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
2516
2517
2518        if (hists->uid_filter_str)
2519                printed += snprintf(bf + printed, size - printed,
2520                                    ", UID: %s", hists->uid_filter_str);
2521        if (thread) {
2522                if (hists__has(hists, thread)) {
2523                        printed += scnprintf(bf + printed, size - printed,
2524                                    ", Thread: %s(%d)",
2525                                     (thread->comm_set ? thread__comm_str(thread) : ""),
2526                                    thread->tid);
2527                } else {
2528                        printed += scnprintf(bf + printed, size - printed,
2529                                    ", Thread: %s",
2530                                     (thread->comm_set ? thread__comm_str(thread) : ""));
2531                }
2532        }
2533        if (dso)
2534                printed += scnprintf(bf + printed, size - printed,
2535                                    ", DSO: %s", dso->short_name);
2536        if (socket_id > -1)
2537                printed += scnprintf(bf + printed, size - printed,
2538                                    ", Processor Socket: %d", socket_id);
2539
2540        return printed;
2541}
2542
2543int parse_filter_percentage(const struct option *opt __maybe_unused,
2544                            const char *arg, int unset __maybe_unused)
2545{
2546        if (!strcmp(arg, "relative"))
2547                symbol_conf.filter_relative = true;
2548        else if (!strcmp(arg, "absolute"))
2549                symbol_conf.filter_relative = false;
2550        else {
2551                pr_debug("Invalid percentage: %s\n", arg);
2552                return -1;
2553        }
2554
2555        return 0;
2556}
2557
2558int perf_hist_config(const char *var, const char *value)
2559{
2560        if (!strcmp(var, "hist.percentage"))
2561                return parse_filter_percentage(NULL, value, 0);
2562
2563        return 0;
2564}
2565
2566int __hists__init(struct hists *hists, struct perf_hpp_list *hpp_list)
2567{
2568        memset(hists, 0, sizeof(*hists));
2569        hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
2570        hists->entries_in = &hists->entries_in_array[0];
2571        hists->entries_collapsed = RB_ROOT;
2572        hists->entries = RB_ROOT;
2573        pthread_mutex_init(&hists->lock, NULL);
2574        hists->socket_filter = -1;
2575        hists->hpp_list = hpp_list;
2576        INIT_LIST_HEAD(&hists->hpp_formats);
2577        return 0;
2578}
2579
2580static void hists__delete_remaining_entries(struct rb_root *root)
2581{
2582        struct rb_node *node;
2583        struct hist_entry *he;
2584
2585        while (!RB_EMPTY_ROOT(root)) {
2586                node = rb_first(root);
2587                rb_erase(node, root);
2588
2589                he = rb_entry(node, struct hist_entry, rb_node_in);
2590                hist_entry__delete(he);
2591        }
2592}
2593
2594static void hists__delete_all_entries(struct hists *hists)
2595{
2596        hists__delete_entries(hists);
2597        hists__delete_remaining_entries(&hists->entries_in_array[0]);
2598        hists__delete_remaining_entries(&hists->entries_in_array[1]);
2599        hists__delete_remaining_entries(&hists->entries_collapsed);
2600}
2601
2602static void hists_evsel__exit(struct perf_evsel *evsel)
2603{
2604        struct hists *hists = evsel__hists(evsel);
2605        struct perf_hpp_fmt *fmt, *pos;
2606        struct perf_hpp_list_node *node, *tmp;
2607
2608        hists__delete_all_entries(hists);
2609
2610        list_for_each_entry_safe(node, tmp, &hists->hpp_formats, list) {
2611                perf_hpp_list__for_each_format_safe(&node->hpp, fmt, pos) {
2612                        list_del(&fmt->list);
2613                        free(fmt);
2614                }
2615                list_del(&node->list);
2616                free(node);
2617        }
2618}
2619
2620static int hists_evsel__init(struct perf_evsel *evsel)
2621{
2622        struct hists *hists = evsel__hists(evsel);
2623
2624        __hists__init(hists, &perf_hpp_list);
2625        return 0;
2626}
2627
2628/*
2629 * XXX We probably need a hists_evsel__exit() to free the hist_entries
2630 * stored in the rbtree...
2631 */
2632
2633int hists__init(void)
2634{
2635        int err = perf_evsel__object_config(sizeof(struct hists_evsel),
2636                                            hists_evsel__init,
2637                                            hists_evsel__exit);
2638        if (err)
2639                fputs("FATAL ERROR: Couldn't setup hists class\n", stderr);
2640
2641        return err;
2642}
2643
2644void perf_hpp_list__init(struct perf_hpp_list *list)
2645{
2646        INIT_LIST_HEAD(&list->fields);
2647        INIT_LIST_HEAD(&list->sorts);
2648}
2649