From 63df0e4bc368adbd12ed70ed4789d8d52d65661d Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 20 Mar 2023 14:22:35 -0700 Subject: perf map: Add accessor for dso 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 == NULL. Make the possibility of NULL consistent. - in thread.c thread__memcpy fix use of spaces and use tabs. Committer notes: Did missing conversions on these files: tools/perf/arch/powerpc/util/skip-callchain-idx.c tools/perf/arch/powerpc/util/sym-handling.c tools/perf/ui/browsers/hists.c tools/perf/ui/gtk/annotate.c tools/perf/util/cs-etm.c tools/perf/util/thread.c tools/perf/util/unwind-libunwind-local.c tools/perf/util/unwind-libunwind.c Signed-off-by: Ian Rogers Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230320212248.1175731-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'tools/perf/builtin-inject.c') 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, } if (thread__find_map(thread, sample->cpumode, sample->ip, &al)) { - if (!al.map->dso->hit) { - al.map->dso->hit = 1; - dso__inject_build_id(al.map->dso, tool, machine, + struct dso *dso = map__dso(al.map); + + if (!dso->hit) { + dso->hit = 1; + dso__inject_build_id(dso, tool, machine, sample->cpumode, al.map->flags); } } -- cgit v1.2.3-59-g8ed1b From ddee3f2bddc11f850f7f6fcfc04bc26ceeab23ce Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Tue, 4 Apr 2023 13:59:45 -0700 Subject: perf map: Add accessors for ->prot, ->priv and ->flags 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 Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexey Bayduraev Cc: Andi Kleen Cc: Andrew Morton Cc: Andy Shevchenko Cc: Darren Hart Cc: Davidlohr Bueso Cc: Dmitriy Vyukov Cc: Eric Dumazet Cc: German Gomez Cc: Hao Luo Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Kajol Jain Cc: Kan Liang Cc: Leo Yan Cc: Madhavan Srinivasan Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Miaoqian Lin Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Shunsuke Nakamura Cc: Song Liu Cc: Stephane Eranian Cc: Stephen Brennan Cc: Steven Rostedt (VMware) Cc: Thomas Gleixner Cc: Thomas Richter Cc: Yury Norov Link: https://lore.kernel.org/r/20230404205954.2245628-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- 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(-) (limited to 'tools/perf/builtin-inject.c') 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 = 1; dso__inject_build_id(dso, tool, machine, - sample->cpumode, al.map->flags); + sample->cpumode, map__flags(al.map)); } } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2a6e2cee5e0d..c066452219c8 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -849,13 +849,14 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp) maps__for_each_entry(maps, rb_node) { struct map *map = rb_node->map; const struct dso *dso = map__dso(map); + u32 prot = map__prot(map); printed += fprintf(fp, "%*s %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" 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 @@ next_pair: mem_end = map__unmap_ip(vmlinux_map, map__end(map)); pair = maps__find(kallsyms.kmaps, mem_start); - if (pair == NULL || pair->priv) + if (pair == NULL || map__priv(pair)) continue; if (map__start(pair) == mem_start) { @@ -351,7 +351,7 @@ next_pair: maps__for_each_entry(maps, rb_node) { struct map *map = rb_node->map; - if (!map->priv) { + if (!map__priv(map)) { if (!header_printed) { pr_info("WARN: Maps only in kallsyms:\n"); header_printed = 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; } +static inline u32 map__flags(const struct map *map) +{ + return map->flags; +} + +static inline u32 map__prot(const struct map *map) +{ + return map->prot; +} + +static inline bool map__priv(const struct map *map) +{ + return map->priv; +} + static inline size_t map__size(const struct map *map) { return map__end(map) - map__start(map); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 87a3ba584af5..80c9960c37e5 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1540,7 +1540,7 @@ sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right) */ if ((left->cpumode != 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.min && !l_dso->id.ino && !l_dso->id.ino_generation) { /* userspace anonymous */ @@ -1576,8 +1576,8 @@ static int hist_entry__dcacheline_snprintf(struct hist_entry *he, char *bf, /* print [s] for shared data mmaps */ if ((he->cpumode != 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 = 's'; else if (!map) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 9ba49c1ef6ef..5c075d77a792 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1396,7 +1396,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, } /* Read new maps into temporary lists */ - err = file__read_maps(fd, map->prot & PROT_EXEC, kcore_mapfn, &md, + err = file__read_maps(fd, map__prot(map) & PROT_EXEC, kcore_mapfn, &md, &is_64_bit); if (err) goto out_err; @@ -1509,7 +1509,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map, close(fd); - 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); -- cgit v1.2.3-59-g8ed1b From 79b40a1b182bcca381bb59d0219e1dd681a64981 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 12 Apr 2023 09:50:08 -0300 Subject: perf inject: Use zfree() to reduce chances of use after free Do defensive programming by using zfree() to initialize freed pointers to NULL, so that eventual use after free result in a NULL pointer deref instead of more subtle behaviour. Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools/perf/builtin-inject.c') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index fd2b38458a5d..76723ac314b6 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -1311,10 +1311,10 @@ static void guest_session__exit(struct guest_session *gs) if (gs->tmp_fd >= 0) close(gs->tmp_fd); unlink(gs->tmp_file_name); - free(gs->tmp_file_name); + zfree(&gs->tmp_file_name); } - free(gs->vcpu); - free(gs->perf_data_file); + zfree(&gs->vcpu); + zfree(&gs->perf_data_file); } static void get_tsc_conv(struct perf_tsc_conversion *tc, struct perf_record_time_conv *time_conv) -- cgit v1.2.3-59-g8ed1b From 7031edac9dbc0f880c9fbaa40ca08b5de34239c6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 17 Apr 2023 18:28:01 -0300 Subject: perf dso: Add dso__filename_with_chroot() to reduce number of accesses to dso->nsinfo members We'll need to reference count dso->nsinfo, so reduce the number of direct accesses by having a shorter form of obtaining a filename with a chroot (namespace one). Cc: Adrian Hunter Cc: Alexey Bayduraev Cc: Dmitriy Vyukov Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Cc: Riccardo Mancini Cc: Stephane Eranian Cc: Stephen Brennan Link: https://lore.kernel.org/lkml/ZD26ZlqSbgSyH5lX@kernel.org [ Used nsinfo__pid(dso->nsinfo), as it was already present ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 4 +--- tools/perf/util/annotate.c | 3 +-- tools/perf/util/dso.c | 7 ++++++- tools/perf/util/dso.h | 2 ++ tools/perf/util/dsos.c | 3 +-- tools/perf/util/symbol.c | 3 +-- 6 files changed, 12 insertions(+), 10 deletions(-) (limited to 'tools/perf/builtin-inject.c') diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 76723ac314b6..61766eead4f4 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -630,10 +630,8 @@ static int dso__read_build_id(struct dso *dso) if (filename__read_build_id(dso->long_name, &dso->bid) > 0) dso->has_build_id = true; else if (dso->nsinfo) { - char *new_name; + char *new_name = dso__filename_with_chroot(dso, dso->long_name); - new_name = filename_with_chroot(dso->nsinfo->pid, - dso->long_name); if (new_name && filename__read_build_id(new_name, &dso->bid) > 0) dso->has_build_id = true; free(new_name); diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index e2693a1c28d5..ca9f0add68f4 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1692,8 +1692,7 @@ fallback: mutex_lock(&dso->lock); if (access(filename, R_OK) && errno == ENOENT && dso->nsinfo) { - char *new_name = filename_with_chroot(dso->nsinfo->pid, - filename); + char *new_name = dso__filename_with_chroot(dso, filename); if (new_name) { strlcpy(filename, new_name, filename_size); free(new_name); diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e36b418df2c6..a86614599269 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -491,6 +491,11 @@ static int do_open(char *name) return -1; } +char *dso__filename_with_chroot(const struct dso *dso, const char *filename) +{ + return filename_with_chroot(nsinfo__pid(dso->nsinfo), filename); +} + static int __open_dso(struct dso *dso, struct machine *machine) { int fd = -EINVAL; @@ -515,7 +520,7 @@ static int __open_dso(struct dso *dso, struct machine *machine) if (errno != ENOENT || dso->nsinfo == NULL) goto out; - new_name = filename_with_chroot(dso->nsinfo->pid, name); + new_name = dso__filename_with_chroot(dso, name); if (!new_name) goto out; diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 58d94175e714..0b7c7633b9f6 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -266,6 +266,8 @@ static inline bool dso__has_symbols(const struct dso *dso) return !RB_EMPTY_ROOT(&dso->symbols.rb_root); } +char *dso__filename_with_chroot(const struct dso *dso, const char *filename); + bool dso__sorted_by_name(const struct dso *dso); void dso__set_sorted_by_name(struct dso *dso); void dso__sort_by_name(struct dso *dso); diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index 2bd23e4cf19e..cf80aa42dd07 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -91,8 +91,7 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits) have_build_id = true; pos->has_build_id = true; } else if (errno == ENOENT && pos->nsinfo) { - char *new_name = filename_with_chroot(pos->nsinfo->pid, - pos->long_name); + char *new_name = dso__filename_with_chroot(pos, pos->long_name); if (new_name && filename__read_build_id(new_name, &pos->bid) > 0) { diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 91ebf93e0c20..e7f63670688e 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1963,8 +1963,7 @@ int dso__load(struct dso *dso, struct map *map) is_reg = is_regular_file(name); if (!is_reg && errno == ENOENT && dso->nsinfo) { - char *new_name = filename_with_chroot(dso->nsinfo->pid, - name); + char *new_name = dso__filename_with_chroot(dso, name); if (new_name) { is_reg = is_regular_file(new_name); strlcpy(name, new_name, PATH_MAX); -- cgit v1.2.3-59-g8ed1b