From nobody Wed Dec 17 12:44:25 2025 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 9CEA9C4167B for ; Mon, 27 Nov 2023 22:11:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233834AbjK0WKv (ORCPT ); Mon, 27 Nov 2023 17:10:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42888 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233629AbjK0WKK (ORCPT ); Mon, 27 Nov 2023 17:10:10 -0500 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 A3F8A1FC3 for ; Mon, 27 Nov 2023 14:09:54 -0800 (PST) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-5ccc8b7f578so74972927b3.2 for ; Mon, 27 Nov 2023 14:09:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1701122994; x=1701727794; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=sC9pWEdGHkV6UqwtMjznbO4EVka6FCL+6wxqZTEv7z0=; b=groGiyreRezsq2aGgJfbxFC/7tWkflyO7kEreSj4IIBfYEHS/XGS1ibFXW5r/iPPhV OlCcDHbGlE5uKME2EPEBbqH2PIuKk5pup5SYg1T7xpFu0NaTlWKRyHsPaNhzzHE56NEo RlHgjydUjpxg4x+zPGKijTJ0G0ievjp4Fme7ZlBYdtz/y/ca2zUAhuZszNF2CdNIoLHB C6OF3ppPhIAKgHYh+NI2JHjHA1IMmhUQQNDiWZvWPtYgE7k79gDwGgLrASOORfTHlWl5 wYKJXKLMXayANJdvdUuq5uMAHRiCPwAMXu3uAD+kUyVbNFeTzkMNd4kqiFA5o9kCTh/L 9wRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701122994; x=1701727794; h=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=sC9pWEdGHkV6UqwtMjznbO4EVka6FCL+6wxqZTEv7z0=; b=OGQxTOrTvZxMFL6kF7WzlQo/ZikqUD7ZPkDxWfG4daSATK/9dtj0/4BYgiz4ZehYVd Jvb10qavr4uBAFby7oodJ4SG3BBwGR8sM0GnryaLbMIwPiPF7fgRkv/6r5qM1l2E1JGe /CBpCHpTdXB+3VLU7Ek/Lfr2ukZT9Nhgg+cOXW7K6FspSivAopWZEF7msgEJLSIkdI5K s/iC7OZrp2vZwxeXvATcGmLP1TFEwbW9sjhfIK1xu1V3kiGyZEUuRubYl2EB9FRjGeGM IPsMpTyqkBQnElbIHWLvoSXErZSLPo9mLW0gxZ4A7+mEQdzkoEhXf7UIK0oDt+jZEnzm otzQ== X-Gm-Message-State: AOJu0YzEefJD3xV8NpGOZc1rVeykbcZ5JAjidT9/5vjG5/RQDKl8AWu/ vCMvniBaXrZFkhaqD/anUaIUUnvIjacM X-Google-Smtp-Source: AGHT+IHfirbxAvMxai/fbKmvgfNBNTz13SNrhFQLatTn1CUpgOnhX1uBAOIH+/0AnF3F/+oRXdmYN4+UtQY4 X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:829:6e77:9093:f39b]) (user=irogers job=sendgmr) by 2002:a05:690c:88f:b0:5be:9742:cc3a with SMTP id cd15-20020a05690c088f00b005be9742cc3amr472817ywb.4.1701122993829; Mon, 27 Nov 2023 14:09:53 -0800 (PST) Date: Mon, 27 Nov 2023 14:08:25 -0800 In-Reply-To: <20231127220902.1315692-1-irogers@google.com> Message-Id: <20231127220902.1315692-14-irogers@google.com> Mime-Version: 1.0 References: <20231127220902.1315692-1-irogers@google.com> X-Mailer: git-send-email 2.43.0.rc1.413.gea7ed67945-goog Subject: [PATCH v5 13/50] perf maps: Move symbol maps functions to maps.c From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Nick Terrell , Kan Liang , Andi Kleen , Kajol Jain , Athira Rajeev , Huacai Chen , Masami Hiramatsu , Vincent Whitchurch , "Steinar H. Gunderson" , Liam Howlett , Miguel Ojeda , Colin Ian King , Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong , Ming Wang , James Clark , K Prateek Nayak , Sean Christopherson , Leo Yan , Ravi Bangoria , German Gomez , Changbin Du , Paolo Bonzini , Li Dong , Sandipan Das , liuwenyu , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Guilherme Amadio Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move the find and certain other symbol maps__* functions to maps.c for better abstraction. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim --- tools/perf/util/maps.c | 238 +++++++++++++++++++++++++++++++++++++ tools/perf/util/maps.h | 12 ++ tools/perf/util/symbol.c | 248 --------------------------------------- tools/perf/util/symbol.h | 1 - 4 files changed, 250 insertions(+), 249 deletions(-) diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 233438c95b53..9a011aed4b75 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -475,3 +475,241 @@ struct map_rb_node *map_rb_node__next(struct map_rb_n= ode *node) =20 return rb_entry(next, struct map_rb_node, rb_node); } + +static int map__strcmp(const void *a, const void *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); + + 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; +} + +static int map__strcmp_name(const void *name, const void *b) +{ + const struct dso *dso =3D map__dso(*(const struct map **)b); + + return strcmp(name, dso->short_name); +} + +void __maps__sort_by_name(struct maps *maps) +{ + qsort(maps__maps_by_name(maps), maps__nr_maps(maps), sizeof(struct map *)= , map__strcmp); +} + +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), + maps__nr_maps(maps) * sizeof(struct map *)); + int i =3D 0; + + if (maps_by_name =3D=3D NULL) + return -1; + + up_read(maps__lock(maps)); + down_write(maps__lock(maps)); + + RC_CHK_ACCESS(maps)->maps_by_name =3D maps_by_name; + RC_CHK_ACCESS(maps)->nr_maps_allocated =3D maps__nr_maps(maps); + + maps__for_each_entry(maps, rb_node) + maps_by_name[i++] =3D map__get(rb_node->map); + + __maps__sort_by_name(maps); + + up_write(maps__lock(maps)); + down_read(maps__lock(maps)); + + return 0; +} + +static struct map *__maps__find_by_name(struct maps *maps, const char *nam= e) +{ + struct map **mapp; + + if (maps__maps_by_name(maps) =3D=3D NULL && + map__groups__sort_by_name_from_rbtree(maps)) + return NULL; + + mapp =3D bsearch(name, maps__maps_by_name(maps), maps__nr_maps(maps), + sizeof(*mapp), map__strcmp_name); + if (mapp) + return *mapp; + return NULL; +} + +struct map *maps__find_by_name(struct maps *maps, const char *name) +{ + struct map_rb_node *rb_node; + struct map *map; + + down_read(maps__lock(maps)); + + + 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); + + if (strcmp(dso->short_name, name) =3D=3D 0) { + map =3D RC_CHK_ACCESS(maps)->last_search_by_name; + goto out_unlock; + } + } + /* + * If we have maps->maps_by_name, then the name isn't in the rbtree, + * as maps->maps_by_name mirrors the rbtree when lookups by name are + * made. + */ + map =3D __maps__find_by_name(maps, name); + if (map || maps__maps_by_name(maps) !=3D NULL) + goto out_unlock; + + /* Fallback to traversing the rbtree... */ + maps__for_each_entry(maps, rb_node) { + struct dso *dso; + + map =3D rb_node->map; + dso =3D map__dso(map); + if (strcmp(dso->short_name, name) =3D=3D 0) { + RC_CHK_ACCESS(maps)->last_search_by_name =3D map; + goto out_unlock; + } + } + map =3D NULL; + +out_unlock: + up_read(maps__lock(maps)); + return map; +} + +void maps__fixup_end(struct maps *maps) +{ + struct map_rb_node *prev =3D NULL, *curr; + + down_write(maps__lock(maps)); + + maps__for_each_entry(maps, curr) { + if (prev !=3D NULL && !map__end(prev->map)) + map__set_end(prev->map, map__start(curr->map)); + + prev =3D curr; + } + + /* + * We still haven't the actual symbols, so guess the + * last map final address. + */ + if (curr && !map__end(curr->map)) + map__set_end(curr->map, ~0ULL); + + up_write(maps__lock(maps)); +} + +/* + * Merges map into maps by splitting the new map within the existing map + * regions. + */ +int maps__merge_in(struct maps *kmaps, struct map *new_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; + + /* no overload with this one */ + if (map__end(new_map) < map__start(old_map) || + map__start(new_map) >=3D map__end(old_map)) + continue; + + if (map__start(new_map) < map__start(old_map)) { + /* + * |new...... + * |old.... + */ + if (map__end(new_map) < map__end(old_map)) { + /* + * |new......| -> |new..| + * |old....| -> |old....| + */ + map__set_end(new_map, map__start(old_map)); + } else { + /* + * |new.............| -> |new..| |new..| + * |old....| -> |old....| + */ + struct map_list_node *m =3D map_list_node__new(); + + if (!m) { + err =3D -ENOMEM; + goto out; + } + + m->map =3D map__clone(new_map); + if (!m->map) { + free(m); + err =3D -ENOMEM; + goto out; + } + + map__set_end(m->map, map__start(old_map)); + list_add_tail(&m->node, &merged); + map__add_pgoff(new_map, map__end(old_map) - map__start(new_map)); + map__set_start(new_map, map__end(old_map)); + } + } else { + /* + * |new...... + * |old.... + */ + if (map__end(new_map) < map__end(old_map)) { + /* + * |new..| -> x + * |old.........| -> |old.........| + */ + map__put(new_map); + new_map =3D NULL; + break; + } else { + /* + * |new......| -> |new...| + * |old....| -> |old....| + */ + map__add_pgoff(new_map, map__end(old_map) - map__start(new_map)); + map__set_start(new_map, map__end(old_map)); + } + } + } + +out: + while (!list_empty(&merged)) { + struct map_list_node *old_node; + + old_node =3D list_entry(merged.next, struct map_list_node, node); + list_del_init(&old_node->node); + if (!err) + err =3D maps__insert(kmaps, old_node->map); + map__put(old_node->map); + free(old_node); + } + + if (new_map) { + if (!err) + err =3D maps__insert(kmaps, new_map); + map__put(new_map); + } + return err; +} diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index 83144e0645ed..a689149be8c4 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -21,6 +21,16 @@ struct map_rb_node { struct map *map; }; =20 +struct map_list_node { + struct list_head node; + struct map *map; +}; + +static inline struct map_list_node *map_list_node__new(void) +{ + return malloc(sizeof(struct map_list_node)); +} + 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); @@ -133,4 +143,6 @@ int maps__merge_in(struct maps *kmaps, struct map *new_= map); =20 void __maps__sort_by_name(struct maps *maps); =20 +void maps__fixup_end(struct maps *maps); + #endif // __PERF_MAPS_H diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 314c0263bf3c..1cc42b8d8afb 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -48,11 +48,6 @@ 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, @@ -90,11 +85,6 @@ 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); @@ -270,29 +260,6 @@ void symbols__fixup_end(struct rb_root_cached *symbols= , bool is_kallsyms) curr->end =3D roundup(curr->start, 4096) + 4096; } =20 -void maps__fixup_end(struct maps *maps) -{ - struct map_rb_node *prev =3D NULL, *curr; - - down_write(maps__lock(maps)); - - maps__for_each_entry(maps, curr) { - if (prev !=3D NULL && !map__end(prev->map)) - map__set_end(prev->map, map__start(curr->map)); - - prev =3D curr; - } - - /* - * We still haven't the actual symbols, so guess the - * last map final address. - */ - if (curr && !map__end(curr->map)) - map__set_end(curr->map, ~0ULL); - - up_write(maps__lock(maps)); -} - struct symbol *symbol__new(u64 start, u64 len, u8 binding, u8 type, const = char *name) { size_t namelen =3D strlen(name) + 1; @@ -1270,103 +1237,6 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgof= f, void *data) return 0; } =20 -/* - * Merges map into maps by splitting the new map within the existing map - * regions. - */ -int maps__merge_in(struct maps *kmaps, struct map *new_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; - - /* no overload with this one */ - if (map__end(new_map) < map__start(old_map) || - map__start(new_map) >=3D map__end(old_map)) - continue; - - if (map__start(new_map) < map__start(old_map)) { - /* - * |new...... - * |old.... - */ - if (map__end(new_map) < map__end(old_map)) { - /* - * |new......| -> |new..| - * |old....| -> |old....| - */ - map__set_end(new_map, map__start(old_map)); - } else { - /* - * |new.............| -> |new..| |new..| - * |old....| -> |old....| - */ - struct map_list_node *m =3D map_list_node__new(); - - if (!m) { - err =3D -ENOMEM; - goto out; - } - - m->map =3D map__clone(new_map); - if (!m->map) { - free(m); - err =3D -ENOMEM; - goto out; - } - - map__set_end(m->map, map__start(old_map)); - list_add_tail(&m->node, &merged); - map__add_pgoff(new_map, map__end(old_map) - map__start(new_map)); - map__set_start(new_map, map__end(old_map)); - } - } else { - /* - * |new...... - * |old.... - */ - if (map__end(new_map) < map__end(old_map)) { - /* - * |new..| -> x - * |old.........| -> |old.........| - */ - map__put(new_map); - new_map =3D NULL; - break; - } else { - /* - * |new......| -> |new...| - * |old....| -> |old....| - */ - map__add_pgoff(new_map, map__end(old_map) - map__start(new_map)); - map__set_start(new_map, map__end(old_map)); - } - } - } - -out: - while (!list_empty(&merged)) { - struct map_list_node *old_node; - - old_node =3D list_entry(merged.next, struct map_list_node, node); - list_del_init(&old_node->node); - if (!err) - err =3D maps__insert(kmaps, old_node->map); - map__put(old_node->map); - free(old_node); - } - - if (new_map) { - if (!err) - err =3D maps__insert(kmaps, new_map); - map__put(new_map); - } - return err; -} - static int dso__load_kcore(struct dso *dso, struct map *map, const char *kallsyms_filename) { @@ -2065,124 +1935,6 @@ int dso__load(struct dso *dso, struct map *map) return ret; } =20 -static int map__strcmp(const void *a, const void *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); - - 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; -} - -static int map__strcmp_name(const void *name, const void *b) -{ - const struct dso *dso =3D map__dso(*(const struct map **)b); - - return strcmp(name, dso->short_name); -} - -void __maps__sort_by_name(struct maps *maps) -{ - qsort(maps__maps_by_name(maps), maps__nr_maps(maps), sizeof(struct map *)= , map__strcmp); -} - -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), - maps__nr_maps(maps) * sizeof(struct map *)); - int i =3D 0; - - if (maps_by_name =3D=3D NULL) - return -1; - - up_read(maps__lock(maps)); - down_write(maps__lock(maps)); - - RC_CHK_ACCESS(maps)->maps_by_name =3D maps_by_name; - RC_CHK_ACCESS(maps)->nr_maps_allocated =3D maps__nr_maps(maps); - - maps__for_each_entry(maps, rb_node) - maps_by_name[i++] =3D map__get(rb_node->map); - - __maps__sort_by_name(maps); - - up_write(maps__lock(maps)); - down_read(maps__lock(maps)); - - return 0; -} - -static struct map *__maps__find_by_name(struct maps *maps, const char *nam= e) -{ - struct map **mapp; - - if (maps__maps_by_name(maps) =3D=3D NULL && - map__groups__sort_by_name_from_rbtree(maps)) - return NULL; - - mapp =3D bsearch(name, maps__maps_by_name(maps), maps__nr_maps(maps), - sizeof(*mapp), map__strcmp_name); - if (mapp) - return *mapp; - return NULL; -} - -struct map *maps__find_by_name(struct maps *maps, const char *name) -{ - struct map_rb_node *rb_node; - struct map *map; - - down_read(maps__lock(maps)); - - - 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); - - if (strcmp(dso->short_name, name) =3D=3D 0) { - map =3D RC_CHK_ACCESS(maps)->last_search_by_name; - goto out_unlock; - } - } - /* - * If we have maps->maps_by_name, then the name isn't in the rbtree, - * as maps->maps_by_name mirrors the rbtree when lookups by name are - * made. - */ - map =3D __maps__find_by_name(maps, name); - if (map || maps__maps_by_name(maps) !=3D NULL) - goto out_unlock; - - /* Fallback to traversing the rbtree... */ - maps__for_each_entry(maps, rb_node) { - struct dso *dso; - - map =3D rb_node->map; - dso =3D map__dso(map); - if (strcmp(dso->short_name, name) =3D=3D 0) { - RC_CHK_ACCESS(maps)->last_search_by_name =3D map; - goto out_unlock; - } - } - map =3D NULL; - -out_unlock: - up_read(maps__lock(maps)); - return map; -} - int dso__load_vmlinux(struct dso *dso, struct map *map, const char *vmlinux, bool vmlinux_allocated) { diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index af87c46b3f89..071837ddce2a 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -189,7 +189,6 @@ void __symbols__insert(struct rb_root_cached *symbols, = struct symbol *sym, void symbols__insert(struct rb_root_cached *symbols, struct symbol *sym); void symbols__fixup_duplicate(struct rb_root_cached *symbols); void symbols__fixup_end(struct rb_root_cached *symbols, bool is_kallsyms); -void maps__fixup_end(struct maps *maps); =20 typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data); int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, --=20 2.43.0.rc1.413.gea7ed67945-goog