From nobody Mon Feb 9 13:35:23 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