From nobody Sun Feb 8 15:46:51 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 D226BC6FD1C for ; Mon, 20 Mar 2023 21:23:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230052AbjCTVXi (ORCPT ); Mon, 20 Mar 2023 17:23:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230183AbjCTVX2 (ORCPT ); Mon, 20 Mar 2023 17:23:28 -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 2CB31AD06 for ; Mon, 20 Mar 2023 14:23:12 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5419fb7d6c7so133750327b3.11 for ; Mon, 20 Mar 2023 14:23:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347390; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=HTn2hjAh9Nouc/rloylNMSTmI2V2EkvcDVrDtj6Buak=; b=ED4uu1cgrIA7/03LoG5QjbNozmLYwWmKk28oUbN/R7ZuqxeNQO1yCL08meB7mt5y/i 2oysP80gCiauwPCKEIMwJdHihdsS/NFaInK7q880rjAqkPBJoQHqnEZr562MJGQuIfP+ /QyEx6DFATCfUibw0/KV5P5LMKiFWkL5DdXFrbWiNiUcvIBobcaDQOgPrABTrKOOz2PH 25CJhOvu0OYxDbZ+GA5d0NHtVaPJENTBKFME7g4Gh40j1FyKMyq17ylnFZUXlq1Z/wXJ rGDBiHNc6od9mxmSlhBQnK2w8NY6ERnbAMBPDIbOmq0kV5q+LJb6ILKM+bt/cXSmrwFx YUWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347390; 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=HTn2hjAh9Nouc/rloylNMSTmI2V2EkvcDVrDtj6Buak=; b=SLeHyZr4Bo+y05d9VmL1CA2TrkEK02+D+DFJVRRMWVHKWqy+O4hrASRKlHt4o9PaMG 8lxbmiQMx4Tyhs0/jY1I4tVZ+m9C2PJ1InlZnr0kO69E8Xz1jZ2wRfqMJM0TyyYWA+Mc +dR4QQgno7VQviYPMvY7hBGFraaV1j+/fYbB7a6F8FZloL5C99cWiU+o9Qbco0U4EsXm GrZ5kjaMy0yveElDlSZQ8rZlZuUcV/sZqjXJfszozw5uw9DF6t8FPqLCYWuG/h76guQU cbg9ZxXh6mbVdT8ZP4HISv0J+lRKoL+ir7c2ZrpONQJ1IMggQsy/ZN9/4HP3bLSbHuCa MZzQ== X-Gm-Message-State: AAQBX9fwdDkdruerO2LcfVAKQk5893vzasG4DaF9fR8hcO0KXZTJoQ8m Q7nCfIoNKX68WBX8Dl75QaBH7nJQNhzp X-Google-Smtp-Source: AKy350a1BNEp7EjVeycZAHWABjXgUIRfgqyJiYf32UghqDdonZ8WFKIxrZ4GEUp1TwFz9RYbQ4THIqaczZcV X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a25:9289:0:b0:a5f:0:bf12 with SMTP id y9-20020a259289000000b00a5f0000bf12mr389640ybl.13.1679347390628; Mon, 20 Mar 2023 14:23:10 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:32 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-2-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 01/17] perf map: Move map list node into symbol 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" Using a perf map as a list node is only done in symbol. Move the list_node struct into symbol as a single pointer to the map. This makes reference count behavior more obvious and easy to check. Signed-off-by: Ian Rogers --- tools/perf/util/map.h | 5 +-- tools/perf/util/symbol.c | 93 ++++++++++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 35 deletions(-) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 3dcfe06db6b3..2879cae05ee0 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -16,10 +16,7 @@ struct maps; struct machine; =20 struct map { - union { - struct rb_node rb_node; - struct list_head node; - }; + struct rb_node rb_node; u64 start; u64 end; bool erange_warned:1; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a458aa8b87bb..65e0c3d126f1 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -48,6 +48,11 @@ static bool symbol__is_idle(const char *name); int vmlinux_path__nr_entries; char **vmlinux_path; =20 +struct map_list_node { + struct list_head node; + struct map *map; +}; + struct symbol_conf symbol_conf =3D { .nanosecs =3D false, .use_modules =3D true, @@ -85,6 +90,11 @@ static enum dso_binary_type binary_type_symtab[] =3D { =20 #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) =20 +static struct map_list_node *map_list_node__new(void) +{ + return malloc(sizeof(struct map_list_node)); +} + static bool symbol_type__filter(char symbol_type) { symbol_type =3D toupper(symbol_type); @@ -1219,16 +1229,21 @@ struct kcore_mapfn_data { static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) { struct kcore_mapfn_data *md =3D data; - struct map *map; + struct map_list_node *list_node =3D map_list_node__new(); =20 - map =3D map__new2(start, md->dso); - if (map =3D=3D NULL) + if (!list_node) return -ENOMEM; =20 - map->end =3D map->start + len; - map->pgoff =3D pgoff; + list_node->map =3D map__new2(start, md->dso); + if (!list_node->map) { + free(list_node); + return -ENOMEM; + } + + list_node->map->end =3D list_node->map->start + len; + list_node->map->pgoff =3D pgoff; =20 - list_add(&map->node, &md->maps); + list_add(&list_node->node, &md->maps); =20 return 0; } @@ -1264,12 +1279,18 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) * |new.............| -> |new..| |new..| * |old....| -> |old....| */ - struct map *m =3D map__clone(new_map); + struct map_list_node *m =3D map_list_node__new(); =20 if (!m) return -ENOMEM; =20 - m->end =3D old_map->start; + m->map =3D map__clone(new_map); + if (!m->map) { + free(m); + return -ENOMEM; + } + + m->map->end =3D old_map->start; list_add_tail(&m->node, &merged); new_map->pgoff +=3D old_map->end - new_map->start; new_map->start =3D old_map->end; @@ -1299,10 +1320,13 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) } =20 while (!list_empty(&merged)) { - old_map =3D list_entry(merged.next, struct map, node); - list_del_init(&old_map->node); - maps__insert(kmaps, old_map); - map__put(old_map); + struct map_list_node *old_node; + + old_node =3D list_entry(merged.next, struct map_list_node, node); + list_del_init(&old_node->node); + maps__insert(kmaps, old_node->map); + map__put(old_node->map); + free(old_node); } =20 if (new_map) { @@ -1317,7 +1341,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, { struct maps *kmaps =3D map__kmaps(map); struct kcore_mapfn_data md; - struct map *old_map, *new_map, *replacement_map =3D NULL, *next; + struct map *old_map, *replacement_map =3D NULL, *next; struct machine *machine; bool is_64_bit; int err, fd; @@ -1378,11 +1402,12 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, /* Find the kernel map using the '_stext' symbol */ if (!kallsyms__get_function_start(kallsyms_filename, "_stext", &stext)) { u64 replacement_size =3D 0; + struct map_list_node *new_node; =20 - list_for_each_entry(new_map, &md.maps, node) { - u64 new_size =3D new_map->end - new_map->start; + list_for_each_entry(new_node, &md.maps, node) { + u64 new_size =3D new_node->map->end - new_node->map->start; =20 - if (!(stext >=3D new_map->start && stext < new_map->end)) + if (!(stext >=3D new_node->map->start && stext < new_node->map->end)) continue; =20 /* @@ -1392,40 +1417,43 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, * falls within more than one in the list. */ if (!replacement_map || new_size < replacement_size) { - replacement_map =3D new_map; + replacement_map =3D new_node->map; replacement_size =3D new_size; } } } =20 if (!replacement_map) - replacement_map =3D list_entry(md.maps.next, struct map, node); + replacement_map =3D list_entry(md.maps.next, struct map_list_node, node)= ->map; =20 /* Add new maps */ while (!list_empty(&md.maps)) { - new_map =3D list_entry(md.maps.next, struct map, node); - list_del_init(&new_map->node); - if (new_map =3D=3D replacement_map) { - map->start =3D new_map->start; - map->end =3D new_map->end; - map->pgoff =3D new_map->pgoff; - map->map_ip =3D new_map->map_ip; - map->unmap_ip =3D new_map->unmap_ip; + struct map_list_node *new_node; + + new_node =3D list_entry(md.maps.next, struct map_list_node, node); + list_del_init(&new_node->node); + if (new_node->map =3D=3D replacement_map) { + map->start =3D new_node->map->start; + map->end =3D new_node->map->end; + map->pgoff =3D new_node->map->pgoff; + map->map_ip =3D new_node->map->map_ip; + map->unmap_ip =3D new_node->map->unmap_ip; /* Ensure maps are correctly ordered */ map__get(map); maps__remove(kmaps, map); maps__insert(kmaps, map); map__put(map); - map__put(new_map); + map__put(new_node->map); } else { /* * Merge kcore map into existing maps, * and ensure that current maps (eBPF) * stay intact. */ - if (maps__merge_in(kmaps, new_map)) + if (maps__merge_in(kmaps, new_node->map)) goto out_err; } + free(new_node); } =20 if (machine__is(machine, "x86_64")) { @@ -1462,9 +1490,12 @@ static int dso__load_kcore(struct dso *dso, struct m= ap *map, =20 out_err: while (!list_empty(&md.maps)) { - map =3D list_entry(md.maps.next, struct map, node); - list_del_init(&map->node); - map__put(map); + struct map_list_node *list_node; + + list_node =3D list_entry(md.maps.next, struct map_list_node, node); + list_del_init(&list_node->node); + map__put(list_node->map); + free(list_node); } close(fd); return -EINVAL; --=20 2.40.0.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 9C564C7619A for ; Mon, 20 Mar 2023 21:23:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230114AbjCTVXz (ORCPT ); Mon, 20 Mar 2023 17:23:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229995AbjCTVXr (ORCPT ); Mon, 20 Mar 2023 17:23:47 -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 BD0F538036 for ; Mon, 20 Mar 2023 14:23:20 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id i11-20020a256d0b000000b0086349255277so14350575ybc.8 for ; Mon, 20 Mar 2023 14:23:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347398; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=nwfJHR3uDeVFPoUwsnTQRvdix/5zBLz6Y91JeFwQQFU=; b=DTesJb6co4v+Onwn+ESWXt32fvvJwVx+xUKTOHNVG3OqyqACcokI6XcSXYR4/Xmul2 GtyEEJUnK1H12dwyrzOEl2pGP2wE7voxJ2GhOAYkxmQdk1DikSIV2oM/0vdDHdQXHLPQ aF/8fSaSI0yd7E+Xkos4lRUHjWqUFnnGLlsiYQ7E3P249m2DeXRj+goPxTkQK5SI9Nm/ Swyl6G1YP222hINlKXdmp4LBvfFWJfRGXeA1I2t9cig1hs7d/G3IC+iW+1tVWBVsQjAK uKxpND8wSJDRW2eaG1HyUju6Vl5R177FEy5Venm+fGN1tgUSgdwZu2vs2dFADSoJK5pJ WpDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347398; 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=nwfJHR3uDeVFPoUwsnTQRvdix/5zBLz6Y91JeFwQQFU=; b=TzwLmDePuKpVc//4hrB0dsjEWN2hUFL5RGmCW9GegOv0zGufFVxrGOm2vT6/GXguIA 0l//mwtGpzVhHE78HZEIy8/Z/pGH+cgLTAR6kGJJ7uOesggHp45rMEJKbA+y23/eDKYd OmB1xBKt2bUxCoiilqO2syAwF69U1xXIMTO/grwhU8XKS+0geQti6QxN4O5T6euCXOLg hiPKNVnp0zRYOTSL0kEMFd/VvZ0SZVm/iP4fNEhm1f/X3l1i64sBSAFmCYdR6UldfzUK wWze3WAzHtBjscTrfX/pU2DBW74bMXnRvQCo8ONqVfTMON7Wz4DjyI7W9c2UNERaWeLg WS6g== X-Gm-Message-State: AAQBX9eqF0zl9HGqcSP6w7uNEPsJFqq5ikY5pOJLSbPgJr1h256/QTSp +nUdRzMFgclL4WqbCeZkLIWyFtqpcTLm X-Google-Smtp-Source: AKy350bBf9o0wCHgoGW3qE82LYrMMACmPs658gYzT2A7fqiGwAm+qQdCre3/yIK6dqzwL1UVqji7FtbC2vlE X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:1003:b0:b3c:637f:ad00 with SMTP id w3-20020a056902100300b00b3c637fad00mr6160ybt.5.1679347398084; Mon, 20 Mar 2023 14:23:18 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:33 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-3-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 02/17] perf maps: Remove rb_node from struct 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" struct map is reference counted, having it also be a node in an red-black tree complicates the reference counting. Switch to having a map_rb_node which is a red-block tree node but points at the reference counted struct map. This reference is responsible for a single reference count. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/util/event.c | 13 +- tools/perf/builtin-report.c | 6 +- tools/perf/tests/maps.c | 8 +- tools/perf/tests/vmlinux-kallsyms.c | 17 ++- tools/perf/util/bpf_lock_contention.c | 2 +- tools/perf/util/machine.c | 68 ++++++---- tools/perf/util/map.c | 16 --- tools/perf/util/map.h | 1 - tools/perf/util/maps.c | 180 +++++++++++++++++--------- tools/perf/util/maps.h | 17 ++- tools/perf/util/probe-event.c | 18 ++- tools/perf/util/symbol-elf.c | 9 +- tools/perf/util/symbol.c | 77 +++++++---- tools/perf/util/synthetic-events.c | 26 ++-- tools/perf/util/thread.c | 10 +- tools/perf/util/vdso.c | 7 +- 16 files changed, 291 insertions(+), 184 deletions(-) diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/ev= ent.c index e4288d09f3a0..17bf60babfbd 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -19,7 +19,7 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *= tool, struct machine *machine) { int rc =3D 0; - struct map *pos; + struct map_rb_node *pos; struct maps *kmaps =3D machine__kernel_maps(machine); union perf_event *event =3D zalloc(sizeof(event->mmap) + machine->id_hdr_size); @@ -33,11 +33,12 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool= *tool, maps__for_each_entry(kmaps, pos) { struct kmap *kmap; size_t size; + struct map *map =3D pos->map; =20 - if (!__map__is_extra_kernel_map(pos)) + if (!__map__is_extra_kernel_map(map)) continue; =20 - kmap =3D map__kmap(pos); + kmap =3D map__kmap(map); =20 size =3D sizeof(event->mmap) - sizeof(event->mmap.filename) + PERF_ALIGN(strlen(kmap->name) + 1, sizeof(u64)) + @@ -58,9 +59,9 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *= tool, =20 event->mmap.header.size =3D size; =20 - event->mmap.start =3D pos->start; - event->mmap.len =3D pos->end - pos->start; - event->mmap.pgoff =3D pos->pgoff; + event->mmap.start =3D map->start; + event->mmap.len =3D map->end - map->start; + event->mmap.pgoff =3D map->pgoff; 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 6400615b5e98..c453b7fa7418 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -840,9 +840,11 @@ static struct task *tasks_list(struct task *task, stru= ct machine *machine) static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) { size_t printed =3D 0; - struct map *map; + struct map_rb_node *rb_node; + + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; =20 - maps__for_each_entry(maps, map) { printed +=3D fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRI= x64 " %" PRIu64 " %s\n", indent, "", map->start, map->end, map->prot & PROT_READ ? 'r' : '-', diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index a69988a89d26..8246d37e4b7a 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -15,10 +15,12 @@ struct map_def { =20 static int check_maps(struct map_def *merged, unsigned int size, struct ma= ps *maps) { - struct map *map; + struct map_rb_node *rb_node; unsigned int i =3D 0; =20 - maps__for_each_entry(maps, map) { + 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)); =20 @@ -74,7 +76,7 @@ static int test__maps__merge_in(struct test_suite *t __ma= ybe_unused, int subtest =20 map->start =3D bpf_progs[i].start; map->end =3D bpf_progs[i].end; - maps__insert(maps, map); + TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) =3D=3D 0= ); map__put(map); } =20 diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index 8ab035b55875..c8abb3ca8347 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -118,7 +118,8 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused int err =3D TEST_FAIL; struct rb_node *nd; struct symbol *sym; - struct map *kallsyms_map, *vmlinux_map, *map; + struct map *kallsyms_map, *vmlinux_map; + struct map_rb_node *rb_node; struct machine kallsyms, vmlinux; struct maps *maps; u64 mem_start, mem_end; @@ -290,15 +291,15 @@ static int test__vmlinux_matches_kallsyms(struct test= _suite *test __maybe_unused =20 header_printed =3D false; =20 - maps__for_each_entry(maps, map) { - struct map * + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; /* * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while * the kernel will have the path for the vmlinux file being used, * so use the short name, less descriptive but the same ("[kernel]" in * both cases. */ - pair =3D maps__find_by_name(kallsyms.kmaps, (map->dso->kernel ? + struct map *pair =3D maps__find_by_name(kallsyms.kmaps, (map->dso->kerne= l ? map->dso->short_name : map->dso->name)); if (pair) { @@ -314,8 +315,8 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused =20 header_printed =3D false; =20 - maps__for_each_entry(maps, map) { - struct map *pair; + 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); mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, map->end); @@ -344,7 +345,9 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused =20 maps =3D machine__kernel_maps(&kallsyms); =20 - maps__for_each_entry(maps, map) { + maps__for_each_entry(maps, rb_node) { + struct map *map =3D rb_node->map; + if (!map->priv) { if (!header_printed) { pr_info("WARN: Maps only in kallsyms:\n"); diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lo= ck_contention.c index 235fc7150545..0b47863d2460 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -282,7 +282,7 @@ int lock_contention_read(struct lock_contention *con) } =20 /* make sure it loads the kernel map */ - map__load(maps__first(machine->kmaps)); + map__load(maps__first(machine->kmaps)->map); =20 prev_key =3D NULL; while (!bpf_map_get_next_key(fd, prev_key, &key)) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 803c9d1803dd..93a07079d174 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -882,6 +882,7 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, =20 if (!map) { struct dso *dso =3D dso__new(event->ksymbol.name); + int err; =20 if (dso) { dso->kernel =3D DSO_SPACE__KERNEL; @@ -901,8 +902,11 @@ static int machine__process_ksymbol_register(struct ma= chine *machine, =20 map->start =3D event->ksymbol.addr; map->end =3D map->start + event->ksymbol.len; - maps__insert(machine__kernel_maps(machine), map); + err =3D maps__insert(machine__kernel_maps(machine), map); map__put(map); + if (err) + return err; + dso__set_loaded(dso); =20 if (is_bpf_image(event->ksymbol.name)) { @@ -1002,6 +1006,7 @@ static struct map *machine__addnew_module_map(struct = machine *machine, u64 start struct map *map =3D NULL; struct kmod_path m; struct dso *dso; + int err; =20 if (kmod_path__parse_name(&m, filename)) return NULL; @@ -1014,10 +1019,14 @@ static struct map *machine__addnew_module_map(struc= t machine *machine, u64 start if (map =3D=3D NULL) goto out; =20 - maps__insert(machine__kernel_maps(machine), map); + err =3D maps__insert(machine__kernel_maps(machine), map); =20 /* Put the map here because maps__insert already got it */ map__put(map); + + /* If maps__insert failed, return NULL. */ + if (err) + map =3D NULL; out: /* put the dso here, corresponding to machine__findnew_module_dso */ dso__put(dso); @@ -1184,10 +1193,11 @@ int machine__create_extra_kernel_map(struct machine= *machine, { struct kmap *kmap; struct map *map; + int err; =20 map =3D map__new2(xm->start, kernel); if (!map) - return -1; + return -ENOMEM; =20 map->end =3D xm->end; map->pgoff =3D xm->pgoff; @@ -1196,14 +1206,16 @@ int machine__create_extra_kernel_map(struct machine= *machine, =20 strlcpy(kmap->name, xm->name, KMAP_NAME_LEN); =20 - maps__insert(machine__kernel_maps(machine), map); + err =3D maps__insert(machine__kernel_maps(machine), map); =20 - pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", - kmap->name, map->start, map->end); + if (!err) { + pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", + kmap->name, map->start, map->end); + } =20 map__put(map); =20 - return 0; + return err; } =20 static u64 find_entry_trampoline(struct dso *dso) @@ -1244,16 +1256,16 @@ int machine__map_x86_64_entry_trampolines(struct ma= chine *machine, struct maps *kmaps =3D machine__kernel_maps(machine); int nr_cpus_avail, cpu; bool found =3D false; - struct map *map; + struct map_rb_node *rb_node; u64 pgoff; =20 /* * In the vmlinux case, pgoff is a virtual address which must now be * mapped to a vmlinux offset. */ - maps__for_each_entry(kmaps, map) { + maps__for_each_entry(kmaps, rb_node) { + struct map *dest_map, *map =3D rb_node->map; struct kmap *kmap =3D __map__kmap(map); - struct map *dest_map; =20 if (!kmap || !is_entry_trampoline(kmap->name)) continue; @@ -1308,11 +1320,10 @@ __machine__create_kernel_maps(struct machine *machi= ne, struct dso *kernel) =20 machine->vmlinux_map =3D map__new2(0, kernel); if (machine->vmlinux_map =3D=3D NULL) - return -1; + return -ENOMEM; =20 machine->vmlinux_map->map_ip =3D machine->vmlinux_map->unmap_ip =3D ident= ity__map_ip; - maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); - return 0; + return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map); } =20 void machine__destroy_kernel_maps(struct machine *machine) @@ -1634,25 +1645,26 @@ static void machine__set_kernel_mmap(struct machine= *machine, machine->vmlinux_map->end =3D ~0ULL; } =20 -static void machine__update_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); + int err; =20 map__get(map); maps__remove(machine__kernel_maps(machine), map); =20 machine__set_kernel_mmap(machine, start, end); =20 - maps__insert(machine__kernel_maps(machine), map); + err =3D maps__insert(machine__kernel_maps(machine), map); map__put(map); + return err; } =20 int machine__create_kernel_maps(struct machine *machine) { struct dso *kernel =3D machine__get_kernel(machine); const char *name =3D NULL; - struct map *map; u64 start =3D 0, end =3D ~0ULL; int ret; =20 @@ -1684,7 +1696,9 @@ int machine__create_kernel_maps(struct machine *machi= ne) * we have a real start address now, so re-order the kmaps * assume it's the last in the kmaps */ - machine__update_kernel_mmap(machine, start, end); + ret =3D machine__update_kernel_mmap(machine, start, end); + if (ret < 0) + goto out_put; } =20 if (machine__create_extra_kernel_maps(machine, kernel)) @@ -1692,9 +1706,12 @@ int machine__create_kernel_maps(struct machine *mach= ine) =20 if (end =3D=3D ~0ULL) { /* update end address of the kernel map using adjacent module address */ - map =3D map__next(machine__kernel_map(machine)); - if (map) - machine__set_kernel_mmap(machine, start, map->start); + struct map_rb_node *rb_node =3D maps__find_node(machine__kernel_maps(mac= hine), + machine__kernel_map(machine)); + struct map_rb_node *next =3D map_rb_node__next(rb_node); + + if (next) + machine__set_kernel_mmap(machine, start, next->map->start); } =20 out_put: @@ -1827,7 +1844,10 @@ static int machine__process_kernel_mmap_event(struct= machine *machine, if (strstr(kernel->long_name, "vmlinux")) dso__set_short_name(kernel, "[kernel.vmlinux]", false); =20 - machine__update_kernel_mmap(machine, xm->start, xm->end); + if (machine__update_kernel_mmap(machine, xm->start, xm->end) < 0) { + dso__put(kernel); + goto out_problem; + } =20 if (build_id__is_defined(bid)) dso__set_build_id(kernel, bid); @@ -3325,11 +3345,11 @@ int machine__for_each_dso(struct machine *machine, = machine__dso_t fn, void *priv int machine__for_each_kernel_map(struct machine *machine, machine__map_t f= n, void *priv) { struct maps *maps =3D machine__kernel_maps(machine); - struct map *map; + struct map_rb_node *pos; int err =3D 0; =20 - for (map =3D maps__first(maps); map !=3D NULL; map =3D map__next(map)) { - err =3D fn(map, priv); + maps__for_each_entry(maps, pos) { + err =3D fn(pos->map, priv); if (err !=3D 0) { break; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index f3a3d9b3a40d..7620cfa114d4 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -111,7 +111,6 @@ void map__init(struct map *map, u64 start, u64 end, u64= pgoff, struct dso *dso) map->dso =3D dso__get(dso); map->map_ip =3D map__map_ip; map->unmap_ip =3D map__unmap_ip; - RB_CLEAR_NODE(&map->rb_node); map->erange_warned =3D false; refcount_set(&map->refcnt, 1); } @@ -397,7 +396,6 @@ struct map *map__clone(struct map *from) map =3D memdup(from, size); if (map !=3D NULL) { refcount_set(&map->refcnt, 1); - RB_CLEAR_NODE(&map->rb_node); dso__get(map->dso); } =20 @@ -537,20 +535,6 @@ bool map__contains_symbol(const struct map *map, const= struct symbol *sym) return ip >=3D map->start && ip < map->end; } =20 -static struct map *__map__next(struct map *map) -{ - struct rb_node *next =3D rb_next(&map->rb_node); - - if (next) - return rb_entry(next, struct map, rb_node); - return NULL; -} - -struct map *map__next(struct map *map) -{ - return map ? __map__next(map) : NULL; -} - struct kmap *__map__kmap(struct map *map) { if (!map->dso || !map->dso->kernel) diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 2879cae05ee0..d1a6f85fd31d 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -16,7 +16,6 @@ struct maps; struct machine; =20 struct map { - struct rb_node rb_node; u64 start; u64 end; bool erange_warned:1; diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 37bd5b40000d..83ec126bcbe5 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -10,8 +10,6 @@ #include "ui/ui.h" #include "unwind.h" =20 -static void __maps__insert(struct maps *maps, struct map *map); - static void maps__init(struct maps *maps, struct machine *machine) { maps->entries =3D RB_ROOT; @@ -32,10 +30,44 @@ static void __maps__free_maps_by_name(struct maps *maps) maps->nr_maps_allocated =3D 0; } =20 -void maps__insert(struct maps *maps, struct map *map) +static int __maps__insert(struct maps *maps, struct map *map) { + struct rb_node **p =3D &maps->entries.rb_node; + struct rb_node *parent =3D NULL; + const u64 ip =3D map->start; + struct map_rb_node *m, *new_rb_node; + + new_rb_node =3D malloc(sizeof(*new_rb_node)); + if (!new_rb_node) + return -ENOMEM; + + RB_CLEAR_NODE(&new_rb_node->rb_node); + new_rb_node->map =3D map; + + while (*p !=3D NULL) { + parent =3D *p; + m =3D rb_entry(parent, struct map_rb_node, rb_node); + if (ip < m->map->start) + p =3D &(*p)->rb_left; + else + p =3D &(*p)->rb_right; + } + + rb_link_node(&new_rb_node->rb_node, parent, p); + rb_insert_color(&new_rb_node->rb_node, &maps->entries); + map__get(map); + return 0; +} + +int maps__insert(struct maps *maps, struct map *map) +{ + int err; + down_write(&maps->lock); - __maps__insert(maps, map); + err =3D __maps__insert(maps, map); + if (err) + goto out; + ++maps->nr_maps; =20 if (map->dso && map->dso->kernel) { @@ -59,32 +91,39 @@ void maps__insert(struct maps *maps, struct map *map) =20 if (maps_by_name =3D=3D NULL) { __maps__free_maps_by_name(maps); - up_write(&maps->lock); - return; + err =3D -ENOMEM; + goto out; } =20 maps->maps_by_name =3D maps_by_name; maps->nr_maps_allocated =3D nr_allocate; - } +} maps->maps_by_name[maps->nr_maps - 1] =3D map; __maps__sort_by_name(maps); } + out: up_write(&maps->lock); + return err; } =20 -static void __maps__remove(struct maps *maps, struct map *map) +static void __maps__remove(struct maps *maps, struct map_rb_node *rb_node) { - rb_erase_init(&map->rb_node, &maps->entries); - map__put(map); + rb_erase_init(&rb_node->rb_node, &maps->entries); + map__put(rb_node->map); + free(rb_node); } =20 void maps__remove(struct maps *maps, struct map *map) { + struct map_rb_node *rb_node; + down_write(&maps->lock); if (maps->last_search_by_name =3D=3D map) maps->last_search_by_name =3D NULL; =20 - __maps__remove(maps, 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__free_maps_by_name(maps); @@ -93,11 +132,12 @@ void maps__remove(struct maps *maps, struct map *map) =20 static void __maps__purge(struct maps *maps) { - struct map *pos, *next; + struct map_rb_node *pos, *next; =20 maps__for_each_entry_safe(maps, pos, next) { rb_erase_init(&pos->rb_node, &maps->entries); - map__put(pos); + map__put(pos->map); + free(pos); } } =20 @@ -153,21 +193,21 @@ struct symbol *maps__find_symbol(struct maps *maps, u= 64 addr, struct map **mapp) struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *na= me, struct map **mapp) { struct symbol *sym; - struct map *pos; + struct map_rb_node *pos; =20 down_read(&maps->lock); =20 maps__for_each_entry(maps, pos) { - sym =3D map__find_symbol_by_name(pos, name); + sym =3D map__find_symbol_by_name(pos->map, name); =20 if (sym =3D=3D NULL) continue; - if (!map__contains_symbol(pos, sym)) { + if (!map__contains_symbol(pos->map, sym)) { sym =3D NULL; continue; } if (mapp !=3D NULL) - *mapp =3D pos; + *mapp =3D pos->map; goto out; } =20 @@ -196,15 +236,15 @@ int maps__find_ams(struct maps *maps, struct addr_map= _symbol *ams) size_t maps__fprintf(struct maps *maps, FILE *fp) { size_t printed =3D 0; - struct map *pos; + struct map_rb_node *pos; =20 down_read(&maps->lock); =20 maps__for_each_entry(maps, pos) { printed +=3D fprintf(fp, "Map:"); - printed +=3D map__fprintf(pos, fp); + printed +=3D map__fprintf(pos->map, fp); if (verbose > 2) { - printed +=3D dso__fprintf(pos->dso, fp); + printed +=3D dso__fprintf(pos->map->dso, fp); printed +=3D fprintf(fp, "--\n"); } } @@ -231,11 +271,11 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) next =3D root->rb_node; first =3D NULL; while (next) { - struct map *pos =3D rb_entry(next, struct map, rb_node); + struct map_rb_node *pos =3D rb_entry(next, struct map_rb_node, rb_node); =20 - if (pos->end > map->start) { + if (pos->map->end > map->start) { first =3D next; - if (pos->start <=3D map->start) + if (pos->map->start <=3D map->start) break; next =3D next->rb_left; } else @@ -244,14 +284,14 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) =20 next =3D first; while (next) { - struct map *pos =3D rb_entry(next, struct map, rb_node); + struct map_rb_node *pos =3D rb_entry(next, struct map_rb_node, rb_node); next =3D rb_next(&pos->rb_node); =20 /* * Stop if current map starts after map->end. * Maps are ordered by start: next will not overlap for sure. */ - if (pos->start >=3D map->end) + if (pos->map->start >=3D map->end) break; =20 if (verbose >=3D 2) { @@ -262,7 +302,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) } else { fputs("overlapping maps:\n", fp); map__fprintf(map, fp); - map__fprintf(pos, fp); + map__fprintf(pos->map, fp); } } =20 @@ -271,8 +311,8 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) * Now check if we need to create new maps for areas not * overlapped by the new map: */ - if (map->start > pos->start) { - struct map *before =3D map__clone(pos); + if (map->start > pos->map->start) { + struct map *before =3D map__clone(pos->map); =20 if (before =3D=3D NULL) { err =3D -ENOMEM; @@ -280,14 +320,17 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) } =20 before->end =3D map->start; - __maps__insert(maps, before); + err =3D __maps__insert(maps, before); + if (err) + goto put_map; + if (verbose >=3D 2 && !use_browser) map__fprintf(before, fp); map__put(before); } =20 - if (map->end < pos->end) { - struct map *after =3D map__clone(pos); + if (map->end < pos->map->end) { + struct map *after =3D map__clone(pos->map); =20 if (after =3D=3D NULL) { err =3D -ENOMEM; @@ -295,15 +338,19 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) } =20 after->start =3D map->end; - after->pgoff +=3D map->end - pos->start; - assert(pos->map_ip(pos, map->end) =3D=3D after->map_ip(after, map->end)= ); - __maps__insert(maps, after); + after->pgoff +=3D map->end - pos->map->start; + assert(pos->map->map_ip(pos->map, map->end) =3D=3D + after->map_ip(after, map->end)); + err =3D __maps__insert(maps, after); + if (err) + goto put_map; + if (verbose >=3D 2 && !use_browser) map__fprintf(after, fp); map__put(after); } put_map: - map__put(pos); + map__put(pos->map); =20 if (err) goto out; @@ -322,12 +369,12 @@ int maps__clone(struct thread *thread, struct maps *p= arent) { struct maps *maps =3D thread->maps; int err; - struct map *map; + struct map_rb_node *rb_node; =20 down_read(&parent->lock); =20 - maps__for_each_entry(parent, map) { - struct map *new =3D map__clone(map); + maps__for_each_entry(parent, rb_node) { + struct map *new =3D map__clone(rb_node->map); =20 if (new =3D=3D NULL) { err =3D -ENOMEM; @@ -338,7 +385,10 @@ int maps__clone(struct thread *thread, struct maps *pa= rent) if (err) goto out_unlock; =20 - maps__insert(maps, new); + err =3D maps__insert(maps, new); + if (err) + goto out_unlock; + map__put(new); } =20 @@ -348,40 +398,31 @@ int maps__clone(struct thread *thread, struct maps *p= arent) return err; } =20 -static void __maps__insert(struct maps *maps, struct map *map) +struct map_rb_node *maps__find_node(struct maps *maps, struct map *map) { - struct rb_node **p =3D &maps->entries.rb_node; - struct rb_node *parent =3D NULL; - const u64 ip =3D map->start; - struct map *m; + struct map_rb_node *rb_node; =20 - while (*p !=3D NULL) { - parent =3D *p; - m =3D rb_entry(parent, struct map, rb_node); - if (ip < m->start) - p =3D &(*p)->rb_left; - else - p =3D &(*p)->rb_right; + maps__for_each_entry(maps, rb_node) { + if (rb_node->map =3D=3D map) + return rb_node; } - - rb_link_node(&map->rb_node, parent, p); - rb_insert_color(&map->rb_node, &maps->entries); - map__get(map); + return NULL; } =20 struct map *maps__find(struct maps *maps, u64 ip) { struct rb_node *p; - struct map *m; + struct map_rb_node *m; + =20 down_read(&maps->lock); =20 p =3D maps->entries.rb_node; while (p !=3D NULL) { - m =3D rb_entry(p, struct map, rb_node); - if (ip < m->start) + m =3D rb_entry(p, struct map_rb_node, rb_node); + if (ip < m->map->start) p =3D p->rb_left; - else if (ip >=3D m->end) + else if (ip >=3D m->map->end) p =3D p->rb_right; else goto out; @@ -390,14 +431,29 @@ struct map *maps__find(struct maps *maps, u64 ip) m =3D NULL; out: up_read(&maps->lock); - return m; + return m ? m->map : NULL; } =20 -struct map *maps__first(struct maps *maps) +struct map_rb_node *maps__first(struct maps *maps) { struct rb_node *first =3D rb_first(&maps->entries); =20 if (first) - return rb_entry(first, struct map, rb_node); + return rb_entry(first, struct map_rb_node, rb_node); return NULL; } + +struct map_rb_node *map_rb_node__next(struct map_rb_node *node) +{ + struct rb_node *next; + + if (!node) + return NULL; + + next =3D rb_next(&node->rb_node); + + if (!next) + return NULL; + + return rb_entry(next, struct map_rb_node, rb_node); +} diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index 7e729ff42749..512746ec0f9a 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -15,15 +15,22 @@ struct map; struct maps; struct thread; =20 +struct map_rb_node { + struct rb_node rb_node; + struct map *map; +}; + +struct map_rb_node *maps__first(struct maps *maps); +struct map_rb_node *map_rb_node__next(struct map_rb_node *node); +struct map_rb_node *maps__find_node(struct maps *maps, struct map *map); struct map *maps__find(struct maps *maps, u64 addr); -struct map *maps__first(struct maps *maps); -struct map *map__next(struct map *map); =20 #define maps__for_each_entry(maps, map) \ - for (map =3D maps__first(maps); map; map =3D map__next(map)) + for (map =3D maps__first(maps); map; map =3D map_rb_node__next(map)) =20 #define maps__for_each_entry_safe(maps, map, next) \ - for (map =3D maps__first(maps), next =3D map__next(map); map; map =3D nex= t, next =3D map__next(map)) + 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 { struct rb_root entries; @@ -63,7 +70,7 @@ void maps__put(struct maps *maps); int maps__clone(struct thread *thread, struct maps *parent); size_t maps__fprintf(struct maps *maps, FILE *fp); =20 -void maps__insert(struct maps *maps, struct map *map); +int maps__insert(struct maps *maps, struct map *map); =20 void maps__remove(struct maps *maps, struct map *map); =20 diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 881d94f65a6b..cdf5d655d84c 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -151,23 +151,27 @@ static int kernel_get_symbol_address_by_name(const ch= ar *name, u64 *addr, static struct map *kernel_get_module_map(const char *module) { struct maps *maps =3D machine__kernel_maps(host_machine); - struct map *pos; + struct map_rb_node *pos; =20 /* A file path -- this is an offline module */ if (module && strchr(module, '/')) return dso__new_map(module); =20 if (!module) { - pos =3D machine__kernel_map(host_machine); - return map__get(pos); + struct map *map =3D machine__kernel_map(host_machine); + + return map__get(map); } =20 maps__for_each_entry(maps, pos) { /* short_name is "[module]" */ - if (strncmp(pos->dso->short_name + 1, module, - pos->dso->short_name_len - 2) =3D=3D 0 && - module[pos->dso->short_name_len - 2] =3D=3D '\0') { - return map__get(pos); + const char *short_name =3D pos->map->dso->short_name; + u16 short_name_len =3D pos->map->dso->short_name_len; + + if (strncmp(short_name + 1, module, + short_name_len - 2) =3D=3D 0 && + module[short_name_len - 2] =3D=3D '\0') { + return map__get(pos->map); } } return NULL; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index c0a2de42c51b..325fbeea8dff 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1355,10 +1355,14 @@ static int dso__process_kernel_symbol(struct dso *d= so, struct map *map, map->unmap_ip =3D map__unmap_ip; /* Ensure maps are correctly ordered */ if (kmaps) { + int err; + map__get(map); maps__remove(kmaps, map); - maps__insert(kmaps, map); + err =3D maps__insert(kmaps, map); map__put(map); + if (err) + return err; } } =20 @@ -1411,7 +1415,8 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; } curr_dso->symtab_type =3D dso->symtab_type; - maps__insert(kmaps, curr_map); + if (maps__insert(kmaps, curr_map)) + return -1; /* * Add it before we drop the reference to curr_map, i.e. while * we still are sure to have a reference to this DSO via diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 65e0c3d126f1..d9aa41e20d5f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -273,13 +273,13 @@ void symbols__fixup_end(struct rb_root_cached *symbol= s, bool is_kallsyms) =20 void maps__fixup_end(struct maps *maps) { - struct map *prev =3D NULL, *curr; + struct map_rb_node *prev =3D NULL, *curr; =20 down_write(&maps->lock); =20 maps__for_each_entry(maps, curr) { - if (prev !=3D NULL && !prev->end) - prev->end =3D curr->start; + if (prev !=3D NULL && !prev->map->end) + prev->map->end =3D curr->map->start; =20 prev =3D curr; } @@ -288,8 +288,8 @@ void maps__fixup_end(struct maps *maps) * We still haven't the actual symbols, so guess the * last map final address. */ - if (curr && !curr->end) - curr->end =3D ~0ULL; + if (curr && !curr->map->end) + curr->map->end =3D ~0ULL; =20 up_write(&maps->lock); } @@ -942,7 +942,10 @@ static int maps__split_kallsyms(struct maps *kmaps, st= ruct dso *dso, u64 delta, } =20 curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; - maps__insert(kmaps, curr_map); + if (maps__insert(kmaps, curr_map)) { + dso__put(ndso); + return -1; + } ++kernel_range; } else if (delta) { /* Kernel was relocated at boot time */ @@ -1130,14 +1133,15 @@ int compare_proc_modules(const char *from, const ch= ar *to) static int do_validate_kcore_modules(const char *filename, struct maps *km= aps) { struct rb_root modules =3D RB_ROOT; - struct map *old_map; + struct map_rb_node *old_node; int err; =20 err =3D read_proc_modules(filename, &modules); if (err) return err; =20 - maps__for_each_entry(kmaps, old_map) { + maps__for_each_entry(kmaps, old_node) { + struct map *old_map =3D old_node->map; struct module_info *mi; =20 if (!__map__is_kmodule(old_map)) { @@ -1254,10 +1258,13 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgof= f, void *data) */ int maps__merge_in(struct maps *kmaps, struct map *new_map) { - struct map *old_map; + struct map_rb_node *rb_node; LIST_HEAD(merged); + int err =3D 0; + + maps__for_each_entry(kmaps, rb_node) { + struct map *old_map =3D rb_node->map; =20 - maps__for_each_entry(kmaps, old_map) { /* no overload with this one */ if (new_map->end < old_map->start || new_map->start >=3D old_map->end) @@ -1281,13 +1288,16 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) */ struct map_list_node *m =3D map_list_node__new(); =20 - if (!m) - return -ENOMEM; + if (!m) { + err =3D -ENOMEM; + goto out; + } =20 m->map =3D map__clone(new_map); if (!m->map) { free(m); - return -ENOMEM; + err =3D -ENOMEM; + goto out; } =20 m->map->end =3D old_map->start; @@ -1319,21 +1329,24 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) } } =20 +out: while (!list_empty(&merged)) { struct map_list_node *old_node; =20 old_node =3D list_entry(merged.next, struct map_list_node, node); list_del_init(&old_node->node); - maps__insert(kmaps, old_node->map); + if (!err) + err =3D maps__insert(kmaps, old_node->map); map__put(old_node->map); free(old_node); } =20 if (new_map) { - maps__insert(kmaps, new_map); + if (!err) + err =3D maps__insert(kmaps, new_map); map__put(new_map); } - return 0; + return err; } =20 static int dso__load_kcore(struct dso *dso, struct map *map, @@ -1341,7 +1354,8 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, { struct maps *kmaps =3D map__kmaps(map); struct kcore_mapfn_data md; - struct map *old_map, *replacement_map =3D NULL, *next; + struct map *replacement_map =3D NULL; + struct map_rb_node *old_node, *next; struct machine *machine; bool is_64_bit; int err, fd; @@ -1388,7 +1402,9 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, } =20 /* Remove old maps */ - maps__for_each_entry_safe(kmaps, old_map, next) { + maps__for_each_entry_safe(kmaps, old_node, next) { + struct map *old_map =3D old_node->map; + /* * We need to preserve eBPF maps even if they are * covered by kcore, because we need to access @@ -1441,17 +1457,21 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, /* Ensure maps are correctly ordered */ map__get(map); maps__remove(kmaps, map); - maps__insert(kmaps, map); + err =3D maps__insert(kmaps, map); map__put(map); map__put(new_node->map); + if (err) + goto out_err; } else { /* * Merge kcore map into existing maps, * and ensure that current maps (eBPF) * stay intact. */ - if (maps__merge_in(kmaps, new_node->map)) + if (maps__merge_in(kmaps, new_node->map)) { + err =3D -EINVAL; goto out_err; + } } free(new_node); } @@ -1498,7 +1518,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, free(list_node); } close(fd); - return -EINVAL; + return err; } =20 /* @@ -2042,8 +2062,9 @@ void __maps__sort_by_name(struct maps *maps) =20 static int map__groups__sort_by_name_from_rbtree(struct maps *maps) { - struct map *map; - struct map **maps_by_name =3D realloc(maps->maps_by_name, maps->nr_maps *= sizeof(map)); + struct map_rb_node *rb_node; + struct map **maps_by_name =3D realloc(maps->maps_by_name, + maps->nr_maps * sizeof(struct map *)); int i =3D 0; =20 if (maps_by_name =3D=3D NULL) @@ -2055,8 +2076,8 @@ static int map__groups__sort_by_name_from_rbtree(stru= ct maps *maps) maps->maps_by_name =3D maps_by_name; maps->nr_maps_allocated =3D maps->nr_maps; =20 - maps__for_each_entry(maps, map) - maps_by_name[i++] =3D map; + maps__for_each_entry(maps, rb_node) + maps_by_name[i++] =3D rb_node->map; =20 __maps__sort_by_name(maps); =20 @@ -2082,6 +2103,7 @@ static struct map *__maps__find_by_name(struct maps *= maps, const char *name) =20 struct map *maps__find_by_name(struct maps *maps, const char *name) { + struct map_rb_node *rb_node; struct map *map; =20 down_read(&maps->lock); @@ -2100,12 +2122,13 @@ struct map *maps__find_by_name(struct maps *maps, c= onst char *name) goto out_unlock; =20 /* Fallback to traversing the rbtree... */ - maps__for_each_entry(maps, map) + maps__for_each_entry(maps, rb_node) { + map =3D rb_node->map; if (strcmp(map->dso->short_name, name) =3D=3D 0) { maps->last_search_by_name =3D map; goto out_unlock; } - + } map =3D NULL; =20 out_unlock: diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 6def01036eb5..57b95c1d7e39 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -669,7 +669,7 @@ int perf_event__synthesize_modules(struct perf_tool *to= ol, perf_event__handler_t struct machine *machine) { int rc =3D 0; - struct map *pos; + struct map_rb_node *pos; struct maps *maps =3D machine__kernel_maps(machine); union perf_event *event; size_t size =3D symbol_conf.buildid_mmap2 ? @@ -692,37 +692,39 @@ int perf_event__synthesize_modules(struct perf_tool *= tool, perf_event__handler_t event->header.misc =3D PERF_RECORD_MISC_GUEST_KERNEL; =20 maps__for_each_entry(maps, pos) { - if (!__map__is_kmodule(pos)) + struct map *map =3D pos->map; + + if (!__map__is_kmodule(map)) continue; =20 if (symbol_conf.buildid_mmap2) { - size =3D PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); + size =3D PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); event->mmap2.header.type =3D PERF_RECORD_MMAP2; event->mmap2.header.size =3D (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size)); memset(event->mmap2.filename + size, 0, machine->id_hdr_size); event->mmap2.header.size +=3D machine->id_hdr_size; - event->mmap2.start =3D pos->start; - event->mmap2.len =3D pos->end - pos->start; + event->mmap2.start =3D map->start; + event->mmap2.len =3D map->end - map->start; event->mmap2.pid =3D machine->pid; =20 - memcpy(event->mmap2.filename, pos->dso->long_name, - pos->dso->long_name_len + 1); + memcpy(event->mmap2.filename, map->dso->long_name, + map->dso->long_name_len + 1); =20 perf_record_mmap2__read_build_id(&event->mmap2, machine, false); } else { - size =3D PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); + size =3D PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); event->mmap.header.type =3D PERF_RECORD_MMAP; event->mmap.header.size =3D (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size)); memset(event->mmap.filename + size, 0, machine->id_hdr_size); event->mmap.header.size +=3D machine->id_hdr_size; - event->mmap.start =3D pos->start; - event->mmap.len =3D pos->end - pos->start; + event->mmap.start =3D map->start; + event->mmap.len =3D map->end - map->start; event->mmap.pid =3D machine->pid; =20 - memcpy(event->mmap.filename, pos->dso->long_name, - pos->dso->long_name_len + 1); + memcpy(event->mmap.filename, map->dso->long_name, + map->dso->long_name_len + 1); } =20 if (perf_tool__process_synth_event(tool, event, machine, process) !=3D 0= ) { diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index a2490a20eb56..24e53bd55f7d 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -352,9 +352,7 @@ int thread__insert_map(struct thread *thread, struct ma= p *map) return ret; =20 maps__fixup_overlappings(thread->maps, map, stderr); - maps__insert(thread->maps, map); - - return 0; + return maps__insert(thread->maps, map); } =20 static int __thread__prepare_access(struct thread *thread) @@ -362,12 +360,12 @@ static int __thread__prepare_access(struct thread *th= read) bool initialized =3D false; int err =3D 0; struct maps *maps =3D thread->maps; - struct map *map; + struct map_rb_node *rb_node; =20 down_read(&maps->lock); =20 - maps__for_each_entry(maps, map) { - err =3D unwind__prepare_access(thread->maps, map, &initialized); + maps__for_each_entry(maps, rb_node) { + err =3D unwind__prepare_access(thread->maps, rb_node->map, &initialized); if (err || initialized) break; } diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 43beb169631d..835c39efb80d 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -144,10 +144,11 @@ static enum dso_type machine__thread_dso_type(struct = machine *machine, struct thread *thread) { enum dso_type dso_type =3D DSO__TYPE_UNKNOWN; - struct map *map; + struct map_rb_node *rb_node; + + maps__for_each_entry(thread->maps, rb_node) { + struct dso *dso =3D rb_node->map->dso; =20 - maps__for_each_entry(thread->maps, map) { - struct dso *dso =3D map->dso; if (!dso || dso->long_name[0] !=3D '/') continue; dso_type =3D dso__type(dso, machine); --=20 2.40.0.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 C13C7C6FD1D for ; Mon, 20 Mar 2023 21:24:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230227AbjCTVYK (ORCPT ); Mon, 20 Mar 2023 17:24:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47068 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230032AbjCTVX6 (ORCPT ); Mon, 20 Mar 2023 17:23:58 -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 0E1103757C for ; Mon, 20 Mar 2023 14:23:28 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 3-20020a250b03000000b00b5f1fab9897so13476511ybl.19 for ; Mon, 20 Mar 2023 14:23:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347405; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=jlo12XpcFaWTYtJM5rXRVFgodkiIGL4KsQD9FBA5xgk=; b=EahGboGwU25X8k80EJSCCa5jqq29D85/uOc4Aw9ou1wNfOHA4P8oDWumuHEhoh/qUp d+B+hNy+Uqdjn872skIfQrDKOXDsIwYi/0laxOCdseGekQK1QXJmC8AnqDKgYVa3Ihu4 O1DFopRZ3u8I0wD+FUylzcG7zz0tuCBE5SV9Y57O5QgcAtoyXoL9bGs5gWqvpVRo0XwA X/CAbymrX2wqt+cYFoC1z/+fxe2EB1VGQgq6OE0Y3iYreykUhsAUVJR0NPnVJWHlQsWd k7DJw9uUw8Ai0M+ViOPtf5BzFIcZphmcZXbLBY+dkWKEsS3xkN+8hQ6h0yMlBROMH0IU qhMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347405; 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=jlo12XpcFaWTYtJM5rXRVFgodkiIGL4KsQD9FBA5xgk=; b=4Eqv5KSqnhKvpmGMjFOZks8Emk6SJWoAfK2eZLT2G8gySu097Txff9vhA2uLvD1CLi FHbVPdcygdYKKnuNOA+rHXIYjZOjA+rzqoBky37AiS5UNlBCxyMa4IxEfhyI6yCmJ6Fj jOXqk1rYlXlDAFkeF6oh9eVISLTL4Mm2sTZttm/DOCmVFd5qr+E/tvAd8ql5DGm9dQT3 LWU+qEyKU/PncInUV1kN6trhEA/2eqV2FlZUDuZrxm/r6/GOT5+jDi6/9KMUQvYnbKwG a12CSlv+ROHh24RCyxI44ysyRxaX1ZGKQTxyvHR25VKQ/KXYlCq1/n+8VO0P6lWGx5W2 HHDw== X-Gm-Message-State: AAQBX9eETPRGM1VaiY1NIbouG0WJJrbI/Sslyz+AYw3PpAw82BGyQIYv kUVOgD9G2zK9j5QY7h90LLUXXeab8Mi9 X-Google-Smtp-Source: AKy350bvZNdC8+nFETj3PI6z1zvvfaaf0JazllMwdXWBSMTb/ueiLyjHhNovTTLQHlU9G/YWtI+s7+mtCiy7 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:168d:b0:b3b:fb47:8534 with SMTP id bx13-20020a056902168d00b00b3bfb478534mr484339ybb.5.1679347405424; Mon, 20 Mar 2023 14:23:25 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:34 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-4-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 03/17] perf maps: Add functions to access maps 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" Introduce functions to access struct maps. These functions reduce the number of places reference counting is necessary. While tidying APIs do some small const-ification, in particlar to unwind_libunwind_ops. Signed-off-by: Ian Rogers --- .../scripts/python/Perf-Trace-Util/Context.c | 7 +- tools/perf/tests/code-reading.c | 2 +- tools/perf/ui/browsers/hists.c | 3 +- tools/perf/util/callchain.c | 9 +-- tools/perf/util/db-export.c | 12 ++-- tools/perf/util/dlfilter.c | 8 ++- tools/perf/util/event.c | 4 +- tools/perf/util/hist.c | 2 +- tools/perf/util/machine.c | 2 +- tools/perf/util/map.c | 14 ++-- tools/perf/util/maps.c | 71 +++++++++++-------- tools/perf/util/maps.h | 47 +++++++++--- .../scripting-engines/trace-event-python.c | 2 +- tools/perf/util/sort.c | 2 +- tools/perf/util/symbol-elf.c | 2 +- tools/perf/util/symbol.c | 44 ++++++------ tools/perf/util/thread-stack.c | 4 +- tools/perf/util/thread.c | 4 +- tools/perf/util/unwind-libunwind-local.c | 16 +++-- tools/perf/util/unwind-libunwind.c | 31 ++++---- 20 files changed, 175 insertions(+), 111 deletions(-) diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/pe= rf/scripts/python/Perf-Trace-Util/Context.c index b0d449f41650..feedd02b3b3d 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c @@ -100,10 +100,11 @@ static PyObject *perf_sample_insn(PyObject *obj, PyOb= ject *args) if (!c) return NULL; =20 - if (c->sample->ip && !c->sample->insn_len && - c->al->thread->maps && c->al->thread->maps->machine) - script_fetch_insn(c->sample, c->al->thread, c->al->thread->maps->machine= ); + if (c->sample->ip && !c->sample->insn_len && c->al->thread->maps) { + struct machine *machine =3D maps__machine(c->al->thread->maps); =20 + script_fetch_insn(c->sample, c->al->thread, machine); + } if (!c->sample->insn_len) Py_RETURN_NONE; /* N.B. This is a return statement */ =20 diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index fb67fd5ebd9f..8d2036f2f944 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -269,7 +269,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, len =3D al.map->end - addr; =20 /* Read the object code using perf */ - ret_len =3D dso__data_read_offset(al.map->dso, thread->maps->machine, + ret_len =3D dso__data_read_offset(al.map->dso, maps__machine(thread->maps= ), al.addr, buf1, len); if (ret_len !=3D len) { pr_debug("dso__data_read_offset failed\n"); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index b72ee6822222..572ff38ceb0f 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3139,7 +3139,8 @@ static int evsel__hists_browse(struct evsel *evsel, i= nt nr_events, const char *h continue; case 'k': if (browser->selection !=3D NULL) - hists_browser__zoom_map(browser, browser->selection->maps->machine->vm= linux_map); + hists_browser__zoom_map(browser, + maps__machine(browser->selection->maps)->vmlinux_map); continue; case 'V': verbose =3D (verbose + 1) % 4; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index a093a15f048f..0aa979f64565 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1112,6 +1112,8 @@ int hist_entry__append_callchain(struct hist_entry *h= e, struct perf_sample *samp int fill_callchain_info(struct addr_location *al, struct callchain_cursor_= node *node, bool hide_unresolved) { + struct machine *machine =3D maps__machine(node->ms.maps); + al->maps =3D node->ms.maps; al->map =3D node->ms.map; al->sym =3D node->ms.sym; @@ -1124,9 +1126,8 @@ int fill_callchain_info(struct addr_location *al, str= uct callchain_cursor_node * if (al->map =3D=3D NULL) goto out; } - - if (al->maps =3D=3D machine__kernel_maps(al->maps->machine)) { - if (machine__is_host(al->maps->machine)) { + if (al->maps =3D=3D machine__kernel_maps(machine)) { + if (machine__is_host(machine)) { al->cpumode =3D PERF_RECORD_MISC_KERNEL; al->level =3D 'k'; } else { @@ -1134,7 +1135,7 @@ int fill_callchain_info(struct addr_location *al, str= uct callchain_cursor_node * al->level =3D 'g'; } } else { - if (machine__is_host(al->maps->machine)) { + if (machine__is_host(machine)) { al->cpumode =3D PERF_RECORD_MISC_USER; al->level =3D '.'; } else if (perf_guest) { diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index e0d4f08839fb..1cfcfdd3cf52 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -181,7 +181,7 @@ static int db_ids_from_al(struct db_export *dbe, struct= addr_location *al, if (al->map) { struct dso *dso =3D al->map->dso; =20 - err =3D db_export__dso(dbe, dso, al->maps->machine); + err =3D db_export__dso(dbe, dso, maps__machine(al->maps)); if (err) return err; *dso_db_id =3D dso->db_id; @@ -354,19 +354,21 @@ int db_export__sample(struct db_export *dbe, union pe= rf_event *event, }; struct thread *main_thread; struct comm *comm =3D NULL; + struct machine *machine; int err; =20 err =3D db_export__evsel(dbe, evsel); if (err) return err; =20 - err =3D db_export__machine(dbe, al->maps->machine); + machine =3D maps__machine(al->maps); + err =3D db_export__machine(dbe, machine); if (err) return err; =20 - main_thread =3D thread__main_thread(al->maps->machine, thread); + main_thread =3D thread__main_thread(machine, thread); =20 - err =3D db_export__threads(dbe, thread, main_thread, al->maps->machine, &= comm); + err =3D db_export__threads(dbe, thread, main_thread, machine, &comm); if (err) goto out_put; =20 @@ -380,7 +382,7 @@ int db_export__sample(struct db_export *dbe, union perf= _event *event, goto out_put; =20 if (dbe->cpr) { - struct call_path *cp =3D call_path_from_sample(dbe, al->maps->machine, + struct call_path *cp =3D call_path_from_sample(dbe, machine, thread, sample, evsel); if (cp) { diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index 37beb7530288..fe2a0752a0f6 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -197,8 +197,12 @@ static const __u8 *dlfilter__insn(void *ctx, __u32 *le= n) if (!al->thread && machine__resolve(d->machine, al, d->sample) < 0) return NULL; =20 - if (al->thread->maps && al->thread->maps->machine) - script_fetch_insn(d->sample, al->thread, al->thread->maps->machine); + if (al->thread->maps) { + struct machine *machine =3D maps__machine(al->thread->maps); + + if (machine) + script_fetch_insn(d->sample, al->thread, machine); + } } =20 if (!d->sample->insn_len) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 1fa14598b916..f40cdd6ac126 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -572,7 +572,7 @@ struct map *thread__find_map(struct thread *thread, u8 = cpumode, u64 addr, struct addr_location *al) { struct maps *maps =3D thread->maps; - struct machine *machine =3D maps->machine; + struct machine *machine =3D maps__machine(maps); bool load_map =3D false; =20 al->maps =3D maps; @@ -637,7 +637,7 @@ struct map *thread__find_map_fb(struct thread *thread, = u8 cpumode, u64 addr, struct addr_location *al) { struct map *map =3D thread__find_map(thread, cpumode, addr, al); - struct machine *machine =3D thread->maps->machine; + struct machine *machine =3D maps__machine(thread->maps); u8 addr_cpumode =3D machine__addr_cpumode(machine, cpumode, addr); =20 if (map || addr_cpumode =3D=3D cpumode) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 3670136a0074..1b0e89cd5d99 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -241,7 +241,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) =20 if (h->cgroup) { const char *cgrp_name =3D "unknown"; - struct cgroup *cgrp =3D cgroup__find(h->ms.maps->machine->env, + struct cgroup *cgrp =3D cgroup__find(maps__machine(h->ms.maps)->env, h->cgroup); if (cgrp !=3D NULL) cgrp_name =3D cgrp->name; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 93a07079d174..446c0273259d 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2842,7 +2842,7 @@ static int find_prev_cpumode(struct ip_callchain *cha= in, struct thread *thread, static u64 get_leaf_frame_caller(struct perf_sample *sample, struct thread *thread, int usr_idx) { - if (machine__normalized_is(thread->maps->machine, "arm64")) + if (machine__normalized_is(maps__machine(thread->maps), "arm64")) return get_leaf_frame_caller_aarch64(sample, thread, usr_idx); else return 0; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 7620cfa114d4..a99dbde656a2 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -234,7 +234,7 @@ bool __map__is_kernel(const struct map *map) { if (!map->dso->kernel) return false; - return machine__kernel_map(map__kmaps((struct map *)map)->machine) =3D=3D= map; + return machine__kernel_map(maps__machine(map__kmaps((struct map *)map))) = =3D=3D map; } =20 bool __map__is_extra_kernel_map(const struct map *map) @@ -475,11 +475,15 @@ u64 map__rip_2objdump(struct map *map, u64 rip) * kcore may not either. However the trampoline object code is on the * main kernel map, so just use that instead. */ - if (kmap && is_entry_trampoline(kmap->name) && kmap->kmaps && kmap->kmaps= ->machine) { - struct map *kernel_map =3D machine__kernel_map(kmap->kmaps->machine); + if (kmap && is_entry_trampoline(kmap->name) && kmap->kmaps) { + struct machine *machine =3D maps__machine(kmap->kmaps); =20 - if (kernel_map) - map =3D kernel_map; + if (machine) { + struct map *kernel_map =3D machine__kernel_map(machine); + + if (kernel_map) + map =3D kernel_map; + } } =20 if (!map->dso->adjust_symbols) diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 83ec126bcbe5..91bb015caede 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -13,7 +13,7 @@ static void maps__init(struct maps *maps, struct machine *machine) { maps->entries =3D RB_ROOT; - init_rwsem(&maps->lock); + init_rwsem(maps__lock(maps)); maps->machine =3D machine; maps->last_search_by_name =3D NULL; maps->nr_maps =3D 0; @@ -32,7 +32,7 @@ static void __maps__free_maps_by_name(struct maps *maps) =20 static int __maps__insert(struct maps *maps, struct map *map) { - struct rb_node **p =3D &maps->entries.rb_node; + struct rb_node **p =3D &maps__entries(maps)->rb_node; struct rb_node *parent =3D NULL; const u64 ip =3D map->start; struct map_rb_node *m, *new_rb_node; @@ -54,7 +54,7 @@ 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); + rb_insert_color(&new_rb_node->rb_node, maps__entries(maps)); map__get(map); return 0; } @@ -63,7 +63,7 @@ int maps__insert(struct maps *maps, struct map *map) { int err; =20 - down_write(&maps->lock); + down_write(maps__lock(maps)); err =3D __maps__insert(maps, map); if (err) goto out; @@ -84,10 +84,11 @@ int maps__insert(struct maps *maps, struct map *map) * If we already performed some search by name, then we need to add the j= ust * inserted map and resort. */ - if (maps->maps_by_name) { - if (maps->nr_maps > maps->nr_maps_allocated) { - int nr_allocate =3D maps->nr_maps * 2; - struct map **maps_by_name =3D realloc(maps->maps_by_name, nr_allocate *= sizeof(map)); + if (maps__maps_by_name(maps)) { + if (maps__nr_maps(maps) > 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)); =20 if (maps_by_name =3D=3D NULL) { __maps__free_maps_by_name(maps); @@ -97,18 +98,18 @@ int maps__insert(struct maps *maps, struct map *map) =20 maps->maps_by_name =3D maps_by_name; maps->nr_maps_allocated =3D nr_allocate; -} - maps->maps_by_name[maps->nr_maps - 1] =3D map; + } + maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] =3D map; __maps__sort_by_name(maps); } out: - up_write(&maps->lock); + up_write(maps__lock(maps)); return err; } =20 static void __maps__remove(struct maps *maps, struct map_rb_node *rb_node) { - rb_erase_init(&rb_node->rb_node, &maps->entries); + rb_erase_init(&rb_node->rb_node, maps__entries(maps)); map__put(rb_node->map); free(rb_node); } @@ -117,7 +118,7 @@ void maps__remove(struct maps *maps, struct map *map) { struct map_rb_node *rb_node; =20 - down_write(&maps->lock); + down_write(maps__lock(maps)); if (maps->last_search_by_name =3D=3D map) maps->last_search_by_name =3D NULL; =20 @@ -125,9 +126,9 @@ void maps__remove(struct maps *maps, struct map *map) assert(rb_node->map =3D=3D map); __maps__remove(maps, rb_node); --maps->nr_maps; - if (maps->maps_by_name) + if (maps__maps_by_name(maps)) __maps__free_maps_by_name(maps); - up_write(&maps->lock); + up_write(maps__lock(maps)); } =20 static void __maps__purge(struct maps *maps) @@ -135,7 +136,7 @@ static void __maps__purge(struct maps *maps) struct map_rb_node *pos, *next; =20 maps__for_each_entry_safe(maps, pos, next) { - rb_erase_init(&pos->rb_node, &maps->entries); + rb_erase_init(&pos->rb_node, maps__entries(maps)); map__put(pos->map); free(pos); } @@ -143,9 +144,9 @@ static void __maps__purge(struct maps *maps) =20 static void maps__exit(struct maps *maps) { - down_write(&maps->lock); + down_write(maps__lock(maps)); __maps__purge(maps); - up_write(&maps->lock); + up_write(maps__lock(maps)); } =20 bool maps__empty(struct maps *maps) @@ -170,6 +171,14 @@ void maps__delete(struct maps *maps) free(maps); } =20 +struct maps *maps__get(struct maps *maps) +{ + if (maps) + refcount_inc(&maps->refcnt); + + return maps; +} + void maps__put(struct maps *maps) { if (maps && refcount_dec_and_test(&maps->refcnt)) @@ -195,7 +204,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *m= aps, const char *name, st struct symbol *sym; struct map_rb_node *pos; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 maps__for_each_entry(maps, pos) { sym =3D map__find_symbol_by_name(pos->map, name); @@ -213,7 +222,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *m= aps, const char *name, st =20 sym =3D NULL; out: - up_read(&maps->lock); + up_read(maps__lock(maps)); return sym; } =20 @@ -238,7 +247,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp) size_t printed =3D 0; struct map_rb_node *pos; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 maps__for_each_entry(maps, pos) { printed +=3D fprintf(fp, "Map:"); @@ -249,7 +258,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp) } } =20 - up_read(&maps->lock); + up_read(maps__lock(maps)); =20 return printed; } @@ -260,9 +269,9 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) struct rb_node *next, *first; int err =3D 0; =20 - down_write(&maps->lock); + down_write(maps__lock(maps)); =20 - root =3D &maps->entries; + root =3D maps__entries(maps); =20 /* * Find first map where end > map->start. @@ -358,7 +367,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) =20 err =3D 0; out: - up_write(&maps->lock); + up_write(maps__lock(maps)); return err; } =20 @@ -371,7 +380,7 @@ int maps__clone(struct thread *thread, struct maps *par= ent) int err; struct map_rb_node *rb_node; =20 - down_read(&parent->lock); + down_read(maps__lock(parent)); =20 maps__for_each_entry(parent, rb_node) { struct map *new =3D map__clone(rb_node->map); @@ -394,7 +403,7 @@ int maps__clone(struct thread *thread, struct maps *par= ent) =20 err =3D 0; out_unlock: - up_read(&parent->lock); + up_read(maps__lock(parent)); return err; } =20 @@ -415,9 +424,9 @@ struct map *maps__find(struct maps *maps, u64 ip) struct map_rb_node *m; =20 =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 - p =3D maps->entries.rb_node; + p =3D maps__entries(maps)->rb_node; while (p !=3D NULL) { m =3D rb_entry(p, struct map_rb_node, rb_node); if (ip < m->map->start) @@ -430,13 +439,13 @@ struct map *maps__find(struct maps *maps, u64 ip) =20 m =3D NULL; out: - up_read(&maps->lock); + up_read(maps__lock(maps)); return m ? m->map : NULL; } =20 struct map_rb_node *maps__first(struct maps *maps) { - struct rb_node *first =3D rb_first(&maps->entries); + struct rb_node *first =3D rb_first(maps__entries(maps)); =20 if (first) return rb_entry(first, struct map_rb_node, rb_node); diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index 512746ec0f9a..bde3390c7096 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -43,7 +43,7 @@ struct maps { unsigned int nr_maps_allocated; #ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space; - struct unwind_libunwind_ops *unwind_libunwind_ops; + const struct unwind_libunwind_ops *unwind_libunwind_ops; #endif }; =20 @@ -58,20 +58,51 @@ struct kmap { struct maps *maps__new(struct machine *machine); void maps__delete(struct maps *maps); bool maps__empty(struct maps *maps); +int maps__clone(struct thread *thread, struct maps *parent); + +struct maps *maps__get(struct maps *maps); +void maps__put(struct maps *maps); =20 -static inline struct maps *maps__get(struct maps *maps) +static inline struct rb_root *maps__entries(struct maps *maps) { - if (maps) - refcount_inc(&maps->refcnt); - return maps; + return &maps->entries; } =20 -void maps__put(struct maps *maps); -int maps__clone(struct thread *thread, struct maps *parent); +static inline struct machine *maps__machine(struct maps *maps) +{ + return maps->machine; +} + +static inline struct rw_semaphore *maps__lock(struct maps *maps) +{ + return &maps->lock; +} + +static inline struct map **maps__maps_by_name(struct maps *maps) +{ + return maps->maps_by_name; +} + +static inline unsigned int maps__nr_maps(const struct maps *maps) +{ + return maps->nr_maps; +} + +#ifdef HAVE_LIBUNWIND_SUPPORT +static inline void *maps__addr_space(struct maps *maps) +{ + return maps->addr_space; +} + +static inline const struct unwind_libunwind_ops *maps__unwind_libunwind_op= s(const struct maps *maps) +{ + return maps->unwind_libunwind_ops; +} +#endif + size_t maps__fprintf(struct maps *maps, FILE *fp); =20 int maps__insert(struct maps *maps, struct map *map); - void maps__remove(struct maps *maps, struct map *map); =20 struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map *= *mapp); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index 0f4ef61f2ffa..e5cc18f6fcda 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -1288,7 +1288,7 @@ static void python_export_sample_table(struct db_expo= rt *dbe, =20 tuple_set_d64(t, 0, es->db_id); tuple_set_d64(t, 1, es->evsel->db_id); - tuple_set_d64(t, 2, es->al->maps->machine->db_id); + tuple_set_d64(t, 2, maps__machine(es->al->maps)->db_id); tuple_set_d64(t, 3, es->al->thread->db_id); tuple_set_d64(t, 4, es->comm_db_id); tuple_set_d64(t, 5, es->dso_db_id); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 093a0c8b2e3d..e04d9bddba11 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -762,7 +762,7 @@ static int hist_entry__cgroup_snprintf(struct hist_entr= y *he, const char *cgrp_name =3D "N/A"; =20 if (he->cgroup) { - struct cgroup *cgrp =3D cgroup__find(he->ms.maps->machine->env, + struct cgroup *cgrp =3D cgroup__find(maps__machine(he->ms.maps)->env, he->cgroup); if (cgrp !=3D NULL) cgrp_name =3D cgrp->name; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 325fbeea8dff..ccdafc3971ac 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1422,7 +1422,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, * we still are sure to have a reference to this DSO via * *curr_map->dso. */ - dsos__add(&kmaps->machine->dsos, curr_dso); + dsos__add(&maps__machine(kmaps)->dsos, curr_dso); /* kmaps already got it */ map__put(curr_map); dso__set_loaded(curr_dso); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index d9aa41e20d5f..efd047bab373 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -275,7 +275,7 @@ void maps__fixup_end(struct maps *maps) { struct map_rb_node *prev =3D NULL, *curr; =20 - down_write(&maps->lock); + down_write(maps__lock(maps)); =20 maps__for_each_entry(maps, curr) { if (prev !=3D NULL && !prev->map->end) @@ -291,7 +291,7 @@ void maps__fixup_end(struct maps *maps) if (curr && !curr->map->end) curr->map->end =3D ~0ULL; =20 - up_write(&maps->lock); + up_write(maps__lock(maps)); } =20 struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const = char *name) @@ -844,7 +844,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, if (!kmaps) return -1; =20 - machine =3D kmaps->machine; + machine =3D maps__machine(kmaps); =20 x86_64 =3D machine__is(machine, "x86_64"); =20 @@ -968,7 +968,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, =20 if (curr_map !=3D initial_map && dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST && - machine__is_default_guest(kmaps->machine)) { + machine__is_default_guest(maps__machine(kmaps))) { dso__set_loaded(curr_map->dso); } =20 @@ -1365,7 +1365,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, if (!kmaps) return -EINVAL; =20 - machine =3D kmaps->machine; + machine =3D maps__machine(kmaps); =20 /* This function requires that the map is the kernel map */ if (!__map__is_kernel(map)) @@ -1892,7 +1892,7 @@ int dso__load(struct dso *dso, struct map *map) else if (dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST) ret =3D dso__load_guest_kernel_sym(dso, map); =20 - machine =3D map__kmaps(map)->machine; + machine =3D maps__machine(map__kmaps(map)); if (machine__is(machine, "x86_64")) machine__map_x86_64_entry_trampolines(machine, dso); goto out; @@ -2057,32 +2057,32 @@ static int map__strcmp_name(const void *name, const= void *b) =20 void __maps__sort_by_name(struct maps *maps) { - qsort(maps->maps_by_name, maps->nr_maps, sizeof(struct map *), map__strcm= p); + qsort(maps__maps_by_name(maps), maps__nr_maps(maps), sizeof(struct map *)= , map__strcmp); } =20 static int map__groups__sort_by_name_from_rbtree(struct maps *maps) { struct map_rb_node *rb_node; - struct map **maps_by_name =3D realloc(maps->maps_by_name, - maps->nr_maps * sizeof(struct map *)); + struct map **maps_by_name =3D realloc(maps__maps_by_name(maps), + maps__nr_maps(maps) * sizeof(struct map *)); int i =3D 0; =20 if (maps_by_name =3D=3D NULL) return -1; =20 - up_read(&maps->lock); - down_write(&maps->lock); + 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->nr_maps_allocated =3D maps__nr_maps(maps); =20 maps__for_each_entry(maps, rb_node) maps_by_name[i++] =3D rb_node->map; =20 __maps__sort_by_name(maps); =20 - up_write(&maps->lock); - down_read(&maps->lock); + up_write(maps__lock(maps)); + down_read(maps__lock(maps)); =20 return 0; } @@ -2091,11 +2091,12 @@ static struct map *__maps__find_by_name(struct maps= *maps, const char *name) { struct map **mapp; =20 - if (maps->maps_by_name =3D=3D NULL && + if (maps__maps_by_name(maps) =3D=3D NULL && map__groups__sort_by_name_from_rbtree(maps)) return NULL; =20 - mapp =3D bsearch(name, maps->maps_by_name, maps->nr_maps, sizeof(*mapp), = map__strcmp_name); + mapp =3D bsearch(name, maps__maps_by_name(maps), maps__nr_maps(maps), + sizeof(*mapp), map__strcmp_name); if (mapp) return *mapp; return NULL; @@ -2106,9 +2107,10 @@ struct map *maps__find_by_name(struct maps *maps, co= nst char *name) struct map_rb_node *rb_node; struct map *map; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 - if (maps->last_search_by_name && strcmp(maps->last_search_by_name->dso->s= hort_name, name) =3D=3D 0) { + if (maps->last_search_by_name && + strcmp(maps->last_search_by_name->dso->short_name, name) =3D=3D 0) { map =3D maps->last_search_by_name; goto out_unlock; } @@ -2118,7 +2120,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) * made. */ map =3D __maps__find_by_name(maps, name); - if (map || maps->maps_by_name !=3D NULL) + if (map || maps__maps_by_name(maps) !=3D NULL) goto out_unlock; =20 /* Fallback to traversing the rbtree... */ @@ -2132,7 +2134,7 @@ struct map *maps__find_by_name(struct maps *maps, con= st char *name) map =3D NULL; =20 out_unlock: - up_read(&maps->lock); + up_read(maps__lock(maps)); return map; } =20 @@ -2384,7 +2386,7 @@ static int dso__load_guest_kernel_sym(struct dso *dso= , struct map *map) { int err; const char *kallsyms_filename; - struct machine *machine =3D map__kmaps(map)->machine; + struct machine *machine =3D maps__machine(map__kmaps(map)); char path[PATH_MAX]; =20 if (machine->kallsyms_filename) { diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index 1b992bbba4e8..4b85c1728012 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c @@ -155,8 +155,8 @@ static int thread_stack__init(struct thread_stack *ts, = struct thread *thread, ts->br_stack_sz =3D br_stack_sz; } =20 - if (thread->maps && thread->maps->machine) { - struct machine *machine =3D thread->maps->machine; + if (thread->maps && maps__machine(thread->maps)) { + struct machine *machine =3D maps__machine(thread->maps); const char *arch =3D perf_env__arch(machine->env); =20 ts->kernel_start =3D machine__kernel_start(machine); diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 24e53bd55f7d..292585a52281 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -362,7 +362,7 @@ static int __thread__prepare_access(struct thread *thre= ad) struct maps *maps =3D thread->maps; struct map_rb_node *rb_node; =20 - down_read(&maps->lock); + down_read(maps__lock(maps)); =20 maps__for_each_entry(maps, rb_node) { err =3D unwind__prepare_access(thread->maps, rb_node->map, &initialized); @@ -370,7 +370,7 @@ static int __thread__prepare_access(struct thread *thre= ad) break; } =20 - up_read(&maps->lock); + up_read(maps__lock(maps)); =20 return err; } diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unw= ind-libunwind-local.c index 81b6bd6e1536..952c5ee66fe7 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -665,24 +665,26 @@ static unw_accessors_t accessors =3D { =20 static int _unwind__prepare_access(struct maps *maps) { - maps->addr_space =3D unw_create_addr_space(&accessors, 0); - if (!maps->addr_space) { + void *addr_space =3D unw_create_addr_space(&accessors, 0); + + maps->addr_space =3D addr_space; + if (!addr_space) { pr_err("unwind: Can't create unwind address space.\n"); return -ENOMEM; } =20 - unw_set_caching_policy(maps->addr_space, UNW_CACHE_GLOBAL); + unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL); return 0; } =20 static void _unwind__flush_access(struct maps *maps) { - unw_flush_cache(maps->addr_space, 0, 0); + unw_flush_cache(maps__addr_space(maps), 0, 0); } =20 static void _unwind__finish_access(struct maps *maps) { - unw_destroy_addr_space(maps->addr_space); + unw_destroy_addr_space(maps__addr_space(maps)); } =20 static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, @@ -707,7 +709,7 @@ static int get_entries(struct unwind_info *ui, unwind_e= ntry_cb_t cb, */ if (max_stack - 1 > 0) { WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL"); - addr_space =3D ui->thread->maps->addr_space; + addr_space =3D maps__addr_space(ui->thread->maps); =20 if (addr_space =3D=3D NULL) return -1; @@ -757,7 +759,7 @@ static int _unwind__get_entries(unwind_entry_cb_t cb, v= oid *arg, struct unwind_info ui =3D { .sample =3D data, .thread =3D thread, - .machine =3D thread->maps->machine, + .machine =3D maps__machine(thread->maps), .best_effort =3D best_effort }; =20 diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-li= bunwind.c index 509c287ee762..c14f04082377 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -22,12 +22,13 @@ int unwind__prepare_access(struct maps *maps, struct ma= p *map, bool *initialized const char *arch; enum dso_type dso_type; struct unwind_libunwind_ops *ops =3D local_unwind_libunwind_ops; + struct machine *machine; int err; =20 if (!dwarf_callchain_users) return 0; =20 - if (maps->addr_space) { + if (maps__addr_space(maps)) { pr_debug("unwind: thread map already set, dso=3D%s\n", map->dso->name); if (initialized) @@ -35,15 +36,16 @@ int unwind__prepare_access(struct maps *maps, struct ma= p *map, bool *initialized return 0; } =20 + machine =3D maps__machine(maps); /* env->arch is NULL for live-mode (i.e. perf top) */ - if (!maps->machine->env || !maps->machine->env->arch) + if (!machine->env || !machine->env->arch) goto out_register; =20 - dso_type =3D dso__type(map->dso, maps->machine); + dso_type =3D dso__type(map->dso, machine); if (dso_type =3D=3D DSO__TYPE_UNKNOWN) return 0; =20 - arch =3D perf_env__arch(maps->machine->env); + arch =3D perf_env__arch(machine->env); =20 if (!strcmp(arch, "x86")) { if (dso_type !=3D DSO__TYPE_64BIT) @@ -60,7 +62,7 @@ int unwind__prepare_access(struct maps *maps, struct map = *map, bool *initialized out_register: unwind__register_ops(maps, ops); =20 - err =3D maps->unwind_libunwind_ops->prepare_access(maps); + err =3D maps__unwind_libunwind_ops(maps)->prepare_access(maps); if (initialized) *initialized =3D err ? false : true; return err; @@ -68,14 +70,18 @@ int unwind__prepare_access(struct maps *maps, struct ma= p *map, bool *initialized =20 void unwind__flush_access(struct maps *maps) { - if (maps->unwind_libunwind_ops) - maps->unwind_libunwind_ops->flush_access(maps); + const struct unwind_libunwind_ops *ops =3D maps__unwind_libunwind_ops(map= s); + + if (ops) + ops->flush_access(maps); } =20 void unwind__finish_access(struct maps *maps) { - if (maps->unwind_libunwind_ops) - maps->unwind_libunwind_ops->finish_access(maps); + const struct unwind_libunwind_ops *ops =3D maps__unwind_libunwind_ops(map= s); + + if (ops) + ops->finish_access(maps); } =20 int unwind__get_entries(unwind_entry_cb_t cb, void *arg, @@ -83,8 +89,9 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct perf_sample *data, int max_stack, bool best_effort) { - if (thread->maps->unwind_libunwind_ops) - return thread->maps->unwind_libunwind_ops->get_entries(cb, arg, thread, = data, - max_stack, best_effort); + const struct unwind_libunwind_ops *ops =3D maps__unwind_libunwind_ops(thr= ead->maps); + + if (ops) + return ops->get_entries(cb, arg, thread, data, max_stack); return 0; } --=20 2.40.0.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 A379FC6FD1C for ; Mon, 20 Mar 2023 21:24:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230072AbjCTVYW (ORCPT ); Mon, 20 Mar 2023 17:24:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230193AbjCTVYG (ORCPT ); Mon, 20 Mar 2023 17:24:06 -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 C32027D8E for ; Mon, 20 Mar 2023 14:23:34 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-536a4eba107so135456317b3.19 for ; Mon, 20 Mar 2023 14:23:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347412; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=sCPsVarVbCCpTaNQyEy/KRjlDglBfjSGr3AOUxgUf4c=; b=tOVAKSqbxj9z9O9MP4/376ahvhcVUDV9mErh+W9STA4pJYWSpWL3Ok0Uu/AIkRFxbK Y485AgfUCelZMnmegMhgPZI5/8ULRqyasCCUETSPfnlgjG6lvlF2hQbhWgRjueIYEaJb hRqoOrEWiwppBOA+6k9XzDxvtPyVdYwX1i+CakNE2KlvW/9Doyq4nowJnZyrNESOns90 lSAgPe/f27Z6pDIOykZO9apwneiin+ozhuc4+ZWfK8PQhyQEJJ/muw8J8nF+yOPP6GhW t21V/Jn1kSnQ0pO5pomsYOoT9IgW4wKwt2ofh0VsfKrI6FBFABButsrOOih71k3ORT6q 27Mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347412; 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=sCPsVarVbCCpTaNQyEy/KRjlDglBfjSGr3AOUxgUf4c=; b=h278G9qo/0VCnwi2avKpsiyUEv6tUKEI4GavZdHmZj5LG57czdx68A8+kOgIJbsej3 4TDb1DyoY9ThG84ut+k8ucXiO7E/9rJdEoe0KfVf5kTFHFU52QIxuFKcdYSr+T4vdthN mblCKUk8Zk4YxLFiht7z/Zh6u7JAu5NcQ5aTKnqwqt7nwpRVJDdAGcl70vogcbcTXyqn L4H5wB0Ugo0yMp0oPZ63o9q0LmOBQu0SPbsSDdMcxsZDHx9btLVS+0YweO/L8sN4r0K1 WIcTHuoTJAvuxR7nX1BJ6btv6chhGTW9wZZkuiCnjpqrbFjCebU6PoCUvFlx5rWLdzja BqCQ== X-Gm-Message-State: AO0yUKUda8smUKyjJPfbUdf0J62+5hfk7/ty2tGsHBVUFtTx3l6om51m xUF948WkrhZPxGGe6obak/OtCa/+5MTW X-Google-Smtp-Source: AK7set+P0DcGW9BbPtSbZnffnWchgFZ6x/ekRsq9ca6oiSdzlHSm+w//+BbtYhvvLABmbTCm7lbExUwOkD/Q X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a81:431b:0:b0:544:94fe:4244 with SMTP id q27-20020a81431b000000b0054494fe4244mr11170099ywa.10.1679347412727; Mon, 20 Mar 2023 14:23:32 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:35 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-5-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 04/17] perf map: Add accessor for dso 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, with dso being the most frequently accessed variable. Add an accessor so that the reference count check is only necessary in one place. Additional changes: - add a dso variable to avoid repeated map__dso calls. - in builtin-mem.c dump_raw_samples, code only partially tested for dso =3D=3D NULL. Make the possibility of NULL consistent. - in thread.c thread__memcpy fix use of spaces and use tabs. Signed-off-by: Ian Rogers --- tools/perf/builtin-annotate.c | 11 ++- tools/perf/builtin-buildid-list.c | 2 +- tools/perf/builtin-inject.c | 8 +- tools/perf/builtin-kallsyms.c | 4 +- tools/perf/builtin-mem.c | 10 +- tools/perf/builtin-report.c | 7 +- tools/perf/builtin-script.c | 19 ++-- tools/perf/builtin-top.c | 11 ++- tools/perf/builtin-trace.c | 2 +- .../scripts/python/Perf-Trace-Util/Context.c | 6 +- tools/perf/tests/code-reading.c | 28 +++--- tools/perf/tests/hists_common.c | 8 +- tools/perf/tests/hists_cumulate.c | 4 +- tools/perf/tests/hists_filter.c | 4 +- tools/perf/tests/hists_output.c | 2 +- tools/perf/tests/maps.c | 2 +- tools/perf/tests/symbols.c | 6 +- tools/perf/tests/vmlinux-kallsyms.c | 13 ++- tools/perf/ui/browsers/annotate.c | 9 +- tools/perf/ui/browsers/hists.c | 16 ++-- tools/perf/ui/browsers/map.c | 4 +- tools/perf/util/annotate.c | 16 ++-- tools/perf/util/auxtrace.c | 2 +- tools/perf/util/block-info.c | 4 +- tools/perf/util/bpf-event.c | 10 +- tools/perf/util/build-id.c | 2 +- tools/perf/util/callchain.c | 6 +- tools/perf/util/data-convert-json.c | 10 +- tools/perf/util/db-export.c | 4 +- tools/perf/util/dlfilter.c | 10 +- tools/perf/util/event.c | 9 +- tools/perf/util/evsel_fprintf.c | 2 +- tools/perf/util/hist.c | 10 +- tools/perf/util/intel-pt.c | 45 +++++---- tools/perf/util/machine.c | 70 ++++++++------ tools/perf/util/map.c | 96 ++++++++++++------- tools/perf/util/map.h | 7 +- tools/perf/util/maps.c | 7 +- tools/perf/util/probe-event.c | 30 +++--- .../util/scripting-engines/trace-event-perl.c | 10 +- .../scripting-engines/trace-event-python.c | 16 ++-- tools/perf/util/sort.c | 49 +++++----- tools/perf/util/symbol-elf.c | 2 +- tools/perf/util/symbol.c | 55 +++++++---- tools/perf/util/synthetic-events.c | 12 +-- tools/perf/util/thread.c | 25 +++-- tools/perf/util/unwind-libdw.c | 10 +- tools/perf/util/vdso.c | 2 +- 48 files changed, 404 insertions(+), 293 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 4750fac7bf93..9e220159e320 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -205,7 +205,7 @@ static int process_branch_callback(struct evsel *evsel, return 0; =20 if (a.map !=3D NULL) - a.map->dso->hit =3D 1; + map__dso(a.map)->hit =3D 1; =20 hist__account_cycles(sample->branch_stack, al, sample, false, NULL); =20 @@ -235,10 +235,11 @@ static int evsel__add_sample(struct evsel *evsel, str= uct perf_sample *sample, * the DSO? */ if (al->sym !=3D NULL) { - rb_erase_cached(&al->sym->rb_node, - &al->map->dso->symbols); + struct dso *dso =3D map__dso(al->map); + + rb_erase_cached(&al->sym->rb_node, &dso->symbols); symbol__delete(al->sym); - dso__reset_find_symbol_cache(al->map->dso); + dso__reset_find_symbol_cache(dso); } return 0; } @@ -320,7 +321,7 @@ static void hists__find_annotations(struct hists *hists, struct hist_entry *he =3D rb_entry(nd, struct hist_entry, rb_node); struct annotation *notes; =20 - if (he->ms.sym =3D=3D NULL || he->ms.map->dso->annotate_warned) + if (he->ms.sym =3D=3D NULL || map__dso(he->ms.map)->annotate_warned) goto find_next; =20 if (ann->sym_hist_filter && diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid= -list.c index 00bfe89f0b5d..cad9ed44ce7c 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -24,7 +24,7 @@ =20 static int buildid__map_cb(struct map *map, void *arg __maybe_unused) { - const struct dso *dso =3D map->dso; + const struct dso *dso =3D map__dso(map); char bid_buf[SBUILD_ID_SIZE]; =20 memset(bid_buf, 0, sizeof(bid_buf)); diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 10bb1d494258..8f6909dd8a54 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -753,9 +753,11 @@ int perf_event__inject_buildid(struct perf_tool *tool,= union perf_event *event, } =20 if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) { - if (!al.map->dso->hit) { - al.map->dso->hit =3D 1; - dso__inject_build_id(al.map->dso, tool, machine, + struct dso *dso =3D map__dso(al.map); + + if (!dso->hit) { + dso->hit =3D 1; + dso__inject_build_id(dso, tool, machine, sample->cpumode, al.map->flags); } } diff --git a/tools/perf/builtin-kallsyms.c b/tools/perf/builtin-kallsyms.c index c08ee81529e8..5638ca4dbd8e 100644 --- a/tools/perf/builtin-kallsyms.c +++ b/tools/perf/builtin-kallsyms.c @@ -28,6 +28,7 @@ static int __cmd_kallsyms(int argc, const char **argv) =20 for (i =3D 0; i < argc; ++i) { struct map *map; + const struct dso *dso; struct symbol *symbol =3D machine__find_kernel_symbol_by_name(machine, a= rgv[i], &map); =20 if (symbol =3D=3D NULL) { @@ -35,8 +36,9 @@ static int __cmd_kallsyms(int argc, const char **argv) continue; } =20 + dso =3D map__dso(map); printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n= ", - symbol->name, map->dso->short_name, map->dso->long_name, + symbol->name, dso->short_name, dso->long_name, map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end), symbol->start, symbol->end); } diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index dedd612eae5e..1e27188b0de1 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -200,6 +200,7 @@ dump_raw_samples(struct perf_tool *tool, struct addr_location al; const char *fmt, *field_sep; char str[PAGE_SIZE_NAME_LEN]; + struct dso *dso =3D NULL; =20 if (machine__resolve(machine, &al, sample) < 0) { fprintf(stderr, "problem processing %d event, skipping it.\n", @@ -210,8 +211,11 @@ dump_raw_samples(struct perf_tool *tool, if (al.filtered || (mem->hide_unresolved && al.sym =3D=3D NULL)) goto out_put; =20 - if (al.map !=3D NULL) - al.map->dso->hit =3D 1; + if (al.map !=3D NULL) { + dso =3D map__dso(al.map); + if (dso) + dso->hit =3D 1; + } =20 field_sep =3D symbol_conf.field_sep; if (field_sep) { @@ -252,7 +256,7 @@ dump_raw_samples(struct perf_tool *tool, symbol_conf.field_sep, sample->data_src, symbol_conf.field_sep, - al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", + dso ? dso->long_name : "???", al.sym ? al.sym->name : "???"); out_put: addr_location__put(&al); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c453b7fa7418..02ca87c13e91 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -314,7 +314,7 @@ static int process_sample_event(struct perf_tool *tool, } =20 if (al.map !=3D NULL) - al.map->dso->hit =3D 1; + map__dso(al.map)->hit =3D 1; =20 if (ui__has_annotation() || rep->symbol_ipc || rep->total_cycles_mode) { hist__account_cycles(sample->branch_stack, &al, sample, @@ -603,7 +603,7 @@ static void report__warn_kptr_restrict(const struct rep= ort *rep) return; =20 if (kernel_map =3D=3D NULL || - (kernel_map->dso->hit && + (map__dso(kernel_map)->hit && (kernel_kmap->ref_reloc_sym =3D=3D NULL || kernel_kmap->ref_reloc_sym->addr =3D=3D 0))) { const char *desc =3D @@ -844,6 +844,7 @@ static size_t maps__fprintf_task(struct maps *maps, int= indent, FILE *fp) =20 maps__for_each_entry(maps, rb_node) { struct map *map =3D rb_node->map; + const struct dso *dso =3D map__dso(map); =20 printed +=3D fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRI= x64 " %" PRIu64 " %s\n", indent, "", map->start, map->end, @@ -852,7 +853,7 @@ static size_t maps__fprintf_task(struct maps *maps, int= indent, FILE *fp) map->prot & PROT_EXEC ? 'x' : '-', map->flags & MAP_SHARED ? 's' : 'p', map->pgoff, - map->dso->id.ino, map->dso->name); + dso->id.ino, dso->name); } =20 return printed; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 976f8bfe099c..9c7eb900ff7c 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1011,11 +1011,11 @@ static int perf_sample__fprintf_brstackoff(struct p= erf_sample *sample, to =3D entries[i].to; =20 if (thread__find_map_fb(thread, sample->cpumode, from, &alf) && - !alf.map->dso->adjust_symbols) + !map__dso(alf.map)->adjust_symbols) from =3D map__map_ip(alf.map, from); =20 if (thread__find_map_fb(thread, sample->cpumode, to, &alt) && - !alt.map->dso->adjust_symbols) + !map__dso(alt.map)->adjust_symbols) to =3D map__map_ip(alt.map, to); =20 printed +=3D fprintf(fp, " 0x%"PRIx64, from); @@ -1044,6 +1044,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, long offset, len; struct addr_location al; bool kernel; + struct dso *dso; =20 if (!start || !end) return 0; @@ -1074,11 +1075,12 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, return 0; } =20 - if (!thread__find_map(thread, *cpumode, start, &al) || !al.map->dso) { + dso =3D map__dso(al.map); + if (!thread__find_map(thread, *cpumode, start, &al) || !dso) { pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); return 0; } - if (al.map->dso->data.status =3D=3D DSO_DATA_STATUS_ERROR) { + if (dso->data.status =3D=3D DSO_DATA_STATUS_ERROR) { pr_debug("\tcannot resolve %" PRIx64 "-%" PRIx64 "\n", start, end); return 0; } @@ -1087,10 +1089,10 @@ static int grab_bb(u8 *buffer, u64 start, u64 end, map__load(al.map); =20 offset =3D al.map->map_ip(al.map, start); - len =3D dso__data_read_offset(al.map->dso, machine, offset, (u8 *)buffer, + len =3D dso__data_read_offset(dso, machine, offset, (u8 *)buffer, end - start + MAXINSN); =20 - *is64bit =3D al.map->dso->is_64_bit; + *is64bit =3D dso->is_64_bit; if (len <=3D 0) pr_debug("\tcannot fetch code for block at %" PRIx64 "-%" PRIx64 "\n", start, end); @@ -1104,10 +1106,11 @@ static int map__fprintf_srccode(struct map *map, u6= 4 addr, FILE *fp, struct srcc unsigned line; int len; char *srccode; + struct dso *dso =3D map__dso(map); =20 - if (!map || !map->dso) + if (!map || !dso) return 0; - srcfile =3D get_srcline_split(map->dso, + srcfile =3D get_srcline_split(dso, map__rip_2objdump(map, addr), &line); if (!srcfile) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index d4b5b02bab73..5010eee8fbae 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -114,6 +114,7 @@ static int perf_top__parse_source(struct perf_top *top,= struct hist_entry *he) struct symbol *sym; struct annotation *notes; struct map *map; + struct dso *dso; int err =3D -1; =20 if (!he || !he->ms.sym) @@ -123,12 +124,12 @@ static int perf_top__parse_source(struct perf_top *to= p, struct hist_entry *he) =20 sym =3D he->ms.sym; map =3D he->ms.map; + dso =3D map__dso(map); =20 /* * We can't annotate with just /proc/kallsyms */ - if (map->dso->symtab_type =3D=3D DSO_BINARY_TYPE__KALLSYMS && - !dso__is_kcore(map->dso)) { + if (dso->symtab_type =3D=3D DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(d= so)) { pr_err("Can't annotate %s: No vmlinux file was found in the " "path\n", sym->name); sleep(1); @@ -169,6 +170,7 @@ static void ui__warn_map_erange(struct map *map, struct= symbol *sym, u64 ip) { struct utsname uts; int err =3D uname(&uts); + struct dso *dso =3D map__dso(map); =20 ui__warning("Out of bounds address found:\n\n" "Addr: %" PRIx64 "\n" @@ -180,7 +182,7 @@ static void ui__warn_map_erange(struct map *map, struct= symbol *sym, u64 ip) "Tools: %s\n\n" "Not all samples will be on the annotation output.\n\n" "Please report to linux-kernel@vger.kernel.org\n", - ip, map->dso->long_name, dso__symtab_origin(map->dso), + ip, dso->long_name, dso__symtab_origin(dso), map->start, map->end, sym->start, sym->end, sym->binding =3D=3D STB_GLOBAL ? 'g' : sym->binding =3D=3D STB_LOCAL ? 'l' : 'w', sym->name, @@ -810,7 +812,8 @@ static void perf_event__process_sample(struct perf_tool= *tool, __map__is_kernel(al.map) && map__has_symbols(al.map)) { if (symbol_conf.vmlinux_name) { char serr[256]; - dso__strerror_load(al.map->dso, serr, sizeof(serr)); + + dso__strerror_load(map__dso(al.map), serr, sizeof(serr)); ui__warning("The %s file can't be used: %s\n%s", symbol_conf.vmlinux_name, serr, msg); } else { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index b363c609818b..72ef0bebb06b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2863,7 +2863,7 @@ static void print_location(FILE *f, struct perf_sampl= e *sample, { =20 if ((verbose > 0 || print_dso) && al->map) - fprintf(f, "%s@", al->map->dso->long_name); + fprintf(f, "%s@", map__dso(al->map)->long_name); =20 if ((verbose > 0 || print_sym) && al->sym) fprintf(f, "%s+0x%" PRIx64, al->sym->name, diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/pe= rf/scripts/python/Perf-Trace-Util/Context.c index feedd02b3b3d..53b1587db403 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c @@ -145,6 +145,7 @@ static PyObject *perf_sample_src(PyObject *obj, PyObjec= t *args, bool get_srccode char *srccode =3D NULL; PyObject *result; struct map *map; + struct dso *dso; int len =3D 0; u64 addr; =20 @@ -153,9 +154,10 @@ static PyObject *perf_sample_src(PyObject *obj, PyObje= ct *args, bool get_srccode =20 map =3D c->al->map; addr =3D c->al->addr; + dso =3D map ? map__dso(map) : NULL; =20 - if (map && map->dso) - srcfile =3D get_srcline_split(map->dso, map__rip_2objdump(map, addr), &l= ine); + if (dso) + srcfile =3D get_srcline_split(dso, map__rip_2objdump(map, addr), &line); =20 if (get_srccode) { if (srcfile) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index 8d2036f2f944..936c61546e64 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -237,10 +237,11 @@ static int read_object_code(u64 addr, size_t len, u8 = cpumode, char decomp_name[KMOD_DECOMP_LEN]; bool decomp =3D false; int ret, err =3D 0; + struct dso *dso; =20 pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); =20 - if (!thread__find_map(thread, cpumode, addr, &al) || !al.map->dso) { + if (!thread__find_map(thread, cpumode, addr, &al) || !map__dso(al.map)) { if (cpumode =3D=3D PERF_RECORD_MISC_HYPERVISOR) { pr_debug("Hypervisor address can not be resolved - skipping\n"); goto out; @@ -250,11 +251,10 @@ static int read_object_code(u64 addr, size_t len, u8 = cpumode, err =3D -1; goto out; } + dso =3D map__dso(al.map); + pr_debug("File is: %s\n", dso->long_name); =20 - pr_debug("File is: %s\n", al.map->dso->long_name); - - if (al.map->dso->symtab_type =3D=3D DSO_BINARY_TYPE__KALLSYMS && - !dso__is_kcore(al.map->dso)) { + if (dso->symtab_type =3D=3D DSO_BINARY_TYPE__KALLSYMS && !dso__is_kcore(d= so)) { pr_debug("Unexpected kernel address - skipping\n"); goto out; } @@ -269,7 +269,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, len =3D al.map->end - addr; =20 /* Read the object code using perf */ - ret_len =3D dso__data_read_offset(al.map->dso, maps__machine(thread->maps= ), + ret_len =3D dso__data_read_offset(dso, maps__machine(thread->maps), al.addr, buf1, len); if (ret_len !=3D len) { pr_debug("dso__data_read_offset failed\n"); @@ -287,7 +287,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, } =20 /* objdump struggles with kcore - try each map only once */ - if (dso__is_kcore(al.map->dso)) { + if (dso__is_kcore(dso)) { size_t d; =20 for (d =3D 0; d < state->done_cnt; d++) { @@ -304,9 +304,9 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, state->done[state->done_cnt++] =3D al.map->start; } =20 - objdump_name =3D al.map->dso->long_name; - if (dso__needs_decompress(al.map->dso)) { - if (dso__decompress_kmodule_path(al.map->dso, objdump_name, + objdump_name =3D dso->long_name; + if (dso__needs_decompress(dso)) { + if (dso__decompress_kmodule_path(dso, objdump_name, decomp_name, sizeof(decomp_name)) < 0) { pr_debug("decompression failed\n"); @@ -335,7 +335,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, len -=3D ret; if (len) { pr_debug("Reducing len to %zu\n", len); - } else if (dso__is_kcore(al.map->dso)) { + } else if (dso__is_kcore(dso)) { /* * objdump cannot handle very large segments * that may be found in kcore. @@ -572,6 +572,7 @@ static int do_test_code_reading(bool try_kcore) pid_t pid; struct map *map; bool have_vmlinux, have_kcore, excl_kernel =3D false; + struct dso *dso; =20 pid =3D getpid(); =20 @@ -595,8 +596,9 @@ static int do_test_code_reading(bool try_kcore) pr_debug("map__load failed\n"); goto out_err; } - have_vmlinux =3D dso__is_vmlinux(map->dso); - have_kcore =3D dso__is_kcore(map->dso); + dso =3D map__dso(map); + have_vmlinux =3D dso__is_vmlinux(dso); + have_kcore =3D dso__is_kcore(dso); =20 /* 2nd time through we just try kcore */ if (try_kcore && !have_kcore) diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_commo= n.c index 6f34d08b84e5..745ab18d17db 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -179,9 +179,11 @@ void print_hists_in(struct hists *hists) he =3D rb_entry(node, struct hist_entry, rb_node_in); =20 if (!he->filtered) { + struct dso *dso =3D map__dso(he->ms.map); + pr_info("%2d: entry: %-8s [%-8s] %20s: period =3D %"PRIu64"\n", i, thread__comm_str(he->thread), - he->ms.map->dso->short_name, + dso->short_name, he->ms.sym->name, he->stat.period); } =20 @@ -206,9 +208,11 @@ void print_hists_out(struct hists *hists) he =3D rb_entry(node, struct hist_entry, rb_node); =20 if (!he->filtered) { + struct dso *dso =3D map__dso(he->ms.map); + pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period =3D %"PRIu64"/%"PRIu64= "\n", i, thread__comm_str(he->thread), he->thread->tid, - he->ms.map->dso->short_name, + dso->short_name, he->ms.sym->name, he->stat.period, he->stat_acc ? he->stat_acc->period : 0); } diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cum= ulate.c index b42d37ff2399..f00ec9abdbcd 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -150,12 +150,12 @@ static void del_hist_entries(struct hists *hists) typedef int (*test_fn_t)(struct evsel *, struct machine *); =20 #define COMM(he) (thread__comm_str(he->thread)) -#define DSO(he) (he->ms.map->dso->short_name) +#define DSO(he) (map__dso(he->ms.map)->short_name) #define SYM(he) (he->ms.sym->name) #define CPU(he) (he->cpu) #define PID(he) (he->thread->tid) #define DEPTH(he) (he->callchain->max_depth) -#define CDSO(cl) (cl->ms.map->dso->short_name) +#define CDSO(cl) (map__dso(cl->ms.map)->short_name) #define CSYM(cl) (cl->ms.sym->name) =20 struct result { diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filte= r.c index 8e1ceeb9b7b6..7c552549f4a4 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -194,7 +194,7 @@ static int test__hists_filter(struct test_suite *test _= _maybe_unused, int subtes hists__filter_by_thread(hists); =20 /* now applying dso filter for 'kernel' */ - hists->dso_filter =3D fake_samples[0].map->dso; + hists->dso_filter =3D map__dso(fake_samples[0].map); hists__filter_by_dso(hists); =20 if (verbose > 2) { @@ -288,7 +288,7 @@ static int test__hists_filter(struct test_suite *test _= _maybe_unused, int subtes =20 /* now applying all filters at once. */ hists->thread_filter =3D fake_samples[1].thread; - hists->dso_filter =3D fake_samples[1].map->dso; + hists->dso_filter =3D map__dso(fake_samples[1].map); hists__filter_by_thread(hists); hists__filter_by_dso(hists); =20 diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_outpu= t.c index 62b0093253e3..428d11a938f2 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -116,7 +116,7 @@ static void del_hist_entries(struct hists *hists) typedef int (*test_fn_t)(struct evsel *, struct machine *); =20 #define COMM(he) (thread__comm_str(he->thread)) -#define DSO(he) (he->ms.map->dso->short_name) +#define DSO(he) (map__dso(he->ms.map)->short_name) #define SYM(he) (he->ms.sym->name) #define CPU(he) (he->cpu) #define PID(he) (he->thread->tid) diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index 8246d37e4b7a..ae7028fbf79e 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -26,7 +26,7 @@ static int check_maps(struct map_def *merged, unsigned in= t size, struct maps *ma =20 TEST_ASSERT_VAL("wrong map start", map->start =3D=3D merged[i].start); TEST_ASSERT_VAL("wrong map end", map->end =3D=3D merged[i].end); - TEST_ASSERT_VAL("wrong map name", !strcmp(map->dso->name, merged[i].nam= e)); + 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= ); =20 i++; diff --git a/tools/perf/tests/symbols.c b/tools/perf/tests/symbols.c index 0793f8f419e2..2d1aa42d36a9 100644 --- a/tools/perf/tests/symbols.c +++ b/tools/perf/tests/symbols.c @@ -102,6 +102,7 @@ static int test_file(struct test_info *ti, char *filena= me) { struct map *map =3D NULL; int ret, nr; + struct dso *dso; =20 pr_debug("Testing %s\n", filename); =20 @@ -109,7 +110,8 @@ static int test_file(struct test_info *ti, char *filena= me) if (ret !=3D TEST_OK) return ret; =20 - nr =3D dso__load(map->dso, map); + dso =3D map__dso(map); + nr =3D dso__load(dso, map); if (nr < 0) { pr_debug("dso__load() failed!\n"); ret =3D TEST_FAIL; @@ -122,7 +124,7 @@ static int test_file(struct test_info *ti, char *filena= me) goto out_put; } =20 - ret =3D test_dso(map->dso); + ret =3D test_dso(dso); out_put: map__put(map); =20 diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index c8abb3ca8347..c614c2db7e89 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -293,15 +293,16 @@ static int test__vmlinux_matches_kallsyms(struct test= _suite *test __maybe_unused =20 maps__for_each_entry(maps, rb_node) { struct map *map =3D rb_node->map; + struct dso *dso =3D map__dso(map); /* * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while * the kernel will have the path for the vmlinux file being used, * so use the short name, less descriptive but the same ("[kernel]" in * both cases. */ - struct map *pair =3D maps__find_by_name(kallsyms.kmaps, (map->dso->kerne= l ? - map->dso->short_name : - map->dso->name)); + struct map *pair =3D maps__find_by_name(kallsyms.kmaps, (dso->kernel ? + dso->short_name : + dso->name)); if (pair) { pair->priv =3D 1; } else { @@ -326,17 +327,19 @@ static int test__vmlinux_matches_kallsyms(struct test= _suite *test __maybe_unused continue; =20 if (pair->start =3D=3D mem_start) { + struct dso *dso =3D map__dso(map); + if (!header_printed) { pr_info("WARN: Maps in vmlinux with a different name in kallsyms:\n"); header_printed =3D true; } =20 pr_info("WARN: %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - map->start, map->end, map->pgoff, map->dso->name); + map->start, map->end, map->pgoff, dso->name); if (mem_end !=3D pair->end) pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, pair->start, pair->end, pair->pgoff); - pr_info(" %s\n", pair->dso->name); + pr_info(" %s\n", dso->name); pair->priv =3D 1; } } diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/ann= otate.c index c03fa76c02ff..12c3ce530e42 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -441,7 +441,8 @@ static void ui_browser__init_asm_mode(struct ui_browser= *browser) static int sym_title(struct symbol *sym, struct map *map, char *title, size_t sz, int percent_type) { - return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, map->dso->l= ong_name, + return snprintf(title, sz, "%s %s [Percent: %s]", sym->name, + map__dso(map)->long_name, percent_type_str(percent_type)); } =20 @@ -964,20 +965,22 @@ int symbol__tui_annotate(struct map_symbol *ms, struc= t evsel *evsel, }, .opts =3D opts, }; + struct dso *dso; int ret =3D -1, err; int not_annotated =3D list_empty(¬es->src->source); =20 if (sym =3D=3D NULL) return -1; =20 - if (ms->map->dso->annotate_warned) + dso =3D map__dso(ms->map); + if (dso->annotate_warned) return -1; =20 if (not_annotated) { err =3D symbol__annotate2(ms, evsel, opts, &browser.arch); if (err) { char msg[BUFSIZ]; - ms->map->dso->annotate_warned =3D true; + dso->annotate_warned =3D true; symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s:\n%s", sym->name, msg); goto out_free_offsets; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 572ff38ceb0f..66d8c0802ecd 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2487,7 +2487,7 @@ static struct symbol *symbol__new_unresolved(u64 addr= , struct map *map) return NULL; } =20 - dso__insert_symbol(map->dso, sym); + dso__insert_symbol(map__dso(map), sym); } =20 return sym; @@ -2499,7 +2499,7 @@ add_annotate_opt(struct hist_browser *browser __maybe= _unused, struct map_symbol *ms, u64 addr) { - if (!ms->map || !ms->map->dso || ms->map->dso->annotate_warned) + if (!ms->map || !map__dso(ms->map) || map__dso(ms->map)->annotate_warned) return 0; =20 if (!ms->sym) @@ -2590,8 +2590,10 @@ static int hists_browser__zoom_map(struct hist_brows= er *browser, struct map *map ui_helpline__pop(); } else { ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DS= O\"", - __map__is_kernel(map) ? "the Kernel" : map->dso->short_name); - browser->hists->dso_filter =3D map->dso; + __map__is_kernel(map) + ? "the Kernel" + : map__dso(map)->short_name); + browser->hists->dso_filter =3D map__dso(map); perf_hpp__set_elide(HISTC_DSO, true); pstack__push(browser->pstack, &browser->hists->dso_filter); } @@ -2616,7 +2618,7 @@ add_dso_opt(struct hist_browser *browser, struct popu= p_action *act, =20 if (asprintf(optstr, "Zoom %s %s DSO (use the 'k' hotkey to zoom directly= into the kernel)", browser->hists->dso_filter ? "out of" : "into", - __map__is_kernel(map) ? "the Kernel" : map->dso->short_name) < 0) + __map__is_kernel(map) ? "the Kernel" : map__dso(map)->short_name) <= 0) return 0; =20 act->ms.map =3D map; @@ -3091,8 +3093,8 @@ static int evsel__hists_browse(struct evsel *evsel, i= nt nr_events, const char *h =20 if (!browser->selection || !browser->selection->map || - !browser->selection->map->dso || - browser->selection->map->dso->annotate_warned) { + !map__dso(browser->selection->map) || + map__dso(browser->selection->map)->annotate_warned) { continue; } =20 diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 3d49b916c9e4..3d1b958d8832 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -76,7 +76,7 @@ static int map_browser__run(struct map_browser *browser) { int key; =20 - if (ui_browser__show(&browser->b, browser->map->dso->long_name, + if (ui_browser__show(&browser->b, map__dso(browser->map)->long_name, "Press ESC to exit, %s / to search", verbose > 0 ? "" : "restart with -v to use") < 0) return -1; @@ -106,7 +106,7 @@ int map__browse(struct map *map) { struct map_browser mb =3D { .b =3D { - .entries =3D &map->dso->symbols, + .entries =3D &map__dso(map)->symbols, .refresh =3D ui_browser__rb_tree_refresh, .seek =3D ui_browser__rb_tree_seek, .write =3D map_browser__write, diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index db475e44f42f..9494b34e84fc 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1593,7 +1593,7 @@ static void delete_last_nop(struct symbol *sym) =20 int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *= buf, size_t buflen) { - struct dso *dso =3D ms->map->dso; + struct dso *dso =3D map__dso(ms->map); =20 BUG_ON(buflen =3D=3D 0); =20 @@ -1735,7 +1735,7 @@ static int symbol__disassemble_bpf(struct symbol *sym, struct map *map =3D args->ms.map; struct perf_bpil *info_linear; struct disassemble_info info; - struct dso *dso =3D map->dso; + struct dso *dso =3D map__dso(map); int pc =3D 0, count, sub_id; struct btf *btf =3D NULL; char tpath[PATH_MAX]; @@ -1958,7 +1958,7 @@ static int symbol__disassemble(struct symbol *sym, st= ruct annotate_args *args) { struct annotation_options *opts =3D args->options; struct map *map =3D args->ms.map; - struct dso *dso =3D map->dso; + struct dso *dso =3D map__dso(map); char *command; FILE *file; char symfs_filename[PATH_MAX]; @@ -2403,7 +2403,7 @@ int symbol__annotate_printf(struct map_symbol *ms, st= ruct evsel *evsel, { struct map *map =3D ms->map; struct symbol *sym =3D ms->sym; - struct dso *dso =3D map->dso; + struct dso *dso =3D map__dso(map); char *filename; const char *d_filename; const char *evsel_name =3D evsel__name(evsel); @@ -2586,7 +2586,7 @@ int map_symbol__annotation_dump(struct map_symbol *ms= , struct evsel *evsel, } =20 fprintf(fp, "%s() %s\nEvent: %s\n\n", - ms->sym->name, ms->map->dso->long_name, ev_name); + ms->sym->name, map__dso(ms->map)->long_name, ev_name); symbol__annotate_fprintf2(ms->sym, fp, opts); =20 fclose(fp); @@ -2812,7 +2812,7 @@ static void annotation__calc_lines(struct annotation = *notes, struct map *map, if (percent_max <=3D 0.5) continue; =20 - al->path =3D get_srcline(map->dso, notes->start + al->offset, NULL, + al->path =3D get_srcline(map__dso(map), notes->start + al->offset, NULL, false, true, notes->start + al->offset); insert_source_line(&tmp_root, al, opts); } @@ -2831,7 +2831,7 @@ static void symbol__calc_lines(struct map_symbol *ms,= struct rb_root *root, int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts) { - struct dso *dso =3D ms->map->dso; + struct dso *dso =3D map__dso(ms->map); struct symbol *sym =3D ms->sym; struct rb_root source_line =3D RB_ROOT; struct hists *hists =3D evsel__hists(evsel); @@ -2867,7 +2867,7 @@ int symbol__tty_annotate2(struct map_symbol *ms, stru= ct evsel *evsel, int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel, struct annotation_options *opts) { - struct dso *dso =3D ms->map->dso; + struct dso *dso =3D map__dso(ms->map); struct symbol *sym =3D ms->sym; struct rb_root source_line =3D RB_ROOT; int err; diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 498ff7f24463..2341de8573c0 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -2557,7 +2557,7 @@ static struct dso *load_dso(const char *name) if (map__load(map) < 0) pr_err("File '%s' not found or has no symbols.\n", name); =20 - dso =3D dso__get(map->dso); + dso =3D dso__get(map__dso(map)); =20 map__put(map); =20 diff --git a/tools/perf/util/block-info.c b/tools/perf/util/block-info.c index 5ecd4f401f32..16a7b4adcf18 100644 --- a/tools/perf/util/block-info.c +++ b/tools/perf/util/block-info.c @@ -317,9 +317,9 @@ static int block_dso_entry(struct perf_hpp_fmt *fmt, st= ruct perf_hpp *hpp, struct block_fmt *block_fmt =3D container_of(fmt, struct block_fmt, fmt); struct map *map =3D he->ms.map; =20 - if (map && map->dso) { + if (map && map__dso(map)) { return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, - map->dso->short_name); + map__dso(map)->short_name); } =20 return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 025f331b3867..38fcf3ba5749 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -57,10 +57,12 @@ static int machine__process_bpf_event_load(struct machi= ne *machine, struct map *map =3D maps__find(machine__kernel_maps(machine), addr); =20 if (map) { - map->dso->binary_type =3D DSO_BINARY_TYPE__BPF_PROG_INFO; - map->dso->bpf_prog.id =3D id; - map->dso->bpf_prog.sub_id =3D i; - map->dso->bpf_prog.env =3D env; + struct dso *dso =3D map__dso(map); + + dso->binary_type =3D DSO_BINARY_TYPE__BPF_PROG_INFO; + dso->bpf_prog.id =3D id; + dso->bpf_prog.sub_id =3D i; + dso->bpf_prog.env =3D env; } } return 0; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index ea9c083ab1e3..06a8cd88cbef 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -59,7 +59,7 @@ int build_id__mark_dso_hit(struct perf_tool *tool __maybe= _unused, } =20 if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) - al.map->dso->hit =3D 1; + map__dso(al.map)->hit =3D 1; =20 thread__put(thread); return 0; diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 0aa979f64565..9e9c39dd9d2b 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -701,8 +701,8 @@ static enum match_result match_chain_strings(const char= *left, static enum match_result match_chain_dso_addresses(struct map *left_map, u= 64 left_ip, struct map *right_map, u64 right_ip) { - struct dso *left_dso =3D left_map ? left_map->dso : NULL; - struct dso *right_dso =3D right_map ? right_map->dso : NULL; + struct dso *left_dso =3D left_map ? map__dso(left_map) : NULL; + struct dso *right_dso =3D right_map ? map__dso(right_map) : NULL; =20 if (left_dso !=3D right_dso) return left_dso < right_dso ? MATCH_LT : MATCH_GT; @@ -1174,7 +1174,7 @@ char *callchain_list__sym_name(struct callchain_list = *cl, if (show_dso) scnprintf(bf + printed, bfsize - printed, " %s", cl->ms.map ? - cl->ms.map->dso->short_name : + map__dso(cl->ms.map)->short_name : "unknown"); =20 return bf; diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-con= vert-json.c index ba9d93ce9463..653709ab867a 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -128,15 +128,17 @@ static void output_sample_callchain_entry(struct perf= _tool *tool, output_json_key_format(out, false, 5, "ip", "\"0x%" PRIx64 "\"", ip); =20 if (al && al->sym && al->sym->namelen) { + struct dso *dso =3D al->map ? map__dso(al->map) : NULL; + fputc(',', out); output_json_key_string(out, false, 5, "symbol", al->sym->name); =20 - if (al->map && al->map->dso) { - const char *dso =3D al->map->dso->short_name; + if (dso) { + const char *dso_name =3D dso->short_name; =20 - if (dso && strlen(dso) > 0) { + if (dso_name && strlen(dso_name) > 0) { fputc(',', out); - output_json_key_string(out, false, 5, "dso", dso); + output_json_key_string(out, false, 5, "dso", dso_name); } } } diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index 1cfcfdd3cf52..84c970c11794 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -179,7 +179,7 @@ static int db_ids_from_al(struct db_export *dbe, struct= addr_location *al, int err; =20 if (al->map) { - struct dso *dso =3D al->map->dso; + struct dso *dso =3D map__dso(al->map); =20 err =3D db_export__dso(dbe, dso, maps__machine(al->maps)); if (err) @@ -255,7 +255,7 @@ static struct call_path *call_path_from_sample(struct d= b_export *dbe, al.addr =3D node->ip; =20 if (al.map && !al.sym) - al.sym =3D dso__find_symbol(al.map->dso, al.addr); + al.sym =3D dso__find_symbol(map__dso(al.map), al.addr); =20 db_ids_from_al(dbe, &al, &dso_db_id, &sym_db_id, &offset); =20 diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index fe2a0752a0f6..8a7ffe0d805a 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -29,7 +29,7 @@ static void al_to_d_al(struct addr_location *al, struct p= erf_dlfilter_al *d_al) =20 d_al->size =3D sizeof(*d_al); if (al->map) { - struct dso *dso =3D al->map->dso; + struct dso *dso =3D map__dso(al->map); =20 if (symbol_conf.show_kernel_path && dso->long_name) d_al->dso =3D dso->long_name; @@ -220,6 +220,7 @@ static const char *dlfilter__srcline(void *ctx, __u32 *= line_no) unsigned int line =3D 0; char *srcfile =3D NULL; struct map *map; + struct dso *dso; u64 addr; =20 if (!d->ctx_valid || !line_no) @@ -231,9 +232,10 @@ static const char *dlfilter__srcline(void *ctx, __u32 = *line_no) =20 map =3D al->map; addr =3D al->addr; + dso =3D map ? map__dso(map) : NULL; =20 - if (map && map->dso) - srcfile =3D get_srcline_split(map->dso, map__rip_2objdump(map, addr), &l= ine); + if (dso) + srcfile =3D get_srcline_split(dso, map__rip_2objdump(map, addr), &line); =20 *line_no =3D line; return srcfile; @@ -279,7 +281,7 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip,= void *buf, __u32 len) offset =3D map->map_ip(map, ip); if (ip + len >=3D map->end) len =3D map->end - ip; - return dso__data_read_offset(map->dso, d->machine, offset, buf, len); + return dso__data_read_offset(map__dso(map), d->machine, offset, buf, len); } =20 static const struct perf_dlfilter_fns perf_dlfilter_fns =3D { diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index f40cdd6ac126..2ddc75dee019 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -685,6 +685,7 @@ int machine__resolve(struct machine *machine, struct ad= dr_location *al, struct perf_sample *sample) { struct thread *thread; + struct dso *dso; =20 if (symbol_conf.guest_code && !machine__is_host(machine)) thread =3D machine__findnew_guest_code(machine, sample->pid); @@ -695,9 +696,11 @@ int machine__resolve(struct machine *machine, struct a= ddr_location *al, =20 dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid= ); thread__find_map(thread, sample->cpumode, sample->ip, al); + dso =3D al->map ? map__dso(al->map) : NULL; dump_printf(" ...... dso: %s\n", - al->map ? al->map->dso->long_name : - al->level =3D=3D 'H' ? "[hypervisor]" : ""); + dso + ? dso->long_name + : (al->level =3D=3D 'H' ? "[hypervisor]" : "")); =20 if (thread__is_filtered(thread)) al->filtered |=3D (1 << HIST_FILTER__THREAD); @@ -715,8 +718,6 @@ int machine__resolve(struct machine *machine, struct ad= dr_location *al, } =20 if (al->map) { - struct dso *dso =3D al->map->dso; - if (symbol_conf.dso_list && (!dso || !(strlist__has_entry(symbol_conf.dso_list, dso->short_name) || diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprint= f.c index bd22c4932d10..dff5d8c4b06d 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -155,7 +155,7 @@ int sample__fprintf_callchain(struct perf_sample *sampl= e, int left_alignment, =20 if (print_ip) { /* Show binary offset for userspace addr */ - if (map && !map->dso->kernel) + if (map && !map__dso(map)->kernel) printed +=3D fprintf(fp, "%c%16" PRIx64, s, addr); else printed +=3D fprintf(fp, "%c%16" PRIx64, s, node->ip); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 1b0e89cd5d99..fdf0562d2fd3 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -106,7 +106,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) hists__set_col_len(hists, HISTC_THREAD, len + 8); =20 if (h->ms.map) { - len =3D dso__name_len(h->ms.map->dso); + len =3D dso__name_len(map__dso(h->ms.map)); hists__new_col_len(hists, HISTC_DSO, len); } =20 @@ -120,7 +120,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) symlen +=3D BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); =20 - symlen =3D dso__name_len(h->branch_info->from.ms.map->dso); + symlen =3D dso__name_len(map__dso(h->branch_info->from.ms.map)); hists__new_col_len(hists, HISTC_DSO_FROM, symlen); } else { symlen =3D unresolved_col_width + 4 + 2; @@ -135,7 +135,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) symlen +=3D BITS_PER_LONG / 4 + 2 + 3; hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); =20 - symlen =3D dso__name_len(h->branch_info->to.ms.map->dso); + symlen =3D dso__name_len(map__dso(h->branch_info->to.ms.map)); hists__new_col_len(hists, HISTC_DSO_TO, symlen); } else { symlen =3D unresolved_col_width + 4 + 2; @@ -180,7 +180,7 @@ void hists__calc_col_len(struct hists *hists, struct hi= st_entry *h) } =20 if (h->mem_info->daddr.ms.map) { - symlen =3D dso__name_len(h->mem_info->daddr.ms.map->dso); + symlen =3D dso__name_len(map__dso(h->mem_info->daddr.ms.map)); hists__new_col_len(hists, HISTC_MEM_DADDR_DSO, symlen); } else { @@ -2104,7 +2104,7 @@ static bool hists__filter_entry_by_dso(struct hists *= hists, struct hist_entry *he) { if (hists->dso_filter !=3D NULL && - (he->ms.map =3D=3D NULL || he->ms.map->dso !=3D hists->dso_filter)) { + (he->ms.map =3D=3D NULL || map__dso(he->ms.map) !=3D hists->dso_filte= r)) { he->filtered |=3D (1 << HIST_FILTER__DSO); return true; } diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 955c1b9dc6a4..8cec88e09792 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -801,17 +801,19 @@ static int intel_pt_walk_next_insn(struct intel_pt_in= sn *intel_pt_insn, } =20 while (1) { - if (!thread__find_map(thread, cpumode, *ip, &al) || !al.map->dso) { + struct dso *dso; + + if (!thread__find_map(thread, cpumode, *ip, &al) || !map__dso(al.map)) { if (al.map) intel_pt_log("ERROR: thread has no dso for %#" PRIx64 "\n", *ip); else intel_pt_log("ERROR: thread has no map for %#" PRIx64 "\n", *ip); return -EINVAL; } + dso =3D map__dso(al.map); =20 - if (al.map->dso->data.status =3D=3D DSO_DATA_STATUS_ERROR && - dso__data_status_seen(al.map->dso, - DSO_DATA_STATUS_SEEN_ITRACE)) + if (dso->data.status =3D=3D DSO_DATA_STATUS_ERROR && + dso__data_status_seen(dso, DSO_DATA_STATUS_SEEN_ITRACE)) return -ENOENT; =20 offset =3D al.map->map_ip(al.map, *ip); @@ -819,7 +821,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn= *intel_pt_insn, if (!to_ip && one_map) { struct intel_pt_cache_entry *e; =20 - e =3D intel_pt_cache_lookup(al.map->dso, machine, offset); + e =3D intel_pt_cache_lookup(dso, machine, offset); if (e && (!max_insn_cnt || e->insn_cnt <=3D max_insn_cnt)) { *insn_cnt_ptr =3D e->insn_cnt; @@ -829,8 +831,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn= *intel_pt_insn, intel_pt_insn->emulated_ptwrite =3D e->emulated_ptwrite; intel_pt_insn->length =3D e->length; intel_pt_insn->rel =3D e->rel; - memcpy(intel_pt_insn->buf, e->insn, - INTEL_PT_INSN_BUF_SZ); + memcpy(intel_pt_insn->buf, e->insn, INTEL_PT_INSN_BUF_SZ); intel_pt_log_insn_no_data(intel_pt_insn, *ip); return 0; } @@ -842,17 +843,17 @@ static int intel_pt_walk_next_insn(struct intel_pt_in= sn *intel_pt_insn, /* Load maps to ensure dso->is_64_bit has been updated */ map__load(al.map); =20 - x86_64 =3D al.map->dso->is_64_bit; + x86_64 =3D dso->is_64_bit; =20 while (1) { - len =3D dso__data_read_offset(al.map->dso, machine, + len =3D dso__data_read_offset(dso, machine, offset, buf, INTEL_PT_INSN_BUF_SZ); if (len <=3D 0) { intel_pt_log("ERROR: failed to read at offset %#" PRIx64 " ", offset); if (intel_pt_enable_logging) - dso__fprintf(al.map->dso, intel_pt_log_fp()); + dso__fprintf(dso, intel_pt_log_fp()); return -EINVAL; } =20 @@ -871,7 +872,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn= *intel_pt_insn, goto out; /* Check for emulated ptwrite */ offs =3D offset + intel_pt_insn->length; - eptw =3D intel_pt_emulated_ptwrite(al.map->dso, machine, offs); + eptw =3D intel_pt_emulated_ptwrite(dso, machine, offs); intel_pt_insn->emulated_ptwrite =3D eptw; goto out; } @@ -906,13 +907,13 @@ static int intel_pt_walk_next_insn(struct intel_pt_in= sn *intel_pt_insn, if (to_ip) { struct intel_pt_cache_entry *e; =20 - e =3D intel_pt_cache_lookup(al.map->dso, machine, start_offset); + e =3D intel_pt_cache_lookup(map__dso(al.map), machine, start_offset); if (e) return 0; } =20 /* Ignore cache errors */ - intel_pt_cache_add(al.map->dso, machine, start_offset, insn_cnt, + intel_pt_cache_add(map__dso(al.map), machine, start_offset, insn_cnt, *ip - start_ip, intel_pt_insn); =20 return 0; @@ -983,13 +984,12 @@ static int __intel_pt_pgd_ip(uint64_t ip, void *data) if (!thread) return -EINVAL; =20 - if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso) + if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map)) return -EINVAL; =20 offset =3D al.map->map_ip(al.map, ip); =20 - return intel_pt_match_pgd_ip(ptq->pt, ip, offset, - al.map->dso->long_name); + return intel_pt_match_pgd_ip(ptq->pt, ip, offset, map__dso(al.map)->long_= name); } =20 static bool intel_pt_pgd_ip(uint64_t ip, void *data) @@ -2744,7 +2744,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u6= 4 *ptss_ip) if (map__load(map)) return 0; =20 - start =3D dso__first_symbol(map->dso); + start =3D dso__first_symbol(map__dso(map)); =20 for (sym =3D start; sym; sym =3D dso__next_symbol(sym)) { if (sym->binding =3D=3D STB_GLOBAL && @@ -3381,18 +3381,21 @@ static int intel_pt_text_poke(struct intel_pt *pt, = union perf_event *event) return 0; =20 for (; cnt; cnt--, addr--) { + struct dso *dso; + if (intel_pt_find_map(thread, cpumode, addr, &al)) { if (addr < event->text_poke.addr) return 0; continue; } =20 - if (!al.map->dso || !al.map->dso->auxtrace_cache) + dso =3D map__dso(al.map); + if (!dso || !dso->auxtrace_cache) continue; =20 offset =3D al.map->map_ip(al.map, addr); =20 - e =3D intel_pt_cache_lookup(al.map->dso, machine, offset); + e =3D intel_pt_cache_lookup(dso, machine, offset); if (!e) continue; =20 @@ -3405,9 +3408,9 @@ static int intel_pt_text_poke(struct intel_pt *pt, un= ion perf_event *event) if (e->branch !=3D INTEL_PT_BR_NO_BRANCH) return 0; } else { - intel_pt_cache_invalidate(al.map->dso, machine, offset); + intel_pt_cache_invalidate(dso, machine, offset); intel_pt_log("Invalidated instruction cache for %s at %#"PRIx64"\n", - al.map->dso->long_name, addr); + dso->long_name, addr); } } =20 diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 446c0273259d..6e32344e66dc 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -47,7 +47,7 @@ static void __machine__remove_thread(struct machine *mach= ine, struct thread *th, =20 static struct dso *machine__kernel_dso(struct machine *machine) { - return machine->vmlinux_map->dso; + return map__dso(machine->vmlinux_map); } =20 static void dsos__init(struct dsos *dsos) @@ -878,12 +878,13 @@ static int machine__process_ksymbol_register(struct m= achine *machine, struct perf_sample *sample __maybe_unused) { struct symbol *sym; + struct dso *dso; struct map *map =3D maps__find(machine__kernel_maps(machine), event->ksym= bol.addr); =20 if (!map) { - struct dso *dso =3D dso__new(event->ksymbol.name); int err; =20 + dso =3D dso__new(event->ksymbol.name); if (dso) { dso->kernel =3D DSO_SPACE__KERNEL; map =3D map__new2(0, dso); @@ -895,9 +896,9 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, } =20 if (event->ksymbol.ksym_type =3D=3D PERF_RECORD_KSYMBOL_TYPE_OOL) { - map->dso->binary_type =3D DSO_BINARY_TYPE__OOL; - map->dso->data.file_size =3D event->ksymbol.len; - dso__set_loaded(map->dso); + dso->binary_type =3D DSO_BINARY_TYPE__OOL; + dso->data.file_size =3D event->ksymbol.len; + dso__set_loaded(dso); } =20 map->start =3D event->ksymbol.addr; @@ -913,6 +914,8 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, dso->binary_type =3D DSO_BINARY_TYPE__BPF_IMAGE; dso__set_long_name(dso, "", false); } + } else { + dso =3D map__dso(map); } =20 sym =3D symbol__new(map->map_ip(map, map->start), @@ -920,7 +923,7 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, 0, 0, event->ksymbol.name); if (!sym) return -ENOMEM; - dso__insert_symbol(map->dso, sym); + dso__insert_symbol(dso, sym); return 0; } =20 @@ -938,9 +941,11 @@ static int machine__process_ksymbol_unregister(struct = machine *machine, if (map !=3D machine->vmlinux_map) maps__remove(machine__kernel_maps(machine), map); else { - sym =3D dso__find_symbol(map->dso, map->map_ip(map, map->start)); + struct dso *dso =3D map__dso(map); + + sym =3D dso__find_symbol(dso, map->map_ip(map, map->start)); if (sym) - dso__delete_symbol(map->dso, sym); + dso__delete_symbol(dso, sym); } =20 return 0; @@ -964,6 +969,7 @@ int machine__process_text_poke(struct machine *machine,= union perf_event *event, { struct map *map =3D maps__find(machine__kernel_maps(machine), event->text= _poke.addr); u8 cpumode =3D event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; + struct dso *dso =3D map ? map__dso(map) : NULL; =20 if (dump_trace) perf_event__fprintf_text_poke(event, machine, stdout); @@ -976,7 +982,7 @@ int machine__process_text_poke(struct machine *machine,= union perf_event *event, return 0; } =20 - if (map && map->dso) { + if (dso) { u8 *new_bytes =3D event->text_poke.bytes + event->text_poke.old_len; int ret; =20 @@ -985,7 +991,7 @@ int machine__process_text_poke(struct machine *machine,= union perf_event *event, * must be done prior to using kernel maps. */ map__load(map); - ret =3D dso__data_write_cache_addr(map->dso, map, machine, + ret =3D dso__data_write_cache_addr(dso, map, machine, event->text_poke.addr, new_bytes, event->text_poke.new_len); @@ -1421,10 +1427,11 @@ int machines__create_kernel_maps(struct machines *m= achines, pid_t pid) int machine__load_kallsyms(struct machine *machine, const char *filename) { struct map *map =3D machine__kernel_map(machine); - int ret =3D __dso__load_kallsyms(map->dso, filename, map, true); + struct dso *dso =3D map__dso(map); + int ret =3D __dso__load_kallsyms(dso, filename, map, true); =20 if (ret > 0) { - dso__set_loaded(map->dso); + dso__set_loaded(dso); /* * Since /proc/kallsyms will have multiple sessions for the * kernel, with modules between them, fixup the end of all @@ -1439,10 +1446,11 @@ int machine__load_kallsyms(struct machine *machine,= const char *filename) int machine__load_vmlinux_path(struct machine *machine) { struct map *map =3D machine__kernel_map(machine); - int ret =3D dso__load_vmlinux_path(map->dso, map); + struct dso *dso =3D map__dso(map); + int ret =3D dso__load_vmlinux_path(dso, map); =20 if (ret > 0) - dso__set_loaded(map->dso); + dso__set_loaded(dso); =20 return ret; } @@ -1484,6 +1492,7 @@ static bool is_kmod_dso(struct dso *dso) static int maps__set_module_path(struct maps *maps, const char *path, stru= ct kmod_path *m) { char *long_name; + struct dso *dso; struct map *map =3D maps__find_by_name(maps, m->name); =20 if (map =3D=3D NULL) @@ -1493,16 +1502,17 @@ static int maps__set_module_path(struct maps *maps,= const char *path, struct kmo if (long_name =3D=3D NULL) return -ENOMEM; =20 - dso__set_long_name(map->dso, long_name, true); - dso__kernel_module_get_build_id(map->dso, ""); + dso =3D map__dso(map); + dso__set_long_name(dso, long_name, true); + dso__kernel_module_get_build_id(dso, ""); =20 /* * Full name could reveal us kmod compression, so * we need to update the symtab_type if needed. */ - if (m->comp && is_kmod_dso(map->dso)) { - map->dso->symtab_type++; - map->dso->comp =3D m->comp; + if (m->comp && is_kmod_dso(dso)) { + dso->symtab_type++; + dso->comp =3D m->comp; } =20 return 0; @@ -1601,7 +1611,7 @@ static int machine__create_module(void *arg, const ch= ar *name, u64 start, return -1; map->end =3D start + size; =20 - dso__kernel_module_get_build_id(map->dso, machine->root_dir); + dso__kernel_module_get_build_id(map__dso(map), machine->root_dir); =20 return 0; } @@ -1787,7 +1797,7 @@ static int machine__process_kernel_mmap_event(struct = machine *machine, map->end =3D map->start + xm->end - xm->start; =20 if (build_id__is_defined(bid)) - dso__set_build_id(map->dso, bid); + dso__set_build_id(map__dso(map), bid); =20 } else if (is_kernel_mmap) { const char *symbol_name =3D xm->name + strlen(mmap_name); @@ -2247,18 +2257,20 @@ static char *callchain_srcline(struct map_symbol *m= s, u64 ip) { struct map *map =3D ms->map; char *srcline =3D NULL; + struct dso *dso; =20 if (!map || callchain_param.key =3D=3D CCKEY_FUNCTION) return srcline; =20 - srcline =3D srcline__tree_find(&map->dso->srclines, ip); + dso =3D map__dso(map); + srcline =3D srcline__tree_find(&dso->srclines, ip); if (!srcline) { bool show_sym =3D false; bool show_addr =3D callchain_param.key =3D=3D CCKEY_ADDRESS; =20 - srcline =3D get_srcline(map->dso, map__rip_2objdump(map, ip), + srcline =3D get_srcline(dso, map__rip_2objdump(map, ip), ms->sym, show_sym, show_addr, ip); - srcline__tree_insert(&map->dso->srclines, ip, srcline); + srcline__tree_insert(&dso->srclines, ip, srcline); } =20 return srcline; @@ -3034,6 +3046,7 @@ static int append_inlines(struct callchain_cursor *cu= rsor, struct map_symbol *ms struct map *map =3D ms->map; struct inline_node *inline_node; struct inline_list *ilist; + struct dso *dso; u64 addr; int ret =3D 1; =20 @@ -3042,13 +3055,14 @@ static int append_inlines(struct callchain_cursor *= cursor, struct map_symbol *ms =20 addr =3D map__map_ip(map, ip); addr =3D map__rip_2objdump(map, addr); + dso =3D map__dso(map); =20 - inline_node =3D inlines__tree_find(&map->dso->inlined_nodes, addr); + inline_node =3D inlines__tree_find(&dso->inlined_nodes, addr); if (!inline_node) { - inline_node =3D dso__parse_addr_inlines(map->dso, addr, sym); + inline_node =3D dso__parse_addr_inlines(dso, addr, sym); if (!inline_node) return ret; - inlines__tree_insert(&map->dso->inlined_nodes, inline_node); + inlines__tree_insert(&dso->inlined_nodes, inline_node); } =20 list_for_each_entry(ilist, &inline_node->val, list) { @@ -3325,7 +3339,7 @@ char *machine__resolve_kernel_addr(void *vmachine, un= signed long long *addrp, ch if (sym =3D=3D NULL) return NULL; =20 - *modp =3D __map__is_kmodule(map) ? (char *)map->dso->short_name : NULL; + *modp =3D __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NU= LL; *addrp =3D map->unmap_ip(map, sym->start); return sym->name; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index a99dbde656a2..90062af6675a 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -232,7 +232,7 @@ struct map *map__new2(u64 start, struct dso *dso) =20 bool __map__is_kernel(const struct map *map) { - if (!map->dso->kernel) + if (!map__dso(map)->kernel) return false; return machine__kernel_map(maps__machine(map__kmaps((struct map *)map))) = =3D=3D map; } @@ -247,8 +247,9 @@ bool __map__is_extra_kernel_map(const struct map *map) bool __map__is_bpf_prog(const struct map *map) { const char *name; + struct dso *dso =3D map__dso(map); =20 - if (map->dso->binary_type =3D=3D DSO_BINARY_TYPE__BPF_PROG_INFO) + if (dso->binary_type =3D=3D DSO_BINARY_TYPE__BPF_PROG_INFO) return true; =20 /* @@ -256,15 +257,16 @@ bool __map__is_bpf_prog(const struct map *map) * type of DSO_BINARY_TYPE__BPF_PROG_INFO. In such cases, we can * guess the type based on name. */ - name =3D map->dso->short_name; + name =3D dso->short_name; return name && (strstr(name, "bpf_prog_") =3D=3D name); } =20 bool __map__is_bpf_image(const struct map *map) { const char *name; + struct dso *dso =3D map__dso(map); =20 - if (map->dso->binary_type =3D=3D DSO_BINARY_TYPE__BPF_IMAGE) + if (dso->binary_type =3D=3D DSO_BINARY_TYPE__BPF_IMAGE) return true; =20 /* @@ -272,18 +274,20 @@ bool __map__is_bpf_image(const struct map *map) * type of DSO_BINARY_TYPE__BPF_IMAGE. In such cases, we can * guess the type based on name. */ - name =3D map->dso->short_name; + name =3D dso->short_name; return name && is_bpf_image(name); } =20 bool __map__is_ool(const struct map *map) { - return map->dso && map->dso->binary_type =3D=3D DSO_BINARY_TYPE__OOL; + const struct dso *dso =3D map__dso(map); + + return dso && dso->binary_type =3D=3D DSO_BINARY_TYPE__OOL; } =20 bool map__has_symbols(const struct map *map) { - return dso__has_symbols(map->dso); + return dso__has_symbols(map__dso(map)); } =20 static void map__exit(struct map *map) @@ -306,18 +310,23 @@ void map__put(struct map *map) =20 void map__fixup_start(struct map *map) { - struct rb_root_cached *symbols =3D &map->dso->symbols; + struct dso *dso =3D map__dso(map); + struct rb_root_cached *symbols =3D &dso->symbols; struct rb_node *nd =3D rb_first_cached(symbols); + if (nd !=3D NULL) { struct symbol *sym =3D rb_entry(nd, struct symbol, rb_node); + map->start =3D sym->start; } } =20 void map__fixup_end(struct map *map) { - struct rb_root_cached *symbols =3D &map->dso->symbols; + struct dso *dso =3D map__dso(map); + struct rb_root_cached *symbols =3D &dso->symbols; struct rb_node *nd =3D rb_last(&symbols->rb_root); + if (nd !=3D NULL) { struct symbol *sym =3D rb_entry(nd, struct symbol, rb_node); map->end =3D sym->end; @@ -328,18 +337,19 @@ void map__fixup_end(struct map *map) =20 int map__load(struct map *map) { - const char *name =3D map->dso->long_name; + struct dso *dso =3D map__dso(map); + const char *name =3D dso->long_name; int nr; =20 - if (dso__loaded(map->dso)) + if (dso__loaded(dso)) return 0; =20 - nr =3D dso__load(map->dso, map); + nr =3D dso__load(dso, map); if (nr < 0) { - if (map->dso->has_build_id) { + if (dso->has_build_id) { char sbuild_id[SBUILD_ID_SIZE]; =20 - build_id__sprintf(&map->dso->bid, sbuild_id); + build_id__sprintf(&dso->bid, sbuild_id); pr_debug("%s with build id %s not found", name, sbuild_id); } else pr_debug("Failed to open %s", name); @@ -371,32 +381,36 @@ struct symbol *map__find_symbol(struct map *map, u64 = addr) if (map__load(map) < 0) return NULL; =20 - return dso__find_symbol(map->dso, addr); + return dso__find_symbol(map__dso(map), addr); } =20 struct symbol *map__find_symbol_by_name(struct map *map, const char *name) { + struct dso *dso; + if (map__load(map) < 0) return NULL; =20 - if (!dso__sorted_by_name(map->dso)) - dso__sort_by_name(map->dso); + dso =3D map__dso(map); + if (!dso__sorted_by_name(dso)) + dso__sort_by_name(dso); =20 - return dso__find_symbol_by_name(map->dso, name); + return dso__find_symbol_by_name(dso, name); } =20 struct map *map__clone(struct map *from) { size_t size =3D sizeof(struct map); struct map *map; + struct dso *dso =3D map__dso(from); =20 - if (from->dso && from->dso->kernel) + if (dso && dso->kernel) size +=3D sizeof(struct kmap); =20 map =3D memdup(from, size); if (map !=3D NULL) { refcount_set(&map->refcnt, 1); - dso__get(map->dso); + dso__get(dso); } =20 return map; @@ -404,20 +418,23 @@ struct map *map__clone(struct map *from) =20 size_t map__fprintf(struct map *map, FILE *fp) { + const struct dso *dso =3D map__dso(map); + return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", - map->start, map->end, map->pgoff, map->dso->name); + map->start, map->end, map->pgoff, dso->name); } =20 size_t map__fprintf_dsoname(struct map *map, FILE *fp) { char buf[symbol_conf.pad_output_len_dso + 1]; const char *dsoname =3D "[unknown]"; + const struct dso *dso =3D map ? map__dso(map) : NULL; =20 - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname =3D map->dso->long_name; + if (dso) { + if (symbol_conf.show_kernel_path && dso->long_name) + dsoname =3D dso->long_name; else - dsoname =3D map->dso->name; + dsoname =3D dso->name; } =20 if (symbol_conf.pad_output_len_dso) { @@ -432,15 +449,17 @@ char *map__srcline(struct map *map, u64 addr, struct = symbol *sym) { if (map =3D=3D NULL) return SRCLINE_UNKNOWN; - return get_srcline(map->dso, map__rip_2objdump(map, addr), sym, true, tru= e, addr); + + return get_srcline(map__dso(map), map__rip_2objdump(map, addr), sym, true= , true, addr); } =20 int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, FILE *fp) { + const struct dso *dso =3D map ? map__dso(map) : NULL; int ret =3D 0; =20 - if (map && map->dso) { + if (dso) { char *srcline =3D map__srcline(map, addr, NULL); if (strncmp(srcline, SRCLINE_UNKNOWN, strlen(SRCLINE_UNKNOWN)) !=3D 0) ret =3D fprintf(fp, "%s%s", prefix, srcline); @@ -469,6 +488,7 @@ void srccode_state_free(struct srccode_state *state) u64 map__rip_2objdump(struct map *map, u64 rip) { struct kmap *kmap =3D __map__kmap(map); + const struct dso *dso =3D map__dso(map); =20 /* * vmlinux does not have program headers for PTI entry trampolines and @@ -486,18 +506,18 @@ u64 map__rip_2objdump(struct map *map, u64 rip) } } =20 - if (!map->dso->adjust_symbols) + if (!dso->adjust_symbols) return rip; =20 - if (map->dso->rel) + if (dso->rel) return rip - 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 (map->dso->kernel =3D=3D DSO_SPACE__USER) - return rip + map->dso->text_offset; + if (dso->kernel =3D=3D DSO_SPACE__USER) + return rip + dso->text_offset; =20 return map->unmap_ip(map, rip) - map->reloc; } @@ -516,18 +536,20 @@ u64 map__rip_2objdump(struct map *map, u64 rip) */ u64 map__objdump_2mem(struct map *map, u64 ip) { - if (!map->dso->adjust_symbols) + const struct dso *dso =3D map__dso(map); + + if (!dso->adjust_symbols) return map->unmap_ip(map, ip); =20 - if (map->dso->rel) + if (dso->rel) 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 (map->dso->kernel =3D=3D DSO_SPACE__USER) - return map->unmap_ip(map, ip - map->dso->text_offset); + if (dso->kernel =3D=3D DSO_SPACE__USER) + return map->unmap_ip(map, ip - dso->text_offset); =20 return ip + map->reloc; } @@ -541,7 +563,9 @@ bool map__contains_symbol(const struct map *map, const = struct symbol *sym) =20 struct kmap *__map__kmap(struct map *map) { - if (!map->dso || !map->dso->kernel) + const struct dso *dso =3D map__dso(map); + + if (!dso || !dso->kernel) return NULL; return (struct kmap *)(map + 1); } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index d1a6f85fd31d..36c5add0144d 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -47,6 +47,11 @@ u64 map__unmap_ip(const struct map *map, u64 ip); /* Returns ip */ u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); =20 +static inline struct dso *map__dso(const struct map *map) +{ + return map->dso; +} + static inline size_t map__size(const struct map *map) { return map->end - map->start; @@ -69,7 +74,7 @@ struct thread; * Note: caller must ensure map->dso is not NULL (map is loaded). */ #define map__for_each_symbol(map, pos, n) \ - dso__for_each_symbol(map->dso, pos, n) + dso__for_each_symbol(map__dso(map), pos, n) =20 /* map__for_each_symbol_with_name - iterate over the symbols in the given = map * that have the given name diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 91bb015caede..09ec6bbafcbc 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -62,6 +62,7 @@ static int __maps__insert(struct maps *maps, struct map *= map) int maps__insert(struct maps *maps, struct map *map) { int err; + const struct dso *dso =3D map__dso(map); =20 down_write(maps__lock(maps)); err =3D __maps__insert(maps, map); @@ -70,7 +71,7 @@ int maps__insert(struct maps *maps, struct map *map) =20 ++maps->nr_maps; =20 - if (map->dso && map->dso->kernel) { + if (dso && dso->kernel) { struct kmap *kmap =3D map__kmap(map); =20 if (kmap) @@ -253,7 +254,7 @@ size_t maps__fprintf(struct maps *maps, FILE *fp) printed +=3D fprintf(fp, "Map:"); printed +=3D map__fprintf(pos->map, fp); if (verbose > 2) { - printed +=3D dso__fprintf(pos->map->dso, fp); + printed +=3D dso__fprintf(map__dso(pos->map), fp); printed +=3D fprintf(fp, "--\n"); } } @@ -307,7 +308,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) =20 if (use_browser) { pr_debug("overlapping maps in %s (disable tui for more info)\n", - map->dso->name); + map__dso(map)->name); } else { fputs("overlapping maps:\n", fp); map__fprintf(map, fp); diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index cdf5d655d84c..b26670a26005 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -165,8 +165,9 @@ static struct map *kernel_get_module_map(const char *mo= dule) =20 maps__for_each_entry(maps, pos) { /* short_name is "[module]" */ - const char *short_name =3D pos->map->dso->short_name; - u16 short_name_len =3D pos->map->dso->short_name_len; + struct dso *dso =3D map__dso(pos->map); + const char *short_name =3D dso->short_name; + u16 short_name_len =3D dso->short_name_len; =20 if (strncmp(short_name + 1, module, short_name_len - 2) =3D=3D 0 && @@ -182,13 +183,15 @@ struct map *get_target_map(const char *target, struct= nsinfo *nsi, bool user) /* Init maps of given executable or kernel */ if (user) { struct map *map; + struct dso *dso; =20 map =3D dso__new_map(target); - if (map && map->dso) { - mutex_lock(&map->dso->lock); - nsinfo__put(map->dso->nsinfo); - map->dso->nsinfo =3D nsinfo__get(nsi); - mutex_unlock(&map->dso->lock); + dso =3D map ? map__dso(map) : NULL; + if (dso) { + mutex_lock(&dso->lock); + nsinfo__put(dso->nsinfo); + dso->nsinfo =3D nsinfo__get(nsi); + mutex_unlock(&dso->lock); } return map; } else { @@ -341,7 +344,7 @@ static int kernel_get_module_dso(const char *module, st= ruct dso **pdso) snprintf(module_name, sizeof(module_name), "[%s]", module); map =3D maps__find_by_name(machine__kernel_maps(host_machine), module_na= me); if (map) { - dso =3D map->dso; + dso =3D map__dso(map); goto found; } pr_debug("Failed to find module %s.\n", module); @@ -349,7 +352,7 @@ static int kernel_get_module_dso(const char *module, st= ruct dso **pdso) } =20 map =3D machine__kernel_map(host_machine); - dso =3D map->dso; + dso =3D map__dso(map); if (!dso->has_build_id) dso__read_running_kernel_build_id(dso, host_machine); =20 @@ -3737,6 +3740,7 @@ int show_available_funcs(const char *target, struct n= sinfo *nsi, { struct rb_node *nd; struct map *map; + struct dso *dso; int ret; =20 ret =3D init_probe_symbol_maps(user); @@ -3762,14 +3766,14 @@ int show_available_funcs(const char *target, struct= nsinfo *nsi, (target) ? : "kernel"); goto end; } - if (!dso__sorted_by_name(map->dso)) - dso__sort_by_name(map->dso); + dso =3D map__dso(map); + if (!dso__sorted_by_name(dso)) + dso__sort_by_name(dso); =20 /* Show all (filtered) symbols */ setup_pager(); =20 - for (nd =3D rb_first_cached(&map->dso->symbol_names); nd; - nd =3D rb_next(nd)) { + for (nd =3D rb_first_cached(&dso->symbol_names); nd; nd =3D rb_next(nd)) { struct symbol_name_rb_node *pos =3D rb_entry(nd, struct symbol_name_rb_n= ode, rb_node); =20 if (strfilter__compare(_filter, pos->sym.name)) diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/p= erf/util/scripting-engines/trace-event-perl.c index 83fd2fd0ba16..039d0365ad41 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c @@ -315,12 +315,14 @@ static SV *perl_process_callchain(struct perf_sample = *sample, =20 if (node->ms.map) { struct map *map =3D node->ms.map; + struct dso *dso =3D map ? map__dso(map) : NULL; const char *dsoname =3D "[unknown]"; - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname =3D map->dso->long_name; + + if (dso) { + if (symbol_conf.show_kernel_path && dso->long_name) + dsoname =3D dso->long_name; else - dsoname =3D map->dso->name; + dsoname =3D dso->name; } if (!hv_stores(elem, "dso", newSVpv(dsoname,0))) { hv_undef(elem); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index e5cc18f6fcda..b8e5c6f61d80 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -390,12 +390,13 @@ static PyObject *get_field_numeric_entry(struct tep_e= vent *event, static const char *get_dsoname(struct map *map) { const char *dsoname =3D "[unknown]"; + struct dso *dso =3D map ? map__dso(map) : NULL; =20 - if (map && map->dso) { - if (symbol_conf.show_kernel_path && map->dso->long_name) - dsoname =3D map->dso->long_name; + if (dso) { + if (symbol_conf.show_kernel_path && dso->long_name) + dsoname =3D dso->long_name; else - dsoname =3D map->dso->name; + dsoname =3D dso->name; } =20 return dsoname; @@ -780,9 +781,10 @@ static void set_sym_in_dict(PyObject *dict, struct add= r_location *al, char sbuild_id[SBUILD_ID_SIZE]; =20 if (al->map) { - pydict_set_item_string_decref(dict, dso_field, - _PyUnicode_FromString(al->map->dso->name)); - build_id__sprintf(&al->map->dso->bid, sbuild_id); + struct dso *dso =3D map__dso(al->map); + + pydict_set_item_string_decref(dict, dso_field, _PyUnicode_FromString(dso= ->name)); + build_id__sprintf(&dso->bid, sbuild_id); pydict_set_item_string_decref(dict, dso_bid_field, _PyUnicode_FromString(sbuild_id)); pydict_set_item_string_decref(dict, dso_map_start, diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index e04d9bddba11..d7b6b734bf90 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -184,8 +184,8 @@ struct sort_entry sort_comm =3D { =20 static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r) { - struct dso *dso_l =3D map_l ? map_l->dso : NULL; - struct dso *dso_r =3D map_r ? map_r->dso : NULL; + struct dso *dso_l =3D map_l ? map__dso(map_l) : NULL; + struct dso *dso_r =3D map_r ? map__dso(map_r) : NULL; const char *dso_name_l, *dso_name_r; =20 if (!dso_l || !dso_r) @@ -211,13 +211,13 @@ sort__dso_cmp(struct hist_entry *left, struct hist_en= try *right) static int _hist_entry__dso_snprintf(struct map *map, char *bf, size_t size, unsigned int width) { - if (map && map->dso) { - const char *dso_name =3D verbose > 0 ? map->dso->long_name : - map->dso->short_name; - return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); - } + const struct dso *dso =3D map ? map__dso(map) : NULL; + const char *dso_name =3D "[unknown]"; + + if (dso) + dso_name =3D verbose > 0 ? dso->long_name : dso->short_name; =20 - return repsep_snprintf(bf, size, "%-*.*s", width, width, "[unknown]"); + return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); } =20 static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf, @@ -233,7 +233,7 @@ static int hist_entry__dso_filter(struct hist_entry *he= , int type, const void *a if (type !=3D HIST_FILTER__DSO) return -1; =20 - return dso && (!he->ms.map || he->ms.map->dso !=3D dso); + return dso && (!he->ms.map || map__dso(he->ms.map) !=3D dso); } =20 struct sort_entry sort_dso =3D { @@ -313,11 +313,11 @@ static int _hist_entry__sym_snprintf(struct map_symbo= l *ms, size_t ret =3D 0; =20 if (verbose > 0) { - char o =3D map ? dso__symtab_origin(map->dso) : '!'; + struct dso *dso =3D map ? map__dso(map) : NULL; + char o =3D dso ? dso__symtab_origin(dso) : '!'; u64 rip =3D ip; =20 - if (map && map->dso && map->dso->kernel - && map->dso->adjust_symbols) + if (dso && dso->kernel && dso->adjust_symbols) rip =3D map->unmap_ip(map, ip); =20 ret +=3D repsep_snprintf(bf, size, "%-#*llx %c ", @@ -595,7 +595,7 @@ static char *hist_entry__get_srcfile(struct hist_entry = *e) if (!map) return no_srcfile; =20 - sf =3D __get_srcline(map->dso, map__rip_2objdump(map, e->ip), + sf =3D __get_srcline(map__dso(map), map__rip_2objdump(map, e->ip), e->ms.sym, false, true, true, e->ip); if (!strcmp(sf, SRCLINE_UNKNOWN)) return no_srcfile; @@ -941,7 +941,7 @@ static int hist_entry__dso_from_filter(struct hist_entr= y *he, int type, return -1; =20 return dso && (!he->branch_info || !he->branch_info->from.ms.map || - he->branch_info->from.ms.map->dso !=3D dso); + map__dso(he->branch_info->from.ms.map) !=3D dso); } =20 static int64_t @@ -973,7 +973,7 @@ static int hist_entry__dso_to_filter(struct hist_entry = *he, int type, return -1; =20 return dso && (!he->branch_info || !he->branch_info->to.ms.map || - he->branch_info->to.ms.map->dso !=3D dso); + map__dso(he->branch_info->to.ms.map) !=3D dso); } =20 static int64_t @@ -1465,6 +1465,7 @@ sort__dcacheline_cmp(struct hist_entry *left, struct = hist_entry *right) { u64 l, r; struct map *l_map, *r_map; + struct dso *l_dso, *r_dso; int rc; =20 if (!left->mem_info) return -1; @@ -1484,7 +1485,9 @@ sort__dcacheline_cmp(struct hist_entry *left, struct = hist_entry *right) if (!l_map) return -1; if (!r_map) return 1; =20 - rc =3D dso__cmp_id(l_map->dso, r_map->dso); + l_dso =3D map__dso(l_map); + r_dso =3D map__dso(r_map); + rc =3D dso__cmp_id(l_dso, r_dso); if (rc) return rc; /* @@ -1496,9 +1499,8 @@ 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_map->dso->id.maj && !l_map->dso->id.min && - !l_map->dso->id.ino && !l_map->dso->id.ino_generation) { + (!(l_map->flags & MAP_SHARED)) && !l_dso->id.maj && !l_dso->id.min && + !l_dso->id.ino && !l_dso->id.ino_generation) { /* userspace anonymous */ =20 if (left->thread->pid_ > right->thread->pid_) return -1; @@ -1526,6 +1528,7 @@ static int hist_entry__dcacheline_snprintf(struct his= t_entry *he, char *bf, =20 if (he->mem_info) { struct map *map =3D he->mem_info->daddr.ms.map; + struct dso *dso =3D map__dso(map); =20 addr =3D cl_address(he->mem_info->daddr.al_addr, chk_double_cl); ms =3D &he->mem_info->daddr.ms; @@ -1534,8 +1537,7 @@ static int hist_entry__dcacheline_snprintf(struct his= t_entry *he, char *bf, if ((he->cpumode !=3D PERF_RECORD_MISC_KERNEL) && map && !(map->prot & PROT_EXEC) && (map->flags & MAP_SHARED) && - (map->dso->id.maj || map->dso->id.min || - map->dso->id.ino || map->dso->id.ino_generation)) + (dso->id.maj || dso->id.min || dso->id.ino || dso->id.ino_generation= )) level =3D 's'; else if (!map) level =3D 'X'; @@ -2031,9 +2033,8 @@ sort__dso_size_cmp(struct hist_entry *left, struct hi= st_entry *right) static int _hist_entry__dso_size_snprintf(struct map *map, char *bf, size_t bf_size, unsigned int width) { - if (map && map->dso) - return repsep_snprintf(bf, bf_size, "%*d", width, - map__size(map)); + if (map && map__dso(map)) + return repsep_snprintf(bf, bf_size, "%*d", width, map__size(map)); =20 return repsep_snprintf(bf, bf_size, "%*s", width, "unknown"); } diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index ccdafc3971ac..97085ad7fe9b 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1429,7 +1429,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, *curr_mapp =3D curr_map; *curr_dsop =3D curr_dso; } else - *curr_dsop =3D curr_map->dso; + *curr_dsop =3D map__dso(curr_map); =20 return 0; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index efd047bab373..13176ed5bd27 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -791,6 +791,7 @@ static int maps__split_kallsyms_for_kcore(struct maps *= kmaps, struct dso *dso) *root =3D RB_ROOT_CACHED; =20 while (next) { + struct dso *curr_map_dso; char *module; =20 pos =3D rb_entry(next, struct symbol, rb_node); @@ -808,13 +809,13 @@ static int maps__split_kallsyms_for_kcore(struct maps= *kmaps, struct dso *dso) symbol__delete(pos); continue; } - + curr_map_dso =3D map__dso(curr_map); pos->start -=3D curr_map->start - curr_map->pgoff; if (pos->end > curr_map->end) pos->end =3D curr_map->end; if (pos->end) pos->end -=3D curr_map->start - curr_map->pgoff; - symbols__insert(&curr_map->dso->symbols, pos); + symbols__insert(&curr_map_dso->symbols, pos); ++count; } =20 @@ -856,12 +857,14 @@ static int maps__split_kallsyms(struct maps *kmaps, s= truct dso *dso, u64 delta, =20 module =3D strchr(pos->name, '\t'); if (module) { + struct dso *curr_map_dso; + if (!symbol_conf.use_modules) goto discard_symbol; =20 *module++ =3D '\0'; - - if (strcmp(curr_map->dso->short_name, module)) { + curr_map_dso =3D map__dso(curr_map); + if (strcmp(curr_map_dso->short_name, module)) { if (curr_map !=3D initial_map && dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(machine)) { @@ -872,7 +875,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, * symbols are in its kmap. Mark it as * loaded. */ - dso__set_loaded(curr_map->dso); + dso__set_loaded(curr_map_dso); } =20 curr_map =3D maps__find_by_name(kmaps, module); @@ -884,8 +887,8 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, curr_map =3D initial_map; goto discard_symbol; } - - if (curr_map->dso->loaded && + curr_map_dso =3D map__dso(curr_map); + if (curr_map_dso->loaded && !machine__is_default_guest(machine)) goto discard_symbol; } @@ -954,8 +957,10 @@ static int maps__split_kallsyms(struct maps *kmaps, st= ruct dso *dso, u64 delta, } add_symbol: if (curr_map !=3D initial_map) { + struct dso *curr_map_dso =3D map__dso(curr_map); + rb_erase_cached(&pos->rb_node, root); - symbols__insert(&curr_map->dso->symbols, pos); + symbols__insert(&curr_map_dso->symbols, pos); ++moved; } else ++count; @@ -969,7 +974,7 @@ static int maps__split_kallsyms(struct maps *kmaps, str= uct dso *dso, u64 delta, if (curr_map !=3D initial_map && dso->kernel =3D=3D DSO_SPACE__KERNEL_GUEST && machine__is_default_guest(maps__machine(kmaps))) { - dso__set_loaded(curr_map->dso); + dso__set_loaded(map__dso(curr_map)); } =20 return count + moved; @@ -1143,13 +1148,14 @@ static int do_validate_kcore_modules(const char *fi= lename, struct maps *kmaps) maps__for_each_entry(kmaps, old_node) { struct map *old_map =3D old_node->map; struct module_info *mi; + struct dso *dso; =20 if (!__map__is_kmodule(old_map)) { continue; } - + dso =3D map__dso(old_map); /* Module must be in memory at the same address */ - mi =3D find_module(old_map->dso->short_name, &modules); + mi =3D find_module(dso->short_name, &modules); if (!mi || mi->start !=3D old_map->start) { err =3D -EINVAL; goto out; @@ -2045,14 +2051,17 @@ int dso__load(struct dso *dso, struct map *map) =20 static int map__strcmp(const void *a, const void *b) { - const struct map *ma =3D *(const struct map **)a, *mb =3D *(const struct = map **)b; - return strcmp(ma->dso->short_name, mb->dso->short_name); + const struct dso *dso_a =3D map__dso(*(const struct map **)a); + const struct dso *dso_b =3D map__dso(*(const struct map **)b); + + return strcmp(dso_a->short_name, dso_b->short_name); } =20 static int map__strcmp_name(const void *name, const void *b) { - const struct map *map =3D *(const struct map **)b; - return strcmp(name, map->dso->short_name); + const struct dso *dso =3D map__dso(*(const struct map **)b); + + return strcmp(name, dso->short_name); } =20 void __maps__sort_by_name(struct maps *maps) @@ -2109,10 +2118,13 @@ 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 && - strcmp(maps->last_search_by_name->dso->short_name, name) =3D=3D 0) { - map =3D maps->last_search_by_name; - goto out_unlock; + if (maps->last_search_by_name) { + const struct dso *dso =3D map__dso(maps->last_search_by_name); + + if (strcmp(dso->short_name, name) =3D=3D 0) { + map =3D maps->last_search_by_name; + goto out_unlock; + } } /* * If we have maps->maps_by_name, then the name isn't in the rbtree, @@ -2125,8 +2137,11 @@ struct map *maps__find_by_name(struct maps *maps, co= nst char *name) =20 /* Fallback to traversing the rbtree... */ maps__for_each_entry(maps, rb_node) { + struct dso *dso; + map =3D rb_node->map; - if (strcmp(map->dso->short_name, name) =3D=3D 0) { + dso =3D map__dso(map); + if (strcmp(dso->short_name, name) =3D=3D 0) { maps->last_search_by_name =3D map; goto out_unlock; } diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index 57b95c1d7e39..fbd1a882b013 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -693,12 +693,14 @@ int perf_event__synthesize_modules(struct perf_tool *= tool, perf_event__handler_t =20 maps__for_each_entry(maps, pos) { struct map *map =3D pos->map; + struct dso *dso; =20 if (!__map__is_kmodule(map)) continue; =20 + dso =3D map__dso(map); if (symbol_conf.buildid_mmap2) { - size =3D PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); + size =3D PERF_ALIGN(dso->long_name_len + 1, sizeof(u64)); event->mmap2.header.type =3D PERF_RECORD_MMAP2; event->mmap2.header.size =3D (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size)); @@ -708,12 +710,11 @@ int perf_event__synthesize_modules(struct perf_tool *= tool, perf_event__handler_t event->mmap2.len =3D map->end - map->start; event->mmap2.pid =3D machine->pid; =20 - memcpy(event->mmap2.filename, map->dso->long_name, - map->dso->long_name_len + 1); + memcpy(event->mmap2.filename, dso->long_name, dso->long_name_len + 1); =20 perf_record_mmap2__read_build_id(&event->mmap2, machine, false); } else { - size =3D PERF_ALIGN(map->dso->long_name_len + 1, sizeof(u64)); + size =3D PERF_ALIGN(dso->long_name_len + 1, sizeof(u64)); event->mmap.header.type =3D PERF_RECORD_MMAP; event->mmap.header.size =3D (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size)); @@ -723,8 +724,7 @@ int perf_event__synthesize_modules(struct perf_tool *to= ol, perf_event__handler_t event->mmap.len =3D map->end - map->start; event->mmap.pid =3D machine->pid; =20 - memcpy(event->mmap.filename, map->dso->long_name, - map->dso->long_name_len + 1); + memcpy(event->mmap.filename, dso->long_name, dso->long_name_len + 1); } =20 if (perf_tool__process_synth_event(tool, event, machine, process) !=3D 0= ) { diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 292585a52281..42fdc80a6f2e 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -448,23 +448,22 @@ struct thread *thread__main_thread(struct machine *ma= chine, struct thread *threa int thread__memcpy(struct thread *thread, struct machine *machine, void *buf, u64 ip, int len, bool *is64bit) { - u8 cpumode =3D PERF_RECORD_MISC_USER; - struct addr_location al; - long offset; + u8 cpumode =3D PERF_RECORD_MISC_USER; + struct addr_location al; + long offset; =20 - if (machine__kernel_ip(machine, ip)) - cpumode =3D PERF_RECORD_MISC_KERNEL; + if (machine__kernel_ip(machine, ip)) + cpumode =3D PERF_RECORD_MISC_KERNEL; =20 - if (!thread__find_map(thread, cpumode, ip, &al) || !al.map->dso || - al.map->dso->data.status =3D=3D DSO_DATA_STATUS_ERROR || - map__load(al.map) < 0) - return -1; + if (!thread__find_map(thread, cpumode, ip, &al) || !map__dso(al.map) || + map__dso(al.map)->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); - if (is64bit) - *is64bit =3D al.map->dso->is_64_bit; + offset =3D al.map->map_ip(al.map, ip); + if (is64bit) + *is64bit =3D map__dso(al.map)->is_64_bit; =20 - return dso__data_read_offset(al.map->dso, machine, offset, buf, len= ); + return dso__data_read_offset(map__dso(al.map), machine, offset, buf, len); } =20 void thread__free_stitch_list(struct thread *thread) diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 94aa40f6e348..c8cba9d4bfd9 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -52,7 +52,7 @@ static int __report_module(struct addr_location *al, u64 = ip, thread__find_symbol(ui->thread, PERF_RECORD_MISC_USER, ip, al); =20 if (al->map) - dso =3D al->map->dso; + dso =3D map__dso(al->map); =20 if (!dso) return 0; @@ -134,17 +134,17 @@ static int access_dso_mem(struct unwind_info *ui, Dwa= rf_Addr addr, { struct addr_location al; ssize_t size; + struct dso *dso; =20 if (!thread__find_map(ui->thread, PERF_RECORD_MISC_USER, addr, &al)) { pr_debug("unwind: no map for %lx\n", (unsigned long)addr); return -1; } - - if (!al.map->dso) + dso =3D map__dso(al.map); + if (!dso) return -1; =20 - size =3D dso__data_read_addr(al.map->dso, al.map, ui->machine, - addr, (u8 *) data, sizeof(*data)); + size =3D dso__data_read_addr(dso, al.map, ui->machine, addr, (u8 *) data,= sizeof(*data)); =20 return !(size =3D=3D sizeof(*data)); } diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 835c39efb80d..ec777ee11493 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -147,7 +147,7 @@ static enum dso_type machine__thread_dso_type(struct ma= chine *machine, struct map_rb_node *rb_node; =20 maps__for_each_entry(thread->maps, rb_node) { - struct dso *dso =3D rb_node->map->dso; + struct dso *dso =3D map__dso(rb_node->map); =20 if (!dso || dso->long_name[0] !=3D '/') continue; --=20 2.40.0.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 B13BEC6FD1D for ; Mon, 20 Mar 2023 21:24:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230323AbjCTVYc (ORCPT ); Mon, 20 Mar 2023 17:24:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229898AbjCTVYP (ORCPT ); Mon, 20 Mar 2023 17:24:15 -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 D742818AAB for ; Mon, 20 Mar 2023 14:23:45 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id e11-20020a5b004b000000b00b37118ce5a7so14509002ybp.10 for ; Mon, 20 Mar 2023 14:23:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347420; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=YVpDoD1EtljxxnMNg4hbmCXcWrkBwNDgBIuGmLtz0Po=; b=kQjNUMYCRA9X+bGmigd7EV5+58PYFjRQlqIcBD7mec8AqXOH5n55McSbrO2WtbIO7m 003lgJwSRM04TBlUu5qNhdGiM2shzH2Z+ca6HVVgfpRJnJ87eALQiuv0KX68u1lYufBq HubFvQqxxhrb25vbVmBq5H2sis421IqeyU3M7P/ilSPEo8744985s/nb/bQq0xorniFV V9iFHMCH/5S8GNX6mSDLattfjl+xgy+Ymp8n2dP21tVgGCB+p6Et2Dmss4ZtIKPCicbw /qN8gjMBx2DLzIWrZdQA/VACvwdjkTnT7ekgI4FpU9pyn1o/wEFcSlqKJPW/aPpbnOQg pCOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347420; 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=YVpDoD1EtljxxnMNg4hbmCXcWrkBwNDgBIuGmLtz0Po=; b=gCAKWXB83sITPy4DqYATjhmOXWvgj8txLuar4iZxCL5NWnOIGnXXhTPdhXYPMAhzjf hQKk+vvYcBK/yhiIiLZnsfCCOBw1D2qi/yR9nAm7Wuo5Jo7tIaBa7tRlqzZAKzqnUV20 4VpdhLRHqBr/1Mb3WAi4VvNSdcjWFvtN+pP98Fjpa074BtK5LdBR8ySWCDS/lh23ocwW SSWBsIwP25Rfb1/RTBdGkxpHnW4w0oK1x6kq5cChT0M/ro5TZhWtWxvZWi4+F1tVcP8F 4SMvrr6uXv8pUT4Kq0ncz2Ru8dNwv06PWZ1UKHj7XE0MGCqpg5M6N5PBfhutbVVUeyS3 aylw== X-Gm-Message-State: AO0yUKWbRSd4wyOp6uEgSNKO5Y0CXf9KwQ03m0jwvn3CjjdlbaSchdOE WRhzPnJWnLpWy4Z+L1BGQWMF1rLj2cOk X-Google-Smtp-Source: AK7set8haAcnyjN1MgWHAZg7+mqm7/pM8mPvyXP/wX13wIx67RQQptcH1/gKTvvf3/0Sx89P+jRUaEMw9wqd X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a81:e50d:0:b0:541:a0cc:2a09 with SMTP id s13-20020a81e50d000000b00541a0cc2a09mr10933951ywl.7.1679347420460; Mon, 20 Mar 2023 14:23:40 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:36 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-6-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 05/17] perf map: Add accessor for start and end 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, start and end are frequently accessed variables. Add an accessor so that the reference count check is only necessary in one place. Signed-off-by: Ian Rogers --- tools/perf/arch/x86/tests/dwarf-unwind.c | 2 +- tools/perf/arch/x86/util/event.c | 4 +- tools/perf/builtin-buildid-list.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/tests/code-reading.c | 8 +-- tools/perf/tests/maps.c | 4 +- tools/perf/tests/mmap-thread-lookup.c | 2 +- tools/perf/tests/vmlinux-kallsyms.c | 14 +++--- tools/perf/util/annotate.c | 4 +- tools/perf/util/dlfilter.c | 8 +-- tools/perf/util/intel-pt.c | 8 +-- tools/perf/util/machine.c | 14 +++--- tools/perf/util/map.c | 8 +-- tools/perf/util/map.h | 12 ++++- tools/perf/util/maps.c | 30 ++++++------ tools/perf/util/probe-event.c | 4 +- .../scripting-engines/trace-event-python.c | 6 +-- tools/perf/util/symbol-elf.c | 8 +-- tools/perf/util/symbol.c | 49 ++++++++++--------- tools/perf/util/symbol_fprintf.c | 2 +- tools/perf/util/synthetic-events.c | 16 +++--- tools/perf/util/unwind-libdw.c | 6 +-- 24 files changed, 114 insertions(+), 103 deletions(-) diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86= /tests/dwarf-unwind.c index a54dea7c112f..497593be80f2 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -33,7 +33,7 @@ static int sample_ustack(struct perf_sample *sample, return -1; } =20 - stack_size =3D map->end - sp; + stack_size =3D map__end(map) - sp; stack_size =3D stack_size > STACK_SIZE ? STACK_SIZE : stack_size; =20 memcpy(buf, (void *) sp, stack_size); diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/ev= ent.c index 17bf60babfbd..3b2475707756 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -59,8 +59,8 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *= tool, =20 event->mmap.header.size =3D size; =20 - event->mmap.start =3D map->start; - event->mmap.len =3D map->end - map->start; + event->mmap.start =3D map__start(map); + event->mmap.len =3D map__size(map); event->mmap.pgoff =3D map->pgoff; event->mmap.pid =3D machine->pid; =20 diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid= -list.c index cad9ed44ce7c..eea28cbcc0b7 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -30,7 +30,7 @@ static int buildid__map_cb(struct map *map, void *arg __m= aybe_unused) memset(bid_buf, 0, sizeof(bid_buf)); if (dso->has_build_id) build_id__sprintf(&dso->bid, bid_buf); - printf("%s %16" PRIx64 " %16" PRIx64, bid_buf, map->start, map->end); + printf("%s %16" PRIx64 " %16" PRIx64, bid_buf, map__start(map), map__end(= map)); if (dso->long_name !=3D NULL) { printf(" %s", dso->long_name); } else if (dso->short_name !=3D NULL) { diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 02ca87c13e91..4ce1aef3e253 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -847,7 +847,7 @@ static size_t maps__fprintf_task(struct maps *maps, int= indent, FILE *fp) const struct dso *dso =3D map__dso(map); =20 printed +=3D fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRI= x64 " %" PRIu64 " %s\n", - indent, "", map->start, map->end, + indent, "", map__start(map), map__end(map), map->prot & PROT_READ ? 'r' : '-', map->prot & PROT_WRITE ? 'w' : '-', map->prot & PROT_EXEC ? 'x' : '-', diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 9c7eb900ff7c..eb49689d0f00 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1209,7 +1209,7 @@ static int ip__fprintf_sym(uint64_t addr, struct thre= ad *thread, if (al.addr < al.sym->end) off =3D al.addr - al.sym->start; else - off =3D al.addr - al.map->start - al.sym->start; + off =3D al.addr - map__start(al.map) - al.sym->start; printed +=3D fprintf(fp, "\t%s", al.sym->name); if (off) printed +=3D fprintf(fp, "%+d", off); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 5010eee8fbae..b45565f718f4 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -183,7 +183,7 @@ static void ui__warn_map_erange(struct map *map, struct= symbol *sym, u64 ip) "Not all samples will be on the annotation output.\n\n" "Please report to linux-kernel@vger.kernel.org\n", ip, dso->long_name, dso__symtab_origin(dso), - map->start, map->end, sym->start, sym->end, + map__start(map), map__end(map), sym->start, sym->end, sym->binding =3D=3D STB_GLOBAL ? 'g' : sym->binding =3D=3D STB_LOCAL ? 'l' : 'w', sym->name, err ? "[unknown]" : uts.machine, diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-readin= g.c index 936c61546e64..1545fcaa95c6 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -265,8 +265,8 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, len =3D BUFSZ; =20 /* Do not go off the map */ - if (addr + len > al.map->end) - len =3D al.map->end - addr; + if (addr + len > map__end(al.map)) + len =3D map__end(al.map) - addr; =20 /* Read the object code using perf */ ret_len =3D dso__data_read_offset(dso, maps__machine(thread->maps), @@ -291,7 +291,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, size_t d; =20 for (d =3D 0; d < state->done_cnt; d++) { - if (state->done[d] =3D=3D al.map->start) { + if (state->done[d] =3D=3D map__start(al.map)) { pr_debug("kcore map tested already"); pr_debug(" - skipping\n"); goto out; @@ -301,7 +301,7 @@ static int read_object_code(u64 addr, size_t len, u8 cp= umode, pr_debug("Too many kcore maps - skipping\n"); goto out; } - state->done[state->done_cnt++] =3D al.map->start; + state->done[state->done_cnt++] =3D map__start(al.map); } =20 objdump_name =3D dso->long_name; diff --git a/tools/perf/tests/maps.c b/tools/perf/tests/maps.c index ae7028fbf79e..fd0c464fcf95 100644 --- a/tools/perf/tests/maps.c +++ b/tools/perf/tests/maps.c @@ -24,8 +24,8 @@ static int check_maps(struct map_def *merged, unsigned in= t size, struct maps *ma if (i > 0) TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i = =3D=3D size)); =20 - TEST_ASSERT_VAL("wrong map start", map->start =3D=3D merged[i].start); - TEST_ASSERT_VAL("wrong map end", map->end =3D=3D merged[i].end); + 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= ); =20 diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-= thread-lookup.c index a4301fc7b770..5cc4644e353d 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -202,7 +202,7 @@ static int mmap_events(synth_cb synth) break; } =20 - pr_debug("map %p, addr %" PRIx64 "\n", al.map, al.map->start); + pr_debug("map %p, addr %" PRIx64 "\n", al.map, map__start(al.map)); } =20 machine__delete_threads(machine); diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux= -kallsyms.c index c614c2db7e89..0a75623172c2 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -267,7 +267,7 @@ static int test__vmlinux_matches_kallsyms(struct test_s= uite *test __maybe_unused =20 continue; } - } else if (mem_start =3D=3D kallsyms.vmlinux_map->end) { + } else if (mem_start =3D=3D map__end(kallsyms.vmlinux_map)) { /* * Ignore aliases to _etext, i.e. to the end of the kernel text area, * such as __indirect_thunk_end. @@ -319,14 +319,14 @@ static int test__vmlinux_matches_kallsyms(struct test= _suite *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); - mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, map->end); + mem_start =3D vmlinux_map->unmap_ip(vmlinux_map, map__start(map)); + mem_end =3D vmlinux_map->unmap_ip(vmlinux_map, map__end(map)); =20 pair =3D maps__find(kallsyms.kmaps, mem_start); if (pair =3D=3D NULL || pair->priv) continue; =20 - if (pair->start =3D=3D mem_start) { + if (map__start(pair) =3D=3D mem_start) { struct dso *dso =3D map__dso(map); =20 if (!header_printed) { @@ -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->end, map->pgoff, dso->name); - if (mem_end !=3D pair->end) + map__start(map), map__end(map), map->pgoff, dso->name); + if (mem_end !=3D map__end(pair)) pr_info(":\nWARN: *%" PRIx64 "-%" PRIx64 " %" PRIx64, - pair->start, pair->end, pair->pgoff); + map__start(pair), map__end(pair), pair->pgoff); pr_info(" %s\n", dso->name); pair->priv =3D 1; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 9494b34e84fc..f60f5efb2ad9 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1016,13 +1016,13 @@ int addr_map_symbol__account_cycles(struct addr_map= _symbol *ams, if (start && (start->ms.sym =3D=3D ams->ms.sym || (ams->ms.sym && - start->addr =3D=3D ams->ms.sym->start + ams->ms.map->start))) + start->addr =3D=3D ams->ms.sym->start + map__start(ams->ms.map)))) saddr =3D start->al_addr; if (saddr =3D=3D 0) pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx6= 4" saddr %"PRIx64"\n", ams->addr, start ? start->addr : 0, - ams->ms.sym ? ams->ms.sym->start + ams->ms.map->start : 0, + ams->ms.sym ? ams->ms.sym->start + map__start(ams->ms.map) : 0, saddr); err =3D symbol__account_cycles(ams->al_addr, saddr, ams->ms.sym, cycles); if (err) diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index 8a7ffe0d805a..fe401fa4be02 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -51,7 +51,7 @@ static void al_to_d_al(struct addr_location *al, struct p= erf_dlfilter_al *d_al) if (al->addr < sym->end) d_al->symoff =3D al->addr - sym->start; else - d_al->symoff =3D al->addr - al->map->start - sym->start; + d_al->symoff =3D al->addr - map__start(al->map) - sym->start; d_al->sym_binding =3D sym->binding; } else { d_al->sym =3D NULL; @@ -268,7 +268,7 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip,= void *buf, __u32 len) =20 map =3D al->map; =20 - if (map && ip >=3D map->start && ip < map->end && + if (map && ip >=3D map__start(map) && ip < map__end(map) && machine__kernel_ip(d->machine, ip) =3D=3D machine__kernel_ip(d->machi= ne, d->sample->ip)) goto have_map; =20 @@ -279,8 +279,8 @@ static __s32 dlfilter__object_code(void *ctx, __u64 ip,= void *buf, __u32 len) map =3D a.map; have_map: offset =3D map->map_ip(map, ip); - if (ip + len >=3D map->end) - len =3D map->end - 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); } =20 diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 8cec88e09792..a2e62daa708e 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c @@ -887,7 +887,7 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn= *intel_pt_insn, goto out_no_cache; } =20 - if (*ip >=3D al.map->end) + if (*ip >=3D map__end(al.map)) break; =20 offset +=3D intel_pt_insn->length; @@ -2750,7 +2750,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u6= 4 *ptss_ip) if (sym->binding =3D=3D STB_GLOBAL && !strcmp(sym->name, "__switch_to")) { ip =3D map->unmap_ip(map, sym->start); - if (ip >=3D map->start && ip < map->end) { + if (ip >=3D map__start(map) && ip < map__end(map)) { switch_ip =3D ip; break; } @@ -2768,7 +2768,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 (!strcmp(sym->name, ptss)) { ip =3D map->unmap_ip(map, sym->start); - if (ip >=3D map->start && ip < map->end) { + if (ip >=3D map__start(map) && ip < map__end(map)) { *ptss_ip =3D ip; break; } @@ -3356,7 +3356,7 @@ static int intel_pt_process_aux_output_hw_id(struct i= ntel_pt *pt, static int intel_pt_find_map(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al) { - if (!al->map || addr < al->map->start || addr >=3D al->map->end) { + if (!al->map || addr < map__start(al->map) || addr >=3D map__end(al->map)= ) { if (!thread__find_map(thread, cpumode, addr, al)) return -1; } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 6e32344e66dc..08fb3ab0c205 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -902,7 +902,7 @@ static int machine__process_ksymbol_register(struct mac= hine *machine, } =20 map->start =3D event->ksymbol.addr; - map->end =3D map->start + event->ksymbol.len; + map->end =3D map__start(map) + event->ksymbol.len; err =3D maps__insert(machine__kernel_maps(machine), map); map__put(map); if (err) @@ -918,7 +918,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), + sym =3D symbol__new(map->map_ip(map, map__start(map)), event->ksymbol.len, 0, 0, event->ksymbol.name); if (!sym) @@ -943,7 +943,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)); + sym =3D dso__find_symbol(dso, map->map_ip(map, map__start(map))); if (sym) dso__delete_symbol(dso, sym); } @@ -1216,7 +1216,7 @@ int machine__create_extra_kernel_map(struct machine *= machine, =20 if (!err) { pr_debug2("Added extra kernel map %s %" PRIx64 "-%" PRIx64 "\n", - kmap->name, map->start, map->end); + kmap->name, map__start(map), map__end(map)); } =20 map__put(map); @@ -1721,7 +1721,7 @@ int machine__create_kernel_maps(struct machine *machi= ne) struct map_rb_node *next =3D map_rb_node__next(rb_node); =20 if (next) - machine__set_kernel_mmap(machine, start, next->map->start); + machine__set_kernel_mmap(machine, start, map__start(next->map)); } =20 out_put: @@ -1794,7 +1794,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 + xm->end - xm->start; + 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); @@ -3288,7 +3288,7 @@ int machine__get_kernel_start(struct machine *machine) * kernel_start =3D 1ULL << 63 for x86_64. */ if (!err && !machine__is(machine, "x86_64")) - machine->kernel_start =3D map->start; + machine->kernel_start =3D map__start(map); } return err; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 90062af6675a..416fc449bde8 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->end, map->pgoff, dso->name); + map__start(map), map__end(map), map->pgoff, dso->name); } =20 size_t map__fprintf_dsoname(struct map *map, FILE *fp) @@ -558,7 +558,7 @@ bool map__contains_symbol(const struct map *map, const = struct symbol *sym) { u64 ip =3D map->unmap_ip(map, sym->start); =20 - return ip >=3D map->start && ip < map->end; + return ip >=3D map__start(map) && ip < map__end(map); } =20 struct kmap *__map__kmap(struct map *map) @@ -592,12 +592,12 @@ struct maps *map__kmaps(struct map *map) =20 u64 map__map_ip(const struct map *map, u64 ip) { - return ip - map->start + map->pgoff; + return ip - map__start(map) + map->pgoff; } =20 u64 map__unmap_ip(const struct map *map, u64 ip) { - return ip + map->start - map->pgoff; + return ip + map__start(map) - map->pgoff; } =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 36c5add0144d..16646b94fa3a 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -52,9 +52,19 @@ static inline struct dso *map__dso(const struct map *map) return map->dso; } =20 +static inline u64 map__start(const struct map *map) +{ + return map->start; +} + +static inline u64 map__end(const struct map *map) +{ + return map->end; +} + static inline size_t map__size(const struct map *map) { - return map->end - map->start; + return map__end(map) - map__start(map); } =20 /* rip/ip <-> addr suitable for passing to `objdump --start-address=3D` */ diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 09ec6bbafcbc..1fd57db72226 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -34,7 +34,7 @@ static int __maps__insert(struct maps *maps, struct map *= map) { struct rb_node **p =3D &maps__entries(maps)->rb_node; struct rb_node *parent =3D NULL; - const u64 ip =3D map->start; + const u64 ip =3D map__start(map); struct map_rb_node *m, *new_rb_node; =20 new_rb_node =3D malloc(sizeof(*new_rb_node)); @@ -47,7 +47,7 @@ static int __maps__insert(struct maps *maps, struct map *= map) while (*p !=3D NULL) { parent =3D *p; m =3D rb_entry(parent, struct map_rb_node, rb_node); - if (ip < m->map->start) + if (ip < map__start(m->map)) p =3D &(*p)->rb_left; else p =3D &(*p)->rb_right; @@ -229,7 +229,7 @@ struct symbol *maps__find_symbol_by_name(struct maps *m= aps, const char *name, st =20 int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) { - if (ams->addr < ams->ms.map->start || ams->addr >=3D ams->ms.map->end) { + if (ams->addr < map__start(ams->ms.map) || ams->addr >=3D map__end(ams->m= s.map)) { if (maps =3D=3D NULL) return -1; ams->ms.map =3D maps__find(maps, ams->addr); @@ -283,9 +283,9 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) while (next) { struct map_rb_node *pos =3D rb_entry(next, struct map_rb_node, rb_node); =20 - if (pos->map->end > map->start) { + if (map__end(pos->map) > map__start(map)) { first =3D next; - if (pos->map->start <=3D map->start) + if (map__start(pos->map) <=3D map__start(map)) break; next =3D next->rb_left; } else @@ -301,7 +301,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) * Stop if current map starts after map->end. * Maps are ordered by start: next will not overlap for sure. */ - if (pos->map->start >=3D map->end) + if (map__start(pos->map) >=3D map__end(map)) break; =20 if (verbose >=3D 2) { @@ -321,7 +321,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) * Now check if we need to create new maps for areas not * overlapped by the new map: */ - if (map->start > pos->map->start) { + if (map__start(map) > map__start(pos->map)) { struct map *before =3D map__clone(pos->map); =20 if (before =3D=3D NULL) { @@ -329,7 +329,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) goto put_map; } =20 - before->end =3D map->start; + before->end =3D map__start(map); err =3D __maps__insert(maps, before); if (err) goto put_map; @@ -339,7 +339,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) map__put(before); } =20 - if (map->end < pos->map->end) { + if (map->end < map__end(pos->map)) { struct map *after =3D map__clone(pos->map); =20 if (after =3D=3D NULL) { @@ -347,10 +347,10 @@ int maps__fixup_overlappings(struct maps *maps, struc= t map *map, FILE *fp) goto put_map; } =20 - after->start =3D map->end; - after->pgoff +=3D map->end - pos->map->start; - assert(pos->map->map_ip(pos->map, map->end) =3D=3D - after->map_ip(after, map->end)); + 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))); err =3D __maps__insert(maps, after); if (err) goto put_map; @@ -430,9 +430,9 @@ struct map *maps__find(struct maps *maps, u64 ip) p =3D maps__entries(maps)->rb_node; while (p !=3D NULL) { m =3D rb_entry(p, struct map_rb_node, rb_node); - if (ip < m->map->start) + if (ip < map__start(m->map)) p =3D p->rb_left; - else if (ip >=3D m->map->end) + else if (ip >=3D map__end(m->map)) p =3D p->rb_right; else goto out; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index b26670a26005..4d9dbeeb6014 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -143,7 +143,7 @@ static int kernel_get_symbol_address_by_name(const char= *name, u64 *addr, return -ENOENT; *addr =3D map->unmap_ip(map, sym->start) - ((reloc) ? 0 : map->reloc) - - ((reladdr) ? map->start : 0); + ((reladdr) ? map__start(map) : 0); } return 0; } @@ -257,7 +257,7 @@ static bool kprobe_warn_out_range(const char *symbol, u= 64 address) =20 map =3D kernel_get_module_map(NULL); if (map) { - ret =3D address <=3D map->start || map->end < address; + ret =3D address <=3D map__start(map) || map__end(map) < address; if (ret) pr_warning("%s is out of .text, skip it.\n", symbol); map__put(map); diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools= /perf/util/scripting-engines/trace-event-python.c index b8e5c6f61d80..cbf09eaf3734 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -409,7 +409,7 @@ static unsigned long get_offset(struct symbol *sym, str= uct addr_location *al) if (al->addr < sym->end) offset =3D al->addr - sym->start; else - offset =3D al->addr - al->map->start - sym->start; + offset =3D al->addr - map__start(al->map) - sym->start; =20 return offset; } @@ -788,9 +788,9 @@ static void set_sym_in_dict(PyObject *dict, struct addr= _location *al, pydict_set_item_string_decref(dict, dso_bid_field, _PyUnicode_FromString(sbuild_id)); pydict_set_item_string_decref(dict, dso_map_start, - PyLong_FromUnsignedLong(al->map->start)); + PyLong_FromUnsignedLong(map__start(al->map))); pydict_set_item_string_decref(dict, dso_map_end, - PyLong_FromUnsignedLong(al->map->end)); + PyLong_FromUnsignedLong(map__end(al->map))); } if (al->sym) { pydict_set_item_string_decref(dict, sym_field, diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 97085ad7fe9b..0542985ecaf6 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1349,7 +1349,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , 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 + shdr->sh_size; + 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; @@ -1391,7 +1391,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, u64 start =3D sym->st_value; =20 if (kmodule) - start +=3D map->start + shdr->sh_offset; + start +=3D map__start(map) + shdr->sh_offset; =20 curr_dso =3D dso__new(dso_name); if (curr_dso =3D=3D NULL) @@ -1409,7 +1409,7 @@ static int dso__process_kernel_symbol(struct dso *dso= , struct map *map, =20 if (adjust_kernel_syms) { curr_map->start =3D shdr->sh_addr + ref_reloc(kmap); - curr_map->end =3D curr_map->start + shdr->sh_size; + curr_map->end =3D map__start(curr_map) + shdr->sh_size; curr_map->pgoff =3D shdr->sh_offset; } else { curr_map->map_ip =3D curr_map->unmap_ip =3D identity__map_ip; @@ -1530,7 +1530,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 - dso->text_offset; + 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 13176ed5bd27..c76582dbe7ff 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -278,8 +278,8 @@ void maps__fixup_end(struct maps *maps) down_write(maps__lock(maps)); =20 maps__for_each_entry(maps, curr) { - if (prev !=3D NULL && !prev->map->end) - prev->map->end =3D curr->map->start; + if (prev !=3D NULL && !map__end(prev->map)) + prev->map->end =3D map__start(curr->map); =20 prev =3D curr; } @@ -288,7 +288,7 @@ void maps__fixup_end(struct maps *maps) * We still haven't the actual symbols, so guess the * last map final address. */ - if (curr && !curr->map->end) + if (curr && !map__end(curr->map)) curr->map->end =3D ~0ULL; =20 up_write(maps__lock(maps)); @@ -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 curr_map->start - curr_map->pgoff; - if (pos->end > curr_map->end) - pos->end =3D curr_map->end; + pos->start -=3D map__start(curr_map) - curr_map->pgoff; + if (pos->end > map__end(curr_map)) + pos->end =3D map__end(curr_map); if (pos->end) - pos->end -=3D curr_map->start - curr_map->pgoff; + pos->end -=3D map__start(curr_map) - curr_map->pgoff; symbols__insert(&curr_map_dso->symbols, pos); ++count; } @@ -1156,7 +1156,7 @@ static int do_validate_kcore_modules(const char *file= name, struct maps *kmaps) dso =3D map__dso(old_map); /* Module must be in memory at the same address */ mi =3D find_module(dso->short_name, &modules); - if (!mi || mi->start !=3D old_map->start) { + if (!mi || mi->start !=3D map__start(old_map)) { err =3D -EINVAL; goto out; } @@ -1250,7 +1250,7 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff,= void *data) return -ENOMEM; } =20 - list_node->map->end =3D list_node->map->start + len; + list_node->map->end =3D map__start(list_node->map) + len; list_node->map->pgoff =3D pgoff; =20 list_add(&list_node->node, &md->maps); @@ -1272,21 +1272,21 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) struct map *old_map =3D rb_node->map; =20 /* no overload with this one */ - if (new_map->end < old_map->start || - new_map->start >=3D old_map->end) + if (map__end(new_map) < map__start(old_map) || + map__start(new_map) >=3D map__end(old_map)) continue; =20 - if (new_map->start < old_map->start) { + if (map__start(new_map) < map__start(old_map)) { /* * |new...... * |old.... */ - if (new_map->end < old_map->end) { + if (map__end(new_map) < map__end(old_map)) { /* * |new......| -> |new..| * |old....| -> |old....| */ - new_map->end =3D old_map->start; + new_map->end =3D map__start(old_map); } else { /* * |new.............| -> |new..| |new..| @@ -1306,17 +1306,17 @@ int maps__merge_in(struct maps *kmaps, struct map *= new_map) goto out; } =20 - m->map->end =3D old_map->start; + m->map->end =3D map__start(old_map); list_add_tail(&m->node, &merged); - new_map->pgoff +=3D old_map->end - new_map->start; - new_map->start =3D old_map->end; + new_map->pgoff +=3D map__end(old_map) - map__start(new_map); + new_map->start =3D map__end(old_map); } } else { /* * |new...... * |old.... */ - if (new_map->end < old_map->end) { + if (map__end(new_map) < map__end(old_map)) { /* * |new..| -> x * |old.........| -> |old.........| @@ -1329,8 +1329,8 @@ int maps__merge_in(struct maps *kmaps, struct map *ne= w_map) * |new......| -> |new...| * |old....| -> |old....| */ - new_map->pgoff +=3D old_map->end - new_map->start; - new_map->start =3D old_map->end; + new_map->pgoff +=3D map__end(old_map) - map__start(new_map); + new_map->start =3D map__end(old_map); } } } @@ -1427,9 +1427,10 @@ static int dso__load_kcore(struct dso *dso, struct m= ap *map, struct map_list_node *new_node; =20 list_for_each_entry(new_node, &md.maps, node) { - u64 new_size =3D new_node->map->end - new_node->map->start; + u64 new_size =3D map__size(new_node->map); =20 - if (!(stext >=3D new_node->map->start && stext < new_node->map->end)) + if (!(stext >=3D map__start(new_node->map) && + stext < map__end(new_node->map))) continue; =20 /* @@ -1455,8 +1456,8 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, new_node =3D list_entry(md.maps.next, struct map_list_node, node); list_del_init(&new_node->node); if (new_node->map =3D=3D replacement_map) { - map->start =3D new_node->map->start; - map->end =3D new_node->map->end; + map->start =3D map__start(new_node->map); + map->end =3D map__end(new_node->map); map->pgoff =3D new_node->map->pgoff; map->map_ip =3D new_node->map->map_ip; map->unmap_ip =3D new_node->map->unmap_ip; diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fpri= ntf.c index 2664fb65e47a..d9e5ad040b6a 100644 --- a/tools/perf/util/symbol_fprintf.c +++ b/tools/perf/util/symbol_fprintf.c @@ -30,7 +30,7 @@ size_t __symbol__fprintf_symname_offs(const struct symbol= *sym, if (al->addr < sym->end) offset =3D al->addr - sym->start; else - offset =3D al->addr - al->map->start - sym->start; + offset =3D al->addr - map__start(al->map) - sym->start; length +=3D fprintf(fp, "+0x%lx", offset); } return length; diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic= -events.c index fbd1a882b013..b2e4afa5efa1 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -706,8 +706,8 @@ int perf_event__synthesize_modules(struct perf_tool *to= ol, perf_event__handler_t (sizeof(event->mmap2.filename) - size)); memset(event->mmap2.filename + size, 0, machine->id_hdr_size); event->mmap2.header.size +=3D machine->id_hdr_size; - event->mmap2.start =3D map->start; - event->mmap2.len =3D map->end - map->start; + event->mmap2.start =3D map__start(map); + event->mmap2.len =3D map__size(map); event->mmap2.pid =3D machine->pid; =20 memcpy(event->mmap2.filename, dso->long_name, dso->long_name_len + 1); @@ -720,8 +720,8 @@ int perf_event__synthesize_modules(struct perf_tool *to= ol, perf_event__handler_t (sizeof(event->mmap.filename) - size)); memset(event->mmap.filename + size, 0, machine->id_hdr_size); event->mmap.header.size +=3D machine->id_hdr_size; - event->mmap.start =3D map->start; - event->mmap.len =3D map->end - map->start; + event->mmap.start =3D map__start(map); + event->mmap.len =3D map__size(map); event->mmap.pid =3D machine->pid; =20 memcpy(event->mmap.filename, dso->long_name, dso->long_name_len + 1); @@ -1143,8 +1143,8 @@ static int __perf_event__synthesize_kernel_mmap(struc= t perf_tool *tool, event->mmap2.header.size =3D (sizeof(event->mmap2) - (sizeof(event->mmap2.filename) - size) + machine->id_hdr_size); event->mmap2.pgoff =3D kmap->ref_reloc_sym->addr; - event->mmap2.start =3D map->start; - event->mmap2.len =3D map->end - event->mmap.start; + event->mmap2.start =3D map__start(map); + event->mmap2.len =3D map__end(map) - event->mmap.start; event->mmap2.pid =3D machine->pid; =20 perf_record_mmap2__read_build_id(&event->mmap2, machine, true); @@ -1156,8 +1156,8 @@ static int __perf_event__synthesize_kernel_mmap(struc= t perf_tool *tool, event->mmap.header.size =3D (sizeof(event->mmap) - (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); event->mmap.pgoff =3D kmap->ref_reloc_sym->addr; - event->mmap.start =3D map->start; - event->mmap.len =3D map->end - event->mmap.start; + event->mmap.start =3D map__start(map); + event->mmap.len =3D map__end(map) - event->mmap.start; event->mmap.pid =3D machine->pid; } =20 diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index c8cba9d4bfd9..b79f57e5648f 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 al->map->start - al->map->pgoff) + if (s !=3D map__start(al->map) - al->map->pgoff) mod =3D 0; } =20 if (!mod) mod =3D dwfl_report_elf(ui->dwfl, dso->short_name, dso->long_name, -1, - al->map->start - al->map->pgoff, false); + map__start(al->map) - al->map->pgoff, 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, - al->map->start - al->map->pgoff, false); + map__start(al->map) - al->map->pgoff, false); } =20 if (mod) { --=20 2.40.0.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 28C2AC761AF for ; Mon, 20 Mar 2023 21:24:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230167AbjCTVYz (ORCPT ); Mon, 20 Mar 2023 17:24:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47370 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229778AbjCTVYS (ORCPT ); Mon, 20 Mar 2023 17:24:18 -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 1D7A23844E for ; Mon, 20 Mar 2023 14:23:52 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-544b71b3114so124417637b3.13 for ; Mon, 20 Mar 2023 14:23:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347428; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=y10GnXOzH9U5tz9iFzVskmw05u/+9XHwA2jBfRW8OlY=; b=oddRU666Q86lKEA4bPXLjt2ayia1jSTcm7XmgFsfqW1X3OM7/W745vJ0DQlJTYFDo1 LSkqHO43iyvSQs3UM5O6rMHkcACaB55y+6zNQYmZzZxqn6lRO6ME1NYtMnoxqJUHfLhP JkdE7KiPziPgkUjJOor2ww26X7wFMC4xiDRmyEkAV/x45PtEVh+6kaIu80tXAc2ktmT7 cUw3SrXJs64RrcbXJzkvKXGPO2frEza4Fgu7KUvOakxpvGElFj/zIJzEFMh6AbEy0PsX IJRvzDeEIInuNuXqJeMUGa1Vetw9T5eavThgOg/b29Moh/dERgPlZ+ekouox40oalz/v oG+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347428; 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=y10GnXOzH9U5tz9iFzVskmw05u/+9XHwA2jBfRW8OlY=; b=08vrHRT7eqZ7npYQL/vRIsBsgKg159kClyTYc8gzhfkJu4HFf1cX672006+lJEkKNd rDFXELCxB0Uk5GMW4A4YLBLnfu87t7c2hrvZOLJC7QifQzWq3UDyZp92gosHaJa8x7DU l3OtOqlKqj+OZQTpiTVMXH1fGY9vgnvqzh2GTS54OmA56ZbFNNzAq0S6S5aqjC9k+fa4 4n/uU8/Mk6FjqH8Wj2m+Whm37mofidEdsmoQhdJxxfEQ//UjIrZzGW9LFgJREQvm5wjw AxUDkfQs6WmZSVahOSSDdr3NyxBePXoYzGK0vgiUzg5PRhjuqgbBXzGIznvJZ6xGY7uB /ngw== X-Gm-Message-State: AAQBX9fLAixt836yNLLFEDcDOYyto5AcDoqN/gLuvSsiATv9KO6PdFdg UjuU6smfRm5/AN890z+LNaHXFX8qvmQC X-Google-Smtp-Source: AKy350Zuufbof6FtUY4Vvd5jNW+C3yO83paEfqQhCYt6zbb/o1XGiVWkoUM/0JZyeyr3PJ3CNXBq0zzY0Jw5 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:1003:b0:b3c:637f:ad00 with SMTP id w3-20020a056902100300b00b3c637fad00mr6874ybt.5.1679347427908; Mon, 20 Mar 2023 14:23:47 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:37 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-7-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 06/17] 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 eb49689d0f00..21944adf4c17 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 08fb3ab0c205..5bf035b23a79 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -3053,7 +3053,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 @@ -3098,7 +3098,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 0542985ecaf6..93ae3f22fd03 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1351,8 +1351,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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 679D9C6FD1C for ; Mon, 20 Mar 2023 21:25:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230233AbjCTVY7 (ORCPT ); Mon, 20 Mar 2023 17:24:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230272AbjCTVY1 (ORCPT ); Mon, 20 Mar 2023 17:24:27 -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 24544392AC for ; Mon, 20 Mar 2023 14:23:57 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-544570e6d82so136839827b3.23 for ; Mon, 20 Mar 2023 14:23:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347435; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=C36mHW3dz6dIezbS8WwzDlxLsWuJC47WtVVE2OA1AAE=; b=rLWjfQPj0t9x03QTFHNcnVQoQTZF/L1gEM7JFj7NCbQ6YVe87AIcC7Y10ETmTatMLE bUB4uFwZd0K332lzK5mjG7me9LwpWZXShd/GMNknqSvIjTywnWKaNXRjYZ8mYjbE1Mwa kCw3BXU/Uc/0s2YUN5wirkTAgKDKCnbwmRiHtiR9dWPalBpZB4cvUQdHkHWd9cYAuWqu 9fsuCJqI/HfiZ1wVQupoVL5V7gWhedCB9qw1AxfeddwmY8y3F2hUV/sS8EsME20BSzD1 1nTku1j9zOUfXuGQc1JUfUUppH8bd8qvS12nnSAgSleHiX/yeEAqkZYgb5ulR6QJuC5+ AkHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347435; 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=C36mHW3dz6dIezbS8WwzDlxLsWuJC47WtVVE2OA1AAE=; b=pLY/a7lFZBM+LgkF9DtW7rDRMwmzY+u5MTwpNbwvQEZvv9iRyjMLIar/y3YNG8tQzj D2I7t+OGh6/hmYxqm6Lhvx0yRgwB05nq10Q73HYgfaqETel3HmZeUJPzuHqlO/Rd/57G yCBQu1/LsiLZlGlnpnuex9qMfuf9mETdI3vgR99YEr5laLr2+ml6Y0PlGlhB/m4OzFbN r5ZfU1i/eLet/PKd1u9r4XvqHusa0FAJ5490oTlatYJiK1x+OaQ2Um3k+gzsbc55LHB9 BYbsR6kJM6gtqISq07zTKbFPQIRDTAIsD8WLS58hEu3kRCQxHr/9HODujk4K7UV3pXg5 OuVg== X-Gm-Message-State: AAQBX9esmfDn9/pogVfdRkX7p8ElmuOMhWmEFLWtHLCdr5b/uTU6Q8lz YYK/l0GUF/NlhiCh16Ku4FYrZIT1f1HJ X-Google-Smtp-Source: AKy350YdoplFSstGffMhuDF60VNga00SzDVhBrClRS4cs3kDho1XTG6lHGnoE1XzYi7AwGMvP+LdizebBaGB X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:1027:b0:b4c:9333:293 with SMTP id x7-20020a056902102700b00b4c93330293mr456113ybt.11.1679347434934; Mon, 20 Mar 2023 14:23:54 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:38 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-8-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 07/17] 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 +- 23 files changed, 80 insertions(+), 65 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 3c8a19ebc496..40b1e53e2d23 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 21944adf4c17..9dc3193f7c1a 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 f60f5efb2ad9..e8570b7cc36f 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -280,7 +280,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; @@ -384,8 +385,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 @@ -408,7 +409,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) { @@ -889,7 +891,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)) { @@ -1985,8 +1987,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 0b47863d2460..9a76fc6484b4 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 5bf035b23a79..afb77bd161e2 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -918,7 +918,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) @@ -943,7 +943,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); } @@ -1278,7 +1278,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) @@ -3340,7 +3340,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 @@ -3383,17 +3383,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 1fd57db72226..ffd4a4a64026 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 d7b6b734bf90..321d4859ae16 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -318,7 +318,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); @@ -329,7 +329,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, @@ -1106,7 +1106,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, @@ -2063,9 +2063,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); } @@ -2077,7 +2077,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 c76582dbe7ff..128d4a66cc0e 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 42fdc80a6f2e..6fe503da712b 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -459,7 +459,7 @@ int thread__memcpy(struct thread *thread, struct machin= e *machine, map__dso(al.map)->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 map__dso(al.map)->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 --=20 2.40.0.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 48344C6FD1C for ; Mon, 20 Mar 2023 21:25:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230273AbjCTVZC (ORCPT ); Mon, 20 Mar 2023 17:25:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230308AbjCTVYb (ORCPT ); Mon, 20 Mar 2023 17:24:31 -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 8315D399EB for ; Mon, 20 Mar 2023 14:24:02 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-541a39df9f4so135794947b3.20 for ; Mon, 20 Mar 2023 14:24:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347441; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=z76sUNZwYgL2J4e+xgHI73pvJbJjEp+YXSErrQxEh7o=; b=FlyoHQJuMJrZe1yqABr+i0WtVSVKeALjh3mVnaYENRCUq7WCHFRBV7I8q0qUP2WK5y 7+js6lEfpaZY1vkiEXtBn2YFpe14tMXbTNw483uQ/04qxh7X/MtC//h+RPmaeXd/wGnl fbTyj7Lgm/AwoVi9NMhBtB8mq0PhfqSyRaRHJvhR3Qa+h5MkylLRwOO8L14BrCcboWGa VNoxKEUqdH4ZsgMU5E+s9QRM7mcyRcXdd8fZfXu/0zUsYnPdqXrwo3CRs0V52nQy40Zv sDingzlVPipMAxSGLbCsHRE2PFMEGNJOUVZm/uefzAA+dl7EK3F/o1oFA0GD6582O6o2 vEKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347441; 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=z76sUNZwYgL2J4e+xgHI73pvJbJjEp+YXSErrQxEh7o=; b=JBITrnWaQNej5HSL0EKYIjtqmZrmnZmsBf11hF8zljBLvAxv1d2yhnarJbokHOs6rI e7GoIxMejMZG/qf/vRLHJmQ7B1NeQEXl/BHRiq/6F4CmlvyghA7YDVBaMQhAwtR8yFSb sgJXKBE2eUbIUs1bLM31/1DHJidy1JtNVUEAu8QrPxp9QzoinL/h9AAcp6FlVGXhqiEH jJDLj9A6oKxS3QxpoQwsJWTLv2nKNb7+2bMTU7el/fDRqwqpI2gIuInHc4CSOFV171qi K3dTqglg5eAoUl+PsHoxkCHckTk+ioRdLOHDavLEp7pxywEEXX4cgUAICTwTfTQ9+gK1 mt4Q== X-Gm-Message-State: AO0yUKVBpwaigIN2A/jGzQvZ4zs8etWUOCOsS9c5Jczne6m1oBxyunl4 ri1riE9+Zjt/E3/JT3hSROV2ToOiMmYw X-Google-Smtp-Source: AK7set/uMY6Wdc56lynovtalfO23sq6qOsRtm/l0PbMp63JFrbHYQ6tz2Np08QrK/5QDWXTdMLj4o7jGOgEk X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a81:b284:0:b0:533:99bb:c296 with SMTP id q126-20020a81b284000000b0053399bbc296mr10251560ywh.5.1679347441448; Mon, 20 Mar 2023 14:24:01 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:39 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-9-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 08/17] 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 4ce1aef3e253..8650d9503b77 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -845,13 +845,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 321d4859ae16..31a8df42cb2f 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1499,7 +1499,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 @@ -1535,8 +1535,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 128d4a66cc0e..e3758519e4d1 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; @@ -1508,7 +1508,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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 91816C6FD1C for ; Mon, 20 Mar 2023 21:25:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230325AbjCTVZJ (ORCPT ); Mon, 20 Mar 2023 17:25:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230328AbjCTVYo (ORCPT ); Mon, 20 Mar 2023 17:24:44 -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 DC9552E82D for ; Mon, 20 Mar 2023 14:24:09 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-544539a729cso133234597b3.5 for ; Mon, 20 Mar 2023 14:24:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347449; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2i4YJs4tQ6IQ1Hen18/XhJnk7dBepvgDbeMX7/u62cc=; b=N1FUGGEH8YTujfk8nF52/4f4t68rCeI9a6d+ravdornaJH/jz45w4CQZf9FkfZjJCK kVcg7U3vDoYJaGkCReZHrT8zaJCUUXIEjQSTne0jJu5sD525nM2QdRTUEdVgM/xGEafY r7div5iMnj0L2SnPfVKXg42Gyp6eeVRDO4L0dyXYxLIpebOmayxnNAEtlerh6RI5U/ec 7VbI22HWjiQKHf0B4SFTIVrJ8HQnU2lDp3ZZ25eegOqYWrARj0+zW7GQBITTaECvnLtI qYFxTHG+PGO1k8jMRpF79uabMUeGqdpDYglsxwN4ZSKkpPwBGgh8yBZLe9hWORQEHqOa +AAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347449; 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=2i4YJs4tQ6IQ1Hen18/XhJnk7dBepvgDbeMX7/u62cc=; b=p6BUWBYjh0g5cU23BArR8zHqu0u9sKOQXhXcOMZf7WxE6YCPsT+B82OLckLZ69gvPf 3u3rfE4Uvq1WrXiqzNbJ48qFOtBvwWQlpcGfT6L8cYT8aw02SvTEF2uoUOvIsfQynV8/ cOJydgtNIwBPRnFcpPBSdpKh9+Q84YJU4vjCJSGXADlce2L3fn0kgkU7TSR299uzpGLx OvfWka3F3UFiNxxzzO17/w+ArC4YMGwdjM8asu9iSBRv5dfKjUNuCzPzMzJqZfS9Z4GA S6ddS5ePJiIclkax9re3jvb9z4e7rMCdE0pll2eLg32+KcRo3Q3uxleq13jOsongobtF BTvw== X-Gm-Message-State: AO0yUKXFofYm3z3Qs+EtM56k2eUwDEKCVYDwPFOvyPSqgJVoW+zmbvM8 Uw/2ak7TrOy6+HSL7UmzF7lhgZq3fx2U X-Google-Smtp-Source: AK7set9iHty3UpWHuzfDR/7IsSyMq15yKKzw6LM0HUS7yHyBvOYOE7kAXVXdLFYP4IN00jbOJvqepeVXh5w/ X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:1002:b0:a27:3ecc:ffe7 with SMTP id w2-20020a056902100200b00a273eccffe7mr6242921ybt.3.1679347448770; Mon, 20 Mar 2023 14:24:08 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:40 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-10-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 09/17] 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 8650d9503b77..c7e4160f64ad 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -853,7 +853,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 afb77bd161e2..916d98885128 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1276,9 +1276,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 e3758519e4d1..ec7a312e7cc1 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; } @@ -1458,7 +1458,7 @@ static int dso__load_kcore(struct dso *dso, struct ma= p *map, if (new_node->map =3D=3D replacement_map) { map->start =3D map__start(new_node->map); map->end =3D map__end(new_node->map); - map->pgoff =3D new_node->map->pgoff; + map->pgoff =3D map__pgoff(new_node->map); map->map_ip =3D new_node->map->map_ip; map->unmap_ip =3D new_node->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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 BFF0FC6FD1C for ; Mon, 20 Mar 2023 21:25:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230390AbjCTVZV (ORCPT ); Mon, 20 Mar 2023 17:25:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47732 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230385AbjCTVYr (ORCPT ); Mon, 20 Mar 2023 17:24:47 -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 163FDAF28 for ; Mon, 20 Mar 2023 14:24:18 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id y144-20020a253296000000b00b69ce0e6f2dso6030332yby.18 for ; Mon, 20 Mar 2023 14:24:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347455; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Py8U8PqFwPIRVvHHDItGJJ+sTjfy4CxHiyg06BPRgeo=; b=NyJCJ9tnHk0O3+MXWps8O+w+74dT2N/H35s635JnpB+eKAu4PfsVf+9YZe/UgUidZo GmwwSaiyfMqeQsT/VjFcQH80sF2Jb0/+SrOUwr9lXuc8dcA2/tKkp81NIl9fKuOuTLKy 96eX3gJxEslHw1/sSTg+yXMDXtdjq1AUbvKr4Gpd+6TcxSxpCYmuT1noXj2jY1bwDFqZ 1N5n7hYx8XHIY/vWbtq3YzmEzVyTcsp3S6blSxAKukRl9TT9NmKMlrT7ogXRGgcWGOGC Ca0iFy3liB7qq87YOP573sINyPrUg8HcOrHLoo0gz+C5vvnmf4omOIvLo1sCLu+VPcUd Dw3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347455; 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=Py8U8PqFwPIRVvHHDItGJJ+sTjfy4CxHiyg06BPRgeo=; b=WfC7zlYvTfUSU7fjw8S4Qc6YjmTu9kUqKqs7dGfWOYsunGXkO4Cl8y0/UWyDBrOTPX NTsFAVW3S325Hlxq4mhML2SCCZEqgM8gU61y+JcM8leFBpAYsgBVrHRR0PxMFZcA8TOf TBeG6p/BmqejCrJqqMrDuilf1LVjvjApPrFF7r4+bAkyqOjcoQQAPiOW6/72kZgkA5JQ f/g1hvS4b/devz19aesTf0HGOEQkUU1fEMTkvKGISDTNdmyXixE+4mD+WdXWuIMZkuxY 2d+wUfVvN+6l+o0lN78sBO6XO5IAP4Qy6TXlyP7pNwOW9XIwo0zQqapuqUM/4G09Zc+4 7LwA== X-Gm-Message-State: AAQBX9dhS2o8IRJNSEuptuJ8p2iUXFBYjBJUtcvPcjuQIJ6fQxDC5KNO BE2jRPsi8KU0iDT/BexfnFO02RY1oAdm X-Google-Smtp-Source: AKy350Zh2/MbdZG8/LZzSAvOCJQEKf8aNlP302UyKhH88CujQvetA0j/fm+vFy4HgPJrvqGVtr9YvsEeG0ma X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:703:b0:b6a:3632:12fd with SMTP id k3-20020a056902070300b00b6a363212fdmr20168ybt.2.1679347455142; Mon, 20 Mar 2023 14:24:15 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:41 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-11-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 10/17] 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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 22C37C6FD1C for ; Mon, 20 Mar 2023 21:25:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229810AbjCTVZZ (ORCPT ); Mon, 20 Mar 2023 17:25:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230462AbjCTVYx (ORCPT ); Mon, 20 Mar 2023 17:24:53 -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 0F1F030B2C for ; Mon, 20 Mar 2023 14:24:25 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-536cb268ab8so136132507b3.17 for ; Mon, 20 Mar 2023 14:24:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347462; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=NZSTAlatdezUNZqdamSKfW9oqDBHQoWsbo0yb5484mE=; b=JdAu8PMKQEi4bieLV725buzM41qbgUkaxsS5tUEVI8F5HKNIJcy0rLUBV+ZmRVoUBt UExOK4KAE9PN+GRurJjXLPifQzi1MVHyxV9t0z4uW5B71GFsNcFeyBeShweFigA0O7aF sXiBIYr6XVhIGAvudgRtIidhoFiGcBZMKkLkJu/0LF7t1oF5Sp0n0E8YOePHLDFqt8LJ JezGb7uWBYwCC1+HIKIL92W9eRpd8Z4cS3BuS+3U2oGEnzuytuL88xPMdwf+kqhn/at9 W+fX+owKMVkc3R4bMl402Gw6mVbY9ZVzZHS7VH6WgsPyixsg1JPaSp7wqLitPMttLRTS sjOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347462; 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=NZSTAlatdezUNZqdamSKfW9oqDBHQoWsbo0yb5484mE=; b=13c00q5HrbQwU4Bwfw6B7GH0w2yj+k6EpnDMrG1xsxILAz4upJJ4dOa7djykfLZst9 lVCMx5+8GsPkYLJwiN5Chbt5A5xMgLZhwQ4+sCUoGYR9RhOx8gMhqdKeSMxCLEB/puT3 TQwb+ry/jN2nWsqzakk+oMylhYb2h6hLTYwln/VBi1ZHuhmpXhUJRDuOQrdHiTSRLzfd o/KSivMqg43hRc92YJuLUZXd5Lq/ATLNSt4zoFnD4sGg/CYGRtz8KxRWzi87k41R88uF xMz+f09nfp4Qi6mDLGfYWygjW7NJVsZi+NeQC5XKK6na6xei5HVC3avfD5d905Icc1B3 xRDw== X-Gm-Message-State: AO0yUKX1hwsnQZSteWJhOtYXCrIl27W2XZ3uLLoZFFbhpFMTHAPPRW3M 3aSkVsTmLf4N7QHM2gKrqgfujIuYtgQK X-Google-Smtp-Source: AK7set80BpnTMxIuVFH04AHkuXSJzpUb15eiPscxY003I+puT5meiAZ0JWqBTIcpCPbxVUsKKLWyB0KsIJSA X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:1002:b0:a27:3ecc:ffe7 with SMTP id w2-20020a056902100200b00a273eccffe7mr6243320ybt.3.1679347462405; Mon, 20 Mar 2023 14:24:22 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:42 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-12-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 11/17] 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 ffd4a4a64026..74e3133f5007 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 ec7a312e7cc1..7904bfff7d0e 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2052,10 +2052,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) @@ -2087,7 +2100,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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 4A3F3C6FD1D for ; Mon, 20 Mar 2023 21:25:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230347AbjCTVZn (ORCPT ); Mon, 20 Mar 2023 17:25:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230367AbjCTVZQ (ORCPT ); Mon, 20 Mar 2023 17:25: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 07E9136462 for ; Mon, 20 Mar 2023 14:24:36 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-544539a729cso133240157b3.5 for ; Mon, 20 Mar 2023 14:24:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347471; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=+KtCffkRlKUj/6PyHm4epmu0CxW4XJhmveznufYgwCI=; b=DZ6GWIVkzebRGgOcdqI2wT53YMfUXpZvpqNCqj3ZyeEG46nJFsL242v1WGyc/1QeN1 9Luv9MZJ+3BY8ycXooZuF3LB0GzZ26c8elBRxcRSnKNCByaglj/O8+Vlv5JjVQS2/kw1 XXFBAlzUASkELTnWk8kgWYHyPvjNTxPUigkFsk+b/4B3j67kChCIQxlR3YhBS2fu55Xr jrBqy8UTJKyfoT41Dik94b/4g2qxMj9b2ZrM7UTswDxRGP23kygXCqCi1QX+Pfs25twq eLgxKAsaq7bckbllav68NqK19awd9KQz1iB9tmBPCJ/y8leDDFcXE7IxPxhQwHIZQVdP a0bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347471; 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=+KtCffkRlKUj/6PyHm4epmu0CxW4XJhmveznufYgwCI=; b=BNn3ggpe9Us+6SNIqERmJQr9JjOjtV7txJ1KeXu83Sr/KLNGltK/IHVodnKr9dy2tT VCYtUetRJ9Cu6f3NmVE+MzfVzhP6uEbrL2HbjPVQhTLGjoW0s8HWypQN+j74Pu5N85T2 I+gBzOHIJTHGyEda1Btj56UTPoNH+WNB5cROdLhrLBCY/S344W/qRz7dlv5qNOOI18ns AP7YTBd5/TKqaObQ3c7AhSBK4VRpXvTcH8xiC4+B/39IME/7smx+DASidugxl/kzQjxv WjIwKaDUx2ydr8qNJQE8e2uqkGsM8pcN4d9mB7M2aicY4VRWHgn2t52YMHEZEc90oiCB kcIQ== X-Gm-Message-State: AAQBX9cczu2M+kdWbn2jft4pOytukwBreJr310MeC53uLba1UuZFj+gy XY6RAce4xa8l2aaBQLUEmUf22vgcHLP7 X-Google-Smtp-Source: AKy350bg/gnqoyrIPdmKvwRKbfS2NvDfJWDP4vPPvtcDhgJXXwUVvM09zXz69maYgMB8VKKF3s7FJFk53wtF X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a25:9289:0:b0:a5f:0:bf12 with SMTP id y9-20020a259289000000b00a5f0000bf12mr391189ybl.13.1679347470925; Mon, 20 Mar 2023 14:24:30 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:43 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-13-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 12/17] 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 fdf0562d2fd3..02b4bf31b1a7 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 916d98885128..502e97010a3c 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -880,21 +880,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; @@ -904,9 +912,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 @@ -921,10 +930,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, @@ -1026,13 +1040,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); @@ -1324,6 +1336,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; @@ -1612,7 +1625,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 @@ -1658,16 +1671,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 @@ -2294,7 +2309,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 @@ -2355,9 +2370,11 @@ static int add_callchain_ip(struct thread *thread, ms.map =3D al.map; ms.sym =3D al.sym; 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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 8F87CC6FD1C for ; Mon, 20 Mar 2023 21:26:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230376AbjCTVZ6 (ORCPT ); Mon, 20 Mar 2023 17:25:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49600 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230248AbjCTVZ2 (ORCPT ); Mon, 20 Mar 2023 17:25:28 -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 50AE6302A1 for ; Mon, 20 Mar 2023 14:24:49 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 204-20020a250fd5000000b00b6d6655dc35so2966939ybp.6 for ; Mon, 20 Mar 2023 14:24:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347480; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Dx+Czfooqx4+y3PtKz3VngTOr7flvK3/ZnOwhjyajRw=; b=Q+n6EUqhYj+IdoEFDVvk6ANpjHNNdXvaBW3gCdTMQk9mwjnqHSMUCPhxWeIfxMAHrI NVfKSReNTU7Gbn7DBB6hBcinYmRvdy7cdvjILkdjHstnuBAr2fiTwItkAHZZVcwtRT/f wtniKmWKLCmnaJZBne28dG+uWL2aO9QUhggoSfnUyz1dOfIAIXC52kYAgX5mX0H2gWv+ xI99cVholotXfrgkFhuxjtrv/O1jfHaGRPpakU4KTGVQPYjihtLkoObTJMRuWRE+ClM8 W0enLg1WWfYqJ5JFzq8jH1SK39d2Id+IqBkK9p/FHSmIndqDl9D4P+mS8ADJMBlnCh8Z 1L+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347480; 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=Dx+Czfooqx4+y3PtKz3VngTOr7flvK3/ZnOwhjyajRw=; b=4tLNvKT9BPSZVfFqF0tJnNp7DXejkJ5O7epa3TaRJ0JOLkPrerDpJyj/OFGfiUPeRo Cg0AlPUyJm+VAOB1DxtvE3yha52H19CsgxEWsf4XodgUkOWXl/95Kq5tGJ8XDM8M03NL XAef2ymuMKuIOwROIVcgU/8B77+XUNb776Eijsq7L9yBIuhYpyHT7jC0PUqCIR8J7mro SBfKTLXnF6ArRMkE9ukniKUJJz5wFcwk4X4WSTMm5LVoFI8eDCGukDEfyrdwkmPn2XwU UmlKTaMnQ6ccEd8dqKMcLaJ4W43+9bC5gxPQPRt77BSXnh9bqwiD/gPOTx7Rse5dhf0G qt8Q== X-Gm-Message-State: AAQBX9fjaIzF2ZShhaJ5MK76rkVlNJYt8FdWAiBivMzejOCwbDjkVfTc vMBKGimc4HIMiBoOkus648MfWKUlxxuT X-Google-Smtp-Source: AKy350ZbdKh1NwspQyhPDDoyG/uJa2t17sY3CpDG/BXxxDQyfVAf2+UE9i8v/XL82NqaZ+NvaLUu30w+NNg7 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a25:5b84:0:b0:b67:d295:d614 with SMTP id p126-20020a255b84000000b00b67d295d614mr403541ybb.12.1679347479801; Mon, 20 Mar 2023 14:24:39 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:44 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-14-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 13/17] 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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 B2B31C7619A for ; Mon, 20 Mar 2023 21:26:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230401AbjCTV0Z (ORCPT ); Mon, 20 Mar 2023 17:26:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230410AbjCTV0C (ORCPT ); Mon, 20 Mar 2023 17:26:02 -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 BC17B399CE for ; Mon, 20 Mar 2023 14:25:02 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-536a5a0b6e3so136736267b3.10 for ; Mon, 20 Mar 2023 14:25:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347486; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Kb4pdWYoXXxgxH3CLp93b6VqLVR3bmV9cj+P/uj/TFI=; b=FEcmSAQ94asx3Ftg3A85HzsnyhqdayOhNlrYQvrHIMje30mr3f0CfX89iTbmoT4ce6 dGFxf9lPrVeSybuzCD3vQ1V7UjNj7ZSwMh/efM5wdA/2Nhrz4nFEcY6xPUNutkMdzKyH QF1h5NmtHDrJ9cFHdjFH1mriKjO5F5fT6rexm6T1KPDS7XCBAOmdR6ZGJ6BykXpL9Y88 BGjeiiOKrJ04hy34USnwxMhaZqLuO90XiVe449mbULxEtkJuOBnPIQZfw/ImJQjw4/FR jBvoTbxRRLRI5JAIK2MQdJwLE8pR0sVknqQdQycEu2g7b/MkM9E43qmYUxltUFN37+ZT 6jHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347486; 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=Kb4pdWYoXXxgxH3CLp93b6VqLVR3bmV9cj+P/uj/TFI=; b=LVQC8G12O3ncZ+E+glKLFSTRseWqdWuOxtBHRSQFcD1YPu6wydpghjqKz+6zhGe1zb qJBb0uG4/GHFZqDwnQAHRaEvfjnPL9fVuDwPnv/tjusojpMztnqSFGRtBMOnEuHpenY1 byOwF75v26Fz15JfticmBKDesP0dDOBBbJiXo2Libz3IrlQp7maGdlqPTLJejBhU4jsp LgQUFeorUfjSq4V1it4MTBA6MILd+XQbpY/1ccHxe+/KRisi1KQBfQC7Yg1vJisgolLz qZc22KJ+Y0JnZnZ6cTbsloR3mIHQNPSsVwVW3Y28ub+9TxcFaKz4hD/Ol7rPMOUTyNMl PDEw== X-Gm-Message-State: AAQBX9cdgdQJLVwp2g9FUWVWr7y1FJCQfxNmVnxl0KKwLr8ux5b9lHcw dioFz7CVyUgIK0ndF0/HYMj6xUdTiVmA X-Google-Smtp-Source: AKy350YYHiATAsiBofs1Ea4bNUxbO8KFX+Hh+6yG94Cm64fP9uXj/o2tVL129TtxO4xY/pLAWXeSCDcZllY1 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a25:b10f:0:b0:b21:5fb4:c6e6 with SMTP id g15-20020a25b10f000000b00b215fb4c6e6mr370481ybj.11.1679347486132; Mon, 20 Mar 2023 14:24:46 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:45 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-15-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 14/17] 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 45d9b8e28e16..25bb52e8c147 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1885,13 +1885,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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 5DC63C7619A for ; Mon, 20 Mar 2023 21:26:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230368AbjCTV0P (ORCPT ); Mon, 20 Mar 2023 17:26:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230240AbjCTVZx (ORCPT ); Mon, 20 Mar 2023 17:25:53 -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 5BDCB3A84A for ; Mon, 20 Mar 2023 14:25:13 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id z31-20020a25a122000000b00b38d2b9a2e9so14168198ybh.3 for ; Mon, 20 Mar 2023 14:25:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347495; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=9d5VHIsvA9UZ1+YJTtLO7nde7SlLSiM5pVs449RNH/o=; b=qhKpTVNKCQn/LR/gWNt+OKGxc0LvmSnpiQpEi7vCLbImDciq8XF7geg8WGZHp13RNg EmrxNqKPqOCiT6u6klxAvjAAwJZcDHkT1oEo1cw20gzuzfMpTxRN3byjbHtu4Ddlxldm xvXoSTNHs/5uhaOtw2zTEDO5yWeo1t3tlgV7S7/8OwCqEtoCv8yeq40J80nqGSmNdLyb /g4iPz2+3rOI5d9NiDgerwp92LTUOQMaGT9PTiXAeSBEB16u/J/ZAs09qARBZ8mtVtOM h4w1F8+YGrzk/QeOZ8bSiCMtIv9tIPCP0F9Ztxcz8hzXFyQX6OL5VwMjmSf8NAbnNFX1 X21g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347495; 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=9d5VHIsvA9UZ1+YJTtLO7nde7SlLSiM5pVs449RNH/o=; b=ePcpuIm8Uf+zBvKOghPNTRPiZNy7IsTgWaGWf4Na+MAu7Ucbu2DOzY2KxaXPsGpvOk g3MTjfo5WSqkrdMog9vjAwv+6KHCS78gjRmcCtByL9RFkzi+pHmvNSO1HI0h56QNXzgo koDstXChjv5wSIeNbRRTviJ3VZpxJkURbDHFD5a3uPyPNXj/Hr339nzoFtLwkfNwfcWS ANF5caOmDR3OZex1qz0cbvcy8OI8XVR6Zt4lgx6PB7kX+Kcz4p7PY6adC5Q52LrmFnNw 52yc4WVLG/QOU/OwbIdpFpoIayAzUVDVG3RQ5MfWzy53VnewvjVPo8RlNAkfhFCof5lV DySA== X-Gm-Message-State: AAQBX9dcLXshCxQPuhlprJOTmoGCSxHpPUNA3Cox0SoLn5UEh/bMpiYt GEJc6lJn9MeFZU3BpAgtxjDOTiFJXxyB X-Google-Smtp-Source: AKy350YJK+zkOXjidRVH66SLC6+qrdiYoHsyTZtR/D5fS2wVNDxKYUYAda4YhIA/5vMiNqNykryKMRyBWlLD X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:3ce:b0:b61:14c8:90fd with SMTP id g14-20020a05690203ce00b00b6114c890fdmr9978ybs.4.1679347495011; Mon, 20 Mar 2023 14:24:55 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:46 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-16-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 15/17] 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 e8570b7cc36f..199f6cd5ad1e 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1701,7 +1701,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 7904bfff7d0e..f5432c7add09 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1962,7 +1962,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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 E7CFDC6FD1D for ; Mon, 20 Mar 2023 21:26:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230407AbjCTV0l (ORCPT ); Mon, 20 Mar 2023 17:26:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49058 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230468AbjCTV0P (ORCPT ); Mon, 20 Mar 2023 17:26:15 -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 EAAD51A65C for ; Mon, 20 Mar 2023 14:25:37 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-536a4eba107so135483327b3.19 for ; Mon, 20 Mar 2023 14:25:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347503; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=icBYGhACTLENBFtI0uAK9GZilU3MMSebJp6keqt4NA0=; b=jGcUqcPVGFax6oc/S4S8LcGtg6Tuujx2Q1ikG5/H9j7LhIDe2QDAzhq+AQ2UiZ1d4y J1GE4K5sr+PAP9ce+SERYJybvNb6dqpZJnmcnqf7yWrPTRAtJT9oXYhJ4/9jCaWGYeYc yO5PXUkWWXpEb6bIXELq0y+rU6tSveJTFMPq4wSMXIbBC7kvE6wVxri6KJGEYRNP+fyB Wj/Bq2bizYry8N1XCT62ajE/PconuhS87rCa8jyBaDnA+I3ZVygtsni9gb7q/w2VJXsj ud+UAncmjX0IWrhwTrznacTDg1xeWIJnv7rDoxKD+kd/OrkWRLdpRxknE4xsXo8ZjB+N swpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347503; 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=icBYGhACTLENBFtI0uAK9GZilU3MMSebJp6keqt4NA0=; b=ljbQ/dmfGfzVqvC0A3SUPVFcQhhijO375PK4oUwwwKBsOut7RGohZX7isg7VjEGcSl jEbZho20rxURj+McEqeUz5wgLs/sKldWmt2QqMMCRMouNo7wNOMpwyjO1ilV0yvrTxRo GHUBVFkbJ8MBUaaTLyLlnC8wIuwFLwlmOL8YBtMKyBF/gzq6TtHdwNLNSPkTXTeXmpPM aaTbQ9M6k+ijM+6d+C04rou+4zXMRwjpIldNRquK1tJBeb+mTpzIuor9+uYiSZQFiHf/ FoHX6P/DGP3AUaQCcuPAZaQK7iBQ8HqNnqyZc/S7xZTi7NoTTYT461DzHQdIm7Rw33xv owxQ== X-Gm-Message-State: AAQBX9ca4Gpng1HfWZ5lHL2fJbGEXLT5S7vmVkTUw5QAN8gw71wfwBaa R8wiJ0moarYF09H1rsK0agVNWX+50vha X-Google-Smtp-Source: AKy350b5F+c1tKe8LfIVMxkrYq9LHCF/Q5UHRj7P1d6wO56g1unbT07IC+jOP6I9+EYXfCIe/AsZk446Gy0U X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a25:d512:0:b0:b45:5cbe:48b3 with SMTP id r18-20020a25d512000000b00b455cbe48b3mr55577ybe.0.1679347503736; Mon, 20 Mar 2023 14:25:03 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:47 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-17-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 16/17] 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 502e97010a3c..cfbced348335 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -434,7 +434,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 74e3133f5007..3c8bbcb2c204 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 f5432c7add09..d99c8e1bb4bf 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2096,8 +2096,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); @@ -2132,11 +2132,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; } } @@ -2156,7 +2157,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 952c5ee66fe7..2947c210576e 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -667,7 +667,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 c14f04082377..48a7aeb3f9ec 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.rc1.284.g88254d51c5-goog From nobody Sun Feb 8 15:46:51 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 D2865C6FD1D for ; Mon, 20 Mar 2023 21:26:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230476AbjCTV0v (ORCPT ); Mon, 20 Mar 2023 17:26:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230436AbjCTV0c (ORCPT ); Mon, 20 Mar 2023 17:26:32 -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 77A5C30B2C for ; Mon, 20 Mar 2023 14:25:51 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-544570e6d82so136862397b3.23 for ; Mon, 20 Mar 2023 14:25:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; t=1679347510; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=kA2P3cCw0w5TexeIUCzMnIczpz6RbPZ7j4N3nKY8zz8=; b=WZfpYLDd0QCgZQKekHT2Bh2DsXKfl1+RNPHWTodXaRgIqij5DVCt77co89dce06a/p FEBb1OcSVgqaS0XsVzjYGfQdG2qsSqhQE0YqQ/h0NVWH8QJRRt7e7LMqJWcg8cw3nmpE haloQhO+miEC1+yzSvXp7+psRyICUw/7eU3P4FV6x0827P8xXNBFabIquiqnO4NZfqXD Vya/bteK1ueUinukEWcDaGFojvkN/BQqlGRkWRYCv0jkz1vqFVzk1SmxYWvpdDqNiSs3 rDCZ8kGGAyxG3EfpXYQDOp/zz221M/yOgnI6GxA6usLNVGg6pcaMq6tSLov6MT5rxIGQ l0YQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679347510; 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=kA2P3cCw0w5TexeIUCzMnIczpz6RbPZ7j4N3nKY8zz8=; b=LldSLZ8buxMiLFK/2pnRZ6NC2lPPpOQ/YwnqgyCkIFHWMoUOA+hdeXftX8newB/8Vv 4g/b9I+IgzyPF+HffMnq0HQfUoNUlBHFg/3qftFq9InQ458aMQNqSK/5Ui060x3tcZD+ q6QuxP9+ddBmlADmEVTruzsmE2dm0KQCqpDtekALHyL6HoLJ5KO1qBOiu+0E88ag5ob7 PJsjm9oryI/E8vrKZ6qs+eaIv3nKC7nHVdZDVZEI/vm8AZ1vqZm4FDQIfSqcp8JdsFPK LPUDSFw4G1boXnqA0O3oYbld2pxOZO0kyllXTSFJdEWYslG7nx5GZtLMrvsvdC4LyxkH BhRA== X-Gm-Message-State: AAQBX9d2wKkptkMpL75gc1AaebwH+/xjXw4p/RYOl62XvDPS3/T+Wxtc h4aH7XN9ncwDy772+yqS5r1HwtCLMESP X-Google-Smtp-Source: AKy350bAC4SLbeTAvwM0rFadDZVHynJ6wRZ6DfU7WaHNnDj0xeuY+gF0h+C0o2OadYCVVyNVVL8Ub2P9FCTA X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:a30f:d1e2:fcd8:aa4d]) (user=irogers job=sendgmr) by 2002:a05:6902:706:b0:b6d:9e38:1017 with SMTP id k6-20020a056902070600b00b6d9e381017mr26860ybt.1.1679347509795; Mon, 20 Mar 2023 14:25:09 -0700 (PDT) Date: Mon, 20 Mar 2023 14:22:48 -0700 In-Reply-To: <20230320212248.1175731-1-irogers@google.com> Message-Id: <20230320212248.1175731-18-irogers@google.com> Mime-Version: 1.0 References: <20230320212248.1175731-1-irogers@google.com> X-Mailer: git-send-email 2.40.0.rc1.284.g88254d51c5-goog Subject: [PATCH v5 17/17] 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 | 13 ++-- tools/perf/util/symbol-elf.c | 26 ++++---- tools/perf/util/symbol.c | 40 +++++++----- 12 files changed, 136 insertions(+), 114 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 b45565f718f4..2605040e6788 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 199f6cd5ad1e..8bae9d78d8c4 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -280,8 +280,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; @@ -409,8 +410,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 cfbced348335..6310d74f6d6d 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -909,8 +909,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; @@ -952,7 +952,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); @@ -1217,8 +1217,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 @@ -1290,7 +1290,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) @@ -1341,7 +1341,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 @@ -1622,7 +1623,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); @@ -1658,14 +1659,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, @@ -1809,7 +1810,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 3c8bbcb2c204..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); @@ -351,7 +351,7 @@ int maps__fixup_overlappings(struct maps *maps, struct = map *map, FILE *fp) map__put(before); } =20 - if (map->end < map__end(pos->map)) { + if (map__end(map) < map__end(pos->map)) { struct map *after =3D map__clone(pos->map); =20 if (after =3D=3D NULL) { @@ -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 93ae3f22fd03..aa6113008627 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1348,11 +1348,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; @@ -1373,7 +1373,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; @@ -1408,11 +1408,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)) @@ -1519,7 +1521,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; } @@ -1530,7 +1532,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 d99c8e1bb4bf..38b2890e4273 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); } } } @@ -1455,12 +1459,12 @@ static int dso__load_kcore(struct dso *dso, struct = map *map, =20 new_node =3D list_entry(md.maps.next, struct map_list_node, node); list_del_init(&new_node->node); - if (new_node->map =3D=3D replacement_map) { - map->start =3D map__start(new_node->map); - map->end =3D map__end(new_node->map); - map->pgoff =3D map__pgoff(new_node->map); - map->map_ip =3D new_node->map->map_ip; - map->unmap_ip =3D new_node->map->unmap_ip; + if (RC_CHK_ACCESS(new_node->map) =3D=3D RC_CHK_ACCESS(replacement_map)) { + RC_CHK_ACCESS(map)->start =3D map__start(new_node->map); + RC_CHK_ACCESS(map)->end =3D map__end(new_node->map); + RC_CHK_ACCESS(map)->pgoff =3D map__pgoff(new_node->map); + RC_CHK_ACCESS(map)->map_ip =3D RC_CHK_ACCESS(new_node->map)->map_ip; + RC_CHK_ACCESS(map)->unmap_ip =3D RC_CHK_ACCESS(new_node->map)->unmap_ip; /* Ensure maps are correctly ordered */ map__get(map); maps__remove(kmaps, map); --=20 2.40.0.rc1.284.g88254d51c5-goog