From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D02DC761A6 for ; Tue, 4 Apr 2023 21:01:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236297AbjDDVBD (ORCPT ); Tue, 4 Apr 2023 17:01:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37544 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235526AbjDDVA5 (ORCPT ); Tue, 4 Apr 2023 17:00:57 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 662A45277 for ; Tue, 4 Apr 2023 14:00:34 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-54476ef9caeso334338617b3.6 for ; Tue, 04 Apr 2023 14:00:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642029; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=mxn0E0FAY/ukx0XogLEmWEdFPlsoSvFOzcJYSSNA4QA=; b=EUczPLAUnJNdgVzKOd0lBOpvV33TEnLbczWC/rsjdAkFVWbXRkLpKdLtTUQ2eA59NV 3kjQNMAjmt0hHcbum8LJQhmqcFQRaG0tN+wrU9XmUuwr7Z7WQqwPHuKY11OqVY2CBC+s yuUeCJm1SfpdG/82QPwOVxuC72GXiqsgdS9pUhq8b0NqbNqPHMwlmarxIaHKetx1N0oV X2jYkMZBPwp6mmSMZo/jDAJoegSUrHNTErbRNx1JYzW4CwoJLZdVXbP1Bowgqyxn9yu0 GYjncY8SADP41G2IX023fOH4PYYhTRMxXxuOsresxexOCZsl1M6iRbjupx9bgcM3I111 TSjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642029; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mxn0E0FAY/ukx0XogLEmWEdFPlsoSvFOzcJYSSNA4QA=; b=KLOyK9gT4F8pq9GvkMXQwgNhkorY5p1tmsDJSltj0BaEamo8jGdmvDUnXJllzCCCI4 FF/5zlopBrY0lgdpTMMgKoFN6He607TwhAF3Z0Gn65/SY2iWeAxiBhZNhEs0x/G65Sge yG2J4Hi303cngnL1oOXTXwnoT0VT+5X0oZydBGy9fLqWmghed3J0DqqG6Zqkg/IfOa+y hdKin+m0b4BZTeeX2ecr8Oxq+nZiJeM30625/f7eFw0Sw/WfL36fISed95bpYJ7gTPk+ /2G0y6fCcxMs6psc4wZN/IUxe8sAueH25wgr5id9ABB2qjdLh80uwN3JKQsCk56UKRUW 29SQ== X-Gm-Message-State: AAQBX9cbh0DohB37ufA+no84niVOlbt7kmYS9AlEoCrDEGe8gHDBV6zP qoI1twTkvAYeO3Hhp+b3ikwvyJH26Cec X-Google-Smtp-Source: AKy350bGRkRJjaPremdg8Fl3wE55T1VIzbQa0ONWjDYvXNRpxQVYvcIcm8zXrULg4hBfad78XdQ/8nZ472fj X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a05:690c:72c:b0:52f:184a:da09 with SMTP id bt12-20020a05690c072c00b0052f184ada09mr392053ywb.2.1680642028954; Tue, 04 Apr 2023 14:00:28 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:43 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-2-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add dso to match comment. This avoids a naming conflict with later added accessor functions for variables in struct map. Signed-off-by: Ian Rogers --- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-script.c | 4 ++-- tools/perf/util/machine.c | 4 ++-- tools/perf/util/map.c | 8 ++++---- tools/perf/util/map.h | 4 ++-- tools/perf/util/symbol-elf.c | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index f3029742b800..4d4b770a401c 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -423,7 +423,7 @@ static u64 find_callsite(struct evsel *evsel, struct pe= rf_sample *sample) if (!caller) { /* found */ if (node->ms.map) - addr =3D map__unmap_ip(node->ms.map, node->ip); + addr =3D map__dso_unmap_ip(node->ms.map, node->ip); else addr =3D node->ip; =20 diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 1d078106abc4..af0a69c7f41f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1012,11 +1012,11 @@ static int perf_sample__fprintf_brstackoff(struct p= erf_sample *sample, =20 if (thread__find_map_fb(thread, sample->cpumode, from, &alf) && !map__dso(alf.map)->adjust_symbols) - from =3D map__map_ip(alf.map, from); + from =3D map__dso_map_ip(alf.map, from); =20 if (thread__find_map_fb(thread, sample->cpumode, to, &alt) && !map__dso(alt.map)->adjust_symbols) - to =3D map__map_ip(alt.map, to); + to =3D map__dso_map_ip(alt.map, to); =20 printed +=3D fprintf(fp, " 0x%"PRIx64, from); if (PRINT_FIELD(DSO)) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 7852b97da10a..9d24980a0a93 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -3058,7 +3058,7 @@ static int append_inlines(struct callchain_cursor *cu= rsor, struct map_symbol *ms if (!symbol_conf.inline_name || !map || !sym) return ret; =20 - addr =3D map__map_ip(map, ip); + addr =3D map__dso_map_ip(map, ip); addr =3D map__rip_2objdump(map, addr); dso =3D map__dso(map); =20 @@ -3103,7 +3103,7 @@ static int unwind_entry(struct unwind_entry *entry, v= oid *arg) * its corresponding binary. */ if (entry->ms.map) - addr =3D map__map_ip(entry->ms.map, entry->ip); + addr =3D map__dso_map_ip(entry->ms.map, entry->ip); =20 srcline =3D callchain_srcline(&entry->ms, addr); return callchain_cursor_append(cursor, entry->ip, &entry->ms, diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 416fc449bde8..d97a6d20626f 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -109,8 +109,8 @@ void map__init(struct map *map, u64 start, u64 end, u64= pgoff, struct dso *dso) map->pgoff =3D pgoff; map->reloc =3D 0; map->dso =3D dso__get(dso); - map->map_ip =3D map__map_ip; - map->unmap_ip =3D map__unmap_ip; + map->map_ip =3D map__dso_map_ip; + map->unmap_ip =3D map__dso_unmap_ip; map->erange_warned =3D false; refcount_set(&map->refcnt, 1); } @@ -590,12 +590,12 @@ struct maps *map__kmaps(struct map *map) return kmap->kmaps; } =20 -u64 map__map_ip(const struct map *map, u64 ip) +u64 map__dso_map_ip(const struct map *map, u64 ip) { return ip - map__start(map) + map->pgoff; } =20 -u64 map__unmap_ip(const struct map *map, u64 ip) +u64 map__dso_unmap_ip(const struct map *map, u64 ip) { return ip + map__start(map) - map->pgoff; } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 16646b94fa3a..9b0a84e46e48 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -41,9 +41,9 @@ struct kmap *map__kmap(struct map *map); struct maps *map__kmaps(struct map *map); =20 /* ip -> dso rip */ -u64 map__map_ip(const struct map *map, u64 ip); +u64 map__dso_map_ip(const struct map *map, u64 ip); /* dso rip -> ip */ -u64 map__unmap_ip(const struct map *map, u64 ip); +u64 map__dso_unmap_ip(const struct map *map, u64 ip); /* Returns ip */ u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); =20 diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index e715869eab8a..c55981116f68 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1357,8 +1357,8 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, map->start =3D shdr->sh_addr + ref_reloc(kmap); map->end =3D map__start(map) + shdr->sh_size; map->pgoff =3D shdr->sh_offset; - map->map_ip =3D map__map_ip; - map->unmap_ip =3D map__unmap_ip; + map->map_ip =3D map__dso_map_ip; + map->unmap_ip =3D map__dso_unmap_ip; /* Ensure maps are correctly ordered */ if (kmaps) { int err; --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0072C761A6 for ; Tue, 4 Apr 2023 21:01:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236126AbjDDVBH (ORCPT ); Tue, 4 Apr 2023 17:01:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236414AbjDDVBB (ORCPT ); Tue, 4 Apr 2023 17:01:01 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C38375583 for ; Tue, 4 Apr 2023 14:00:37 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5461fe3163eso206513497b3.17 for ; Tue, 04 Apr 2023 14:00:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642036; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=tqEAholP6s5JO6IAfeA8IAnwz80MVC9mCMC/N1UGzaI=; b=Pre1RT/RwUnsEu1Z88qVKp832+IMlAFDxrIai7mdO9rB/KmVvPZPA/2kGlwyaqDBgZ LxX3r6onTPTfyrBCZDyorNJXtbhr3cjaktQyoDDO4ljreDjRj9nuLWigTQHX3LafKQpB IxL/rLSh+Pq/xvkzikbXTqWXpeCpznK/Os+Qk+m5auzxdXLEEWXfAvwWIjP7aXofo9xM TAUkPybrvr8AmfEydRKVfdlpNwVmiaf7aiS7m0yXxcFN9uj1LlirV6zGWSue3diMs23X aJi59eAxw+n7CfcpHLO/7QlY/q4trn+1wlMeqOHOcUp4oUZyRRB2qSbniMzVRgHiRwaf /MzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642036; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tqEAholP6s5JO6IAfeA8IAnwz80MVC9mCMC/N1UGzaI=; b=iwQFNJ09GJh3tpOiVaeifWKxIENGKIy9PilAWhbfB/sGcSn5cW7SSqWcvD9axjbdwu X6OtYJpc7q2FAMThmVn5hpYtQ7ouZNWRvjYIHkT3GSy1QcZdLaA+ViOG0OkryOg/kze0 notXJMmBe6s09ENGDnQZPCX0keWSukMcgtAkaHmmnX6NaFRhcyRVFN3boCFvzq/TpL54 ws2kVsyBflfxrcWFbHntlzT3enasVA3AZOMn0tYzd1FU0NlBWKlVVyia35QobCv0reoM 9Z9yZIY3C4samBonB1gKgHnaija/3rUX9KmHyZz/IAXuIRZ53LozdU7r/m43EE325yQT y7DQ== X-Gm-Message-State: AAQBX9fG/Jv+jsElKEK/sqDr8WGE7ecKA5G55+axT2bnCLIhs3H6P/9l TThfY4pmOpdliWBn6oOstC35gdaRgxzZ X-Google-Smtp-Source: AKy350YFGt9Kc+Pfi75dbGIQZ+oOZ2q1vWVyMjN1tPhk5H0Dle4y6QIbciQ0VGUnMuY5t4j/Ue+8Lq2wAvvh X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a81:4513:0:b0:544:d5ce:eb33 with SMTP id s19-20020a814513000000b00544d5ceeb33mr2333239ywa.8.1680642036311; Tue, 04 Apr 2023 14:00:36 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:44 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-3-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 02/12] perf map: Add helper for map_ip and unmap_ip From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Later changes will add reference count checking for struct map, add a helper function to invoke the map_ip and unmap_ip function pointers. The helper allows the reference count check to be in fewer places. Signed-off-by: Ian Rogers --- tools/perf/arch/s390/annotate/instructions.c | 3 ++- tools/perf/builtin-kallsyms.c | 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-lock.c | 4 ++-- tools/perf/builtin-script.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 10 +++++----- tools/perf/util/annotate.c | 16 +++++++++------- tools/perf/util/bpf_lock_contention.c | 4 ++-- tools/perf/util/dlfilter.c | 2 +- tools/perf/util/dso.c | 6 ++++-- tools/perf/util/event.c | 8 ++++---- tools/perf/util/evsel_fprintf.c | 2 +- tools/perf/util/intel-pt.c | 10 +++++----- tools/perf/util/machine.c | 16 ++++++++-------- tools/perf/util/map.c | 10 +++++----- tools/perf/util/map.h | 10 ++++++++++ tools/perf/util/maps.c | 8 ++++---- tools/perf/util/probe-event.c | 8 ++++---- .../util/scripting-engines/trace-event-python.c | 2 +- tools/perf/util/sort.c | 12 ++++++------ tools/perf/util/symbol.c | 4 ++-- tools/perf/util/thread.c | 2 +- tools/perf/util/unwind-libdw.c | 2 +- tools/perf/util/unwind-libunwind-local.c | 2 +- 24 files changed, 81 insertions(+), 66 deletions(-) diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch= /s390/annotate/instructions.c index 0e136630659e..6548933e8dc0 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c @@ -39,7 +39,8 @@ static int s390_call__parse(struct arch *arch, struct ins= _operands *ops, target.addr =3D map__objdump_2mem(map, ops->target.addr); =20 if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D ops->target.addr) + map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D + ops->target.addr) ops->target.sym =3D target.ms.sym; =20 return 0; diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index 5638ca4dbd8e..3751df744577 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c @@ -39,7 +39,7 @@ static int __cmd_kallsyms(int argc, const char **argv) dso =3D map__dso(map); printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n= ", symbol->name, dso->short_name, dso->long_name, - map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end), + map__unmap_ip(map, symbol->start), map__unmap_ip(map, symbol->end), symbol->start, symbol->end); } =20 diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 4d4b770a401c..fcd2ef3bd3f5 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -1024,7 +1024,7 @@ static void __print_slab_result(struct rb_root *root, =20 if (sym !=3D NULL) snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name, - addr - map->unmap_ip(map, sym->start)); + addr - map__unmap_ip(map, sym->start)); else snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr); printf(" %-34s |", buf); diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 32ec58fb80e4..04345b2e7101 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -900,7 +900,7 @@ static int get_symbol_name_offset(struct map *map, stru= ct symbol *sym, u64 ip, return 0; } =20 - offset =3D map->map_ip(map, ip) - sym->start; + offset =3D map__map_ip(map, ip) - sym->start; =20 if (offset) return scnprintf(buf, size, "%s+%#lx", sym->name, offset); @@ -1070,7 +1070,7 @@ static int report_lock_contention_begin_event(struct = evsel *evsel, return -ENOMEM; } =20 - addrs[filters.nr_addrs++] =3D kmap->unmap_ip(kmap, sym->start); + addrs[filters.nr_addrs++] =3D map__unmap_ip(kmap, sym->start); filters.addrs =3D addrs; } } diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index af0a69c7f41f..8fba247b798c 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1088,7 +1088,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, /* Load maps to ensure dso->is_64_bit has been updated */ map__load(al.map); =20 - offset =3D al.map->map_ip(al.map, start); + offset =3D map__map_ip(al.map, start); len =3D dso__data_read_offset(dso, machine, offset, (u8 *)buffer, end - start + MAXINSN); =20 diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index 0a75623172c2..05a322ea3f9f 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -13,7 +13,7 @@ #include "debug.h" #include "machine.h" =20 -#define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x)) +#define UM(x) map__unmap_ip(kallsyms_map, (x)) =20 static bool is_ignored_symbol(const char *name, char type) { @@ -221,8 +221,8 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused if (sym->start =3D=3D sym->end) continue; =20 - mem_start =3D vmlinux_map->unmap_ip(vmlinux_map, sym->start); - mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, sym->end); + mem_start =3D map__unmap_ip(vmlinux_map, sym->start); + mem_end =3D map__unmap_ip(vmlinux_map, sym->end); =20 first_pair =3D machine__find_kernel_symbol(&kallsyms, mem_start, NULL); pair =3D first_pair; @@ -319,8 +319,8 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused maps__for_each_entry(maps, rb_node) { struct map *pair, *map =3D rb_node->map; =20 - mem_start =3D vmlinux_map->unmap_ip(vmlinux_map, map__start(map)); - mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, map__end(map)); + mem_start =3D map__unmap_ip(vmlinux_map, map__start(map)); + mem_end =3D map__unmap_ip(vmlinux_map, map__end(map)); =20 pair =3D maps__find(kallsyms.kmaps, mem_start); if (pair =3D=3D NULL || pair->priv) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index b9cff782d7df..36acdd1bd379 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -272,7 +272,8 @@ static int call__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s target.addr =3D map__objdump_2mem(map, ops->target.addr); =20 if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D ops->target.addr) + map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D + ops->target.addr) ops->target.sym =3D target.ms.sym; =20 return 0; @@ -376,8 +377,8 @@ static int jump__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s } =20 target.addr =3D map__objdump_2mem(map, ops->target.addr); - start =3D map->unmap_ip(map, sym->start), - end =3D map->unmap_ip(map, sym->end); + start =3D map__unmap_ip(map, sym->start); + end =3D map__unmap_ip(map, sym->end); =20 ops->target.outside =3D target.addr < start || target.addr > end; =20 @@ -400,7 +401,8 @@ static int jump__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s * the symbol searching and disassembly should be done. */ if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D ops->target.addr) + map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D + ops->target.addr) ops->target.sym =3D target.ms.sym; =20 if (!ops->target.outside) { @@ -881,7 +883,7 @@ static int __symbol__inc_addr_samples(struct map_symbol= *ms, unsigned offset; struct sym_hist *h; =20 - pr_debug3("%s: addr=3D%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->ma= p, addr)); + pr_debug3("%s: addr=3D%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, a= ddr)); =20 if ((addr < sym->start || addr >=3D sym->end) && (addr !=3D sym->end || sym->start !=3D sym->end)) { @@ -1977,8 +1979,8 @@ static int symbol__disassemble(struct symbol *sym, st= ruct annotate_args *args) return err; =20 pr_debug("%s: filename=3D%s, sym=3D%s, start=3D%#" PRIx64 ", end=3D%#" PR= Ix64 "\n", __func__, - symfs_filename, sym->name, map->unmap_ip(map, sym->start), - map->unmap_ip(map, sym->end)); + symfs_filename, sym->name, map__unmap_ip(map, sym->start), + map__unmap_ip(map, sym->end)); =20 pr_debug("annotating [%p] %30s : [%p] %30s\n", dso, dso->long_name, sym, sym->name); diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lo= ck_contention.c index 8a5d0eb44189..2b3bc544aa3e 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -74,7 +74,7 @@ int lock_contention_prepare(struct lock_contention *con) continue; } =20 - addrs[con->filters->nr_addrs++] =3D kmap->unmap_ip(kmap, sym->start); + addrs[con->filters->nr_addrs++] =3D map__unmap_ip(kmap, sym->start); con->filters->addrs =3D addrs; } naddrs =3D con->filters->nr_addrs; @@ -233,7 +233,7 @@ static const char *lock_contention_get_name(struct lock= _contention *con, if (sym) { unsigned long offset; =20 - offset =3D kmap->map_ip(kmap, addr) - sym->start; + offset =3D map__map_ip(kmap, addr) - sym->start; =20 if (offset =3D=3D 0) return sym->name; diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index fe401fa4be02..16238f823a5e 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -278,7 +278,7 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip,= void *buf, __u32 len) =20 map =3D a.map; have_map: - offset =3D map->map_ip(map, ip); + offset =3D map__map_ip(map, ip); if (ip + len >=3D map__end(map)) len =3D map__end(map) - ip; return dso__data_read_offset(map__dso(map), d->machine, offset, buf, len); diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index f1a14c0ad26d..e36b418df2c6 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1122,7 +1122,8 @@ ssize_t dso__data_read_addr(struct dso *dso, struct m= ap *map, struct machine *machine, u64 addr, u8 *data, ssize_t size) { - u64 offset =3D map->map_ip(map, addr); + u64 offset =3D map__map_ip(map, addr); + return dso__data_read_offset(dso, machine, offset, data, size); } =20 @@ -1162,7 +1163,8 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, s= truct map *map, struct machine *machine, u64 addr, const u8 *data, ssize_t size) { - u64 offset =3D map->map_ip(map, addr); + u64 offset =3D map__map_ip(map, addr); + return dso__data_write_cache_offs(dso, machine, offset, data, size); } =20 diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2ddc75dee019..2712d1a8264e 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -487,7 +487,7 @@ size_t perf_event__fprintf_text_poke(union perf_event *= event, struct machine *ma =20 al.map =3D maps__find(machine__kernel_maps(machine), tp->addr); if (al.map && map__load(al.map) >=3D 0) { - al.addr =3D al.map->map_ip(al.map, tp->addr); + al.addr =3D map__map_ip(al.map, tp->addr); al.sym =3D map__find_symbol(al.map, al.addr); if (al.sym) ret +=3D symbol__fprintf_symname_offs(al.sym, &al, fp); @@ -622,7 +622,7 @@ struct map *thread__find_map(struct thread *thread, u8 = cpumode, u64 addr, */ if (load_map) map__load(al->map); - al->addr =3D al->map->map_ip(al->map, al->addr); + al->addr =3D map__map_ip(al->map, al->addr); } =20 return al->map; @@ -743,12 +743,12 @@ int machine__resolve(struct machine *machine, struct = addr_location *al, } if (!ret && al->sym) { snprintf(al_addr_str, sz, "0x%"PRIx64, - al->map->unmap_ip(al->map, al->sym->start)); + map__unmap_ip(al->map, al->sym->start)); ret =3D strlist__has_entry(symbol_conf.sym_list, al_addr_str); } if (!ret && symbol_conf.addr_list && al->map) { - unsigned long addr =3D al->map->unmap_ip(al->map, al->addr); + unsigned long addr =3D map__unmap_ip(al->map, al->addr); =20 ret =3D intlist__has_entry(symbol_conf.addr_list, addr); if (!ret && symbol_conf.addr_range) { diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprint= f.c index dff5d8c4b06d..a09ac00810b7 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -151,7 +151,7 @@ int sample__fprintf_callchain(struct perf_sample *sampl= e, int left_alignment, printed +=3D fprintf(fp, " <-"); =20 if (map) - addr =3D map->map_ip(map, node->ip); + addr =3D map__map_ip(map, node->ip); =20 if (print_ip) { /* Show binary offset for userspace addr */ diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index a2e62daa708e..fe893c9bab3f 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -816,7 +816,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn= *intel_pt_insn, dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE)) return -ENOENT; =20 - offset =3D al.map->map_ip(al.map, *ip); + offset =3D map__map_ip(al.map, *ip); =20 if (!to_ip && one_map) { struct intel_pt_cache_entry *e; @@ -987,7 +987,7 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data) if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map)) return -EINVAL; =20 - offset =3D al.map->map_ip(al.map, ip); + offset =3D map__map_ip(al.map, ip); =20 return intel_pt_match_pgd_ip(ptq->pt, ip, offset, map__dso(al.map)->long_= name); } @@ -2749,7 +2749,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u6= 4 *ptss_ip) for (sym =3D start; sym; sym =3D dso__next_symbol(sym)) { if (sym->binding =3D=3D STB_GLOBAL && !strcmp(sym->name, "__switch_to")) { - ip =3D map->unmap_ip(map, sym->start); + ip =3D map__unmap_ip(map, sym->start); if (ip >=3D map__start(map) && ip < map__end(map)) { switch_ip =3D ip; break; @@ -2767,7 +2767,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u6= 4 *ptss_ip) =20 for (sym =3D start; sym; sym =3D dso__next_symbol(sym)) { if (!strcmp(sym->name, ptss)) { - ip =3D map->unmap_ip(map, sym->start); + ip =3D map__unmap_ip(map, sym->start); if (ip >=3D map__start(map) && ip < map__end(map)) { *ptss_ip =3D ip; break; @@ -3393,7 +3393,7 @@ static int intel_pt_text_poke(struct intel_pt *pt, un= ion perf_event *event) if (!dso || !dso->auxtrace_cache) continue; =20 - offset =3D al.map->map_ip(al.map, addr); + offset =3D map__map_ip(al.map, addr); =20 e =3D intel_pt_cache_lookup(dso, machine, offset); if (!e) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 9d24980a0a93..d29ec4a04488 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -919,7 +919,7 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, dso =3D map__dso(map); } =20 - sym =3D symbol__new(map->map_ip(map, map__start(map)), + sym =3D symbol__new(map__map_ip(map, map__start(map)), event->ksymbol.len, 0, 0, event->ksymbol.name); if (!sym) @@ -944,7 +944,7 @@ static int machine__process_ksymbol_unregister(struct m= achine *machine, else { struct dso *dso =3D map__dso(map); =20 - sym =3D dso__find_symbol(dso, map->map_ip(map, map__start(map))); + sym =3D dso__find_symbol(dso, map__map_ip(map, map__start(map))); if (sym) dso__delete_symbol(dso, sym); } @@ -1279,7 +1279,7 @@ int machine__map_x86_64_entry_trampolines(struct mach= ine *machine, =20 dest_map =3D maps__find(kmaps, map->pgoff); if (dest_map !=3D map) - map->pgoff =3D dest_map->map_ip(dest_map, map->pgoff); + map->pgoff =3D map__map_ip(dest_map, map->pgoff); found =3D true; } if (found || machine->trampolines_mapped) @@ -3345,7 +3345,7 @@ char *machine__resolve_kernel_addr(void *vmachine, un= signed long long *addrp, ch return NULL; =20 *modp =3D __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NU= LL; - *addrp =3D map->unmap_ip(map, sym->start); + *addrp =3D map__unmap_ip(map, sym->start); return sym->name; } =20 @@ -3388,17 +3388,17 @@ bool machine__is_lock_function(struct machine *mach= ine, u64 addr) return false; } =20 - machine->sched.text_start =3D kmap->unmap_ip(kmap, sym->start); + machine->sched.text_start =3D map__unmap_ip(kmap, sym->start); =20 /* should not fail from here */ sym =3D machine__find_kernel_symbol_by_name(machine, "__sched_text_end",= &kmap); - machine->sched.text_end =3D kmap->unmap_ip(kmap, sym->start); + machine->sched.text_end =3D map__unmap_ip(kmap, sym->start); =20 sym =3D machine__find_kernel_symbol_by_name(machine, "__lock_text_start"= , &kmap); - machine->lock.text_start =3D kmap->unmap_ip(kmap, sym->start); + machine->lock.text_start =3D map__unmap_ip(kmap, sym->start); =20 sym =3D machine__find_kernel_symbol_by_name(machine, "__lock_text_end", = &kmap); - machine->lock.text_end =3D kmap->unmap_ip(kmap, sym->start); + machine->lock.text_end =3D map__unmap_ip(kmap, sym->start); } =20 /* failed to get kernel symbols */ diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index d97a6d20626f..816bffbbf344 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -519,7 +519,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) if (dso->kernel =3D=3D DSO_SPACE__USER) return rip + dso->text_offset; =20 - return map->unmap_ip(map, rip) - map->reloc; + return map__unmap_ip(map, rip) - map->reloc; } =20 /** @@ -539,24 +539,24 @@ u64 map__objdump_2mem(struct map *map, u64 ip) const struct dso *dso =3D map__dso(map); =20 if (!dso->adjust_symbols) - return map->unmap_ip(map, ip); + return map__unmap_ip(map, ip); =20 if (dso->rel) - return map->unmap_ip(map, ip + map->pgoff); + return map__unmap_ip(map, ip + map->pgoff); =20 /* * kernel modules also have DSO_TYPE_USER in dso->kernel, * but all kernel modules are ET_REL, so won't get here. */ if (dso->kernel =3D=3D DSO_SPACE__USER) - return map->unmap_ip(map, ip - dso->text_offset); + return map__unmap_ip(map, ip - dso->text_offset); =20 return ip + map->reloc; } =20 bool map__contains_symbol(const struct map *map, const struct symbol *sym) { - u64 ip =3D map->unmap_ip(map, sym->start); + u64 ip =3D map__unmap_ip(map, sym->start); =20 return ip >=3D map__start(map) && ip < map__end(map); } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 9b0a84e46e48..9118eba71032 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -52,6 +52,16 @@ static inline struct dso *map__dso(const struct map *map) return map->dso; } =20 +static inline u64 map__map_ip(const struct map *map, u64 ip) +{ + return map->map_ip(map, ip); +} + +static inline u64 map__unmap_ip(const struct map *map, u64 ip) +{ + return map->unmap_ip(map, ip); +} + static inline u64 map__start(const struct map *map) { return map->start; diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 21010a2b8e16..0eee27e24c33 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -194,7 +194,7 @@ struct symbol *maps__find_symbol(struct maps *maps, u64= addr, struct map **mapp) if (map !=3D NULL && map__load(map) >=3D 0) { if (mapp !=3D NULL) *mapp =3D map; - return map__find_symbol(map, map->map_ip(map, addr)); + return map__find_symbol(map, map__map_ip(map, addr)); } =20 return NULL; @@ -237,7 +237,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_s= ymbol *ams) return -1; } =20 - ams->al_addr =3D ams->ms.map->map_ip(ams->ms.map, ams->addr); + ams->al_addr =3D map__map_ip(ams->ms.map, ams->addr); ams->ms.sym =3D map__find_symbol(ams->ms.map, ams->al_addr); =20 return ams->ms.sym ? 0 : -1; @@ -349,8 +349,8 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) =20 after->start =3D map__end(map); after->pgoff +=3D map__end(map) - map__start(pos->map); - assert(pos->map->map_ip(pos->map, map__end(map)) =3D=3D - after->map_ip(after, map__end(map))); + assert(map__map_ip(pos->map, map__end(map)) =3D=3D + map__map_ip(after, map__end(map))); err =3D __maps__insert(maps, after); if (err) goto put_map; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 4d9dbeeb6014..bb44a3798df8 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -141,7 +141,7 @@ static int kernel_get_symbol_address_by_name(const char= *name, u64 *addr, sym =3D machine__find_kernel_symbol_by_name(host_machine, name, &map); if (!sym) return -ENOENT; - *addr =3D map->unmap_ip(map, sym->start) - + *addr =3D map__unmap_ip(map, sym->start) - ((reloc) ? 0 : map->reloc) - ((reladdr) ? map__start(map) : 0); } @@ -400,7 +400,7 @@ static int find_alternative_probe_point(struct debuginf= o *dinfo, "Consider identifying the final function used at run time and set = the probe directly on that.\n", pp->function); } else - address =3D map->unmap_ip(map, sym->start) - map->reloc; + address =3D map__unmap_ip(map, sym->start) - map->reloc; break; } if (!address) { @@ -2249,7 +2249,7 @@ static int find_perf_probe_point_from_map(struct prob= e_trace_point *tp, goto out; =20 pp->retprobe =3D tp->retprobe; - pp->offset =3D addr - map->unmap_ip(map, sym->start); + pp->offset =3D addr - map__unmap_ip(map, sym->start); pp->function =3D strdup(sym->name); ret =3D pp->function ? 0 : -ENOMEM; =20 @@ -3123,7 +3123,7 @@ static int find_probe_trace_events_from_map(struct pe= rf_probe_event *pev, goto err_out; } /* Add one probe point */ - tp->address =3D map->unmap_ip(map, sym->start) + pp->offset; + tp->address =3D map__unmap_ip(map, sym->start) + pp->offset; =20 /* Check the kprobe (not in module) is within .text */ if (!pev->uprobes && !pev->target && diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index cbf09eaf3734..41d4f9e6a8b7 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -471,7 +471,7 @@ static PyObject *python_process_callchain(struct perf_s= ample *sample, struct addr_location node_al; unsigned long offset; =20 - node_al.addr =3D map->map_ip(map, node->ip); + node_al.addr =3D map__map_ip(map, node->ip); node_al.map =3D map; offset =3D get_offset(node->ms.sym, &node_al); =20 diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index f161589aefda..87a3ba584af5 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -364,7 +364,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol = *ms, u64 rip =3D ip; =20 if (dso && dso->kernel && dso->adjust_symbols) - rip =3D map->unmap_ip(map, ip); + rip =3D map__unmap_ip(map, ip); =20 ret +=3D repsep_snprintf(bf, size, "%-#*llx %c ", BITS_PER_LONG / 4 + 2, rip, o); @@ -375,7 +375,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol = *ms, if (sym->type =3D=3D STT_OBJECT) { ret +=3D repsep_snprintf(bf + ret, size - ret, "%s", sym->name); ret +=3D repsep_snprintf(bf + ret, size - ret, "+0x%llx", - ip - map->unmap_ip(map, sym->start)); + ip - map__unmap_ip(map, sym->start)); } else { ret +=3D repsep_snprintf(bf + ret, size - ret, "%.*s", width - ret, @@ -1147,7 +1147,7 @@ static int _hist_entry__addr_snprintf(struct map_symb= ol *ms, if (sym->type =3D=3D STT_OBJECT) { ret +=3D repsep_snprintf(bf + ret, size - ret, "%s", sym->name); ret +=3D repsep_snprintf(bf + ret, size - ret, "+0x%llx", - ip - map->unmap_ip(map, sym->start)); + ip - map__unmap_ip(map, sym->start)); } else { ret +=3D repsep_snprintf(bf + ret, size - ret, "%.*s", width - ret, @@ -2104,9 +2104,9 @@ sort__addr_cmp(struct hist_entry *left, struct hist_e= ntry *right) struct map *right_map =3D right->ms.map; =20 if (left_map) - left_ip =3D left_map->unmap_ip(left_map, left_ip); + left_ip =3D map__unmap_ip(left_map, left_ip); if (right_map) - right_ip =3D right_map->unmap_ip(right_map, right_ip); + right_ip =3D map__unmap_ip(right_map, right_ip); =20 return _sort__addr_cmp(left_ip, right_ip); } @@ -2118,7 +2118,7 @@ static int hist_entry__addr_snprintf(struct hist_entr= y *he, char *bf, struct map *map =3D he->ms.map; =20 if (map) - ip =3D map->unmap_ip(map, ip); + ip =3D map__unmap_ip(map, ip); =20 return repsep_snprintf(bf, size, "%-#*llx", width, ip); } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b91deb177091..9ba49c1ef6ef 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -896,8 +896,8 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, * So that we look just like we get from .ko files, * i.e. not prelinked, relative to initial_map->start. */ - pos->start =3D curr_map->map_ip(curr_map, pos->start); - pos->end =3D curr_map->map_ip(curr_map, pos->end); + pos->start =3D map__map_ip(curr_map, pos->start); + pos->end =3D map__map_ip(curr_map, pos->end); } else if (x86_64 && is_entry_trampoline(pos->name)) { /* * These symbols are not needed anymore since the diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index bb7a2ce82d46..4b5bdc277baa 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -464,7 +464,7 @@ int thread__memcpy(struct thread *thread, struct machin= e *machine, if( !dso || dso->data.status =3D=3D DSO_DATA_STATUS_ERROR || map__load(al= .map) < 0) return -1; =20 - offset =3D al.map->map_ip(al.map, ip); + offset =3D map__map_ip(al.map, ip); if (is64bit) *is64bit =3D dso->is_64_bit; =20 diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index b79f57e5648f..538320e4260c 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -115,7 +115,7 @@ static int entry(u64 ip, struct unwind_info *ui) pr_debug("unwind: %s:ip =3D 0x%" PRIx64 " (0x%" PRIx64 ")\n", al.sym ? al.sym->name : "''", ip, - al.map ? al.map->map_ip(al.map, ip) : (u64) 0); + al.map ? map__map_ip(al.map, ip) : (u64) 0); return 0; } =20 diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unw= ind-libunwind-local.c index 1c13f43e7d22..f9a52af48de4 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -640,7 +640,7 @@ static int entry(u64 ip, struct thread *thread, pr_debug("unwind: %s:ip =3D 0x%" PRIx64 " (0x%" PRIx64 ")\n", al.sym ? al.sym->name : "''", ip, - al.map ? al.map->map_ip(al.map, ip) : (u64) 0); + al.map ? map__map_ip(al.map, ip) : (u64) 0); =20 return cb(&e, arg); } --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 15D59C6FD1D for ; Tue, 4 Apr 2023 21:01:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236443AbjDDVBW (ORCPT ); Tue, 4 Apr 2023 17:01:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235526AbjDDVBQ (ORCPT ); Tue, 4 Apr 2023 17:01:16 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D14B74C28 for ; Tue, 4 Apr 2023 14:00:46 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-544781e30easo331880597b3.1 for ; Tue, 04 Apr 2023 14:00:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642044; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=M2robLIprEBFAsbqlI5uLA2rGb41LEGoQT3g1ZHVZHs=; b=URkoMiY57JFr4bg6vTKUNXBlX2RRhIqlneaow3/vn6vUyAjUFLY4w88vTUIHXl85Gs Bx6ODF+dQUmyhOK/LCXPZ/fIufkfpC/xmBnjWSIQyg8wrDyVYVwJW77ehUn8q3B6krba ZzvVEn095I0LwwniwjZb3IvS8fp0ITRipwh3nz+OcMA439mLyAqYRB9UZjqawqPF2NE1 TJuiHdUYwsu2LGUCCsWNo56DSy+uOvjWT9yEjvVHThwiWsbFbkLerfXygtUUvaEl6KzM NTy4HWUgBto4IZ2IQaZP25k3AnNkCPAlXNhuq6qKFtI1TSA4cbf2AC/tjbDIM3y4tPlm BVvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642044; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=M2robLIprEBFAsbqlI5uLA2rGb41LEGoQT3g1ZHVZHs=; b=k9UeTeaWl15irZ1YZTfumJjmH7vTl2z7KcgIZsulS/I1faCu4NGwGGo+Qz7bLU+F7K 4X3lnSvI5cKXgITTvAQ5HfT8JJvfsSJ7nQCnwuE+iR27l55zVwD7SC1av3ZyxGjKBvio iLrwDhyZfu6ZsbTN7QyQDn7W4iMaUkiA2F3VjfATPpUh+xWQZ3j6oHgtisrpl+Sc1YLz jqypJy/Ikwsh1C40ifNQvKloqaHEcSosa2HMChBtAA71IYJL/B8Prsl2cTYaP3JCCXup VjPpkJ9YDtRJSquBVuVQWmtw8F6tnJmxGLO7x8L5yj4865mzw8ziDZspVTXo7KN1I9oY UWuw== X-Gm-Message-State: AAQBX9egKhY14YDMuX4JWMC+YiCDRed25YkN/mrfRaTmJP057ZQwR6pt dsR0UpJujtb6rCtVkojsO0RHGg/vWtMg X-Google-Smtp-Source: AKy350YVIX8GdcOOPZrvfbcZ8BboepzC9grVMGll3G3XLDl2zD70sKHDEHKTRdE62F1zraCcGvjPdROByb2P X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a05:6902:90b:b0:b81:a13:50c3 with SMTP id bu11-20020a056902090b00b00b810a1350c3mr448032ybb.2.1680642044451; Tue, 04 Apr 2023 14:00:44 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:45 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-4-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 03/12] perf map: Add accessors for prot, priv and flags From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Later changes will add reference count checking for struct map. Add an accessor so that the reference count check is only necessary in one place. Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-report.c | 9 +++++---- tools/perf/tests/vmlinux-kallsyms.c | 4 ++-- tools/perf/util/map.h | 15 +++++++++++++++ tools/perf/util/sort.c | 6 +++--- tools/perf/util/symbol.c | 4 ++-- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 8f6909dd8a54..fd2b38458a5d 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -758,7 +758,7 @@ int perf_event__inject_buildid(struct perf_tool *tool, = union perf_event *event, if (!dso->hit) { dso->hit =3D 1; dso__inject_build_id(dso, tool, machine, - sample->cpumode, al.map->flags); + sample->cpumode, map__flags(al.map)); } } =20 diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2a6e2cee5e0d..c066452219c8 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -849,13 +849,14 @@ static size_t maps__fprintf_task(struct maps *maps, i= nt indent, FILE *fp) maps__for_each_entry(maps, rb_node) { struct map *map =3D rb_node->map; const struct dso *dso =3D map__dso(map); + u32 prot =3D map__prot(map); =20 printed +=3D fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRI= x64 " %" PRIu64 " %s\n", indent, "", map__start(map), map__end(map), - map->prot & PROT_READ ? 'r' : '-', - map->prot & PROT_WRITE ? 'w' : '-', - map->prot & PROT_EXEC ? 'x' : '-', - map->flags & MAP_SHARED ? 's' : 'p', + prot & PROT_READ ? 'r' : '-', + prot & PROT_WRITE ? 'w' : '-', + prot & PROT_EXEC ? 'x' : '-', + map__flags(map) ? 's' : 'p', map->pgoff, dso->id.ino, dso->name); } diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index 05a322ea3f9f..7db102868bc2 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -323,7 +323,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused mem_end =3D map__unmap_ip(vmlinux_map, map__end(map)); =20 pair =3D maps__find(kallsyms.kmaps, mem_start); - if (pair =3D=3D NULL || pair->priv) + if (pair =3D=3D NULL || map__priv(pair)) continue; =20 if (map__start(pair) =3D=3D mem_start) { @@ -351,7 +351,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused maps__for_each_entry(maps, rb_node) { struct map *map =3D rb_node->map; =20 - if (!map->priv) { + if (!map__priv(map)) { if (!header_printed) { pr_info("WARN: Maps only in kallsyms:\n"); header_printed =3D true; diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 9118eba71032..fd440c9c279e 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -72,6 +72,21 @@ static inline u64 map__end(const struct map *map) return map->end; } =20 +static inline u32 map__flags(const struct map *map) +{ + return map->flags; +} + +static inline u32 map__prot(const struct map *map) +{ + return map->prot; +} + +static inline bool map__priv(const struct map *map) +{ + return map->priv; +} + static inline size_t map__size(const struct map *map) { return map__end(map) - map__start(map); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 87a3ba584af5..80c9960c37e5 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1540,7 +1540,7 @@ sort__dcacheline_cmp(struct hist_entry *left, struct = hist_entry *right) */ =20 if ((left->cpumode !=3D PERF_RECORD_MISC_KERNEL) && - (!(l_map->flags & MAP_SHARED)) && !l_dso->id.maj && !l_dso->id.min && + (!(map__flags(l_map) & MAP_SHARED)) && !l_dso->id.maj && !l_dso->id.m= in && !l_dso->id.ino && !l_dso->id.ino_generation) { /* userspace anonymous */ =20 @@ -1576,8 +1576,8 @@ static int hist_entry__dcacheline_snprintf(struct his= t_entry *he, char *bf, =20 /* print [s] for shared data mmaps */ if ((he->cpumode !=3D PERF_RECORD_MISC_KERNEL) && - map && !(map->prot & PROT_EXEC) && - (map->flags & MAP_SHARED) && + map && !(map__prot(map) & PROT_EXEC) && + (map__flags(map) & MAP_SHARED) && (dso->id.maj || dso->id.min || dso->id.ino || dso->id.ino_generation= )) level =3D 's'; else if (!map) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 9ba49c1ef6ef..5c075d77a792 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1396,7 +1396,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, } =20 /* Read new maps into temporary lists */ - err =3D file__read_maps(fd, map->prot & PROT_EXEC, kcore_mapfn, &md, + err =3D file__read_maps(fd, map__prot(map) & PROT_EXEC, kcore_mapfn, &md, &is_64_bit); if (err) goto out_err; @@ -1509,7 +1509,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, =20 close(fd); =20 - if (map->prot & PROT_EXEC) + if (map__prot(map) & PROT_EXEC) pr_debug("Using %s for kernel object code\n", kcore_filename); else pr_debug("Using %s for kernel data\n", kcore_filename); --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0148EC761A6 for ; Tue, 4 Apr 2023 21:01:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236545AbjDDVBo (ORCPT ); Tue, 4 Apr 2023 17:01:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236461AbjDDVBS (ORCPT ); Tue, 4 Apr 2023 17:01:18 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7F33E49EC for ; Tue, 4 Apr 2023 14:00:53 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id z14-20020a62d10e000000b0062e01947ef4so134527pfg.11 for ; Tue, 04 Apr 2023 14:00:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642053; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=NTqMk+i14kBQhNGj+iB54TJvhWHGHEix7VEoIVCjH+o=; b=Tx2occNBIdX5b7jB2iYgPuGXZMCwpyVHbaJ/5KSlG31iWgB6Bf44aFnemB3efGLfQo Qu/XebiD6J0z/u/5DH6AiyMAQjvdsy0Ht/iRgS1nWDnheB6it7ID+TgMu9nS9fwBlmuE R55ElxXGRjWYiu0HgXDbZBnj2LTJHYyLpH01JaOClsV3lbDbk6+fJ+g4IOABHOr+Dtdp fSrI3x3ZkvnMOvZOW+z/9Zitrp5Q/+9t6Ef6ycYBnt4HbHgyCORtRU/xgpCU3Od6S2LI 6jxbx1N0Wg1NfRyoa2aiWHFZs7DjjVmEjLY3aqUpyXmhVkTYsGOcB6ykmUxLjah147Sh pdgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642053; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=NTqMk+i14kBQhNGj+iB54TJvhWHGHEix7VEoIVCjH+o=; b=p+zU7rA7l8fhrDh2BEHpSNJr0PKEBwJzLjc0tVsGPdRy0FG+apSE6vnIAAoXITLoAI QR1cAp55ZmfHMw72uOXFnFajXEZrCKn+c5ZU+yWAX2X/JUvTwTpjrg/AgLUImjnjK3m3 hAJsbZSj7nZNlfVSwuLitdpl9Hf0nNC6J3VbougWo0m18nsNMAziB2O0XJHQ416fxj9Z ceRv3CgyZQlWH7ngExIfqcUgPdb1zwMZu2r++oa3PK5ctzKhMLcPlf7Hm5XjO7cwimFo F+36TOxKRG0o4xj0klrP6aWirblYUr8Nz8WHVFt5ILVwI3yLPWN+VUgoozCvik0vIpHl keAA== X-Gm-Message-State: AAQBX9e0GRBdKbnj9uFkFw/lQbfwa/7uDGm8XdHySIu24WJ9D5bb1Vvo Ezg69ayPLpyN7W7uNLWTACHEHjfcMCtL X-Google-Smtp-Source: AKy350aR0+LCtC7ZuR8nlLRzzmcVh7BiTaSdHPR/2Gd7nqq8LjSUSQ+L/dAo7u9PoJOktgluHYd9eNRO6Dth X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:aa7:8891:0:b0:623:129f:6269 with SMTP id z17-20020aa78891000000b00623129f6269mr2094653pfe.1.1680642052919; Tue, 04 Apr 2023 14:00:52 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:46 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-5-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 04/12] perf map: Add accessors for pgoff and reloc From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Later changes will add reference count checking for struct map. Add accessors so that the reference count check is only necessary in one place. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/util/event.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 4 ++-- tools/perf/util/machine.c | 4 ++-- tools/perf/util/map.c | 14 +++++++------- tools/perf/util/map.h | 10 ++++++++++ tools/perf/util/probe-event.c | 8 ++++---- tools/perf/util/symbol.c | 6 +++--- tools/perf/util/unwind-libdw.c | 6 +++--- 9 files changed, 33 insertions(+), 23 deletions(-) diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/ev= ent.c index 3b2475707756..5741ffe47312 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -61,7 +61,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *= tool, =20 event->mmap.start =3D map__start(map); event->mmap.len =3D map__size(map); - event->mmap.pgoff =3D map->pgoff; + event->mmap.pgoff =3D map__pgoff(map); event->mmap.pid =3D machine->pid; =20 strlcpy(event->mmap.filename, kmap->name, PATH_MAX); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c066452219c8..92c6797e7cba 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -857,7 +857,7 @@ static size_t maps__fprintf_task(struct maps *maps, int= indent, FILE *fp) prot & PROT_WRITE ? 'w' : '-', prot & PROT_EXEC ? 'x' : '-', map__flags(map) ? 's' : 'p', - map->pgoff, + map__pgoff(map), dso->id.ino, dso->name); } =20 diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index 7db102868bc2..af511233c764 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -335,10 +335,10 @@ static int test__vmlinux_matches_kallsyms(struct test= _suite *test __maybe_unused } =20 pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - map__start(map), map__end(map), map->pgoff, dso->name); + map__start(map), map__end(map), map__pgoff(map), dso->name); if (mem_end !=3D map__end(pair)) pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, - map__start(pair), map__end(pair), pair->pgoff); + map__start(pair), map__end(pair), map__pgoff(pair)); pr_info(" %s\n", dso->name); pair->priv =3D 1; } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index d29ec4a04488..1ea6f6c06bbb 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1277,9 +1277,9 @@ int machine__map_x86_64_entry_trampolines(struct mach= ine *machine, if (!kmap || !is_entry_trampoline(kmap->name)) continue; =20 - dest_map =3D maps__find(kmaps, map->pgoff); + dest_map =3D maps__find(kmaps, map__pgoff(map)); if (dest_map !=3D map) - map->pgoff =3D map__map_ip(dest_map, map->pgoff); + map->pgoff =3D map__map_ip(dest_map, map__pgoff(map)); found =3D true; } if (found || machine->trampolines_mapped) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 816bffbbf344..1fe367e2cf19 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -421,7 +421,7 @@ size_t map__fprintf(struct map *map, FILE *fp) const struct dso *dso =3D map__dso(map); =20 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", - map__start(map), map__end(map), map->pgoff, dso->name); + map__start(map), map__end(map), map__pgoff(map), dso->name); } =20 size_t map__fprintf_dsoname(struct map *map, FILE *fp) @@ -510,7 +510,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) return rip; =20 if (dso->rel) - return rip - map->pgoff; + return rip - map__pgoff(map); =20 /* * kernel modules also have DSO_TYPE_USER in dso->kernel, @@ -519,7 +519,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) if (dso->kernel =3D=3D DSO_SPACE__USER) return rip + dso->text_offset; =20 - return map__unmap_ip(map, rip) - map->reloc; + return map__unmap_ip(map, rip) - map__reloc(map); } =20 /** @@ -542,7 +542,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) return map__unmap_ip(map, ip); =20 if (dso->rel) - return map__unmap_ip(map, ip + map->pgoff); + return map__unmap_ip(map, ip + map__pgoff(map)); =20 /* * kernel modules also have DSO_TYPE_USER in dso->kernel, @@ -551,7 +551,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) if (dso->kernel =3D=3D DSO_SPACE__USER) return map__unmap_ip(map, ip - dso->text_offset); =20 - return ip + map->reloc; + return ip + map__reloc(map); } =20 bool map__contains_symbol(const struct map *map, const struct symbol *sym) @@ -592,12 +592,12 @@ struct maps *map__kmaps(struct map *map) =20 u64 map__dso_map_ip(const struct map *map, u64 ip) { - return ip - map__start(map) + map->pgoff; + return ip - map__start(map) + map__pgoff(map); } =20 u64 map__dso_unmap_ip(const struct map *map, u64 ip) { - return ip + map__start(map) - map->pgoff; + return ip + map__start(map) - map__pgoff(map); } =20 u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index fd440c9c279e..102485699aa8 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -72,6 +72,16 @@ static inline u64 map__end(const struct map *map) return map->end; } =20 +static inline u64 map__pgoff(const struct map *map) +{ + return map->pgoff; +} + +static inline u64 map__reloc(const struct map *map) +{ + return map->reloc; +} + static inline u32 map__flags(const struct map *map) { return map->flags; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index bb44a3798df8..6e2110d605fb 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -135,14 +135,14 @@ static int kernel_get_symbol_address_by_name(const ch= ar *name, u64 *addr, /* ref_reloc_sym is just a label. Need a special fix*/ reloc_sym =3D kernel_get_ref_reloc_sym(&map); if (reloc_sym && strcmp(name, reloc_sym->name) =3D=3D 0) - *addr =3D (!map->reloc || reloc) ? reloc_sym->addr : + *addr =3D (!map__reloc(map) || reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; else { sym =3D machine__find_kernel_symbol_by_name(host_machine, name, &map); if (!sym) return -ENOENT; *addr =3D map__unmap_ip(map, sym->start) - - ((reloc) ? 0 : map->reloc) - + ((reloc) ? 0 : map__reloc(map)) - ((reladdr) ? map__start(map) : 0); } return 0; @@ -400,7 +400,7 @@ static int find_alternative_probe_point(struct debuginf= o *dinfo, "Consider identifying the final function used at run time and set = the probe directly on that.\n", pp->function); } else - address =3D map__unmap_ip(map, sym->start) - map->reloc; + address =3D map__unmap_ip(map, sym->start) - map__reloc(map); break; } if (!address) { @@ -866,7 +866,7 @@ post_process_kernel_probe_trace_events(struct probe_tra= ce_event *tevs, free(tevs[i].point.symbol); tevs[i].point.symbol =3D tmp; tevs[i].point.offset =3D tevs[i].point.address - - (map->reloc ? reloc_sym->unrelocated_addr : + (map__reloc(map) ? reloc_sym->unrelocated_addr : reloc_sym->addr); } return skipped; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 5c075d77a792..7282119c2990 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -810,11 +810,11 @@ static int maps__split_kallsyms_for_kcore(struct maps= *kmaps, struct dso *dso) continue; } curr_map_dso =3D map__dso(curr_map); - pos->start -=3D map__start(curr_map) - curr_map->pgoff; + pos->start -=3D map__start(curr_map) - map__pgoff(curr_map); if (pos->end > map__end(curr_map)) pos->end =3D map__end(curr_map); if (pos->end) - pos->end -=3D map__start(curr_map) - curr_map->pgoff; + pos->end -=3D map__start(curr_map) - map__pgoff(curr_map); symbols__insert(&curr_map_dso->symbols, pos); ++count; } @@ -1459,7 +1459,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, if (new_map =3D=3D replacement_map) { map->start =3D map__start(new_map); map->end =3D map__end(new_map); - map->pgoff =3D new_map->pgoff; + map->pgoff =3D map__pgoff(new_map); map->map_ip =3D new_map->map_ip; map->unmap_ip =3D new_map->unmap_ip; /* Ensure maps are correctly ordered */ diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 538320e4260c..9565f9906e5d 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -62,19 +62,19 @@ static int __report_module(struct addr_location *al, u6= 4 ip, Dwarf_Addr s; =20 dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL); - if (s !=3D map__start(al->map) - al->map->pgoff) + if (s !=3D map__start(al->map) - map__pgoff(al->map)) mod =3D 0; } =20 if (!mod) mod =3D dwfl_report_elf(ui->dwfl, dso->short_name, dso->long_name, -1, - map__start(al->map) - al->map->pgoff, false); + map__start(al->map) - map__pgoff(al->map), false); if (!mod) { char filename[PATH_MAX]; =20 if (dso__build_id_filename(dso, filename, sizeof(filename), false)) mod =3D dwfl_report_elf(ui->dwfl, dso->short_name, filename, -1, - map__start(al->map) - al->map->pgoff, false); + map__start(al->map) - map__pgoff(al->map), false); } =20 if (mod) { --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48592C6FD1D for ; Tue, 4 Apr 2023 21:01:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232087AbjDDVBy (ORCPT ); Tue, 4 Apr 2023 17:01:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38754 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235445AbjDDVBT (ORCPT ); Tue, 4 Apr 2023 17:01:19 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F1CD524B for ; Tue, 4 Apr 2023 14:01:02 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-54574d6204aso335133227b3.15 for ; Tue, 04 Apr 2023 14:01:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642061; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=1c3l5WcHyBwFdVydt7Y8S6cpo64GHAMEcTV54xz6om8=; b=rLnTcOkdWMbNqcWYqHLw/DvOWhFFp9oUaU3KqHTuQv1jGec4+kwNH10xJt32XTLpDn JQCl2LGCm2xs6Gvjv+RhmHkVQiDzC4RUsKVHc0z+POv9K6noDzosaKT11VTmHMp0Foi6 BU61Ur+4pBUYDufGOF47YJhcM46YSNNEyub6tlpsWhe2p/CBD3vHYC4QhDsYUnHAr7Rj K0zGWV//IJlVfe7Qk3EyrWC3UFQztXIkGARCXc0a/GPNPQH7Gzi6RmxDhSCpIutiFdTq G6v45goC/UBtwRvNEAGBZTZBJB4TdHh+JDDx0c7dnQmw7rp962ql9wuWakgzSG15aI27 5tqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642061; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=1c3l5WcHyBwFdVydt7Y8S6cpo64GHAMEcTV54xz6om8=; b=q8lNvD33droJWhHOeR8B7LI7Vk7BtYppq/ta0X3K6IE0O1Ux7OjdghwhyGIPVSVmvh fXw9YCmY0e9kOhRlbs6AmNI59a611fFhsfEMALFVu4O4kO+uGe8e0AIK0Idh3v4q1pFl PIm/kmzGt7mh5dof92sgjdzy4QaZYMtdOG+vT8y7rb8lBNN7DlYg8tk5DaUi+loZAQYw 2Jdw3YLgWJrLXuYg7OIw5jZO5iBMw7B4iiwbDR7Cpwl4ls8XCxIRZwB2HfepZPR8znPH 296UF/O0empGk7h+kGWhMa7jNn0OMvRO91ryvVozOl+xPdxjqu99h0KEQlr7uW7gbMHb pzTA== X-Gm-Message-State: AAQBX9cIWDxCEPFQnNi8nggDX6fL2iZM4XasQpUGlHe8ebNCW5y8f3ym bukUERY35GvxrP017Ghblo+2robjOXH2 X-Google-Smtp-Source: AKy350YgiPvYJgox6ETVp46YUTQcYLa80zfYiTpxh4w3p0nAszCU5XolwTiMh5JypXuimqmnUQfv+xCow0RY X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a25:d0cf:0:b0:b77:be38:6406 with SMTP id h198-20020a25d0cf000000b00b77be386406mr2295850ybg.9.1680642061207; Tue, 04 Apr 2023 14:01:01 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:47 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-6-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 05/12] perf test: Add extra diagnostics to maps test From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Dump the resultant and comparison maps on failure. Signed-off-by: Ian Rogers --- tools/perf/tests/maps.c | 51 +++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index fd0c464fcf95..1c7293476aca 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include "tests.h" @@ -17,22 +18,42 @@ static int check_maps(struct map_def *merged, unsigned = int size, struct maps *ma { struct map_rb_node *rb_node; unsigned int i =3D 0; - - maps__for_each_entry(maps, rb_node) { - struct map *map =3D rb_node->map; - - if (i > 0) - TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i = =3D=3D size)); - - TEST_ASSERT_VAL("wrong map start", map__start(map) =3D=3D merged[i].sta= rt); - TEST_ASSERT_VAL("wrong map end", map__end(map) =3D=3D merged[i].end); - TEST_ASSERT_VAL("wrong map name", !strcmp(map__dso(map)->name, merged[i= ].name)); - TEST_ASSERT_VAL("wrong map refcnt", refcount_read(&map->refcnt) =3D=3D 1= ); - - i++; + bool failed =3D false; + + if (maps__nr_maps(maps) !=3D size) { + pr_debug("Expected %d maps, got %d", size, maps__nr_maps(maps)); + failed =3D true; + } else { + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; + + if (map__start(map) !=3D merged[i].start || + map__end(map) !=3D merged[i].end || + strcmp(map__dso(map)->name, merged[i].name) || + refcount_read(&map->refcnt) !=3D 1) { + failed =3D true; + } + i++; + } } - - return TEST_OK; + if (failed) { + pr_debug("Expected:\n"); + for (i =3D 0; i < size; i++) { + pr_debug("\tstart: %" PRIu64 " end: %" PRIu64 " name: '%s' refcnt: 1\n", + merged[i].start, merged[i].end, merged[i].name); + } + pr_debug("Got:\n"); + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; + + pr_debug("\tstart: %" PRIu64 " end: %" PRIu64 " name: '%s' refcnt: %d\n= ", + map__start(map), + map__end(map), + map__dso(map)->name, + refcount_read(&map->refcnt)); + } + } + return failed ? TEST_FAIL : TEST_OK; } =20 static int test__maps__merge_in(struct test_suite *t __maybe_unused, int s= ubtest __maybe_unused) --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B01BBC6FD1D for ; Tue, 4 Apr 2023 21:01:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236199AbjDDVBs (ORCPT ); Tue, 4 Apr 2023 17:01:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38778 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235526AbjDDVBX (ORCPT ); Tue, 4 Apr 2023 17:01:23 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7552D59CD for ; Tue, 4 Apr 2023 14:01:09 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id w5-20020a253005000000b00aedd4305ff2so33527363ybw.13 for ; Tue, 04 Apr 2023 14:01:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642068; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=wj0zFnOGjLX2H2pqmjaN/TPZtFXQJuNwPwp/XDMzHTQ=; b=hiCSSAyFc3Fefg1mJbZzl8j/FKOnlkPpEXx19zp0ly1BZRc/R9T9iunS1w2QWke9uR QegPENGF+aNbgBtFN5ccAzQM/H0SdPUksuLqsb4DXGeJH2NO4BffynfHt5I7WGX53yxM hhpFZYh+qirjfk5ZMbSMkqb6Xq8esuRteAXydbB0K20KolVT/d2OmlATTGe5JYHHdn/4 54kTcBj5o8fmek12N512sLdcRv4VAuhqwLbkkWCOxlczXiAiaqLjCJ3OCAM+/5Jd/AmL kQjdOuHqtVhq7/jRQ+1174d9KAvTWHbakVY49PeYYr0bXEatiy6a9mL2CN0N+PyIR4D/ ZOeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642068; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wj0zFnOGjLX2H2pqmjaN/TPZtFXQJuNwPwp/XDMzHTQ=; b=Nw2GV6+8OLcZCMGxkvcZzYNsLcTN/n9t5gCj/+CfZbLH+yZ7Lf+LTQYxG+EqaN/wly D+NDAvUMF6Q7mz6JTfCu4WgbGikAsGZKzSUyXsvs/tz0oFgLE5JiPNdfMCLd2RSjHDhU btSHBkU2ZWN1I5TGTMCQQK6E98pykfER/+R1zGQakcFteO0dk48M0T3wZUwEtkEVjfQg sYQUL6ljzC+ftBl4KMAlR4l7GpJxDar9rSwj2uY8JjznU02TjFbbgh7h56Ky/Z7IVG7R YFsCMPIi3OToHqV5UluOuyebFhbYpKFo0CT42q+cWtSOEfCXyeQnMyXSxA2R4TZYNTio o9AA== X-Gm-Message-State: AAQBX9dHGC9vgyW9qw7Y+8qvR/NHAFzTIxRrDtzGQj4woR9tRK7xgqeB DFSwlQVBPMCKrFBxq0OC9MVJc6pEJhNM X-Google-Smtp-Source: AKy350ZcdHcdBTuvh0rSINk4xC5JyX/qIlqlYqW7u1+yruF7GiLKgVxMIlN1SDDSU7PcYPl1n2916BVQDBnD X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a25:74d7:0:b0:b6d:1483:bc0f with SMTP id p206-20020a2574d7000000b00b6d1483bc0fmr2366307ybc.9.1680642068274; Tue, 04 Apr 2023 14:01:08 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:48 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-7-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 06/12] perf maps: Modify maps_by_name to hold a reference to a map From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To make it clearer about the ownership of a reference count split the by-name case from the regular start-address sorted tree. Put the reference count when maps_by_name is freed, which requires moving a decrement to nr_maps in maps__remove. Add two missing map puts in maps__fixup_overlappings in the event maps__insert fails. Signed-off-by: Ian Rogers --- tools/perf/util/maps.c | 30 ++++++++++++++++-------------- tools/perf/util/symbol.c | 21 +++++++++++++++++---- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 0eee27e24c33..5afed53ea0b4 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -26,6 +26,9 @@ static void __maps__free_maps_by_name(struct maps *maps) /* * Free everything to try to do it from the rbtree in the next search */ + for (unsigned int i =3D 0; i < maps__nr_maps(maps); i++) + map__put(maps__maps_by_name(maps)[i]); + zfree(&maps->maps_by_name); maps->nr_maps_allocated =3D 0; } @@ -42,7 +45,7 @@ static int __maps__insert(struct maps *maps, struct map *= map) return -ENOMEM; =20 RB_CLEAR_NODE(&new_rb_node->rb_node); - new_rb_node->map =3D map; + new_rb_node->map =3D map__get(map); =20 while (*p !=3D NULL) { parent =3D *p; @@ -55,7 +58,6 @@ static int __maps__insert(struct maps *maps, struct map *= map) =20 rb_link_node(&new_rb_node->rb_node, parent, p); rb_insert_color(&new_rb_node->rb_node, maps__entries(maps)); - map__get(map); return 0; } =20 @@ -100,7 +102,7 @@ int maps__insert(struct maps *maps, struct map *map) maps->maps_by_name =3D maps_by_name; maps->nr_maps_allocated =3D nr_allocate; } - maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] =3D map; + maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] =3D map__get(map); __maps__sort_by_name(maps); } out: @@ -126,9 +128,9 @@ void maps__remove(struct maps *maps, struct map *map) rb_node =3D maps__find_node(maps, map); assert(rb_node->map =3D=3D map); __maps__remove(maps, rb_node); - --maps->nr_maps; if (maps__maps_by_name(maps)) __maps__free_maps_by_name(maps); + --maps->nr_maps; up_write(maps__lock(maps)); } =20 @@ -136,6 +138,9 @@ static void __maps__purge(struct maps *maps) { struct map_rb_node *pos, *next; =20 + if (maps__maps_by_name(maps)) + __maps__free_maps_by_name(maps); + maps__for_each_entry_safe(maps, pos, next) { rb_erase_init(&pos->rb_node, maps__entries(maps)); map__put(pos->map); @@ -293,7 +298,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) } =20 next =3D first; - while (next) { + while (next && !err) { struct map_rb_node *pos =3D rb_entry(next, struct map_rb_node, rb_node); next =3D rb_next(&pos->rb_node); =20 @@ -331,8 +336,10 @@ int maps__fixup_overlappings(struct maps *maps, struct= map *map, FILE *fp) =20 before->end =3D map__start(map); err =3D __maps__insert(maps, before); - if (err) + if (err) { + map__put(before); goto put_map; + } =20 if (verbose >=3D 2 && !use_browser) map__fprintf(before, fp); @@ -352,22 +359,17 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) assert(map__map_ip(pos->map, map__end(map)) =3D=3D map__map_ip(after, map__end(map))); err =3D __maps__insert(maps, after); - if (err) + if (err) { + map__put(after); goto put_map; - + } if (verbose >=3D 2 && !use_browser) map__fprintf(after, fp); map__put(after); } put_map: map__put(pos->map); - - if (err) - goto out; } - - err =3D 0; -out: up_write(maps__lock(maps)); return err; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 7282119c2990..91ebf93e0c20 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2053,10 +2053,23 @@ int dso__load(struct dso *dso, struct map *map) =20 static int map__strcmp(const void *a, const void *b) { - const struct dso *dso_a =3D map__dso(*(const struct map **)a); - const struct dso *dso_b =3D map__dso(*(const struct map **)b); + const struct map *map_a =3D *(const struct map **)a; + const struct map *map_b =3D *(const struct map **)b; + const struct dso *dso_a =3D map__dso(map_a); + const struct dso *dso_b =3D map__dso(map_b); + int ret =3D strcmp(dso_a->short_name, dso_b->short_name); =20 - return strcmp(dso_a->short_name, dso_b->short_name); + if (ret =3D=3D 0 && map_a !=3D map_b) { + /* + * Ensure distinct but name equal maps have an order in part to + * aid reference counting. + */ + ret =3D (int)map__start(map_a) - (int)map__start(map_b); + if (ret =3D=3D 0) + ret =3D (int)((intptr_t)map_a - (intptr_t)map_b); + } + + return ret; } =20 static int map__strcmp_name(const void *name, const void *b) @@ -2088,7 +2101,7 @@ static int map__groups__sort_by_name_from_rbtree(stru= ct maps *maps) maps->nr_maps_allocated =3D maps__nr_maps(maps); =20 maps__for_each_entry(maps, rb_node) - maps_by_name[i++] =3D rb_node->map; + maps_by_name[i++] =3D map__get(rb_node->map); =20 __maps__sort_by_name(maps); =20 --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4E9B3C77B60 for ; Tue, 4 Apr 2023 21:02:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235964AbjDDVCO (ORCPT ); Tue, 4 Apr 2023 17:02:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38752 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236544AbjDDVBo (ORCPT ); Tue, 4 Apr 2023 17:01:44 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9EE664ECF for ; Tue, 4 Apr 2023 14:01:18 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id j11-20020a25230b000000b00b6871c296bdso32946910ybj.5 for ; Tue, 04 Apr 2023 14:01:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642076; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=gJJ1iP97nkAnl2cwIEVqTNe6UdQMdJEcOdeemvz0eyw=; b=si1ylUgHVEX73fP5F1iGbjDOecAOzFxVDC8FldSHz+ipgqlSNmb+c88HTU5kd2VZF3 Me/XiCTQqPovewJctawalZKz+UDrqPah+m1VF4OxAM36J137ibpcFxnCCHC1SgAqE1sD amm3MUCvEXEc/L8hC0ijFDhEi1JlpGnHjazLb1TS0pdZ9pUZz4GuoLqYwWt44oi/JbV1 zv/8wJT2LSvQ8MFHD+kh4prdMhz4ydx6rWCbtmM2kzNfRW24S538+1Tg2vTdP/ArVfIY 7ElyuHfuWoollC3yjEgOGFpaTA3WYBM3IX7P/iX5drxsORI0nbjRigXV84AjlAXqAZQh fNHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642076; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gJJ1iP97nkAnl2cwIEVqTNe6UdQMdJEcOdeemvz0eyw=; b=v7AwVZtlLr4r0SEPr8VzacKsN5sX92nylUuxfqSo2pOl93ZtD0Pj08lQGGvCj1pDkf pDnFZvGgBGK3Z09te6AogNhQZGuLb34Oly3HbG7gI12P/LEzzhBSL++sfKPRX12VvNpA tHtwfMHhPjs8JYSXcjrLnXEHZ7bmIY6ArIpTqmsDTypBfl+QrDszFYnJHjV2G6heTAcC EPRruVAss9v9skaYGVrbRZlak6oSJOFE+Djq+kyUtwyOai6h0uR+wdKjFLavP/mnb+ng HvaMLA0AX+c7rD36mxZE75YPRAajl8Bi3HaLd0MKSoHoRLIBilAYeSLRGPVZbzLal21b Ot9w== X-Gm-Message-State: AAQBX9elS62ddW9n3ZCX6VBRKEjeTmFrWK4fDem75F+8g1qYvryomJuT Qq9UZ1b5Bzu9UH3c6TSkihYpYeZARzKB X-Google-Smtp-Source: AKy350ZyIXp/zFE/HjkrdsIOMiX43H4H/vZJZlRCmPoU7QonmocpRzqC6RJc+fxWd5K9xKlioFejWxN2UD+j X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a05:6902:90b:b0:b81:a13:50c3 with SMTP id bu11-20020a056902090b00b00b810a1350c3mr449168ybb.2.1680642076273; Tue, 04 Apr 2023 14:01:16 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:49 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-8-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 07/12] perf map: Changes to reference counting From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When a pointer to a map exists do a get, when that pointer is overwritten or freed, put the map. This avoids issues with gets and puts being inconsistently used causing, use after puts, etc. For example, the map in struct addr_location is changed to hold a reference count. Reference count checking and address sanitizer were used to identify issues. Signed-off-by: Ian Rogers --- tools/perf/tests/code-reading.c | 1 + tools/perf/tests/hists_cumulate.c | 10 ++++ tools/perf/tests/hists_filter.c | 10 ++++ tools/perf/tests/hists_link.c | 18 +++++- tools/perf/tests/hists_output.c | 10 ++++ tools/perf/tests/mmap-thread-lookup.c | 1 + tools/perf/util/callchain.c | 9 +-- tools/perf/util/event.c | 6 +- tools/perf/util/hist.c | 10 ++-- tools/perf/util/machine.c | 79 ++++++++++++++++----------- tools/perf/util/map.c | 2 +- 11 files changed, 112 insertions(+), 44 deletions(-) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index 1545fcaa95c6..efe026a35010 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -366,6 +366,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, } pr_debug("Bytes read match those read by objdump\n"); out: + map__put(al.map); return err; } =20 diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cum= ulate.c index f00ec9abdbcd..8c0e3f334747 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -112,6 +112,7 @@ static int add_hist_entries(struct hists *hists, struct= machine *machine) } =20 fake_samples[i].thread =3D al.thread; + map__put(fake_samples[i].map); fake_samples[i].map =3D al.map; fake_samples[i].sym =3D al.sym; } @@ -147,6 +148,14 @@ static void del_hist_entries(struct hists *hists) } } =20 +static void put_fake_samples(void) +{ + size_t i; + + for (i =3D 0; i < ARRAY_SIZE(fake_samples); i++) + map__put(fake_samples[i].map); +} + typedef int (*test_fn_t)(struct evsel *, struct machine *); =20 #define COMM(he) (thread__comm_str(he->thread)) @@ -733,6 +742,7 @@ static int test__hists_cumulate(struct test_suite *test= __maybe_unused, int subt /* tear down everything */ evlist__delete(evlist); machines__exit(&machines); + put_fake_samples(); =20 return err; } diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filte= r.c index 7c552549f4a4..98eff5935a1c 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -89,6 +89,7 @@ static int add_hist_entries(struct evlist *evlist, } =20 fake_samples[i].thread =3D al.thread; + map__put(fake_samples[i].map); fake_samples[i].map =3D al.map; fake_samples[i].sym =3D al.sym; } @@ -101,6 +102,14 @@ static int add_hist_entries(struct evlist *evlist, return TEST_FAIL; } =20 +static void put_fake_samples(void) +{ + size_t i; + + for (i =3D 0; i < ARRAY_SIZE(fake_samples); i++) + map__put(fake_samples[i].map); +} + static int test__hists_filter(struct test_suite *test __maybe_unused, int = subtest __maybe_unused) { int err =3D TEST_FAIL; @@ -322,6 +331,7 @@ static int test__hists_filter(struct test_suite *test _= _maybe_unused, int subtes evlist__delete(evlist); reset_output_field(); machines__exit(&machines); + put_fake_samples(); =20 return err; } diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index e7e4ee57ce04..64ce8097889c 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -6,6 +6,7 @@ #include "evsel.h" #include "evlist.h" #include "machine.h" +#include "map.h" #include "parse-events.h" #include "hists_common.h" #include "util/mmap.h" @@ -94,6 +95,7 @@ static int add_hist_entries(struct evlist *evlist, struct= machine *machine) } =20 fake_common_samples[k].thread =3D al.thread; + map__put(fake_common_samples[k].map); fake_common_samples[k].map =3D al.map; fake_common_samples[k].sym =3D al.sym; } @@ -126,11 +128,24 @@ static int add_hist_entries(struct evlist *evlist, st= ruct machine *machine) return -1; } =20 +static void put_fake_samples(void) +{ + size_t i, j; + + for (i =3D 0; i < ARRAY_SIZE(fake_common_samples); i++) + map__put(fake_common_samples[i].map); + for (i =3D 0; i < ARRAY_SIZE(fake_samples); i++) { + for (j =3D 0; j < ARRAY_SIZE(fake_samples[0]); j++) + map__put(fake_samples[i][j].map); + } +} + static int find_sample(struct sample *samples, size_t nr_samples, struct thread *t, struct map *m, struct symbol *s) { while (nr_samples--) { - if (samples->thread =3D=3D t && samples->map =3D=3D m && + if (samples->thread =3D=3D t && + samples->map =3D=3D m && samples->sym =3D=3D s) return 1; samples++; @@ -336,6 +351,7 @@ static int test__hists_link(struct test_suite *test __m= aybe_unused, int subtest evlist__delete(evlist); reset_output_field(); machines__exit(&machines); + put_fake_samples(); =20 return err; } diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_outpu= t.c index 428d11a938f2..cebd5226bb12 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -78,6 +78,7 @@ static int add_hist_entries(struct hists *hists, struct m= achine *machine) } =20 fake_samples[i].thread =3D al.thread; + map__put(fake_samples[i].map); fake_samples[i].map =3D al.map; fake_samples[i].sym =3D al.sym; } @@ -113,6 +114,14 @@ static void del_hist_entries(struct hists *hists) } } =20 +static void put_fake_samples(void) +{ + size_t i; + + for (i =3D 0; i < ARRAY_SIZE(fake_samples); i++) + map__put(fake_samples[i].map); +} + typedef int (*test_fn_t)(struct evsel *, struct machine *); =20 #define COMM(he) (thread__comm_str(he->thread)) @@ -620,6 +629,7 @@ static int test__hists_output(struct test_suite *test _= _maybe_unused, int subtes /* tear down everything */ evlist__delete(evlist); machines__exit(&machines); + put_fake_samples(); =20 return err; } diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-= thread-lookup.c index 5cc4644e353d..898eda55b7a8 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -203,6 +203,7 @@ static int mmap_events(synth_cb synth) } =20 pr_debug("map %p, addr %" PRIx64 "\n", al.map, map__start(al.map)); + map__put(al.map); } =20 machine__delete_threads(machine); diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 9e9c39dd9d2b..78dc7b6f7ff7 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -589,7 +589,7 @@ fill_node(struct callchain_node *node, struct callchain= _cursor *cursor) } call->ip =3D cursor_node->ip; call->ms =3D cursor_node->ms; - map__get(call->ms.map); + call->ms.map =3D map__get(call->ms.map); call->srcline =3D cursor_node->srcline; =20 if (cursor_node->branch) { @@ -1067,7 +1067,7 @@ int callchain_cursor_append(struct callchain_cursor *= cursor, node->ip =3D ip; map__zput(node->ms.map); node->ms =3D *ms; - map__get(node->ms.map); + node->ms.map =3D map__get(node->ms.map); node->branch =3D branch; node->nr_loop_iter =3D nr_loop_iter; node->iter_cycles =3D iter_cycles; @@ -1115,7 +1115,8 @@ int fill_callchain_info(struct addr_location *al, str= uct callchain_cursor_node * struct machine *machine =3D maps__machine(node->ms.maps); =20 al->maps =3D node->ms.maps; - al->map =3D node->ms.map; + map__put(al->map); + al->map =3D map__get(node->ms.map); al->sym =3D node->ms.sym; al->srcline =3D node->srcline; al->addr =3D node->ip; @@ -1528,7 +1529,7 @@ int callchain_node__make_parent_list(struct callchain= _node *node) goto out; *new =3D *chain; new->has_children =3D false; - map__get(new->ms.map); + new->ms.map =3D map__get(new->ms.map); list_add_tail(&new->list, &head); } parent =3D parent->parent; diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2712d1a8264e..13f7f85e92e1 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -485,13 +485,14 @@ size_t perf_event__fprintf_text_poke(union perf_event= *event, struct machine *ma if (machine) { struct addr_location al; =20 - al.map =3D maps__find(machine__kernel_maps(machine), tp->addr); + al.map =3D map__get(maps__find(machine__kernel_maps(machine), tp->addr)); if (al.map && map__load(al.map) >=3D 0) { al.addr =3D map__map_ip(al.map, tp->addr); al.sym =3D map__find_symbol(al.map, al.addr); if (al.sym) ret +=3D symbol__fprintf_symname_offs(al.sym, &al, fp); } + map__put(al.map); } ret +=3D fprintf(fp, " old len %u new len %u\n", tp->old_len, tp->new_len= ); old =3D true; @@ -614,7 +615,7 @@ struct map *thread__find_map(struct thread *thread, u8 = cpumode, u64 addr, return NULL; } =20 - al->map =3D maps__find(maps, al->addr); + al->map =3D map__get(maps__find(maps, al->addr)); if (al->map !=3D NULL) { /* * Kernel maps might be changed when loading symbols so loading @@ -773,6 +774,7 @@ int machine__resolve(struct machine *machine, struct ad= dr_location *al, */ void addr_location__put(struct addr_location *al) { + map__zput(al->map); thread__zput(al->thread); } =20 diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e494425cad06..51020da15ffc 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -450,7 +450,7 @@ static int hist_entry__init(struct hist_entry *he, memset(&he->stat, 0, sizeof(he->stat)); } =20 - map__get(he->ms.map); + he->ms.map =3D map__get(he->ms.map); =20 if (he->branch_info) { /* @@ -465,13 +465,13 @@ static int hist_entry__init(struct hist_entry *he, memcpy(he->branch_info, template->branch_info, sizeof(*he->branch_info)); =20 - map__get(he->branch_info->from.ms.map); - map__get(he->branch_info->to.ms.map); + he->branch_info->from.ms.map =3D map__get(he->branch_info->from.ms.map); + he->branch_info->to.ms.map =3D map__get(he->branch_info->to.ms.map); } =20 if (he->mem_info) { - map__get(he->mem_info->iaddr.ms.map); - map__get(he->mem_info->daddr.ms.map); + he->mem_info->iaddr.ms.map =3D map__get(he->mem_info->iaddr.ms.map); + he->mem_info->daddr.ms.map =3D map__get(he->mem_info->daddr.ms.map); } =20 if (hist_entry__has_callchains(he) && symbol_conf.use_callchain) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 1ea6f6c06bbb..25738775834e 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -881,21 +881,29 @@ static int machine__process_ksymbol_register(struct m= achine *machine, struct symbol *sym; struct dso *dso; struct map *map =3D maps__find(machine__kernel_maps(machine), event->ksym= bol.addr); + bool put_map =3D false; + int err =3D 0; =20 if (!map) { - int err; - dso =3D dso__new(event->ksymbol.name); - if (dso) { - dso->kernel =3D DSO_SPACE__KERNEL; - map =3D map__new2(0, dso); - dso__put(dso); - } =20 - if (!dso || !map) { - return -ENOMEM; + if (!dso) { + err =3D -ENOMEM; + goto out; } - + dso->kernel =3D DSO_SPACE__KERNEL; + map =3D map__new2(0, dso); + dso__put(dso); + if (!map) { + err =3D -ENOMEM; + goto out; + } + /* + * The inserted map has a get on it, we need to put to release + * the reference count here, but do it after all accesses are + * done. + */ + put_map =3D true; if (event->ksymbol.ksym_type =3D=3D PERF_RECORD_KSYMBOL_TYPE_OOL) { dso->binary_type =3D DSO_BINARY_TYPE__OOL; dso->data.file_size =3D event->ksymbol.len; @@ -905,9 +913,10 @@ static int machine__process_ksymbol_register(struct ma= chine *machine, map->start =3D event->ksymbol.addr; map->end =3D map__start(map) + event->ksymbol.len; err =3D maps__insert(machine__kernel_maps(machine), map); - map__put(map); - if (err) - return err; + if (err) { + err =3D -ENOMEM; + goto out; + } =20 dso__set_loaded(dso); =20 @@ -922,10 +931,15 @@ static int machine__process_ksymbol_register(struct m= achine *machine, sym =3D symbol__new(map__map_ip(map, map__start(map)), event->ksymbol.len, 0, 0, event->ksymbol.name); - if (!sym) - return -ENOMEM; + if (!sym) { + err =3D -ENOMEM; + goto out; + } dso__insert_symbol(dso, sym); - return 0; +out: + if (put_map) + map__put(map); + return err; } =20 static int machine__process_ksymbol_unregister(struct machine *machine, @@ -1027,13 +1041,11 @@ static struct map *machine__addnew_module_map(struc= t machine *machine, u64 start goto out; =20 err =3D maps__insert(machine__kernel_maps(machine), map); - - /* Put the map here because maps__insert already got it */ - map__put(map); - /* If maps__insert failed, return NULL. */ - if (err) + if (err) { + map__put(map); map =3D NULL; + } out: /* put the dso here, corresponding to machine__findnew_module_dso */ dso__put(dso); @@ -1325,6 +1337,7 @@ __machine__create_kernel_maps(struct machine *machine= , struct dso *kernel) /* In case of renewal the kernel map, destroy previous one */ machine__destroy_kernel_maps(machine); =20 + map__put(machine->vmlinux_map); machine->vmlinux_map =3D map__new2(0, kernel); if (machine->vmlinux_map =3D=3D NULL) return -ENOMEM; @@ -1613,7 +1626,7 @@ static int machine__create_module(void *arg, const ch= ar *name, u64 start, map->end =3D start + size; =20 dso__kernel_module_get_build_id(map__dso(map), machine->root_dir); - + map__put(map); return 0; } =20 @@ -1659,16 +1672,18 @@ static void machine__set_kernel_mmap(struct machine= *machine, static int machine__update_kernel_mmap(struct machine *machine, u64 start, u64 end) { - struct map *map =3D machine__kernel_map(machine); + struct map *orig, *updated; int err; =20 - map__get(map); - maps__remove(machine__kernel_maps(machine), map); + orig =3D machine->vmlinux_map; + updated =3D map__get(orig); =20 + machine->vmlinux_map =3D updated; machine__set_kernel_mmap(machine, start, end); + maps__remove(machine__kernel_maps(machine), orig); + err =3D maps__insert(machine__kernel_maps(machine), updated); + map__put(orig); =20 - err =3D maps__insert(machine__kernel_maps(machine), map); - map__put(map); return err; } =20 @@ -2295,7 +2310,7 @@ static int add_callchain_ip(struct thread *thread, { struct map_symbol ms; struct addr_location al; - int nr_loop_iter =3D 0; + int nr_loop_iter =3D 0, err; u64 iter_cycles =3D 0; const char *srcline =3D NULL; =20 @@ -2360,9 +2375,11 @@ static int add_callchain_ip(struct thread *thread, return 0; =20 srcline =3D callchain_srcline(&ms, al.addr); - return callchain_cursor_append(cursor, ip, &ms, - branch, flags, nr_loop_iter, - iter_cycles, branch_from, srcline); + err =3D callchain_cursor_append(cursor, ip, &ms, + branch, flags, nr_loop_iter, + iter_cycles, branch_from, srcline); + map__put(al.map); + return err; } =20 struct branch_info *sample__resolve_bstack(struct perf_sample *sample, diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 1fe367e2cf19..acbc37359e06 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -410,7 +410,7 @@ struct map *map__clone(struct map *from) map =3D memdup(from, size); if (map !=3D NULL) { refcount_set(&map->refcnt, 1); - dso__get(dso); + map->dso =3D dso__get(dso); } =20 return map; --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A134DC6FD1D for ; Tue, 4 Apr 2023 21:02:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236460AbjDDVCU (ORCPT ); Tue, 4 Apr 2023 17:02:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236433AbjDDVB7 (ORCPT ); Tue, 4 Apr 2023 17:01:59 -0400 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 82E945BA3 for ; Tue, 4 Apr 2023 14:01:25 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id b124-20020a253482000000b00b72947f6a54so33428207yba.14 for ; Tue, 04 Apr 2023 14:01:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642084; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=i5xLBjFXhcm9sYgimeLOoR7dRp+TOGDHizUYLczDSFs=; b=MR40FXnRWvM0PtNwbowixq5oiEk6TvBwN6ON4Eb72CUn7s3L2jydJtAU3Aef+oA/UY 61zED9hKdyXinbgivdq2ur/4/c/TEYdLU7p64Ze+BKPI3s1r11RoksYwLAsa9GU9THnp l67Ynb8L2gCE02Z/B/ERWP3xD4WYX5TikLoatemNqhCbHnInLnhIW7bR3NPDu9vU2VxX fRlElraht1JjTHhNSMwoTXw+BXRK1Bo+t8fdaKBFMb85uaPfsW1tGeSPbF2SghglNEj5 ZUPM4mmt23vNpmQbopvFOYHdv7ljhWs4NRbPwES4+rDxRnhKV7gxpwc+eIUmBJeNR4ou Yczg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642084; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=i5xLBjFXhcm9sYgimeLOoR7dRp+TOGDHizUYLczDSFs=; b=Ua4o1IMQwFUh9A6Fp9+ILKZPzxzRETyWO14rHAgHueLgUhPZp50wc67hTXy2Rn5FjT BGI6VqvHPR/1Z86pufaBofqIYCtNtiv6SGfZevQyGnDjM9GNM4qPduufInFvaoLUGEAY zDgHdJB4PVzcVngjdvjY5iP0sRsabQnyculx+bxnR9lnDc6rUdJKHtdo1TqFXUTzd0XY INTWG+BDGJTjtrOqw4grwNd/ZJsKS2fSfFv7dhAIZquxihXATLyQa2JF23yBrxNDJzQB j577wVT1H3wlGXJHzMT/w+xbbmmIq+65VYgi24xNTQjhM5OCto67n48d/Iw0AbI1iFr/ IMYA== X-Gm-Message-State: AAQBX9eULVmg27En//DumTXaYxjVriiFvbd4ClAV0xObcmel3ZYnk9OC iHKWErYZQ3YeWDLRhOYDdqXy/Jr1RsaY X-Google-Smtp-Source: AKy350b2Qp9xtHHizu722cnYV+snfN2OE0sUVZq5lE5vAnQsNBwrkZZStZmG1KNsXuhm4qMoVrlCIB27YRxP X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a81:c642:0:b0:546:63a:6e23 with SMTP id q2-20020a81c642000000b00546063a6e23mr2324766ywj.0.1680642084270; Tue, 04 Apr 2023 14:01:24 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:50 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-9-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 08/12] libperf: Add reference count checking macros. From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The macros serve as a way to debug use of a reference counted struct. The macros add a memory allocated pointer that is interposed between the reference counted original struct at a get and freed by a put. The pointer replaces the original struct, so use of the struct name via APIs remains unchanged. Signed-off-by: Ian Rogers --- tools/lib/perf/include/internal/rc_check.h | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tools/lib/perf/include/internal/rc_check.h diff --git a/tools/lib/perf/include/internal/rc_check.h b/tools/lib/perf/in= clude/internal/rc_check.h new file mode 100644 index 000000000000..c0626d8beb59 --- /dev/null +++ b/tools/lib/perf/include/internal/rc_check.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ +#ifndef __LIBPERF_INTERNAL_RC_CHECK_H +#define __LIBPERF_INTERNAL_RC_CHECK_H + +#include +#include + +/* + * Shared reference count checking macros. + * + * Reference count checking is an approach to sanitizing the use of refere= nce + * counted structs. It leverages address and leak sanitizers to make sure = gets + * are paired with a put. Reference count checking adds a malloc-ed layer = of + * indirection on a get, and frees it on a put. A missed put will be repor= ted as + * a memory leak. A double put will be reported as a double free. Accessing + * after a put will cause a use-after-free and/or a segfault. + */ + +#ifndef REFCNT_CHECKING +/* Replaces "struct foo" so that the pointer may be interposed. */ +#define DECLARE_RC_STRUCT(struct_name) \ + struct struct_name + +/* Declare a reference counted struct variable. */ +#define RC_STRUCT(struct_name) struct struct_name + +/* + * Interpose the indirection. Result will hold the indirection and object = is the + * reference counted struct. + */ +#define ADD_RC_CHK(result, object) (result =3D object, object) + +/* Strip the indirection layer. */ +#define RC_CHK_ACCESS(object) object + +/* Frees the object and the indirection layer. */ +#define RC_CHK_FREE(object) free(object) + +/* A get operation adding the indirection layer. */ +#define RC_CHK_GET(result, object) ADD_RC_CHK(result, object) + +/* A put operation removing the indirection layer. */ +#define RC_CHK_PUT(object) {} + +#else + +/* Replaces "struct foo" so that the pointer may be interposed. */ +#define DECLARE_RC_STRUCT(struct_name) \ + struct original_##struct_name; \ + struct struct_name { \ + struct original_##struct_name *orig; \ + }; \ + struct original_##struct_name + +/* Declare a reference counted struct variable. */ +#define RC_STRUCT(struct_name) struct original_##struct_name + +/* + * Interpose the indirection. Result will hold the indirection and object = is the + * reference counted struct. + */ +#define ADD_RC_CHK(result, object) \ + ( \ + object ? (result =3D malloc(sizeof(*result)), \ + result ? (result->orig =3D object, result) \ + : (result =3D NULL, NULL)) \ + : (result =3D NULL, NULL) \ + ) + +/* Strip the indirection layer. */ +#define RC_CHK_ACCESS(object) object->orig + +/* Frees the object and the indirection layer. */ +#define RC_CHK_FREE(object) \ + do { \ + zfree(&object->orig); \ + free(object); \ + } while(0) + +/* A get operation adding the indirection layer. */ +#define RC_CHK_GET(result, object) ADD_RC_CHK(result, (object ? object->or= ig : NULL)) + +/* A put operation removing the indirection layer. */ +#define RC_CHK_PUT(object) \ + do { \ + if (object) { \ + object->orig =3D NULL; \ + free(object); \ + } \ + } while(0) + +#endif + +#endif /* __LIBPERF_INTERNAL_RC_CHECK_H */ --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6DDC1C761A6 for ; Tue, 4 Apr 2023 21:02:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236280AbjDDVCh (ORCPT ); Tue, 4 Apr 2023 17:02:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236475AbjDDVCJ (ORCPT ); Tue, 4 Apr 2023 17:02:09 -0400 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 2BC205BB4 for ; Tue, 4 Apr 2023 14:01:34 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id j11-20020a25230b000000b00b6871c296bdso32947727ybj.5 for ; Tue, 04 Apr 2023 14:01:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642092; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=4MH1z+r1E3OK2fLosR1Bnw7h5TqzIm+VpTOh5x47/4k=; b=U+hepWonjTc0PpgFMdZq/ppqwxymOJ5SsruuSq9kBcDuXZjH8rOFJ9tx97hWJIm9Ed 4knpFhj3M7CqWxS2Vam+VmS1vG9LR43xb8r5VfA71Ks8WLjW0ECR0gfFTCKqzhxxP6K1 8KoytNR8DeVjW5EHHzutfZ8HyfYaznjikJN9xbRx9MBcF9ZZcID8ftuC6ZETCIVKi1n/ gvWVH0fdRNYK4j7lkMQbJio9rx4JlLqPAZ6PbZ1lNzSqVqYolYYsu9ar6sGcAGV1QCFM sZHaMIOJW5ivhbi1Iue6zVz/fKX94pruta8QaepkoG5TT58peQXDlRAijYdJ8NGMGuWd IGJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642092; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=4MH1z+r1E3OK2fLosR1Bnw7h5TqzIm+VpTOh5x47/4k=; b=EeTi0r94KVdWQURayjyDypdbxYFd5xoZ5sXOy66qkMRwkgnEfSh0NoUBIzMpy4bWVl HAiUtE3zrBTwB1uzL55p0VafzBbaL4cERFx7p2AFnteEMunxZnnCglj1RVxO190fO7tc Q3CF2Rgym+Y+H+NZj37CVwrUd5Ah82CEL2DSQnYqBDdb8sE4/OvYBaS+qWAAD+HVStxb cnCkrd3zqr2u4E3SIpCfZ7vqP1F5ROvizXxi8QnZIg5sA6okdbEvdTmGcnXuJQ+0HlHU wkh5ruYy6w7DQAvDqFk625jse9959bpjCB+OUjJVhgLn2FJ2n1997TfW5gv98um5Ws2u 2uHw== X-Gm-Message-State: AAQBX9eiERcCrNY4zaV9cbk9TlJjYM4gB8lZydZzz5mLz3McOS+UT37I neujH87swS1/ltNsb1gleCOJyUyM2XqR X-Google-Smtp-Source: AKy350Zg+YrQiQT+uJFg4usYd26OF8CxKjRFlEMz9JDYvawneoUItFGiF8WCvlwdnXd9Zb6jty9VWoaJZreV X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a25:d9c2:0:b0:b69:f11b:690f with SMTP id q185-20020a25d9c2000000b00b69f11b690fmr2282543ybg.6.1680642092594; Tue, 04 Apr 2023 14:01:32 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:51 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-10-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 09/12] perf cpumap: Add reference count checking From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Enabled when REFCNT_CHECKING is defined. The change adds a memory allocated pointer that is interposed between the reference counted cpu map at a get and freed by a put. The pointer replaces the original perf_cpu_map struct, so use of the perf_cpu_map via APIs remains unchanged. Any use of the cpu map without the API requires two versions, handled via the RC_CHK_ACCESS macro. This change is intended to catch: - use after put: using a cpumap after you have put it will cause a segv. - unbalanced puts: two puts for a get will result in a double free that can be captured and reported by tools like address sanitizer, including with the associated stack traces of allocation and frees. - missing puts: if a put is missing then the get turns into a memory leak that can be reported by leak sanitizer, including the stack trace at the point the get occurs. Signed-off-by: Ian Rogers --- tools/lib/perf/Makefile | 2 +- tools/lib/perf/cpumap.c | 94 +++++++++++++----------- tools/lib/perf/include/internal/cpumap.h | 4 +- tools/perf/tests/cpumap.c | 4 +- tools/perf/util/cpumap.c | 40 +++++----- tools/perf/util/pmu.c | 8 +- 6 files changed, 81 insertions(+), 71 deletions(-) diff --git a/tools/lib/perf/Makefile b/tools/lib/perf/Makefile index d8cad124e4c5..3a9b2140aa04 100644 --- a/tools/lib/perf/Makefile +++ b/tools/lib/perf/Makefile @@ -188,7 +188,7 @@ install_lib: libs cp -fpR $(LIBPERF_ALL) $(DESTDIR)$(libdir_SQ) =20 HDRS :=3D bpf_perf.h core.h cpumap.h threadmap.h evlist.h evsel.h event.h = mmap.h -INTERNAL_HDRS :=3D cpumap.h evlist.h evsel.h lib.h mmap.h threadmap.h xyar= ray.h +INTERNAL_HDRS :=3D cpumap.h evlist.h evsel.h lib.h mmap.h rc_check.h threa= dmap.h xyarray.h =20 INSTALL_HDRS_PFX :=3D $(DESTDIR)$(prefix)/include/perf INSTALL_HDRS :=3D $(addprefix $(INSTALL_HDRS_PFX)/, $(HDRS)) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index 6cd0be7c1bb4..56eed1ac80d9 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -10,16 +10,16 @@ #include #include =20 -static struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus) +struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus) { - struct perf_cpu_map *cpus =3D malloc(sizeof(*cpus) + sizeof(struct perf_c= pu) * nr_cpus); - - if (cpus !=3D NULL) { + struct perf_cpu_map *result; + RC_STRUCT(perf_cpu_map) *cpus =3D + malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus); + if (ADD_RC_CHK(result, cpus)) { cpus->nr =3D nr_cpus; refcount_set(&cpus->refcnt, 1); - } - return cpus; + return result; } =20 struct perf_cpu_map *perf_cpu_map__dummy_new(void) @@ -27,7 +27,7 @@ struct perf_cpu_map *perf_cpu_map__dummy_new(void) struct perf_cpu_map *cpus =3D perf_cpu_map__alloc(1); =20 if (cpus) - cpus->map[0].cpu =3D -1; + RC_CHK_ACCESS(cpus)->map[0].cpu =3D -1; =20 return cpus; } @@ -35,23 +35,30 @@ struct perf_cpu_map *perf_cpu_map__dummy_new(void) static void cpu_map__delete(struct perf_cpu_map *map) { if (map) { - WARN_ONCE(refcount_read(&map->refcnt) !=3D 0, + WARN_ONCE(refcount_read(&RC_CHK_ACCESS(map)->refcnt) !=3D 0, "cpu_map refcnt unbalanced\n"); - free(map); + RC_CHK_FREE(map); } } =20 struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map) { - if (map) - refcount_inc(&map->refcnt); - return map; + struct perf_cpu_map *result; + + if (RC_CHK_GET(result, map)) + refcount_inc(&RC_CHK_ACCESS(map)->refcnt); + + return result; } =20 void perf_cpu_map__put(struct perf_cpu_map *map) { - if (map && refcount_dec_and_test(&map->refcnt)) - cpu_map__delete(map); + if (map) { + if (refcount_dec_and_test(&RC_CHK_ACCESS(map)->refcnt)) + cpu_map__delete(map); + else + RC_CHK_PUT(map); + } } =20 static struct perf_cpu_map *cpu_map__default_new(void) @@ -68,7 +75,7 @@ static struct perf_cpu_map *cpu_map__default_new(void) int i; =20 for (i =3D 0; i < nr_cpus; ++i) - cpus->map[i].cpu =3D i; + RC_CHK_ACCESS(cpus)->map[i].cpu =3D i; } =20 return cpus; @@ -94,15 +101,16 @@ static struct perf_cpu_map *cpu_map__trim_new(int nr_c= pus, const struct perf_cpu int i, j; =20 if (cpus !=3D NULL) { - memcpy(cpus->map, tmp_cpus, payload_size); - qsort(cpus->map, nr_cpus, sizeof(struct perf_cpu), cmp_cpu); + memcpy(RC_CHK_ACCESS(cpus)->map, tmp_cpus, payload_size); + qsort(RC_CHK_ACCESS(cpus)->map, nr_cpus, sizeof(struct perf_cpu), cmp_cp= u); /* Remove dups */ j =3D 0; for (i =3D 0; i < nr_cpus; i++) { - if (i =3D=3D 0 || cpus->map[i].cpu !=3D cpus->map[i - 1].cpu) - cpus->map[j++].cpu =3D cpus->map[i].cpu; + if (i =3D=3D 0 || + RC_CHK_ACCESS(cpus)->map[i].cpu !=3D RC_CHK_ACCESS(cpus)->map[i - 1= ].cpu) + RC_CHK_ACCESS(cpus)->map[j++].cpu =3D RC_CHK_ACCESS(cpus)->map[i].cpu; } - cpus->nr =3D j; + RC_CHK_ACCESS(cpus)->nr =3D j; assert(j <=3D nr_cpus); } return cpus; @@ -263,20 +271,20 @@ struct perf_cpu perf_cpu_map__cpu(const struct perf_c= pu_map *cpus, int idx) .cpu =3D -1 }; =20 - if (cpus && idx < cpus->nr) - return cpus->map[idx]; + if (cpus && idx < RC_CHK_ACCESS(cpus)->nr) + return RC_CHK_ACCESS(cpus)->map[idx]; =20 return result; } =20 int perf_cpu_map__nr(const struct perf_cpu_map *cpus) { - return cpus ? cpus->nr : 1; + return cpus ? RC_CHK_ACCESS(cpus)->nr : 1; } =20 bool perf_cpu_map__empty(const struct perf_cpu_map *map) { - return map ? map->map[0].cpu =3D=3D -1 : true; + return map ? RC_CHK_ACCESS(map)->map[0].cpu =3D=3D -1 : true; } =20 int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu) @@ -287,10 +295,10 @@ int perf_cpu_map__idx(const struct perf_cpu_map *cpus= , struct perf_cpu cpu) return -1; =20 low =3D 0; - high =3D cpus->nr; + high =3D RC_CHK_ACCESS(cpus)->nr; while (low < high) { int idx =3D (low + high) / 2; - struct perf_cpu cpu_at_idx =3D cpus->map[idx]; + struct perf_cpu cpu_at_idx =3D RC_CHK_ACCESS(cpus)->map[idx]; =20 if (cpu_at_idx.cpu =3D=3D cpu.cpu) return idx; @@ -316,7 +324,9 @@ struct perf_cpu perf_cpu_map__max(const struct perf_cpu= _map *map) }; =20 // cpu_map__trim_new() qsort()s it, cpu_map__default_new() sorts it as we= ll. - return map->nr > 0 ? map->map[map->nr - 1] : result; + return RC_CHK_ACCESS(map)->nr > 0 + ? RC_CHK_ACCESS(map)->map[RC_CHK_ACCESS(map)->nr - 1] + : result; } =20 /** Is 'b' a subset of 'a'. */ @@ -324,15 +334,15 @@ bool perf_cpu_map__is_subset(const struct perf_cpu_ma= p *a, const struct perf_cpu { if (a =3D=3D b || !b) return true; - if (!a || b->nr > a->nr) + if (!a || RC_CHK_ACCESS(b)->nr > RC_CHK_ACCESS(a)->nr) return false; =20 - for (int i =3D 0, j =3D 0; i < a->nr; i++) { - if (a->map[i].cpu > b->map[j].cpu) + for (int i =3D 0, j =3D 0; i < RC_CHK_ACCESS(a)->nr; i++) { + if (RC_CHK_ACCESS(a)->map[i].cpu > RC_CHK_ACCESS(b)->map[j].cpu) return false; - if (a->map[i].cpu =3D=3D b->map[j].cpu) { + if (RC_CHK_ACCESS(a)->map[i].cpu =3D=3D RC_CHK_ACCESS(b)->map[j].cpu) { j++; - if (j =3D=3D b->nr) + if (j =3D=3D RC_CHK_ACCESS(b)->nr) return true; } } @@ -362,27 +372,27 @@ struct perf_cpu_map *perf_cpu_map__merge(struct perf_= cpu_map *orig, return perf_cpu_map__get(other); } =20 - tmp_len =3D orig->nr + other->nr; + tmp_len =3D RC_CHK_ACCESS(orig)->nr + RC_CHK_ACCESS(other)->nr; tmp_cpus =3D malloc(tmp_len * sizeof(struct perf_cpu)); if (!tmp_cpus) return NULL; =20 /* Standard merge algorithm from wikipedia */ i =3D j =3D k =3D 0; - while (i < orig->nr && j < other->nr) { - if (orig->map[i].cpu <=3D other->map[j].cpu) { - if (orig->map[i].cpu =3D=3D other->map[j].cpu) + while (i < RC_CHK_ACCESS(orig)->nr && j < RC_CHK_ACCESS(other)->nr) { + if (RC_CHK_ACCESS(orig)->map[i].cpu <=3D RC_CHK_ACCESS(other)->map[j].cp= u) { + if (RC_CHK_ACCESS(orig)->map[i].cpu =3D=3D RC_CHK_ACCESS(other)->map[j]= .cpu) j++; - tmp_cpus[k++] =3D orig->map[i++]; + tmp_cpus[k++] =3D RC_CHK_ACCESS(orig)->map[i++]; } else - tmp_cpus[k++] =3D other->map[j++]; + tmp_cpus[k++] =3D RC_CHK_ACCESS(other)->map[j++]; } =20 - while (i < orig->nr) - tmp_cpus[k++] =3D orig->map[i++]; + while (i < RC_CHK_ACCESS(orig)->nr) + tmp_cpus[k++] =3D RC_CHK_ACCESS(orig)->map[i++]; =20 - while (j < other->nr) - tmp_cpus[k++] =3D other->map[j++]; + while (j < RC_CHK_ACCESS(other)->nr) + tmp_cpus[k++] =3D RC_CHK_ACCESS(other)->map[j++]; assert(k <=3D tmp_len); =20 merged =3D cpu_map__trim_new(k, tmp_cpus); diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/incl= ude/internal/cpumap.h index 35dd29642296..6c01bee4d048 100644 --- a/tools/lib/perf/include/internal/cpumap.h +++ b/tools/lib/perf/include/internal/cpumap.h @@ -4,6 +4,7 @@ =20 #include #include +#include =20 /** * A sized, reference counted, sorted array of integers representing CPU @@ -12,7 +13,7 @@ * gaps if CPU numbers were used. For events associated with a pid, rather= than * a CPU, a single dummy map with an entry of -1 is used. */ -struct perf_cpu_map { +DECLARE_RC_STRUCT(perf_cpu_map) { refcount_t refcnt; /** Length of the map array. */ int nr; @@ -24,6 +25,7 @@ struct perf_cpu_map { #define MAX_NR_CPUS 2048 #endif =20 +struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus); int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu= ); bool perf_cpu_map__is_subset(const struct perf_cpu_map *a, const struct pe= rf_cpu_map *b); =20 diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 3150fc1fed6f..d6f77b676d11 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -68,7 +68,7 @@ static int process_event_cpus(struct perf_tool *tool __ma= ybe_unused, TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map) =3D=3D 2); TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 0).cpu =3D=3D 1); TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 1).cpu =3D=3D 256); - TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) =3D=3D 1); + TEST_ASSERT_VAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(map)->refcnt= ) =3D=3D 1); perf_cpu_map__put(map); return 0; } @@ -94,7 +94,7 @@ static int process_event_range_cpus(struct perf_tool *too= l __maybe_unused, TEST_ASSERT_VAL("wrong nr", perf_cpu_map__nr(map) =3D=3D 256); TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 0).cpu =3D=3D 1); TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__max(map).cpu =3D=3D 256); - TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) =3D=3D 1); + TEST_ASSERT_VAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(map)->refcnt= ) =3D=3D 1); perf_cpu_map__put(map); return 0; } diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 5e564974fba4..22453893105f 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -77,9 +77,9 @@ static struct perf_cpu_map *cpu_map__from_entries(const s= truct perf_record_cpu_m * otherwise it would become 65535. */ if (data->cpus_data.cpu[i] =3D=3D (u16) -1) - map->map[i].cpu =3D -1; + RC_CHK_ACCESS(map)->map[i].cpu =3D -1; else - map->map[i].cpu =3D (int) data->cpus_data.cpu[i]; + RC_CHK_ACCESS(map)->map[i].cpu =3D (int) data->cpus_data.cpu[i]; } } =20 @@ -107,7 +107,7 @@ static struct perf_cpu_map *cpu_map__from_mask(const st= ruct perf_record_cpu_map_ =20 perf_record_cpu_map_data__read_one_mask(data, i, local_copy); for_each_set_bit(cpu, local_copy, 64) - map->map[j++].cpu =3D cpu + cpus_per_i; + RC_CHK_ACCESS(map)->map[j++].cpu =3D cpu + cpus_per_i; } return map; =20 @@ -124,11 +124,11 @@ static struct perf_cpu_map *cpu_map__from_range(const= struct perf_record_cpu_map return NULL; =20 if (data->range_cpu_data.any_cpu) - map->map[i++].cpu =3D -1; + RC_CHK_ACCESS(map)->map[i++].cpu =3D -1; =20 for (int cpu =3D data->range_cpu_data.start_cpu; cpu <=3D data->range_cpu= _data.end_cpu; i++, cpu++) - map->map[i].cpu =3D cpu; + RC_CHK_ACCESS(map)->map[i].cpu =3D cpu; =20 return map; } @@ -160,16 +160,13 @@ size_t cpu_map__fprintf(struct perf_cpu_map *map, FIL= E *fp) =20 struct perf_cpu_map *perf_cpu_map__empty_new(int nr) { - struct perf_cpu_map *cpus =3D malloc(sizeof(*cpus) + sizeof(int) * nr); + struct perf_cpu_map *cpus =3D perf_cpu_map__alloc(nr); =20 if (cpus !=3D NULL) { int i; =20 - cpus->nr =3D nr; for (i =3D 0; i < nr; i++) - cpus->map[i].cpu =3D -1; - - refcount_set(&cpus->refcnt, 1); + RC_CHK_ACCESS(cpus)->map[i].cpu =3D -1; } =20 return cpus; @@ -239,7 +236,7 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct per= f_cpu_map *cpus, { int idx; struct perf_cpu cpu; - struct cpu_aggr_map *c =3D cpu_aggr_map__empty_new(cpus->nr); + struct cpu_aggr_map *c =3D cpu_aggr_map__empty_new(perf_cpu_map__nr(cpus)= ); =20 if (!c) return NULL; @@ -263,7 +260,7 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct per= f_cpu_map *cpus, } } /* Trim. */ - if (c->nr !=3D cpus->nr) { + if (c->nr !=3D perf_cpu_map__nr(cpus)) { struct cpu_aggr_map *trimmed_c =3D realloc(c, sizeof(struct cpu_aggr_map) + sizeof(struct aggr_cpu_id) * c->nr); @@ -582,31 +579,32 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, cha= r *buf, size_t size) =20 #define COMMA first ? "" : "," =20 - for (i =3D 0; i < map->nr + 1; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map) + 1; i++) { struct perf_cpu cpu =3D { .cpu =3D INT_MAX }; - bool last =3D i =3D=3D map->nr; + bool last =3D i =3D=3D perf_cpu_map__nr(map); =20 if (!last) - cpu =3D map->map[i]; + cpu =3D perf_cpu_map__cpu(map, i); =20 if (start =3D=3D -1) { start =3D i; if (last) { ret +=3D snprintf(buf + ret, size - ret, "%s%d", COMMA, - map->map[i].cpu); + perf_cpu_map__cpu(map, i).cpu); } - } else if (((i - start) !=3D (cpu.cpu - map->map[start].cpu)) || last) { + } else if (((i - start) !=3D (cpu.cpu - perf_cpu_map__cpu(map, start).cp= u)) || last) { int end =3D i - 1; =20 if (start =3D=3D end) { ret +=3D snprintf(buf + ret, size - ret, "%s%d", COMMA, - map->map[start].cpu); + perf_cpu_map__cpu(map, start).cpu); } else { ret +=3D snprintf(buf + ret, size - ret, "%s%d-%d", COMMA, - map->map[start].cpu, map->map[end].cpu); + perf_cpu_map__cpu(map, start).cpu, + perf_cpu_map__cpu(map, end).cpu); } first =3D false; start =3D i; @@ -633,7 +631,7 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, = char *buf, size_t size) int i, cpu; char *ptr =3D buf; unsigned char *bitmap; - struct perf_cpu last_cpu =3D perf_cpu_map__cpu(map, map->nr - 1); + struct perf_cpu last_cpu =3D perf_cpu_map__cpu(map, perf_cpu_map__nr(map)= - 1); =20 if (buf =3D=3D NULL) return 0; @@ -644,7 +642,7 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, = char *buf, size_t size) return 0; } =20 - for (i =3D 0; i < map->nr; i++) { + for (i =3D 0; i < perf_cpu_map__nr(map); i++) { cpu =3D perf_cpu_map__cpu(map, i).cpu; bitmap[cpu / 8] |=3D 1 << (cpu % 8); } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 78a407b42ad1..c08d42f5e2b4 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1966,13 +1966,13 @@ int perf_pmu__cpus_match(struct perf_pmu *pmu, stru= ct perf_cpu_map *cpus, =20 perf_cpu_map__for_each_cpu(cpu, i, cpus) { if (!perf_cpu_map__has(pmu_cpus, cpu)) - unmatched_cpus->map[unmatched_nr++] =3D cpu; + RC_CHK_ACCESS(unmatched_cpus)->map[unmatched_nr++] =3D cpu; else - matched_cpus->map[matched_nr++] =3D cpu; + RC_CHK_ACCESS(matched_cpus)->map[matched_nr++] =3D cpu; } =20 - unmatched_cpus->nr =3D unmatched_nr; - matched_cpus->nr =3D matched_nr; + RC_CHK_ACCESS(unmatched_cpus)->nr =3D unmatched_nr; + RC_CHK_ACCESS(matched_cpus)->nr =3D matched_nr; *mcpus_ptr =3D matched_cpus; *ucpus_ptr =3D unmatched_cpus; return 0; --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4474C77B60 for ; Tue, 4 Apr 2023 21:02:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236457AbjDDVCs (ORCPT ); Tue, 4 Apr 2023 17:02:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39756 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235705AbjDDVCQ (ORCPT ); Tue, 4 Apr 2023 17:02:16 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5ECEB4C16 for ; Tue, 4 Apr 2023 14:01:44 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-5458201ab8cso341085847b3.23 for ; Tue, 04 Apr 2023 14:01:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642101; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Cq9VBodb3R/VbWR5N61AWlG965y4/Gy2LIMdNOlxP0o=; b=h0+HrOpjRcMfrcPfVJFBpzgeo8cyBDXrklf8YV5yqJTUXqBG/mXMBPd79PqJWG18ob t7n23vp3uTlMIik+sssIKL5RPdQXzW+HE3qFHZdhauV1CMGyv/3UMbWM/vLSF7P47zrW NBfwI/zYCVJkHzXkl4lafQl+1c81/ISKavutFG/I9ptWY51SXAMjTtm5TS2HpXVGyz3X Blk6f9i5W5ViATr6XW4nwTYP7TsocHAN8og3nmfxspbdAWUk/JRJFVtFJ0oeeA400I6g vyXAjkTtbJSvwkLAfDJ+9kmK0dJEHprQkB6q1Kp82wawwnGYPlL+jfVGKmWNuTxKk960 bCHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642101; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Cq9VBodb3R/VbWR5N61AWlG965y4/Gy2LIMdNOlxP0o=; b=34VwIYMiqzryyFb8VOOT5qYWj2tlkRHkd4llrccONHLi1urcIuFtR3DAWxR2L1dqAb O5wnOJ5fwOBr5L1bd51uRcTY6pApKbv0r/aCgyyzj0ds/XM/ruNsYhMiHo3kAhmHooB1 ylkHBqMuk5Y+Lx33K0uYoOxtURVuuY6GPWwZEdrTOV8j1/7qru8dw5j5ncWomGMmmyy3 //PPjoO3dbUG5UkIF7g8/NqPFjMBSJ4NvUQ9ebgPGGabsyz5KvSRMnwPfcIp19KsMmJS +UgYzE4/LI2Nl7LechwBrLMKT0IqC42MfPMIk3xVIl4ZFsO5DpEFO5JYBAqLpEUfEelc e8Jw== X-Gm-Message-State: AAQBX9fT1eX7T8FNdLSh0Bzjq4ayP0wFC7X5KHaZtNsMNPFihitw502p y4CnyApkqhJRedoM87RALNlyImYRwfMz X-Google-Smtp-Source: AKy350bUDGYi5tSNLZ31D/5ZlgJFy2+gNgBQvdU2Hfbc0NERBsZlHTeznXxK2SRMylPfN+KXBfCi0/enyeis X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a25:6e88:0:b0:b4c:9333:2a2 with SMTP id j130-20020a256e88000000b00b4c933302a2mr2320470ybc.9.1680642101460; Tue, 04 Apr 2023 14:01:41 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:52 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-11-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 10/12] perf namespaces: Add reference count checking From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add reference count checking controlled by REFCNT_CHECKING ifdef. The reference count checking interposes an allocated pointer between the reference counted struct on a get and frees the pointer on a put. Accesses after a put cause faults and use after free, missed puts are caughts as leaks and double puts are double frees. This checking helped resolve a memory leak and use after free: https://lore.kernel.org/linux-perf-users/CAP-5=3DfWZH20L4kv-BwVtGLwR=3DEm3A= OOT+Q4QGivvQuYn5AsPRg@mail.gmail.com/ Signed-off-by: Ian Rogers --- tools/perf/builtin-inject.c | 2 +- tools/perf/util/annotate.c | 2 +- tools/perf/util/dso.c | 2 +- tools/perf/util/dsos.c | 2 +- tools/perf/util/namespaces.c | 132 ++++++++++++++++++++--------------- tools/perf/util/namespaces.h | 3 +- tools/perf/util/symbol.c | 2 +- 7 files changed, 83 insertions(+), 62 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index fd2b38458a5d..fe6ddcf7fb1e 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -632,7 +632,7 @@ static int dso__read_build_id(struct dso *dso) else if (dso->nsinfo) { char *new_name; =20 - new_name =3D filename_with_chroot(dso->nsinfo->pid, + new_name =3D filename_with_chroot(RC_CHK_ACCESS(dso->nsinfo)->pid, dso->long_name); if (new_name && filename__read_build_id(new_name, &dso->bid) > 0) dso->has_build_id =3D true; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 36acdd1bd379..733051122959 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1693,7 +1693,7 @@ static int dso__disassemble_filename(struct dso *dso,= char *filename, size_t fil =20 mutex_lock(&dso->lock); if (access(filename, R_OK) && errno =3D=3D ENOENT && dso->nsinfo) { - char *new_name =3D filename_with_chroot(dso->nsinfo->pid, + char *new_name =3D filename_with_chroot(RC_CHK_ACCESS(dso->nsinfo)->pid, filename); if (new_name) { strlcpy(filename, new_name, filename_size); diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e36b418df2c6..6c4129598f5d 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -515,7 +515,7 @@ static int __open_dso(struct dso *dso, struct machine *= machine) if (errno !=3D ENOENT || dso->nsinfo =3D=3D NULL) goto out; =20 - new_name =3D filename_with_chroot(dso->nsinfo->pid, name); + new_name =3D filename_with_chroot(RC_CHK_ACCESS(dso->nsinfo)->pid, name); if (!new_name) goto out; =20 diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index 2bd23e4cf19e..53b989072ec5 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -91,7 +91,7 @@ bool __dsos__read_build_ids(struct list_head *head, bool = with_hits) have_build_id =3D true; pos->has_build_id =3D true; } else if (errno =3D=3D ENOENT && pos->nsinfo) { - char *new_name =3D filename_with_chroot(pos->nsinfo->pid, + char *new_name =3D filename_with_chroot(RC_CHK_ACCESS(pos->nsinfo)->pid, pos->long_name); =20 if (new_name && filename__read_build_id(new_name, diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index dd536220cdb9..8a3b7bd27b19 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -60,7 +60,7 @@ void namespaces__free(struct namespaces *namespaces) free(namespaces); } =20 -static int nsinfo__get_nspid(struct nsinfo *nsi, const char *path) +static int nsinfo__get_nspid(pid_t *tgid, pid_t *nstgid, bool *in_pidns, c= onst char *path) { FILE *f =3D NULL; char *statln =3D NULL; @@ -74,19 +74,18 @@ static int nsinfo__get_nspid(struct nsinfo *nsi, const = char *path) while (getline(&statln, &linesz, f) !=3D -1) { /* Use tgid if CONFIG_PID_NS is not defined. */ if (strstr(statln, "Tgid:") !=3D NULL) { - nsi->tgid =3D (pid_t)strtol(strrchr(statln, '\t'), - NULL, 10); - nsi->nstgid =3D nsinfo__tgid(nsi); + *tgid =3D (pid_t)strtol(strrchr(statln, '\t'), NULL, 10); + *nstgid =3D *tgid; } =20 if (strstr(statln, "NStgid:") !=3D NULL) { nspid =3D strrchr(statln, '\t'); - nsi->nstgid =3D (pid_t)strtol(nspid, NULL, 10); + *nstgid =3D (pid_t)strtol(nspid, NULL, 10); /* * If innermost tgid is not the first, process is in a different * PID namespace. */ - nsi->in_pidns =3D (statln + sizeof("NStgid:") - 1) !=3D nspid; + *in_pidns =3D (statln + sizeof("NStgid:") - 1) !=3D nspid; break; } } @@ -121,8 +120,8 @@ int nsinfo__init(struct nsinfo *nsi) * want to switch as part of looking up dso/map data. */ if (old_stat.st_ino !=3D new_stat.st_ino) { - nsi->need_setns =3D true; - nsi->mntns_path =3D newns; + RC_CHK_ACCESS(nsi)->need_setns =3D true; + RC_CHK_ACCESS(nsi)->mntns_path =3D newns; newns =3D NULL; } =20 @@ -132,13 +131,26 @@ int nsinfo__init(struct nsinfo *nsi) if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsinfo__pid(nsi)) >=3D P= ATH_MAX) goto out; =20 - rv =3D nsinfo__get_nspid(nsi, spath); + rv =3D nsinfo__get_nspid(&RC_CHK_ACCESS(nsi)->tgid, &RC_CHK_ACCESS(nsi)->= nstgid, + &RC_CHK_ACCESS(nsi)->in_pidns, spath); =20 out: free(newns); return rv; } =20 +static struct nsinfo *nsinfo__alloc(void) +{ + struct nsinfo *res; + RC_STRUCT(nsinfo) *nsi; + + nsi =3D calloc(1, sizeof(*nsi)); + if (ADD_RC_CHK(res, nsi)) + refcount_set(&nsi->refcnt, 1); + + return res; +} + struct nsinfo *nsinfo__new(pid_t pid) { struct nsinfo *nsi; @@ -146,22 +158,21 @@ struct nsinfo *nsinfo__new(pid_t pid) if (pid =3D=3D 0) return NULL; =20 - nsi =3D calloc(1, sizeof(*nsi)); - if (nsi !=3D NULL) { - nsi->pid =3D pid; - nsi->tgid =3D pid; - nsi->nstgid =3D pid; - nsi->need_setns =3D false; - nsi->in_pidns =3D false; - /* Init may fail if the process exits while we're trying to look - * at its proc information. In that case, save the pid but - * don't try to enter the namespace. - */ - if (nsinfo__init(nsi) =3D=3D -1) - nsi->need_setns =3D false; + nsi =3D nsinfo__alloc(); + if (!nsi) + return NULL; =20 - refcount_set(&nsi->refcnt, 1); - } + RC_CHK_ACCESS(nsi)->pid =3D pid; + RC_CHK_ACCESS(nsi)->tgid =3D pid; + RC_CHK_ACCESS(nsi)->nstgid =3D pid; + RC_CHK_ACCESS(nsi)->need_setns =3D false; + RC_CHK_ACCESS(nsi)->in_pidns =3D false; + /* Init may fail if the process exits while we're trying to look at its + * proc information. In that case, save the pid but don't try to enter + * the namespace. + */ + if (nsinfo__init(nsi) =3D=3D -1) + RC_CHK_ACCESS(nsi)->need_setns =3D false; =20 return nsi; } @@ -173,21 +184,21 @@ struct nsinfo *nsinfo__copy(const struct nsinfo *nsi) if (nsi =3D=3D NULL) return NULL; =20 - nnsi =3D calloc(1, sizeof(*nnsi)); - if (nnsi !=3D NULL) { - nnsi->pid =3D nsinfo__pid(nsi); - nnsi->tgid =3D nsinfo__tgid(nsi); - nnsi->nstgid =3D nsinfo__nstgid(nsi); - nnsi->need_setns =3D nsinfo__need_setns(nsi); - nnsi->in_pidns =3D nsinfo__in_pidns(nsi); - if (nsi->mntns_path) { - nnsi->mntns_path =3D strdup(nsi->mntns_path); - if (!nnsi->mntns_path) { - free(nnsi); - return NULL; - } + nnsi =3D nsinfo__alloc(); + if (!nnsi) + return NULL; + + RC_CHK_ACCESS(nnsi)->pid =3D nsinfo__pid(nsi); + RC_CHK_ACCESS(nnsi)->tgid =3D nsinfo__tgid(nsi); + RC_CHK_ACCESS(nnsi)->nstgid =3D nsinfo__nstgid(nsi); + RC_CHK_ACCESS(nnsi)->need_setns =3D nsinfo__need_setns(nsi); + RC_CHK_ACCESS(nnsi)->in_pidns =3D nsinfo__in_pidns(nsi); + if (RC_CHK_ACCESS(nsi)->mntns_path) { + RC_CHK_ACCESS(nnsi)->mntns_path =3D strdup(RC_CHK_ACCESS(nsi)->mntns_pat= h); + if (!RC_CHK_ACCESS(nnsi)->mntns_path) { + nsinfo__put(nnsi); + return NULL; } - refcount_set(&nnsi->refcnt, 1); } =20 return nnsi; @@ -195,51 +206,60 @@ struct nsinfo *nsinfo__copy(const struct nsinfo *nsi) =20 static void nsinfo__delete(struct nsinfo *nsi) { - zfree(&nsi->mntns_path); - free(nsi); + if (nsi) { + WARN_ONCE(refcount_read(&RC_CHK_ACCESS(nsi)->refcnt) !=3D 0, + "nsinfo refcnt unbalanced\n"); + zfree(&RC_CHK_ACCESS(nsi)->mntns_path); + RC_CHK_FREE(nsi); + } } =20 struct nsinfo *nsinfo__get(struct nsinfo *nsi) { - if (nsi) - refcount_inc(&nsi->refcnt); - return nsi; + struct nsinfo *result; + + if (RC_CHK_GET(result, nsi)) + refcount_inc(&RC_CHK_ACCESS(nsi)->refcnt); + + return result; } =20 void nsinfo__put(struct nsinfo *nsi) { - if (nsi && refcount_dec_and_test(&nsi->refcnt)) + if (nsi && refcount_dec_and_test(&RC_CHK_ACCESS(nsi)->refcnt)) nsinfo__delete(nsi); + else + RC_CHK_PUT(nsi); } =20 bool nsinfo__need_setns(const struct nsinfo *nsi) { - return nsi->need_setns; + return RC_CHK_ACCESS(nsi)->need_setns; } =20 void nsinfo__clear_need_setns(struct nsinfo *nsi) { - nsi->need_setns =3D false; + RC_CHK_ACCESS(nsi)->need_setns =3D false; } =20 pid_t nsinfo__tgid(const struct nsinfo *nsi) { - return nsi->tgid; + return RC_CHK_ACCESS(nsi)->tgid; } =20 pid_t nsinfo__nstgid(const struct nsinfo *nsi) { - return nsi->nstgid; + return RC_CHK_ACCESS(nsi)->nstgid; } =20 pid_t nsinfo__pid(const struct nsinfo *nsi) { - return nsi->pid; + return RC_CHK_ACCESS(nsi)->pid; } =20 pid_t nsinfo__in_pidns(const struct nsinfo *nsi) { - return nsi->in_pidns; + return RC_CHK_ACCESS(nsi)->in_pidns; } =20 void nsinfo__mountns_enter(struct nsinfo *nsi, @@ -256,7 +276,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi, nc->oldns =3D -1; nc->newns =3D -1; =20 - if (!nsi || !nsi->need_setns) + if (!nsi || !RC_CHK_ACCESS(nsi)->need_setns) return; =20 if (snprintf(curpath, PATH_MAX, "/proc/self/ns/mnt") >=3D PATH_MAX) @@ -270,7 +290,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi, if (oldns < 0) goto errout; =20 - newns =3D open(nsi->mntns_path, O_RDONLY); + newns =3D open(RC_CHK_ACCESS(nsi)->mntns_path, O_RDONLY); if (newns < 0) goto errout; =20 @@ -339,9 +359,9 @@ int nsinfo__stat(const char *filename, struct stat *st,= struct nsinfo *nsi) =20 bool nsinfo__is_in_root_namespace(void) { - struct nsinfo nsi; + pid_t tgid =3D 0, nstgid =3D 0; + bool in_pidns =3D false; =20 - memset(&nsi, 0x0, sizeof(nsi)); - nsinfo__get_nspid(&nsi, "/proc/self/status"); - return !nsi.in_pidns; + nsinfo__get_nspid(&tgid, &nstgid, &in_pidns, "/proc/self/status"); + return !in_pidns; } diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 567829262c42..8c0731c6cbb7 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -13,6 +13,7 @@ #include #include #include +#include =20 #ifndef HAVE_SETNS_SUPPORT int setns(int fd, int nstype); @@ -29,7 +30,7 @@ struct namespaces { struct namespaces *namespaces__new(struct perf_record_namespaces *event); void namespaces__free(struct namespaces *namespaces); =20 -struct nsinfo { +DECLARE_RC_STRUCT(nsinfo) { pid_t pid; pid_t tgid; pid_t nstgid; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 91ebf93e0c20..639343d5577c 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1963,7 +1963,7 @@ int dso__load(struct dso *dso, struct map *map) =20 is_reg =3D is_regular_file(name); if (!is_reg && errno =3D=3D ENOENT && dso->nsinfo) { - char *new_name =3D filename_with_chroot(dso->nsinfo->pid, + char *new_name =3D filename_with_chroot(RC_CHK_ACCESS(dso->nsinfo)->pid, name); if (new_name) { is_reg =3D is_regular_file(new_name); --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05431C6FD1D for ; Tue, 4 Apr 2023 21:03:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236553AbjDDVDA (ORCPT ); Tue, 4 Apr 2023 17:03:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236464AbjDDVC2 (ORCPT ); Tue, 4 Apr 2023 17:02:28 -0400 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 02B0559C3 for ; Tue, 4 Apr 2023 14:01:55 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id e186-20020a2537c3000000b00b72501acf50so33604213yba.20 for ; Tue, 04 Apr 2023 14:01:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642110; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=kuBA4IMvvWXK1xrWf2LCs/CHHemYtB8NYT+JO5jzro0=; b=YfOzmTd6QGWeWXnUNlKSVu6aMGUewsBhjxqey8BvcgMDjwqKxfL2yT2ya/Pc+46zSN zW1cHm827rw+PhSS6CGWu4Cswm+eLmyoOyVTOtWcf2GN+NDKKTdQqA3h9x+hp13wfXIH dwO+6FyXcBiGSKqE46c+I5TbY9zimDGjeNVRzElkBZsUlsvdwaTjUxBZgeirNz+cmz0e e628zBKZOlg75RDQrc9fOlD/jgsaq4gS7lNFObxltoYiuiSRIhAdzsYYzS/CDzlN1YW6 ukjG5xEExET3TIIWAEfFWrZNjIbzBwZhcHc656/qCKQ3XgBkUtuxRUnLwoE+gRUwpTXF PVRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642110; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kuBA4IMvvWXK1xrWf2LCs/CHHemYtB8NYT+JO5jzro0=; b=4LZky/4QE0LegS142wmwtdrrhaafJu4uNK7URkG75WfQySOayXzoVMvASef6zPz0Ij n4GKg86ba9L2vPbTys1EinAyQsYA5v0CPGlTrIf4+o1MnF1IzarZju/oX+Zm12Qj3suw w0aMehIZd3L4TdBe2RGWsA+nu6HfYlpx6F5psy9mfPJYRrzNwND7A+oozFyfKGe0DaHZ Kie+JYa0BB1VqPnzohLOdrNfweRxL8WkoU0PxII8WMUQtNFbyS0hfm0Moc9ljaffk86Y A7xkiF7ok4wST5M4sPpmfQ+lhdlYQJEyQkaRDfzC8XqYSUsSKrY/LEJBkKbQttVqBBZN STAQ== X-Gm-Message-State: AAQBX9eMi6xj47s9gSYCU7/Kt5eg2GBWR3KFoKQ57DrnvLJ6rqrIts+f FDTjYszHXAaYgmOryIqNW+UEBmEAFLR+ X-Google-Smtp-Source: AKy350Yw2BHjiyJKozmoWnZMmM/AsD/8F+ieed0SA8IdDXeAOrdbI3HUOkPB/t5HxId3OXX0WWbxrUmtrxyB X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a25:da02:0:b0:b75:968e:f282 with SMTP id n2-20020a25da02000000b00b75968ef282mr2664463ybf.11.1680642110279; Tue, 04 Apr 2023 14:01:50 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:53 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-12-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 11/12] perf maps: Add reference count checking. From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add reference count checking to make sure of good use of get and put. Add and use accessors to reduce RC_CHK clutter. The only significant issue was in tests/thread-maps-share.c where reference counts were released in the reverse order to acquisition, leading to a use after put. This was fixed by reversing the put order. Signed-off-by: Ian Rogers --- tools/perf/tests/thread-maps-share.c | 29 ++++++------- tools/perf/util/machine.c | 2 +- tools/perf/util/maps.c | 53 +++++++++++++----------- tools/perf/util/maps.h | 17 ++++---- tools/perf/util/symbol.c | 13 +++--- tools/perf/util/unwind-libdw.c | 2 +- tools/perf/util/unwind-libunwind-local.c | 2 +- tools/perf/util/unwind-libunwind.c | 2 +- 8 files changed, 64 insertions(+), 56 deletions(-) diff --git a/tools/perf/tests/thread-maps-share.c b/tools/perf/tests/thread= -maps-share.c index 84edd82c519e..dfe51b21bd7d 100644 --- a/tools/perf/tests/thread-maps-share.c +++ b/tools/perf/tests/thread-maps-share.c @@ -43,12 +43,12 @@ static int test__thread_maps_share(struct test_suite *t= est __maybe_unused, int s leader && t1 && t2 && t3 && other); =20 maps =3D leader->maps; - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->ref= cnt), 4); =20 /* test the maps pointer is shared */ - TEST_ASSERT_VAL("maps don't match", maps =3D=3D t1->maps); - TEST_ASSERT_VAL("maps don't match", maps =3D=3D t2->maps); - TEST_ASSERT_VAL("maps don't match", maps =3D=3D t3->maps); + TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) =3D=3D RC_CHK_ACC= ESS(t1->maps)); + TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) =3D=3D RC_CHK_ACC= ESS(t2->maps)); + TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) =3D=3D RC_CHK_ACC= ESS(t3->maps)); =20 /* * Verify the other leader was created by previous call. @@ -71,25 +71,26 @@ static int test__thread_maps_share(struct test_suite *t= est __maybe_unused, int s machine__remove_thread(machine, other_leader); =20 other_maps =3D other->maps; - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 2); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(other_maps= )->refcnt), 2); =20 - TEST_ASSERT_VAL("maps don't match", other_maps =3D=3D other_leader->maps); + TEST_ASSERT_VAL("maps don't match", + RC_CHK_ACCESS(other_maps) =3D=3D RC_CHK_ACCESS(other_leader->maps)); =20 /* release thread group */ - thread__put(leader); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 3); - - thread__put(t1); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 2); + thread__put(t3); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->ref= cnt), 3); =20 thread__put(t2); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->ref= cnt), 2); =20 - thread__put(t3); + thread__put(t1); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->ref= cnt), 1); + + thread__put(leader); =20 /* release other group */ thread__put(other_leader); - TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 1); + TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(other_maps= )->refcnt), 1); =20 thread__put(other); =20 diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 25738775834e..2d9ce6966238 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -435,7 +435,7 @@ static struct thread *findnew_guest_code(struct machine= *machine, return NULL; =20 /* Assume maps are set up if there are any */ - if (thread->maps->nr_maps) + if (RC_CHK_ACCESS(thread->maps)->nr_maps) return thread; =20 host_thread =3D machine__find_thread(host_machine, -1, pid); diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 5afed53ea0b4..567952587247 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -12,13 +12,13 @@ =20 static void maps__init(struct maps *maps, struct machine *machine) { - maps->entries =3D RB_ROOT; + RC_CHK_ACCESS(maps)->entries =3D RB_ROOT; init_rwsem(maps__lock(maps)); - maps->machine =3D machine; - maps->last_search_by_name =3D NULL; - maps->nr_maps =3D 0; - maps->maps_by_name =3D NULL; - refcount_set(&maps->refcnt, 1); + RC_CHK_ACCESS(maps)->machine =3D machine; + RC_CHK_ACCESS(maps)->last_search_by_name =3D NULL; + RC_CHK_ACCESS(maps)->nr_maps =3D 0; + RC_CHK_ACCESS(maps)->maps_by_name =3D NULL; + refcount_set(&RC_CHK_ACCESS(maps)->refcnt, 1); } =20 static void __maps__free_maps_by_name(struct maps *maps) @@ -29,8 +29,8 @@ static void __maps__free_maps_by_name(struct maps *maps) for (unsigned int i =3D 0; i < maps__nr_maps(maps); i++) map__put(maps__maps_by_name(maps)[i]); =20 - zfree(&maps->maps_by_name); - maps->nr_maps_allocated =3D 0; + zfree(&RC_CHK_ACCESS(maps)->maps_by_name); + RC_CHK_ACCESS(maps)->nr_maps_allocated =3D 0; } =20 static int __maps__insert(struct maps *maps, struct map *map) @@ -71,7 +71,7 @@ int maps__insert(struct maps *maps, struct map *map) if (err) goto out; =20 - ++maps->nr_maps; + ++RC_CHK_ACCESS(maps)->nr_maps; =20 if (dso && dso->kernel) { struct kmap *kmap =3D map__kmap(map); @@ -88,7 +88,7 @@ int maps__insert(struct maps *maps, struct map *map) * inserted map and resort. */ if (maps__maps_by_name(maps)) { - if (maps__nr_maps(maps) > maps->nr_maps_allocated) { + if (maps__nr_maps(maps) > RC_CHK_ACCESS(maps)->nr_maps_allocated) { int nr_allocate =3D maps__nr_maps(maps) * 2; struct map **maps_by_name =3D realloc(maps__maps_by_name(maps), nr_allocate * sizeof(map)); @@ -99,8 +99,8 @@ int maps__insert(struct maps *maps, struct map *map) goto out; } =20 - maps->maps_by_name =3D maps_by_name; - maps->nr_maps_allocated =3D nr_allocate; + RC_CHK_ACCESS(maps)->maps_by_name =3D maps_by_name; + RC_CHK_ACCESS(maps)->nr_maps_allocated =3D nr_allocate; } maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] =3D map__get(map); __maps__sort_by_name(maps); @@ -122,15 +122,15 @@ void maps__remove(struct maps *maps, struct map *map) struct map_rb_node *rb_node; =20 down_write(maps__lock(maps)); - if (maps->last_search_by_name =3D=3D map) - maps->last_search_by_name =3D NULL; + if (RC_CHK_ACCESS(maps)->last_search_by_name =3D=3D map) + RC_CHK_ACCESS(maps)->last_search_by_name =3D NULL; =20 rb_node =3D maps__find_node(maps, map); assert(rb_node->map =3D=3D map); __maps__remove(maps, rb_node); if (maps__maps_by_name(maps)) __maps__free_maps_by_name(maps); - --maps->nr_maps; + --RC_CHK_ACCESS(maps)->nr_maps; up_write(maps__lock(maps)); } =20 @@ -162,33 +162,38 @@ bool maps__empty(struct maps *maps) =20 struct maps *maps__new(struct machine *machine) { - struct maps *maps =3D zalloc(sizeof(*maps)); + struct maps *res; + RC_STRUCT(maps) *maps =3D zalloc(sizeof(*maps)); =20 - if (maps !=3D NULL) - maps__init(maps, machine); + if (ADD_RC_CHK(res, maps)) + maps__init(res, machine); =20 - return maps; + return res; } =20 void maps__delete(struct maps *maps) { maps__exit(maps); unwind__finish_access(maps); - free(maps); + RC_CHK_FREE(maps); } =20 struct maps *maps__get(struct maps *maps) { - if (maps) - refcount_inc(&maps->refcnt); + struct maps *result; =20 - return maps; + if (RC_CHK_GET(result, maps)) + refcount_inc(&RC_CHK_ACCESS(maps)->refcnt); + + return result; } =20 void maps__put(struct maps *maps) { - if (maps && refcount_dec_and_test(&maps->refcnt)) + if (maps && refcount_dec_and_test(&RC_CHK_ACCESS(maps)->refcnt)) maps__delete(maps); + else + RC_CHK_PUT(maps); } =20 struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map *= *mapp) diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index bde3390c7096..0af4b7e42fca 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -8,6 +8,7 @@ #include #include #include "rwsem.h" +#include =20 struct ref_reloc_sym; struct machine; @@ -32,7 +33,7 @@ struct map *maps__find(struct maps *maps, u64 addr); for (map =3D maps__first(maps), next =3D map_rb_node__next(map); map; \ map =3D next, next =3D map_rb_node__next(map)) =20 -struct maps { +DECLARE_RC_STRUCT(maps) { struct rb_root entries; struct rw_semaphore lock; struct machine *machine; @@ -65,38 +66,38 @@ void maps__put(struct maps *maps); =20 static inline struct rb_root *maps__entries(struct maps *maps) { - return &maps->entries; + return &RC_CHK_ACCESS(maps)->entries; } =20 static inline struct machine *maps__machine(struct maps *maps) { - return maps->machine; + return RC_CHK_ACCESS(maps)->machine; } =20 static inline struct rw_semaphore *maps__lock(struct maps *maps) { - return &maps->lock; + return &RC_CHK_ACCESS(maps)->lock; } =20 static inline struct map **maps__maps_by_name(struct maps *maps) { - return maps->maps_by_name; + return RC_CHK_ACCESS(maps)->maps_by_name; } =20 static inline unsigned int maps__nr_maps(const struct maps *maps) { - return maps->nr_maps; + return RC_CHK_ACCESS(maps)->nr_maps; } =20 #ifdef HAVE_LIBUNWIND_SUPPORT static inline void *maps__addr_space(struct maps *maps) { - return maps->addr_space; + return RC_CHK_ACCESS(maps)->addr_space; } =20 static inline const struct unwind_libunwind_ops *maps__unwind_libunwind_op= s(const struct maps *maps) { - return maps->unwind_libunwind_ops; + return RC_CHK_ACCESS(maps)->unwind_libunwind_ops; } #endif =20 diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 639343d5577c..6993b51b9416 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2097,8 +2097,8 @@ static int map__groups__sort_by_name_from_rbtree(stru= ct maps *maps) up_read(maps__lock(maps)); down_write(maps__lock(maps)); =20 - maps->maps_by_name =3D maps_by_name; - maps->nr_maps_allocated =3D maps__nr_maps(maps); + RC_CHK_ACCESS(maps)->maps_by_name =3D maps_by_name; + RC_CHK_ACCESS(maps)->nr_maps_allocated =3D maps__nr_maps(maps); =20 maps__for_each_entry(maps, rb_node) maps_by_name[i++] =3D map__get(rb_node->map); @@ -2133,11 +2133,12 @@ struct map *maps__find_by_name(struct maps *maps, c= onst char *name) =20 down_read(maps__lock(maps)); =20 - if (maps->last_search_by_name) { - const struct dso *dso =3D map__dso(maps->last_search_by_name); + + if (RC_CHK_ACCESS(maps)->last_search_by_name) { + const struct dso *dso =3D map__dso(RC_CHK_ACCESS(maps)->last_search_by_n= ame); =20 if (strcmp(dso->short_name, name) =3D=3D 0) { - map =3D maps->last_search_by_name; + map =3D RC_CHK_ACCESS(maps)->last_search_by_name; goto out_unlock; } } @@ -2157,7 +2158,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) map =3D rb_node->map; dso =3D map__dso(map); if (strcmp(dso->short_name, name) =3D=3D 0) { - maps->last_search_by_name =3D map; + RC_CHK_ACCESS(maps)->last_search_by_name =3D map; goto out_unlock; } } diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 9565f9906e5d..bdccfc511b7e 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -230,7 +230,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct unwind_info *ui, ui_buf =3D { .sample =3D data, .thread =3D thread, - .machine =3D thread->maps->machine, + .machine =3D RC_CHK_ACCESS(thread->maps)->machine, .cb =3D cb, .arg =3D arg, .max_stack =3D max_stack, diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unw= ind-libunwind-local.c index f9a52af48de4..83dd79dcd597 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -677,7 +677,7 @@ static int _unwind__prepare_access(struct maps *maps) { void *addr_space =3D unw_create_addr_space(&accessors, 0); =20 - maps->addr_space =3D addr_space; + RC_CHK_ACCESS(maps)->addr_space =3D addr_space; if (!addr_space) { pr_err("unwind: Can't create unwind address space.\n"); return -ENOMEM; diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-li= bunwind.c index 4378daaafcd3..b54968e6a4e4 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -14,7 +14,7 @@ struct unwind_libunwind_ops __weak *arm64_unwind_libunwin= d_ops; =20 static void unwind__register_ops(struct maps *maps, struct unwind_libunwin= d_ops *ops) { - maps->unwind_libunwind_ops =3D ops; + RC_CHK_ACCESS(maps)->unwind_libunwind_ops =3D ops; } =20 int unwind__prepare_access(struct maps *maps, struct map *map, bool *initi= alized) --=20 2.40.0.348.gf938b09366-goog From nobody Wed Feb 11 06:54:10 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5077EC6FD1D for ; Tue, 4 Apr 2023 21:03:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236535AbjDDVDD (ORCPT ); Tue, 4 Apr 2023 17:03:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236018AbjDDVCa (ORCPT ); Tue, 4 Apr 2023 17:02:30 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0D2995593 for ; Tue, 4 Apr 2023 14:02:01 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id z4-20020a25bb04000000b00b392ae70300so33628933ybg.21 for ; Tue, 04 Apr 2023 14:02:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1680642119; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=5NovpSUg3Y8a/tr5KBGhz5Gi3sSPAFEbgdtSFDoXvB4=; b=krhi9cW5/6yrh3web6LOTAH1lGbx72Mpe8mi7FqV5X+kaHtufqzWAM7PD8CUphO5EI kUiaG6SAsMqTDS1rdTa8dJhKD6sBG52hn0K4NEqcnQY0y0Iy7t8XZNEkSrYkt7BlJDFn AbXqlKh+7ZM3qgX2FsFpnP00XccH3WZkv4z4xO30Cj4wxH8KVSfmRSL7B7eUNQMLOszX pKhztv7c+RV1bX5sSI4/KqKBWFHmIfHd4t9WugwPo2Ytrc00Syo79KM0SBpFuMNN/avO G7s5lVpYrME17gqThpMda8FAvBneYDsJztfU3C7GEUDful6ICAbxTf4S0S8GJhixpmIU pNbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680642119; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=5NovpSUg3Y8a/tr5KBGhz5Gi3sSPAFEbgdtSFDoXvB4=; b=IIetPnDJzdH+Ec8YpKvd+UUHeCMC5ZkDeriiDOjr7MkLTi92g6ThjkIwSe53+sAujt LVbjnPlzNZW4JcZbHBWqr79qPhn/X7ATWBcXz8fge2wx/7KUH6DcwZUnWM7pztmh/2zl DTdXDtE+xpr5ZYU+oFL4eCK2ElZQgw1OIn+wutWjQIAMz8EtnmlOHypRdOigEutlNMcG ybldLGcQbiiuswyLOCkNX7Div9b+OtpZeCnxH7JG7/C39n5FWVeGDLRq/b0DdbR0+WX9 llJD/ZrYsTd+9EpzxtGxnvs3FAYmSwo8yL21bn9ClVKHRay6gUbFiFbTI2kgy0NxnRSP C0OQ== X-Gm-Message-State: AAQBX9cwLyegcm8jBntbGkLGdpdNSPkUVUzbh4FdSJJ5iBfHa1LtkCAR +pgvVbSqsPJ6oCmnzXHuxAg+has73cnG X-Google-Smtp-Source: AKy350YsHCLimEQiTEjBGoKYgRTVSiWFDDMWVK2jAHZa56rHZUBFzbApwTuc8o6bW9Qc3OTVv122JEVYXYYv X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a051:e074:d6f:dc29]) (user=irogers job=sendgmr) by 2002:a25:d2c7:0:b0:98e:6280:74ca with SMTP id j190-20020a25d2c7000000b0098e628074camr2716389ybg.1.1680642118920; Tue, 04 Apr 2023 14:01:58 -0700 (PDT) Date: Tue, 4 Apr 2023 13:59:54 -0700 In-Reply-To: <20230404205954.2245628-1-irogers@google.com> Message-Id: <20230404205954.2245628-13-irogers@google.com> Mime-Version: 1.0 References: <20230404205954.2245628-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.348.gf938b09366-goog Subject: [PATCH v6 12/12] perf map: Add reference count checking From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Thomas Gleixner , Darren Hart , Davidlohr Bueso , James Clark , John Garry , Riccardo Mancini , Yury Norov , Andy Shevchenko , Andrew Morton , Adrian Hunter , Leo Yan , Andi Kleen , Thomas Richter , Kan Liang , Madhavan Srinivasan , Shunsuke Nakamura , Song Liu , Masami Hiramatsu , Steven Rostedt , Miaoqian Lin , Stephen Brennan , Kajol Jain , Alexey Bayduraev , German Gomez , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Eric Dumazet , Dmitry Vyukov , Hao Luo Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" There's no strict get/put policy with map that leads to leaks or use after free. Reference count checking identifies correct pairing of gets and puts. Signed-off-by: Ian Rogers --- tools/perf/arch/s390/annotate/instructions.c | 5 +- tools/perf/builtin-top.c | 4 +- tools/perf/tests/hists_link.c | 2 +- tools/perf/tests/maps.c | 20 +++--- tools/perf/tests/vmlinux-kallsyms.c | 4 +- tools/perf/util/annotate.c | 10 +-- tools/perf/util/machine.c | 25 +++---- tools/perf/util/map.c | 69 +++++++++++--------- tools/perf/util/map.h | 32 +++++---- tools/perf/util/maps.c | 11 ++-- tools/perf/util/symbol-elf.c | 26 ++++---- tools/perf/util/symbol.c | 40 +++++++----- 12 files changed, 135 insertions(+), 113 deletions(-) diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch= /s390/annotate/instructions.c index 6548933e8dc0..9953d510f7c1 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c @@ -39,8 +39,9 @@ static int s390_call__parse(struct arch *arch, struct ins= _operands *ops, target.addr =3D map__objdump_2mem(map, ops->target.addr); =20 if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D - ops->target.addr) + map__rip_2objdump(target.ms.map, + RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr) + ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 return 0; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b803af4329d1..c0b3a98674df 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -191,7 +191,7 @@ static void ui__warn_map_erange(struct map *map, struct= symbol *sym, u64 ip) if (use_browser <=3D 0) sleep(5); =20 - map->erange_warned =3D true; + RC_CHK_ACCESS(map)->erange_warned =3D true; } =20 static void perf_top__record_precise_ip(struct perf_top *top, @@ -225,7 +225,7 @@ static void perf_top__record_precise_ip(struct perf_top= *top, */ mutex_unlock(&he->hists->lock); =20 - if (err =3D=3D -ERANGE && !he->ms.map->erange_warned) + if (err =3D=3D -ERANGE && !RC_CHK_ACCESS(he->ms.map)->erange_warned) ui__warn_map_erange(he->ms.map, sym, ip); else if (err =3D=3D -ENOMEM) { pr_err("Not enough memory for annotating '%s' symbol!\n", diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 64ce8097889c..141e2972e34f 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -145,7 +145,7 @@ static int find_sample(struct sample *samples, size_t n= r_samples, { while (nr_samples--) { if (samples->thread =3D=3D t && - samples->map =3D=3D m && + RC_CHK_ACCESS(samples->map) =3D=3D RC_CHK_ACCESS(m) && samples->sym =3D=3D s) return 1; samples++; diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index 1c7293476aca..b8dab6278bca 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -30,7 +30,7 @@ static int check_maps(struct map_def *merged, unsigned in= t size, struct maps *ma if (map__start(map) !=3D merged[i].start || map__end(map) !=3D merged[i].end || strcmp(map__dso(map)->name, merged[i].name) || - refcount_read(&map->refcnt) !=3D 1) { + refcount_read(&RC_CHK_ACCESS(map)->refcnt) !=3D 1) { failed =3D true; } i++; @@ -50,7 +50,7 @@ static int check_maps(struct map_def *merged, unsigned in= t size, struct maps *ma map__start(map), map__end(map), map__dso(map)->name, - refcount_read(&map->refcnt)); + refcount_read(&RC_CHK_ACCESS(map)->refcnt)); } } return failed ? TEST_FAIL : TEST_OK; @@ -95,8 +95,8 @@ static int test__maps__merge_in(struct test_suite *t __ma= ybe_unused, int subtest map =3D dso__new_map(bpf_progs[i].name); TEST_ASSERT_VAL("failed to create map", map); =20 - map->start =3D bpf_progs[i].start; - map->end =3D bpf_progs[i].end; + RC_CHK_ACCESS(map)->start =3D bpf_progs[i].start; + RC_CHK_ACCESS(map)->end =3D bpf_progs[i].end; TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) =3D=3D 0= ); map__put(map); } @@ -111,16 +111,16 @@ static int test__maps__merge_in(struct test_suite *t = __maybe_unused, int subtest TEST_ASSERT_VAL("failed to create map", map_kcore3); =20 /* kcore1 map overlaps over all bpf maps */ - map_kcore1->start =3D 100; - map_kcore1->end =3D 1000; + RC_CHK_ACCESS(map_kcore1)->start =3D 100; + RC_CHK_ACCESS(map_kcore1)->end =3D 1000; =20 /* kcore2 map hides behind bpf_prog_2 */ - map_kcore2->start =3D 550; - map_kcore2->end =3D 570; + RC_CHK_ACCESS(map_kcore2)->start =3D 550; + RC_CHK_ACCESS(map_kcore2)->end =3D 570; =20 /* kcore3 map hides behind bpf_prog_3, kcore1 and adds new map */ - map_kcore3->start =3D 880; - map_kcore3->end =3D 1100; + RC_CHK_ACCESS(map_kcore3)->start =3D 880; + RC_CHK_ACCESS(map_kcore3)->end =3D 1100; =20 ret =3D maps__merge_in(maps, map_kcore1); TEST_ASSERT_VAL("failed to merge map", !ret); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index af511233c764..a087b24463ff 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -304,7 +304,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused dso->short_name : dso->name)); if (pair) { - pair->priv =3D 1; + RC_CHK_ACCESS(pair)->priv =3D 1; } else { if (!header_printed) { pr_info("WARN: Maps only in vmlinux:\n"); @@ -340,7 +340,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, map__start(pair), map__end(pair), map__pgoff(pair)); pr_info(" %s\n", dso->name); - pair->priv =3D 1; + RC_CHK_ACCESS(pair)->priv =3D 1; } } =20 diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 733051122959..248ada119c91 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -272,8 +272,9 @@ static int call__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s target.addr =3D map__objdump_2mem(map, ops->target.addr); =20 if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D - ops->target.addr) + map__rip_2objdump(target.ms.map, + RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr) + ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 return 0; @@ -401,8 +402,9 @@ static int jump__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s * the symbol searching and disassembly should be done. */ if (maps__find_ams(ms->maps, &target) =3D=3D 0 && - map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.ad= dr)) =3D=3D - ops->target.addr) + map__rip_2objdump(target.ms.map, + RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr) + ) =3D=3D ops->target.addr) ops->target.sym =3D target.ms.sym; =20 if (!ops->target.outside) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 2d9ce6966238..9a472ee52129 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -910,8 +910,8 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, dso__set_loaded(dso); } =20 - map->start =3D event->ksymbol.addr; - map->end =3D map__start(map) + event->ksymbol.len; + RC_CHK_ACCESS(map)->start =3D event->ksymbol.addr; + RC_CHK_ACCESS(map)->end =3D map__start(map) + event->ksymbol.len; err =3D maps__insert(machine__kernel_maps(machine), map); if (err) { err =3D -ENOMEM; @@ -953,7 +953,7 @@ static int machine__process_ksymbol_unregister(struct m= achine *machine, if (!map) return 0; =20 - if (map !=3D machine->vmlinux_map) + if (RC_CHK_ACCESS(map) !=3D RC_CHK_ACCESS(machine->vmlinux_map)) maps__remove(machine__kernel_maps(machine), map); else { struct dso *dso =3D map__dso(map); @@ -1218,8 +1218,8 @@ int machine__create_extra_kernel_map(struct machine *= machine, if (!map) return -ENOMEM; =20 - map->end =3D xm->end; - map->pgoff =3D xm->pgoff; + RC_CHK_ACCESS(map)->end =3D xm->end; + RC_CHK_ACCESS(map)->pgoff =3D xm->pgoff; =20 kmap =3D map__kmap(map); =20 @@ -1291,7 +1291,7 @@ int machine__map_x86_64_entry_trampolines(struct mach= ine *machine, =20 dest_map =3D maps__find(kmaps, map__pgoff(map)); if (dest_map !=3D map) - map->pgoff =3D map__map_ip(dest_map, map__pgoff(map)); + RC_CHK_ACCESS(map)->pgoff =3D map__map_ip(dest_map, map__pgoff(map)); found =3D true; } if (found || machine->trampolines_mapped) @@ -1342,7 +1342,8 @@ __machine__create_kernel_maps(struct machine *machine= , struct dso *kernel) if (machine->vmlinux_map =3D=3D NULL) return -ENOMEM; =20 - machine->vmlinux_map->map_ip =3D machine->vmlinux_map->unmap_ip =3D ident= ity__map_ip; + RC_CHK_ACCESS(machine->vmlinux_map)->map_ip =3D identity__map_ip; + RC_CHK_ACCESS(machine->vmlinux_map)->unmap_ip =3D identity__map_ip; return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); } =20 @@ -1623,7 +1624,7 @@ static int machine__create_module(void *arg, const ch= ar *name, u64 start, map =3D machine__addnew_module_map(machine, start, name); if (map =3D=3D NULL) return -1; - map->end =3D start + size; + RC_CHK_ACCESS(map)->end =3D start + size; =20 dso__kernel_module_get_build_id(map__dso(map), machine->root_dir); map__put(map); @@ -1659,14 +1660,14 @@ static int machine__create_modules(struct machine *= machine) static void machine__set_kernel_mmap(struct machine *machine, u64 start, u64 end) { - machine->vmlinux_map->start =3D start; - machine->vmlinux_map->end =3D end; + RC_CHK_ACCESS(machine->vmlinux_map)->start =3D start; + RC_CHK_ACCESS(machine->vmlinux_map)->end =3D end; /* * Be a bit paranoid here, some perf.data file came with * a zero sized synthesized MMAP event for the kernel. */ if (start =3D=3D 0 && end =3D=3D 0) - machine->vmlinux_map->end =3D ~0ULL; + RC_CHK_ACCESS(machine->vmlinux_map)->end =3D ~0ULL; } =20 static int machine__update_kernel_mmap(struct machine *machine, @@ -1810,7 +1811,7 @@ static int machine__process_kernel_mmap_event(struct = machine *machine, if (map =3D=3D NULL) goto out_problem; =20 - map->end =3D map__start(map) + xm->end - xm->start; + RC_CHK_ACCESS(map)->end =3D map__start(map) + xm->end - xm->start; =20 if (build_id__is_defined(bid)) dso__set_build_id(map__dso(map), bid); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index acbc37359e06..9ac5c909ea9e 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -104,15 +104,15 @@ static inline bool replace_android_lib(const char *fi= lename, char *newfilename) =20 void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso = *dso) { - map->start =3D start; - map->end =3D end; - map->pgoff =3D pgoff; - map->reloc =3D 0; - map->dso =3D dso__get(dso); - map->map_ip =3D map__dso_map_ip; - map->unmap_ip =3D map__dso_unmap_ip; - map->erange_warned =3D false; - refcount_set(&map->refcnt, 1); + RC_CHK_ACCESS(map)->start =3D start; + RC_CHK_ACCESS(map)->end =3D end; + RC_CHK_ACCESS(map)->pgoff =3D pgoff; + RC_CHK_ACCESS(map)->reloc =3D 0; + RC_CHK_ACCESS(map)->dso =3D dso__get(dso); + RC_CHK_ACCESS(map)->map_ip =3D map__dso_map_ip; + RC_CHK_ACCESS(map)->unmap_ip =3D map__dso_unmap_ip; + RC_CHK_ACCESS(map)->erange_warned =3D false; + refcount_set(&RC_CHK_ACCESS(map)->refcnt, 1); } =20 struct map *map__new(struct machine *machine, u64 start, u64 len, @@ -120,11 +120,13 @@ struct map *map__new(struct machine *machine, u64 sta= rt, u64 len, u32 prot, u32 flags, struct build_id *bid, char *filename, struct thread *thread) { - struct map *map =3D malloc(sizeof(*map)); + struct map *res; + RC_STRUCT(map) *map; struct nsinfo *nsi =3D NULL; struct nsinfo *nnsi; =20 - if (map !=3D NULL) { + map =3D malloc(sizeof(*map)); + if (ADD_RC_CHK(res, map)) { char newfilename[PATH_MAX]; struct dso *dso, *header_bid_dso; int anon, no_dso, vdso, android; @@ -167,7 +169,7 @@ struct map *map__new(struct machine *machine, u64 start= , u64 len, if (dso =3D=3D NULL) goto out_delete; =20 - map__init(map, start, start + len, pgoff, dso); + map__init(res, start, start + len, pgoff, dso); =20 if (anon || no_dso) { map->map_ip =3D map->unmap_ip =3D identity__map_ip; @@ -204,10 +206,10 @@ struct map *map__new(struct machine *machine, u64 sta= rt, u64 len, } dso__put(dso); } - return map; + return res; out_delete: nsinfo__put(nsi); - free(map); + RC_CHK_FREE(res); return NULL; } =20 @@ -218,16 +220,18 @@ struct map *map__new(struct machine *machine, u64 sta= rt, u64 len, */ struct map *map__new2(u64 start, struct dso *dso) { - struct map *map =3D calloc(1, (sizeof(*map) + - (dso->kernel ? sizeof(struct kmap) : 0))); - if (map !=3D NULL) { + struct map *res; + RC_STRUCT(map) *map; + + map =3D calloc(1, sizeof(*map) + (dso->kernel ? sizeof(struct kmap) : 0)); + if (ADD_RC_CHK(res, map)) { /* * ->end will be filled after we load all the symbols */ - map__init(map, start, 0, 0, dso); + map__init(res, start, 0, 0, dso); } =20 - return map; + return res; } =20 bool __map__is_kernel(const struct map *map) @@ -292,20 +296,22 @@ bool map__has_symbols(const struct map *map) =20 static void map__exit(struct map *map) { - BUG_ON(refcount_read(&map->refcnt) !=3D 0); - dso__zput(map->dso); + BUG_ON(refcount_read(&RC_CHK_ACCESS(map)->refcnt) !=3D 0); + dso__zput(RC_CHK_ACCESS(map)->dso); } =20 void map__delete(struct map *map) { map__exit(map); - free(map); + RC_CHK_FREE(map); } =20 void map__put(struct map *map) { - if (map && refcount_dec_and_test(&map->refcnt)) + if (map && refcount_dec_and_test(&RC_CHK_ACCESS(map)->refcnt)) map__delete(map); + else + RC_CHK_PUT(map); } =20 void map__fixup_start(struct map *map) @@ -317,7 +323,7 @@ void map__fixup_start(struct map *map) if (nd !=3D NULL) { struct symbol *sym =3D rb_entry(nd, struct symbol, rb_node); =20 - map->start =3D sym->start; + RC_CHK_ACCESS(map)->start =3D sym->start; } } =20 @@ -329,7 +335,7 @@ void map__fixup_end(struct map *map) =20 if (nd !=3D NULL) { struct symbol *sym =3D rb_entry(nd, struct symbol, rb_node); - map->end =3D sym->end; + RC_CHK_ACCESS(map)->end =3D sym->end; } } =20 @@ -400,20 +406,21 @@ struct symbol *map__find_symbol_by_name(struct map *m= ap, const char *name) =20 struct map *map__clone(struct map *from) { - size_t size =3D sizeof(struct map); - struct map *map; + struct map *res; + RC_STRUCT(map) *map; + size_t size =3D sizeof(RC_STRUCT(map)); struct dso *dso =3D map__dso(from); =20 if (dso && dso->kernel) size +=3D sizeof(struct kmap); =20 - map =3D memdup(from, size); - if (map !=3D NULL) { + map =3D memdup(RC_CHK_ACCESS(from), size); + if (ADD_RC_CHK(res, map)) { refcount_set(&map->refcnt, 1); map->dso =3D dso__get(dso); } =20 - return map; + return res; } =20 size_t map__fprintf(struct map *map, FILE *fp) @@ -567,7 +574,7 @@ struct kmap *__map__kmap(struct map *map) =20 if (!dso || !dso->kernel) return NULL; - return (struct kmap *)(map + 1); + return (struct kmap *)(&RC_CHK_ACCESS(map)[1]); } =20 struct kmap *map__kmap(struct map *map) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 102485699aa8..55d047e818e7 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -10,12 +10,13 @@ #include #include #include +#include =20 struct dso; struct maps; struct machine; =20 -struct map { +DECLARE_RC_STRUCT(map) { u64 start; u64 end; bool erange_warned:1; @@ -49,52 +50,52 @@ u64 identity__map_ip(const struct map *map __maybe_unus= ed, u64 ip); =20 static inline struct dso *map__dso(const struct map *map) { - return map->dso; + return RC_CHK_ACCESS(map)->dso; } =20 static inline u64 map__map_ip(const struct map *map, u64 ip) { - return map->map_ip(map, ip); + return RC_CHK_ACCESS(map)->map_ip(map, ip); } =20 static inline u64 map__unmap_ip(const struct map *map, u64 ip) { - return map->unmap_ip(map, ip); + return RC_CHK_ACCESS(map)->unmap_ip(map, ip); } =20 static inline u64 map__start(const struct map *map) { - return map->start; + return RC_CHK_ACCESS(map)->start; } =20 static inline u64 map__end(const struct map *map) { - return map->end; + return RC_CHK_ACCESS(map)->end; } =20 static inline u64 map__pgoff(const struct map *map) { - return map->pgoff; + return RC_CHK_ACCESS(map)->pgoff; } =20 static inline u64 map__reloc(const struct map *map) { - return map->reloc; + return RC_CHK_ACCESS(map)->reloc; } =20 static inline u32 map__flags(const struct map *map) { - return map->flags; + return RC_CHK_ACCESS(map)->flags; } =20 static inline u32 map__prot(const struct map *map) { - return map->prot; + return RC_CHK_ACCESS(map)->prot; } =20 static inline bool map__priv(const struct map *map) { - return map->priv; + return RC_CHK_ACCESS(map)->priv; } =20 static inline size_t map__size(const struct map *map) @@ -153,9 +154,12 @@ struct map *map__clone(struct map *map); =20 static inline struct map *map__get(struct map *map) { - if (map) - refcount_inc(&map->refcnt); - return map; + struct map *result; + + if (RC_CHK_GET(result, map)) + refcount_inc(&RC_CHK_ACCESS(map)->refcnt); + + return result; } =20 void map__put(struct map *map); diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 567952587247..a33ae321c65a 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -126,7 +126,7 @@ void maps__remove(struct maps *maps, struct map *map) RC_CHK_ACCESS(maps)->last_search_by_name =3D NULL; =20 rb_node =3D maps__find_node(maps, map); - assert(rb_node->map =3D=3D map); + assert(rb_node->RC_CHK_ACCESS(map) =3D=3D RC_CHK_ACCESS(map)); __maps__remove(maps, rb_node); if (maps__maps_by_name(maps)) __maps__free_maps_by_name(maps); @@ -339,7 +339,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) goto put_map; } =20 - before->end =3D map__start(map); + RC_CHK_ACCESS(before)->end =3D map__start(map); err =3D __maps__insert(maps, before); if (err) { map__put(before); @@ -359,8 +359,9 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) goto put_map; } =20 - after->start =3D map__end(map); - after->pgoff +=3D map__end(map) - map__start(pos->map); + RC_CHK_ACCESS(after)->start =3D map__end(map); + RC_CHK_ACCESS(after)->pgoff +=3D + map__end(map) - map__start(pos->map); assert(map__map_ip(pos->map, map__end(map)) =3D=3D map__map_ip(after, map__end(map))); err =3D __maps__insert(maps, after); @@ -420,7 +421,7 @@ struct map_rb_node *maps__find_node(struct maps *maps, = struct map *map) struct map_rb_node *rb_node; =20 maps__for_each_entry(maps, rb_node) { - if (rb_node->map =3D=3D map) + if (rb_node->RC_CHK_ACCESS(map) =3D=3D RC_CHK_ACCESS(map)) return rb_node; } return NULL; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index c55981116f68..302599073b5d 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1354,11 +1354,11 @@ static int dso__process_kernel_symbol(struct dso *d= so, struct map *map, */ if (*remap_kernel && dso->kernel && !kmodule) { *remap_kernel =3D false; - map->start =3D shdr->sh_addr + ref_reloc(kmap); - map->end =3D map__start(map) + shdr->sh_size; - map->pgoff =3D shdr->sh_offset; - map->map_ip =3D map__dso_map_ip; - map->unmap_ip =3D map__dso_unmap_ip; + RC_CHK_ACCESS(map)->start =3D shdr->sh_addr + ref_reloc(kmap); + RC_CHK_ACCESS(map)->end =3D map__start(map) + shdr->sh_size; + RC_CHK_ACCESS(map)->pgoff =3D shdr->sh_offset; + RC_CHK_ACCESS(map)->map_ip =3D map__dso_map_ip; + RC_CHK_ACCESS(map)->unmap_ip =3D map__dso_unmap_ip; /* Ensure maps are correctly ordered */ if (kmaps) { int err; @@ -1379,7 +1379,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, */ if (*remap_kernel && kmodule) { *remap_kernel =3D false; - map->pgoff =3D shdr->sh_offset; + RC_CHK_ACCESS(map)->pgoff =3D shdr->sh_offset; } =20 *curr_mapp =3D map; @@ -1414,11 +1414,13 @@ static int dso__process_kernel_symbol(struct dso *d= so, struct map *map, map__kmap(curr_map)->kmaps =3D kmaps; =20 if (adjust_kernel_syms) { - curr_map->start =3D shdr->sh_addr + ref_reloc(kmap); - curr_map->end =3D map__start(curr_map) + shdr->sh_size; - curr_map->pgoff =3D shdr->sh_offset; + RC_CHK_ACCESS(curr_map)->start =3D shdr->sh_addr + ref_reloc(kmap); + RC_CHK_ACCESS(curr_map)->end =3D map__start(curr_map) + + shdr->sh_size; + RC_CHK_ACCESS(curr_map)->pgoff =3D shdr->sh_offset; } else { - curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; + RC_CHK_ACCESS(curr_map)->map_ip =3D identity__map_ip; + RC_CHK_ACCESS(curr_map)->unmap_ip =3D identity__map_ip; } curr_dso->symtab_type =3D dso->symtab_type; if (maps__insert(kmaps, curr_map)) @@ -1525,7 +1527,7 @@ dso__load_sym_internal(struct dso *dso, struct map *m= ap, struct symsrc *syms_ss, if (strcmp(elf_name, kmap->ref_reloc_sym->name)) continue; kmap->ref_reloc_sym->unrelocated_addr =3D sym.st_value; - map->reloc =3D kmap->ref_reloc_sym->addr - + RC_CHK_ACCESS(map)->reloc =3D kmap->ref_reloc_sym->addr - kmap->ref_reloc_sym->unrelocated_addr; break; } @@ -1536,7 +1538,7 @@ dso__load_sym_internal(struct dso *dso, struct map *m= ap, struct symsrc *syms_ss, * attempted to prelink vdso to its virtual address. */ if (dso__is_vdso(dso)) - map->reloc =3D map__start(map) - dso->text_offset; + RC_CHK_ACCESS(map)->reloc =3D map__start(map) - dso->text_offset; =20 dso->adjust_symbols =3D runtime_ss->adjust_symbols || ref_reloc(kmap); /* diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 6993b51b9416..42458582621b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -279,7 +279,7 @@ void maps__fixup_end(struct maps *maps) =20 maps__for_each_entry(maps, curr) { if (prev !=3D NULL && !map__end(prev->map)) - prev->map->end =3D map__start(curr->map); + RC_CHK_ACCESS(prev->map)->end =3D map__start(curr->map); =20 prev =3D curr; } @@ -289,7 +289,7 @@ void maps__fixup_end(struct maps *maps) * last map final address. */ if (curr && !map__end(curr->map)) - curr->map->end =3D ~0ULL; + RC_CHK_ACCESS(curr->map)->end =3D ~0ULL; =20 up_write(maps__lock(maps)); } @@ -865,7 +865,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, *module++ =3D '\0'; curr_map_dso =3D map__dso(curr_map); if (strcmp(curr_map_dso->short_name, module)) { - if (curr_map !=3D initial_map && + if (RC_CHK_ACCESS(curr_map) !=3D RC_CHK_ACCESS(initial_map) && dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(machine)) { /* @@ -944,7 +944,8 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, return -1; } =20 - curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; + RC_CHK_ACCESS(curr_map)->map_ip =3D identity__map_ip; + RC_CHK_ACCESS(curr_map)->unmap_ip =3D identity__map_ip; if (maps__insert(kmaps, curr_map)) { dso__put(ndso); return -1; @@ -1250,8 +1251,8 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff,= void *data) return -ENOMEM; } =20 - list_node->map->end =3D map__start(list_node->map) + len; - list_node->map->pgoff =3D pgoff; + list_node->RC_CHK_ACCESS(map)->end =3D map__start(list_node->map) + len; + list_node->RC_CHK_ACCESS(map)->pgoff =3D pgoff; =20 list_add(&list_node->node, &md->maps); =20 @@ -1286,7 +1287,7 @@ int maps__merge_in(struct maps *kmaps, struct map *ne= w_map) * |new......| -> |new..| * |old....| -> |old....| */ - new_map->end =3D map__start(old_map); + RC_CHK_ACCESS(new_map)->end =3D map__start(old_map); } else { /* * |new.............| -> |new..| |new..| @@ -1306,10 +1307,12 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) goto out; } =20 - m->map->end =3D map__start(old_map); + + RC_CHK_ACCESS(m->map)->end =3D map__start(old_map); list_add_tail(&m->node, &merged); - new_map->pgoff +=3D map__end(old_map) - map__start(new_map); - new_map->start =3D map__end(old_map); + RC_CHK_ACCESS(new_map)->pgoff +=3D + map__end(old_map) - map__start(new_map); + RC_CHK_ACCESS(new_map)->start =3D map__end(old_map); } } else { /* @@ -1329,8 +1332,9 @@ int maps__merge_in(struct maps *kmaps, struct map *ne= w_map) * |new......| -> |new...| * |old....| -> |old....| */ - new_map->pgoff +=3D map__end(old_map) - map__start(new_map); - new_map->start =3D map__end(old_map); + RC_CHK_ACCESS(new_map)->pgoff +=3D + map__end(old_map) - map__start(new_map); + RC_CHK_ACCESS(new_map)->start =3D map__end(old_map); } } } @@ -1456,12 +1460,12 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, =20 list_del_init(&new_node->node); =20 - if (new_map =3D=3D replacement_map) { - map->start =3D map__start(new_map); - map->end =3D map__end(new_map); - map->pgoff =3D map__pgoff(new_map); - map->map_ip =3D new_map->map_ip; - map->unmap_ip =3D new_map->unmap_ip; + if (RC_CHK_ACCESS(new_map) =3D=3D RC_CHK_ACCESS(replacement_map)) { + RC_CHK_ACCESS(map)->start =3D map__start(new_map); + RC_CHK_ACCESS(map)->end =3D map__end(new_map); + RC_CHK_ACCESS(map)->pgoff =3D map__pgoff(new_map); + RC_CHK_ACCESS(map)->map_ip =3D RC_CHK_ACCESS(new_map)->map_ip; + RC_CHK_ACCESS(map)->unmap_ip =3D RC_CHK_ACCESS(new_map)->unmap_ip; /* Ensure maps are correctly ordered */ map__get(map); maps__remove(kmaps, map); --=20 2.40.0.348.gf938b09366-goog