Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp5790178pxb; Wed, 26 Jan 2022 22:31:01 -0800 (PST) X-Google-Smtp-Source: ABdhPJwbjL5J2HJ23Sr6bU8mRUI0KrmzOiQawYkZG+HByBtfvrqySrtpeHIDb9v0TBxYlwAJeC6M X-Received: by 2002:a17:906:c110:: with SMTP id do16mr1199064ejc.175.1643265060935; Wed, 26 Jan 2022 22:31:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643265060; cv=none; d=google.com; s=arc-20160816; b=l1gAyhnYRYUZzG3mzMQQmIDygyla/pTnPC1RzevGjEfN+/yYdw79ioc8w3LRRnSWr8 n2J3ZVm0aDhDynP+AzwjSp7TR3AOKb1m1Ehx2Ebe+vDM/itM9Soj28pgAi5Zini+bQjN TSLlmgjfcTFYxYN3kFoBqSyToDVgI3WJ0MErHsSPikva/XbYeiRcuiTjI5TGYIZlPssK 1ENnP0kp1+pmfilyiPjEGQB/yCf8rkKZbkzYvP1f0xpNeyV0Z5yqSFIIvdrYhydynAHR P3Vn8DzH32kdmmqLsF0xZKyGhrD1CnxCiPs6j83yU3uYqPBfmMSvNToMJ/cr5a1YGAxA tW4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=fn4L0HGNN2ju0/r+GryclIat0kxPJWjrVW3RRH7cvn8=; b=xVepm9TDupKJ4LmyMrr/zpo2vtemroZYNXJ32r3JQunuhSIZwcHFZQBTUo4fUfxOx4 ykd6SRfVps5BgYtN/k1l0onRJyyGxHTnHX6IzgqJLmuXlWm/IjnWdRcWD34BPRH5kVFW rTezEq74F/M6DikrVZaVFd3HPoh8S9FK7gL1sdzqqk+ibL53B7nFLcDsjBiuffhdKlv7 xYcLl969Zv8eAeBVA+HYlN2hBhTnh4E9DWzVzkG5wvq9YUGrbG1QKiDzeYMBrzCLPu45 o+9i0zo8Z8EbzpZRPlPFttWPhbalxzWzi6ykNs/K31fgIBIoZw29DYVzF4pZXPsJ23+b f7rA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=TlLuM7bP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q23si988273ejr.317.2022.01.26.22.30.36; Wed, 26 Jan 2022 22:31:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=TlLuM7bP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233949AbiAZXgA (ORCPT + 99 others); Wed, 26 Jan 2022 18:36:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233720AbiAZXfu (ORCPT ); Wed, 26 Jan 2022 18:35:50 -0500 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 69B23C061759 for ; Wed, 26 Jan 2022 15:35:47 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id i10-20020a25540a000000b0061391789216so2506080ybb.2 for ; Wed, 26 Jan 2022 15:35:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=fn4L0HGNN2ju0/r+GryclIat0kxPJWjrVW3RRH7cvn8=; b=TlLuM7bPykpXZnnqtxK2SkLWz2tyv2/MrWnL2kQM+Z+MOgPtD/nQJMm9IIdyd8+Gb7 IvhhyRm8C3QYkprL+PMTWRXyaPiFwJJINLbHZMvBtI01u5WPATgD/sm1kh76LK03Snew YjVW4O0z0hhfKyuwCe4VciOIZ+H1NpOMcS70XLlFCY7e/Qg86Ljja58l0RHC54cacgvt 1VdLVzwRV0kdxbTwqtbobcvf3H72Lafoc0uIR5FUpgqHXNYg+KSLDJEDRjb/AMExzQJ/ Nd1vQmxehAWsrrylYHi3HzpwFda2l7i0xVuVHz8EKb5QoGOIiJTWcDAJakYgUbyXMsDc LTmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=fn4L0HGNN2ju0/r+GryclIat0kxPJWjrVW3RRH7cvn8=; b=oPBiTAiCjCs1ktVt6h6Kj5+mia7GiXWw7xIln9+mQUnLZKunzUxyj8D/m7l7QC94kF mtsy8vZ9H6LJmNhHNWHKepj+ADnLbY55qx4gbW+dorMQ6sqrQBf/VM7ZPxeKjdL6Vurk cH66ZqEep+ONaa5bHsdeTZU3GaAIQt6GP2lCHJwi/t7gkGFPSXpbRM68VQ0fSdpVJGye cJTN5l/Ilq9NpHkNfbOt/l4mVS95TykVqD5igIjOLyUhJFsyhNHnZvTky/MN9zraPwFd 6b0hf+D0kEdzO5XBVApzKUE3osUVCb2iGDFggPNuqn0MhGIGeI3lUZ3wbnHkLle8Dk5M qKMQ== X-Gm-Message-State: AOAM533cif8aojFSR+z1VPeV3uWA2ufnLwZgDfsJBWAOxkaO8+aF/OzO eaxES3rNg8M6amuPHw0GmvPa3Cfp6FdTM5HlPAzTZfUnzSLswbcSmTTUJEgM1T5N356iGNOovlG MmmBp2JPssRNpUq3HxXznn7i9tPSzRFp+bd36zfP8Kswr1Nc4SsBTOKCZHW3sOhRMeuxOvWa5 X-Received: from uluru3.svl.corp.google.com ([2620:15c:2cd:202:9ce0:6f20:c145:eac]) (user=eranian job=sendgmr) by 2002:a81:6605:: with SMTP id a5mr0ywc.510.1643240146076; Wed, 26 Jan 2022 15:35:46 -0800 (PST) Date: Wed, 26 Jan 2022 15:34:54 -0800 In-Reply-To: <20220126233454.3362047-1-eranian@google.com> Message-Id: <20220126233454.3362047-14-eranian@google.com> Mime-Version: 1.0 References: <20220126233454.3362047-1-eranian@google.com> X-Mailer: git-send-email 2.35.0.rc0.227.g00780c9af4-goog Subject: [PATCH v5 13/13] perf report: add addr_from/addr_to sort dimensions From: Stephane Eranian To: linux-kernel@vger.kernel.org Cc: peterz@infradead.org, kim.phillips@amd.com, acme@redhat.com, jolsa@redhat.com, songliubraving@fb.com Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds a new pair of sorting dimensions used with branch sampling. With the existing symbol_from/symbol_to, branches captured in the same function would be collapsed into a single function if the latency (cycles) was all the same. That is the case on Intel Broadwell for instance. Since Intel Skylake, the latency is captured by hardware and therefore is used to disambiguate branches. This patch adds addr_from/addr_to sort dimensions that will sort branches based on their addresses and not the function there are in. The output is still the function name but the offset within the function is provided to uniquely identify each branch. These new sort dimensions also help with annotate because they create different entries in the histogram which, in turn, generates proper branch annotation. Here is an example using AMD's branch sampling: $ perf record -a -b -c 1000037 -e cpu/branch-brs/ test_prg $ perf report Samples: 6M of event 'cpu/branch-brs/', Event count (approx.): 6901276 Overhead Command Source Shared Object Source Symbol Target Symbol Basic Block Cycle 99.65% test_prg test_prg [.] test_thread [.] test_thread - 0.02% test_prg [kernel.vmlinux] [k] asm_sysvec_apic_timer_interrupt [k] error_entry - $ perf report -F overhead,comm,dso,addr_from,addr_to Samples: 6M of event 'cpu/branch-brs/', Event count (approx.): 6901276 Overhead Command Shared Object Source Address Target Address 4.22% test_prg test_prg [.] test_thread+0x3c [.] test_thread+0x4 4.13% test_prg test_prg [.] test_thread+0x4 [.] test_thread+0x3a 4.09% test_prg test_prg [.] test_thread+0x3a [.] test_thread+0x6 4.08% test_prg test_prg [.] test_thread+0x2 [.] test_thread+0x3c 4.06% test_prg test_prg [.] test_thread+0x3e [.] test_thread+0x2 3.87% test_prg test_prg [.] test_thread+0x6 [.] test_thread+0x38 3.84% test_prg test_prg [.] test_thread [.] test_thread+0x3e 3.76% test_prg test_prg [.] test_thread+0x1e [.] test_thread 3.76% test_prg test_prg [.] test_thread+0x38 [.] test_thread+0x8 3.56% test_prg test_prg [.] test_thread+0x22 [.] test_thread+0x1e 3.54% test_prg test_prg [.] test_thread+0x8 [.] test_thread+0x36 3.47% test_prg test_prg [.] test_thread+0x1c [.] test_thread+0x22 3.45% test_prg test_prg [.] test_thread+0x36 [.] test_thread+0xa 3.28% test_prg test_prg [.] test_thread+0x24 [.] test_thread+0x1c 3.25% test_prg test_prg [.] test_thread+0xa [.] test_thread+0x34 3.24% test_prg test_prg [.] test_thread+0x1a [.] test_thread+0x24 3.20% test_prg test_prg [.] test_thread+0x34 [.] test_thread+0xc 3.04% test_prg test_prg [.] test_thread+0x26 [.] test_thread+0x1a 3.01% test_prg test_prg [.] test_thread+0xc [.] test_thread+0x32 2.98% test_prg test_prg [.] test_thread+0x18 [.] test_thread+0x26 2.94% test_prg test_prg [.] test_thread+0x32 [.] test_thread+0xe 2.76% test_prg test_prg [.] test_thread+0x28 [.] test_thread+0x18 2.73% test_prg test_prg [.] test_thread+0xe [.] test_thread+0x30 2.67% test_prg test_prg [.] test_thread+0x30 [.] test_thread+0x10 2.67% test_prg test_prg [.] test_thread+0x16 [.] test_thread+0x28 2.46% test_prg test_prg [.] test_thread+0x10 [.] test_thread+0x2e 2.44% test_prg test_prg [.] test_thread+0x2a [.] test_thread+0x16 2.38% test_prg test_prg [.] test_thread+0x14 [.] test_thread+0x2a 2.32% test_prg test_prg [.] test_thread+0x2e [.] test_thread+0x12 2.28% test_prg test_prg [.] test_thread+0x12 [.] test_thread+0x2c 2.16% test_prg test_prg [.] test_thread+0x2c [.] test_thread+0x14 0.02% test_prg [kernel.vmlinux] [k] asm_sysvec_apic_ti+0x5 [k] error_entry Signed-off-by: Stephane Eranian --- tools/perf/util/hist.c | 2 + tools/perf/util/hist.h | 2 + tools/perf/util/sort.c | 128 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/sort.h | 2 + 4 files changed, 134 insertions(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0a8033b09e28..1c085ab56534 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -124,6 +124,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) } else { symlen = unresolved_col_width + 4 + 2; hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); + hists__new_col_len(hists, HISTC_ADDR_FROM, symlen); hists__set_unres_dso_col_len(hists, HISTC_DSO_FROM); } @@ -138,6 +139,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) } else { symlen = unresolved_col_width + 4 + 2; hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); + hists__new_col_len(hists, HISTC_ADDR_TO, symlen); hists__set_unres_dso_col_len(hists, HISTC_DSO_TO); } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 2a15e22fb89c..7ed4648d2fc2 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -77,6 +77,8 @@ enum hist_column { HISTC_GLOBAL_INS_LAT, HISTC_LOCAL_P_STAGE_CYC, HISTC_GLOBAL_P_STAGE_CYC, + HISTC_ADDR_FROM, + HISTC_ADDR_TO, HISTC_NR_COLS, /* Last entry */ }; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index cfba8c337783..cd119897dc2b 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -990,6 +990,128 @@ struct sort_entry sort_sym_to = { .se_width_idx = HISTC_SYMBOL_TO, }; +static int _hist_entry__addr_snprintf(struct map_symbol *ms, + u64 ip, char level, char *bf, size_t size, + unsigned int width) +{ + struct symbol *sym = ms->sym; + struct map *map = ms->map; + size_t ret = 0, offs; + + ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); + if (sym && map) { + if (sym->type == STT_OBJECT) { + ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name); + ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", + ip - map->unmap_ip(map, sym->start)); + } else { + ret += repsep_snprintf(bf + ret, size - ret, "%.*s", + width - ret, + sym->name); + offs = ip - sym->start; + if (offs) + ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", offs); + } + } else { + size_t len = BITS_PER_LONG / 4; + ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", + len, ip); + } + + return ret; +} + +static int hist_entry__addr_from_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width) +{ + if (he->branch_info) { + struct addr_map_symbol *from = &he->branch_info->from; + + return _hist_entry__addr_snprintf(&from->ms, from->al_addr, + he->level, bf, size, width); + } + + return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); +} + +static int hist_entry__addr_to_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width) +{ + if (he->branch_info) { + struct addr_map_symbol *to = &he->branch_info->to; + + return _hist_entry__addr_snprintf(&to->ms, to->al_addr, + he->level, bf, size, width); + } + + return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); +} + +static int64_t +sort__addr_from_cmp(struct hist_entry *left, struct hist_entry *right) +{ + struct addr_map_symbol *from_l; + struct addr_map_symbol *from_r; + int64_t ret; + + if (!left->branch_info || !right->branch_info) + return cmp_null(left->branch_info, right->branch_info); + + from_l = &left->branch_info->from; + from_r = &right->branch_info->from; + + /* + * comparing symbol address alone is not enough since it's a + * relative address within a dso. + */ + ret = _sort__dso_cmp(from_l->ms.map, from_r->ms.map); + if (ret != 0) + return ret; + + return _sort__addr_cmp(from_l->addr, from_r->addr); +} + +static int64_t +sort__addr_to_cmp(struct hist_entry *left, struct hist_entry *right) +{ + struct addr_map_symbol *to_l; + struct addr_map_symbol *to_r; + int64_t ret; + + if (!left->branch_info || !right->branch_info) + return cmp_null(left->branch_info, right->branch_info); + + to_l = &left->branch_info->to; + to_r = &right->branch_info->to; + + /* + * comparing symbol address alone is not enough since it's a + * relative address within a dso. + */ + ret = _sort__dso_cmp(to_l->ms.map, to_r->ms.map); + if (ret != 0) + return ret; + + return _sort__addr_cmp(to_l->addr, to_r->addr); +} + +struct sort_entry sort_addr_from = { + .se_header = "Source Address", + .se_cmp = sort__addr_from_cmp, + .se_snprintf = hist_entry__addr_from_snprintf, + .se_filter = hist_entry__sym_from_filter, /* shared with sym_from */ + .se_width_idx = HISTC_ADDR_FROM, +}; + +struct sort_entry sort_addr_to = { + .se_header = "Target Address", + .se_cmp = sort__addr_to_cmp, + .se_snprintf = hist_entry__addr_to_snprintf, + .se_filter = hist_entry__sym_to_filter, /* shared with sym_to */ + .se_width_idx = HISTC_ADDR_TO, +}; + + static int64_t sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right) { @@ -1893,6 +2015,8 @@ static struct sort_dimension bstack_sort_dimensions[] = { DIM(SORT_SRCLINE_FROM, "srcline_from", sort_srcline_from), DIM(SORT_SRCLINE_TO, "srcline_to", sort_srcline_to), DIM(SORT_SYM_IPC, "ipc_lbr", sort_sym_ipc), + DIM(SORT_ADDR_FROM, "addr_from", sort_addr_from), + DIM(SORT_ADDR_TO, "addr_to", sort_addr_to), }; #undef DIM @@ -3126,6 +3250,10 @@ static bool get_elide(int idx, FILE *output) return __get_elide(symbol_conf.dso_from_list, "dso_from", output); case HISTC_DSO_TO: return __get_elide(symbol_conf.dso_to_list, "dso_to", output); + case HISTC_ADDR_FROM: + return __get_elide(symbol_conf.sym_from_list, "addr_from", output); + case HISTC_ADDR_TO: + return __get_elide(symbol_conf.sym_to_list, "addr_to", output); default: break; } diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index f994261888e1..2ddc00d1c464 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -251,6 +251,8 @@ enum sort_type { SORT_SRCLINE_FROM, SORT_SRCLINE_TO, SORT_SYM_IPC, + SORT_ADDR_FROM, + SORT_ADDR_TO, /* memory mode specific sort keys */ __SORT_MEMORY_MODE, -- 2.35.0.rc0.227.g00780c9af4-goog