linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 00/12] Reference count checker and related fixes
@ 2023-04-04 20:59 Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip Ian Rogers
                   ` (11 more replies)
  0 siblings, 12 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

The perf tool has a class of memory problems where reference counts
are used incorrectly. Memory/address sanitizers and valgrind don't
provide useful ways to debug these problems, you see a memory leak
where the only pertinent information is the original allocation
site. What would be more useful is knowing where a get fails to have a
corresponding put, where there are double puts, etc.

This work was motivated by the roll-back of:
https://lore.kernel.org/linux-perf-users/20211118193714.2293728-1-irogers@google.com/
where fixing a missed put resulted in a use-after-free in a different
context. There was a sense in fixing the issue that a game of
wac-a-mole had been embarked upon in adding missed gets and puts.

The basic approach of the change is to add a level of indirection at
the get and put calls. Get allocates a level of indirection that, if
no corresponding put is called, becomes a memory leak (and associated
stack trace) that leak sanitizer can report. Similarly if two puts are
called for the same get, then a double free can be detected by address
sanitizer. This can also detect the use after put, which should also
yield a segv without a sanitizer.

Adding reference count checking to cpu map was done as a proof of
concept, it yielded little other than a location where the use of get
could be cleaner by using its result. Reference count checking on
nsinfo identified a double free of the indirection layer and the
related threads, thereby identifying a data race as discussed here:
 https://lore.kernel.org/linux-perf-users/CAP-5=fWZH20L4kv-BwVtGLwR=Em3AOOT+Q4QGivvQuYn5AsPRg@mail.gmail.com/
Accordingly the dso->lock was extended and use to cover the race.

The v3 version addresses problems in v2, in particular using macros to
avoid #ifdefs. The v3 version applies the reference count checking
approach to two more data structures, maps and map. While maps was
straightforward, struct map showed a problem where reference counted
thing can be on lists and rb-trees that are oblivious to the
reference count. To sanitize this, struct map is changed so that it is
referenced by either a list or rb-tree node and not part of it. This
simplifies the reference count and the patches have caught and fixed a
number of missed or mismatched reference counts relating to struct
map.

The patches are arranged so that API refactors and bug fixes appear
first, then the reference count checker itself appears. This allows
for the refactor and fixes to be applied upstream first, as has
already happened with cpumap.

A wider discussion of the approach is on the mailing list:
 https://lore.kernel.org/linux-perf-users/YffqnynWcc5oFkI5@kernel.org/T/#mf25ccd7a2e03de92cec29d36e2999a8ab5ec7f88
Comparing it to a past approach:
 https://lore.kernel.org/all/20151209021047.10245.8918.stgit@localhost.localdomain/
and to ref_tracker:
 https://lwn.net/Articles/877603/

v6. rebase removing 5 merged changes. Fix missed issues with libunwind.
v5. rebase removing 5 merged changes. Add map_list_node__new to the
    1st patch (perf map: Move map list node into symbol) as suggested
    by Arnaldo. Remove unnecessary map__puts from patch 12 (perf map:
    Changes to reference counting) as suggested by Adrian.
v4. rebases on to acme's perf-tools-next, fixes more issues with
    map/maps and breaks apart the accessor functions to reduce
    individual patch sizes. The accessor functions are mechanical
    changes where the single biggest one is refactoring use of
    map->dso to be map__dso(map).

The v3 change is available here:
https://lore.kernel.org/lkml/20220211103415.2737789-1-irogers@google.com/

Ian Rogers (12):
  perf map: Rename map_ip and unmap_ip
  perf map: Add helper for map_ip and unmap_ip
  perf map: Add accessors for prot, priv and flags
  perf map: Add accessors for pgoff and reloc
  perf test: Add extra diagnostics to maps test
  perf maps: Modify maps_by_name to hold a reference to a map
  perf map: Changes to reference counting
  libperf: Add reference count checking macros.
  perf cpumap: Add reference count checking
  perf namespaces: Add reference count checking
  perf maps: Add reference count checking.
  perf map: Add reference count checking

 tools/lib/perf/Makefile                       |   2 +-
 tools/lib/perf/cpumap.c                       |  94 +++++++------
 tools/lib/perf/include/internal/cpumap.h      |   4 +-
 tools/lib/perf/include/internal/rc_check.h    |  94 +++++++++++++
 tools/perf/arch/s390/annotate/instructions.c  |   4 +-
 tools/perf/arch/x86/util/event.c              |   2 +-
 tools/perf/builtin-inject.c                   |   4 +-
 tools/perf/builtin-kallsyms.c                 |   2 +-
 tools/perf/builtin-kmem.c                     |   4 +-
 tools/perf/builtin-lock.c                     |   4 +-
 tools/perf/builtin-report.c                   |  11 +-
 tools/perf/builtin-script.c                   |   6 +-
 tools/perf/builtin-top.c                      |   4 +-
 tools/perf/tests/code-reading.c               |   1 +
 tools/perf/tests/cpumap.c                     |   4 +-
 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/maps.c                       |  67 ++++++---
 tools/perf/tests/mmap-thread-lookup.c         |   1 +
 tools/perf/tests/thread-maps-share.c          |  29 ++--
 tools/perf/tests/vmlinux-kallsyms.c           |  22 +--
 tools/perf/util/annotate.c                    |  20 +--
 tools/perf/util/bpf_lock_contention.c         |   4 +-
 tools/perf/util/callchain.c                   |   9 +-
 tools/perf/util/cpumap.c                      |  40 +++---
 tools/perf/util/dlfilter.c                    |   2 +-
 tools/perf/util/dso.c                         |   8 +-
 tools/perf/util/dsos.c                        |   2 +-
 tools/perf/util/event.c                       |  14 +-
 tools/perf/util/evsel_fprintf.c               |   2 +-
 tools/perf/util/hist.c                        |  10 +-
 tools/perf/util/intel-pt.c                    |  10 +-
 tools/perf/util/machine.c                     | 126 ++++++++++-------
 tools/perf/util/map.c                         |  95 +++++++------
 tools/perf/util/map.h                         |  57 ++++++--
 tools/perf/util/maps.c                        | 100 +++++++------
 tools/perf/util/maps.h                        |  17 +--
 tools/perf/util/namespaces.c                  | 132 ++++++++++--------
 tools/perf/util/namespaces.h                  |   3 +-
 tools/perf/util/pmu.c                         |   8 +-
 tools/perf/util/probe-event.c                 |  14 +-
 .../scripting-engines/trace-event-python.c    |   2 +-
 tools/perf/util/sort.c                        |  18 +--
 tools/perf/util/symbol-elf.c                  |  26 ++--
 tools/perf/util/symbol.c                      |  88 +++++++-----
 tools/perf/util/thread.c                      |   2 +-
 tools/perf/util/unwind-libdw.c                |  10 +-
 tools/perf/util/unwind-libunwind-local.c      |   4 +-
 tools/perf/util/unwind-libunwind.c            |   2 +-
 51 files changed, 766 insertions(+), 466 deletions(-)
 create mode 100644 tools/lib/perf/include/internal/rc_check.h

-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-05 13:25   ` Arnaldo Carvalho de Melo
  2023-04-04 20:59 ` [PATCH v6 02/12] perf map: Add helper for " Ian Rogers
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 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 perf_sample *sample)
 		if (!caller) {
 			/* found */
 			if (node->ms.map)
-				addr = map__unmap_ip(node->ms.map, node->ip);
+				addr = map__dso_unmap_ip(node->ms.map, node->ip);
 			else
 				addr = node->ip;
 
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 1d078106abc4..af0a69c7f41f 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1012,11 +1012,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
 
 		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
 		    !map__dso(alf.map)->adjust_symbols)
-			from = map__map_ip(alf.map, from);
+			from = map__dso_map_ip(alf.map, from);
 
 		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
 		    !map__dso(alt.map)->adjust_symbols)
-			to = map__map_ip(alt.map, to);
+			to = map__dso_map_ip(alt.map, to);
 
 		printed += fprintf(fp, " 0x%"PRIx64, from);
 		if (PRINT_FIELD(DSO)) {
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 7852b97da10a..9d24980a0a93 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -3058,7 +3058,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms
 	if (!symbol_conf.inline_name || !map || !sym)
 		return ret;
 
-	addr = map__map_ip(map, ip);
+	addr = map__dso_map_ip(map, ip);
 	addr = map__rip_2objdump(map, addr);
 	dso = map__dso(map);
 
@@ -3103,7 +3103,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
 	 * its corresponding binary.
 	 */
 	if (entry->ms.map)
-		addr = map__map_ip(entry->ms.map, entry->ip);
+		addr = map__dso_map_ip(entry->ms.map, entry->ip);
 
 	srcline = 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    = pgoff;
 	map->reloc    = 0;
 	map->dso      = dso__get(dso);
-	map->map_ip   = map__map_ip;
-	map->unmap_ip = map__unmap_ip;
+	map->map_ip   = map__dso_map_ip;
+	map->unmap_ip = map__dso_unmap_ip;
 	map->erange_warned = false;
 	refcount_set(&map->refcnt, 1);
 }
@@ -590,12 +590,12 @@ struct maps *map__kmaps(struct map *map)
 	return kmap->kmaps;
 }
 
-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;
 }
 
-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);
 
 /* 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);
 
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index e715869eab8a..c55981116f68 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1357,8 +1357,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
 			map->start = shdr->sh_addr + ref_reloc(kmap);
 			map->end = map__start(map) + shdr->sh_size;
 			map->pgoff = shdr->sh_offset;
-			map->map_ip = map__map_ip;
-			map->unmap_ip = map__unmap_ip;
+			map->map_ip = map__dso_map_ip;
+			map->unmap_ip = map__dso_unmap_ip;
 			/* Ensure maps are correctly ordered */
 			if (kmaps) {
 				int err;
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 02/12] perf map: Add helper for map_ip and unmap_ip
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-07  1:06   ` Arnaldo Carvalho de Melo
  2023-04-04 20:59 ` [PATCH v6 03/12] perf map: Add accessors for prot, priv and flags Ian Rogers
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 tools/perf/arch/s390/annotate/instructions.c     |  3 ++-
 tools/perf/builtin-kallsyms.c                    |  2 +-
 tools/perf/builtin-kmem.c                        |  2 +-
 tools/perf/builtin-lock.c                        |  4 ++--
 tools/perf/builtin-script.c                      |  2 +-
 tools/perf/tests/vmlinux-kallsyms.c              | 10 +++++-----
 tools/perf/util/annotate.c                       | 16 +++++++++-------
 tools/perf/util/bpf_lock_contention.c            |  4 ++--
 tools/perf/util/dlfilter.c                       |  2 +-
 tools/perf/util/dso.c                            |  6 ++++--
 tools/perf/util/event.c                          |  8 ++++----
 tools/perf/util/evsel_fprintf.c                  |  2 +-
 tools/perf/util/intel-pt.c                       | 10 +++++-----
 tools/perf/util/machine.c                        | 16 ++++++++--------
 tools/perf/util/map.c                            | 10 +++++-----
 tools/perf/util/map.h                            | 10 ++++++++++
 tools/perf/util/maps.c                           |  8 ++++----
 tools/perf/util/probe-event.c                    |  8 ++++----
 .../util/scripting-engines/trace-event-python.c  |  2 +-
 tools/perf/util/sort.c                           | 12 ++++++------
 tools/perf/util/symbol.c                         |  4 ++--
 tools/perf/util/thread.c                         |  2 +-
 tools/perf/util/unwind-libdw.c                   |  2 +-
 tools/perf/util/unwind-libunwind-local.c         |  2 +-
 24 files changed, 81 insertions(+), 66 deletions(-)

diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c
index 0e136630659e..6548933e8dc0 100644
--- a/tools/perf/arch/s390/annotate/instructions.c
+++ b/tools/perf/arch/s390/annotate/instructions.c
@@ -39,7 +39,8 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
 	target.addr = map__objdump_2mem(map, ops->target.addr);
 
 	if (maps__find_ams(ms->maps, &target) == 0 &&
-	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
+	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
+	    ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
 	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 = 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);
 	}
 
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,
 
 		if (sym != NULL)
 			snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name,
-				 addr - map->unmap_ip(map, sym->start));
+				 addr - map__unmap_ip(map, sym->start));
 		else
 			snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr);
 		printf(" %-34s |", buf);
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 32ec58fb80e4..04345b2e7101 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -900,7 +900,7 @@ static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip,
 		return 0;
 	}
 
-	offset = map->map_ip(map, ip) - sym->start;
+	offset = map__map_ip(map, ip) - sym->start;
 
 	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;
 			}
 
-			addrs[filters.nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
+			addrs[filters.nr_addrs++] = map__unmap_ip(kmap, sym->start);
 			filters.addrs = addrs;
 		}
 	}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index af0a69c7f41f..8fba247b798c 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1088,7 +1088,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
 	/* Load maps to ensure dso->is_64_bit has been updated */
 	map__load(al.map);
 
-	offset = al.map->map_ip(al.map, start);
+	offset = map__map_ip(al.map, start);
 	len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,
 				    end - start + MAXINSN);
 
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"
 
-#define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x))
+#define UM(x) map__unmap_ip(kallsyms_map, (x))
 
 static bool is_ignored_symbol(const char *name, char type)
 {
@@ -221,8 +221,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
 		if (sym->start == sym->end)
 			continue;
 
-		mem_start = vmlinux_map->unmap_ip(vmlinux_map, sym->start);
-		mem_end = vmlinux_map->unmap_ip(vmlinux_map, sym->end);
+		mem_start = map__unmap_ip(vmlinux_map, sym->start);
+		mem_end = map__unmap_ip(vmlinux_map, sym->end);
 
 		first_pair = machine__find_kernel_symbol(&kallsyms, mem_start, NULL);
 		pair = first_pair;
@@ -319,8 +319,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
 	maps__for_each_entry(maps, rb_node) {
 		struct map *pair, *map = rb_node->map;
 
-		mem_start = vmlinux_map->unmap_ip(vmlinux_map, map__start(map));
-		mem_end = vmlinux_map->unmap_ip(vmlinux_map, map__end(map));
+		mem_start = map__unmap_ip(vmlinux_map, map__start(map));
+		mem_end = map__unmap_ip(vmlinux_map, map__end(map));
 
 		pair = maps__find(kallsyms.kmaps, mem_start);
 		if (pair == NULL || pair->priv)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index b9cff782d7df..36acdd1bd379 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -272,7 +272,8 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s
 	target.addr = map__objdump_2mem(map, ops->target.addr);
 
 	if (maps__find_ams(ms->maps, &target) == 0 &&
-	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
+	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
+	    ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
 	return 0;
@@ -376,8 +377,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
 	}
 
 	target.addr = map__objdump_2mem(map, ops->target.addr);
-	start = map->unmap_ip(map, sym->start),
-	end = map->unmap_ip(map, sym->end);
+	start = map__unmap_ip(map, sym->start);
+	end = map__unmap_ip(map, sym->end);
 
 	ops->target.outside = target.addr < start || target.addr > end;
 
@@ -400,7 +401,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
 	 * the symbol searching and disassembly should be done.
 	 */
 	if (maps__find_ams(ms->maps, &target) == 0 &&
-	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
+	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
+	    ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
 	if (!ops->target.outside) {
@@ -881,7 +883,7 @@ static int __symbol__inc_addr_samples(struct map_symbol *ms,
 	unsigned offset;
 	struct sym_hist *h;
 
-	pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->map, addr));
+	pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, addr));
 
 	if ((addr < sym->start || addr >= sym->end) &&
 	    (addr != sym->end || sym->start != sym->end)) {
@@ -1977,8 +1979,8 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
 		return err;
 
 	pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\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));
 
 	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_lock_contention.c
index 8a5d0eb44189..2b3bc544aa3e 100644
--- a/tools/perf/util/bpf_lock_contention.c
+++ b/tools/perf/util/bpf_lock_contention.c
@@ -74,7 +74,7 @@ int lock_contention_prepare(struct lock_contention *con)
 				continue;
 			}
 
-			addrs[con->filters->nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
+			addrs[con->filters->nr_addrs++] = map__unmap_ip(kmap, sym->start);
 			con->filters->addrs = addrs;
 		}
 		naddrs = con->filters->nr_addrs;
@@ -233,7 +233,7 @@ static const char *lock_contention_get_name(struct lock_contention *con,
 	if (sym) {
 		unsigned long offset;
 
-		offset = kmap->map_ip(kmap, addr) - sym->start;
+		offset = map__map_ip(kmap, addr) - sym->start;
 
 		if (offset == 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)
 
 	map = a.map;
 have_map:
-	offset = map->map_ip(map, ip);
+	offset = map__map_ip(map, ip);
 	if (ip + len >= map__end(map))
 		len = 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 map *map,
 			    struct machine *machine, u64 addr,
 			    u8 *data, ssize_t size)
 {
-	u64 offset = map->map_ip(map, addr);
+	u64 offset = map__map_ip(map, addr);
+
 	return dso__data_read_offset(dso, machine, offset, data, size);
 }
 
@@ -1162,7 +1163,8 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
 				   struct machine *machine, u64 addr,
 				   const u8 *data, ssize_t size)
 {
-	u64 offset = map->map_ip(map, addr);
+	u64 offset = map__map_ip(map, addr);
+
 	return dso__data_write_cache_offs(dso, machine, offset, data, size);
 }
 
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
 
 		al.map = maps__find(machine__kernel_maps(machine), tp->addr);
 		if (al.map && map__load(al.map) >= 0) {
-			al.addr = al.map->map_ip(al.map, tp->addr);
+			al.addr = map__map_ip(al.map, tp->addr);
 			al.sym = map__find_symbol(al.map, al.addr);
 			if (al.sym)
 				ret += 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 = al->map->map_ip(al->map, al->addr);
+		al->addr = map__map_ip(al->map, al->addr);
 	}
 
 	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 = strlist__has_entry(symbol_conf.sym_list,
 						al_addr_str);
 		}
 		if (!ret && symbol_conf.addr_list && al->map) {
-			unsigned long addr = al->map->unmap_ip(al->map, al->addr);
+			unsigned long addr = map__unmap_ip(al->map, al->addr);
 
 			ret = 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_fprintf.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 *sample, int left_alignment,
 				printed += fprintf(fp, " <-");
 
 			if (map)
-				addr = map->map_ip(map, node->ip);
+				addr = map__map_ip(map, node->ip);
 
 			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;
 
-		offset = al.map->map_ip(al.map, *ip);
+		offset = map__map_ip(al.map, *ip);
 
 		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;
 
-	offset = al.map->map_ip(al.map, ip);
+	offset = map__map_ip(al.map, ip);
 
 	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, u64 *ptss_ip)
 	for (sym = start; sym; sym = dso__next_symbol(sym)) {
 		if (sym->binding == STB_GLOBAL &&
 		    !strcmp(sym->name, "__switch_to")) {
-			ip = map->unmap_ip(map, sym->start);
+			ip = map__unmap_ip(map, sym->start);
 			if (ip >= map__start(map) && ip < map__end(map)) {
 				switch_ip = ip;
 				break;
@@ -2767,7 +2767,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
 
 	for (sym = start; sym; sym = dso__next_symbol(sym)) {
 		if (!strcmp(sym->name, ptss)) {
-			ip = map->unmap_ip(map, sym->start);
+			ip = map__unmap_ip(map, sym->start);
 			if (ip >= map__start(map) && ip < map__end(map)) {
 				*ptss_ip = ip;
 				break;
@@ -3393,7 +3393,7 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event)
 		if (!dso || !dso->auxtrace_cache)
 			continue;
 
-		offset = al.map->map_ip(al.map, addr);
+		offset = map__map_ip(al.map, addr);
 
 		e = intel_pt_cache_lookup(dso, machine, offset);
 		if (!e)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 9d24980a0a93..d29ec4a04488 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -919,7 +919,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
 		dso = map__dso(map);
 	}
 
-	sym = symbol__new(map->map_ip(map, map__start(map)),
+	sym = symbol__new(map__map_ip(map, map__start(map)),
 			  event->ksymbol.len,
 			  0, 0, event->ksymbol.name);
 	if (!sym)
@@ -944,7 +944,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine,
 	else {
 		struct dso *dso = map__dso(map);
 
-		sym = dso__find_symbol(dso, map->map_ip(map, map__start(map)));
+		sym = dso__find_symbol(dso, map__map_ip(map, map__start(map)));
 		if (sym)
 			dso__delete_symbol(dso, sym);
 	}
@@ -1279,7 +1279,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,
 
 		dest_map = maps__find(kmaps, map->pgoff);
 		if (dest_map != map)
-			map->pgoff = dest_map->map_ip(dest_map, map->pgoff);
+			map->pgoff = map__map_ip(dest_map, map->pgoff);
 		found = true;
 	}
 	if (found || machine->trampolines_mapped)
@@ -3345,7 +3345,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch
 		return NULL;
 
 	*modp = __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NULL;
-	*addrp = map->unmap_ip(map, sym->start);
+	*addrp = map__unmap_ip(map, sym->start);
 	return sym->name;
 }
 
@@ -3388,17 +3388,17 @@ bool machine__is_lock_function(struct machine *machine, u64 addr)
 			return false;
 		}
 
-		machine->sched.text_start = kmap->unmap_ip(kmap, sym->start);
+		machine->sched.text_start = map__unmap_ip(kmap, sym->start);
 
 		/* should not fail from here */
 		sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_end", &kmap);
-		machine->sched.text_end = kmap->unmap_ip(kmap, sym->start);
+		machine->sched.text_end = map__unmap_ip(kmap, sym->start);
 
 		sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_start", &kmap);
-		machine->lock.text_start = kmap->unmap_ip(kmap, sym->start);
+		machine->lock.text_start = map__unmap_ip(kmap, sym->start);
 
 		sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_end", &kmap);
-		machine->lock.text_end = kmap->unmap_ip(kmap, sym->start);
+		machine->lock.text_end = map__unmap_ip(kmap, sym->start);
 	}
 
 	/* 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 == DSO_SPACE__USER)
 		return rip + dso->text_offset;
 
-	return map->unmap_ip(map, rip) - map->reloc;
+	return map__unmap_ip(map, rip) - map->reloc;
 }
 
 /**
@@ -539,24 +539,24 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
 	const struct dso *dso = map__dso(map);
 
 	if (!dso->adjust_symbols)
-		return map->unmap_ip(map, ip);
+		return map__unmap_ip(map, ip);
 
 	if (dso->rel)
-		return map->unmap_ip(map, ip + map->pgoff);
+		return map__unmap_ip(map, ip + map->pgoff);
 
 	/*
 	 * 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 == DSO_SPACE__USER)
-		return map->unmap_ip(map, ip - dso->text_offset);
+		return map__unmap_ip(map, ip - dso->text_offset);
 
 	return ip + map->reloc;
 }
 
 bool map__contains_symbol(const struct map *map, const struct symbol *sym)
 {
-	u64 ip = map->unmap_ip(map, sym->start);
+	u64 ip = map__unmap_ip(map, sym->start);
 
 	return ip >= 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;
 }
 
+static inline u64 map__map_ip(const struct map *map, u64 ip)
+{
+	return map->map_ip(map, ip);
+}
+
+static inline u64 map__unmap_ip(const struct map *map, u64 ip)
+{
+	return map->unmap_ip(map, ip);
+}
+
 static inline u64 map__start(const struct map *map)
 {
 	return map->start;
diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
index 21010a2b8e16..0eee27e24c33 100644
--- a/tools/perf/util/maps.c
+++ b/tools/perf/util/maps.c
@@ -194,7 +194,7 @@ struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp)
 	if (map != NULL && map__load(map) >= 0) {
 		if (mapp != NULL)
 			*mapp = map;
-		return map__find_symbol(map, map->map_ip(map, addr));
+		return map__find_symbol(map, map__map_ip(map, addr));
 	}
 
 	return NULL;
@@ -237,7 +237,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams)
 			return -1;
 	}
 
-	ams->al_addr = ams->ms.map->map_ip(ams->ms.map, ams->addr);
+	ams->al_addr = map__map_ip(ams->ms.map, ams->addr);
 	ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr);
 
 	return ams->ms.sym ? 0 : -1;
@@ -349,8 +349,8 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
 
 			after->start = map__end(map);
 			after->pgoff += map__end(map) - map__start(pos->map);
-			assert(pos->map->map_ip(pos->map, map__end(map)) ==
-				after->map_ip(after, map__end(map)));
+			assert(map__map_ip(pos->map, map__end(map)) ==
+				map__map_ip(after, map__end(map)));
 			err = __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 = machine__find_kernel_symbol_by_name(host_machine, name, &map);
 		if (!sym)
 			return -ENOENT;
-		*addr = map->unmap_ip(map, sym->start) -
+		*addr = 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 debuginfo *dinfo,
 					   "Consider identifying the final function used at run time and set the probe directly on that.\n",
 					   pp->function);
 		} else
-			address = map->unmap_ip(map, sym->start) - map->reloc;
+			address = map__unmap_ip(map, sym->start) - map->reloc;
 		break;
 	}
 	if (!address) {
@@ -2249,7 +2249,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
 		goto out;
 
 	pp->retprobe = tp->retprobe;
-	pp->offset = addr - map->unmap_ip(map, sym->start);
+	pp->offset = addr - map__unmap_ip(map, sym->start);
 	pp->function = strdup(sym->name);
 	ret = pp->function ? 0 : -ENOMEM;
 
@@ -3123,7 +3123,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
 			goto err_out;
 		}
 		/* Add one probe point */
-		tp->address = map->unmap_ip(map, sym->start) + pp->offset;
+		tp->address = map__unmap_ip(map, sym->start) + pp->offset;
 
 		/* 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_sample *sample,
 				struct addr_location node_al;
 				unsigned long offset;
 
-				node_al.addr = map->map_ip(map, node->ip);
+				node_al.addr = map__map_ip(map, node->ip);
 				node_al.map  = map;
 				offset = get_offset(node->ms.sym, &node_al);
 
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index f161589aefda..87a3ba584af5 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -364,7 +364,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
 		u64 rip = ip;
 
 		if (dso && dso->kernel && dso->adjust_symbols)
-			rip = map->unmap_ip(map, ip);
+			rip = map__unmap_ip(map, ip);
 
 		ret += repsep_snprintf(bf, size, "%-#*llx %c ",
 				       BITS_PER_LONG / 4 + 2, rip, o);
@@ -375,7 +375,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
 		if (sym->type == STT_OBJECT) {
 			ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
 			ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
-					ip - map->unmap_ip(map, sym->start));
+					ip - map__unmap_ip(map, sym->start));
 		} else {
 			ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
 					       width - ret,
@@ -1147,7 +1147,7 @@ static int _hist_entry__addr_snprintf(struct map_symbol *ms,
 		if (sym->type == STT_OBJECT) {
 			ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
 			ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
-					ip - map->unmap_ip(map, sym->start));
+					ip - map__unmap_ip(map, sym->start));
 		} else {
 			ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
 					       width - ret,
@@ -2104,9 +2104,9 @@ sort__addr_cmp(struct hist_entry *left, struct hist_entry *right)
 	struct map *right_map = right->ms.map;
 
 	if (left_map)
-		left_ip = left_map->unmap_ip(left_map, left_ip);
+		left_ip = map__unmap_ip(left_map, left_ip);
 	if (right_map)
-		right_ip = right_map->unmap_ip(right_map, right_ip);
+		right_ip = map__unmap_ip(right_map, right_ip);
 
 	return _sort__addr_cmp(left_ip, right_ip);
 }
@@ -2118,7 +2118,7 @@ static int hist_entry__addr_snprintf(struct hist_entry *he, char *bf,
 	struct map *map = he->ms.map;
 
 	if (map)
-		ip = map->unmap_ip(map, ip);
+		ip = map__unmap_ip(map, ip);
 
 	return repsep_snprintf(bf, size, "%-#*llx", width, ip);
 }
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index b91deb177091..9ba49c1ef6ef 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -896,8 +896,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct 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 = curr_map->map_ip(curr_map, pos->start);
-			pos->end   = curr_map->map_ip(curr_map, pos->end);
+			pos->start = map__map_ip(curr_map, pos->start);
+			pos->end   = map__map_ip(curr_map, pos->end);
 		} else if (x86_64 && is_entry_trampoline(pos->name)) {
 			/*
 			 * These symbols are not needed anymore since the
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index bb7a2ce82d46..4b5bdc277baa 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -464,7 +464,7 @@ int thread__memcpy(struct thread *thread, struct machine *machine,
 	if( !dso || dso->data.status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0)
 		return -1;
 
-	offset = al.map->map_ip(al.map, ip);
+	offset = map__map_ip(al.map, ip);
 	if (is64bit)
 		*is64bit = dso->is_64_bit;
 
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 = 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;
 }
 
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index 1c13f43e7d22..f9a52af48de4 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -640,7 +640,7 @@ static int entry(u64 ip, struct thread *thread,
 	pr_debug("unwind: %s:ip = 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 cb(&e, arg);
 }
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 03/12] perf map: Add accessors for prot, priv and flags
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 02/12] perf map: Add helper for " Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 04/12] perf map: Add accessors for pgoff and reloc Ian Rogers
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 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 = 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 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
 		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 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
 	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);
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 04/12] perf map: Add accessors for pgoff and reloc
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (2 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 03/12] perf map: Add accessors for prot, priv and flags Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 05/12] perf test: Add extra diagnostics to maps test Ian Rogers
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 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/event.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,
 
 		event->mmap.start = map__start(map);
 		event->mmap.len   = map__size(map);
-		event->mmap.pgoff = map->pgoff;
+		event->mmap.pgoff = map__pgoff(map);
 		event->mmap.pid   = machine->pid;
 
 		strlcpy(event->mmap.filename, kmap->name, PATH_MAX);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c066452219c8..92c6797e7cba 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -857,7 +857,7 @@ static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
 				   prot & PROT_WRITE ? 'w' : '-',
 				   prot & PROT_EXEC ? 'x' : '-',
 				   map__flags(map) ? 's' : 'p',
-				   map->pgoff,
+				   map__pgoff(map),
 				   dso->id.ino, dso->name);
 	}
 
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
 			}
 
 			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 != 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 = 1;
 		}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index d29ec4a04488..1ea6f6c06bbb 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1277,9 +1277,9 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,
 		if (!kmap || !is_entry_trampoline(kmap->name))
 			continue;
 
-		dest_map = maps__find(kmaps, map->pgoff);
+		dest_map = maps__find(kmaps, map__pgoff(map));
 		if (dest_map != map)
-			map->pgoff = map__map_ip(dest_map, map->pgoff);
+			map->pgoff = map__map_ip(dest_map, map__pgoff(map));
 		found = 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 = map__dso(map);
 
 	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);
 }
 
 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;
 
 	if (dso->rel)
-		return rip - map->pgoff;
+		return rip - map__pgoff(map);
 
 	/*
 	 * 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 == DSO_SPACE__USER)
 		return rip + dso->text_offset;
 
-	return map__unmap_ip(map, rip) - map->reloc;
+	return map__unmap_ip(map, rip) - map__reloc(map);
 }
 
 /**
@@ -542,7 +542,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
 		return map__unmap_ip(map, ip);
 
 	if (dso->rel)
-		return map__unmap_ip(map, ip + map->pgoff);
+		return map__unmap_ip(map, ip + map__pgoff(map));
 
 	/*
 	 * 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 == DSO_SPACE__USER)
 		return map__unmap_ip(map, ip - dso->text_offset);
 
-	return ip + map->reloc;
+	return ip + map__reloc(map);
 }
 
 bool map__contains_symbol(const struct map *map, const struct symbol *sym)
@@ -592,12 +592,12 @@ struct maps *map__kmaps(struct map *map)
 
 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);
 }
 
 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);
 }
 
 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;
 }
 
+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 char *name, u64 *addr,
 	/* ref_reloc_sym is just a label. Need a special fix*/
 	reloc_sym = kernel_get_ref_reloc_sym(&map);
 	if (reloc_sym && strcmp(name, reloc_sym->name) == 0)
-		*addr = (!map->reloc || reloc) ? reloc_sym->addr :
+		*addr = (!map__reloc(map) || reloc) ? reloc_sym->addr :
 			reloc_sym->unrelocated_addr;
 	else {
 		sym = machine__find_kernel_symbol_by_name(host_machine, name, &map);
 		if (!sym)
 			return -ENOENT;
 		*addr = 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 debuginfo *dinfo,
 					   "Consider identifying the final function used at run time and set the probe directly on that.\n",
 					   pp->function);
 		} else
-			address = map__unmap_ip(map, sym->start) - map->reloc;
+			address = map__unmap_ip(map, sym->start) - map__reloc(map);
 		break;
 	}
 	if (!address) {
@@ -866,7 +866,7 @@ post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
 			free(tevs[i].point.symbol);
 		tevs[i].point.symbol = tmp;
 		tevs[i].point.offset = tevs[i].point.address -
-			(map->reloc ? reloc_sym->unrelocated_addr :
+			(map__reloc(map) ? reloc_sym->unrelocated_addr :
 				      reloc_sym->addr);
 	}
 	return skipped;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 5c075d77a792..7282119c2990 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -810,11 +810,11 @@ static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso)
 			continue;
 		}
 		curr_map_dso = map__dso(curr_map);
-		pos->start -= map__start(curr_map) - curr_map->pgoff;
+		pos->start -= map__start(curr_map) - map__pgoff(curr_map);
 		if (pos->end > map__end(curr_map))
 			pos->end = map__end(curr_map);
 		if (pos->end)
-			pos->end -= map__start(curr_map) - curr_map->pgoff;
+			pos->end -= map__start(curr_map) - map__pgoff(curr_map);
 		symbols__insert(&curr_map_dso->symbols, pos);
 		++count;
 	}
@@ -1459,7 +1459,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
 		if (new_map == replacement_map) {
 			map->start	= map__start(new_map);
 			map->end	= map__end(new_map);
-			map->pgoff	= new_map->pgoff;
+			map->pgoff	= map__pgoff(new_map);
 			map->map_ip	= new_map->map_ip;
 			map->unmap_ip	= new_map->unmap_ip;
 			/* Ensure maps are correctly ordered */
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 538320e4260c..9565f9906e5d 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -62,19 +62,19 @@ static int __report_module(struct addr_location *al, u64 ip,
 		Dwarf_Addr s;
 
 		dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
-		if (s != map__start(al->map) - al->map->pgoff)
+		if (s != map__start(al->map) - map__pgoff(al->map))
 			mod = 0;
 	}
 
 	if (!mod)
 		mod = 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];
 
 		if (dso__build_id_filename(dso, filename, sizeof(filename), false))
 			mod = 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);
 	}
 
 	if (mod) {
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 05/12] perf test: Add extra diagnostics to maps test
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (3 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 04/12] perf map: Add accessors for pgoff and reloc Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 06/12] perf maps: Modify maps_by_name to hold a reference to a map Ian Rogers
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

Dump the resultant and comparison maps on failure.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 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 <inttypes.h>
 #include <linux/compiler.h>
 #include <linux/kernel.h>
 #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 = 0;
-
-	maps__for_each_entry(maps, rb_node) {
-		struct map *map = rb_node->map;
-
-		if (i > 0)
-			TEST_ASSERT_VAL("less maps expected", (map && i < size) || (!map && i == size));
-
-		TEST_ASSERT_VAL("wrong map start",  map__start(map) == merged[i].start);
-		TEST_ASSERT_VAL("wrong map end",    map__end(map) == 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) == 1);
-
-		i++;
+	bool failed = false;
+
+	if (maps__nr_maps(maps) != size) {
+		pr_debug("Expected %d maps, got %d", size, maps__nr_maps(maps));
+		failed = true;
+	} else {
+		maps__for_each_entry(maps, rb_node) {
+			struct map *map = rb_node->map;
+
+			if (map__start(map) != merged[i].start ||
+			    map__end(map) != merged[i].end ||
+			    strcmp(map__dso(map)->name, merged[i].name) ||
+			    refcount_read(&map->refcnt) != 1) {
+				failed = true;
+			}
+			i++;
+		}
 	}
-
-	return TEST_OK;
+	if (failed) {
+		pr_debug("Expected:\n");
+		for (i = 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 = 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;
 }
 
 static int test__maps__merge_in(struct test_suite *t __maybe_unused, int subtest __maybe_unused)
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 06/12] perf maps: Modify maps_by_name to hold a reference to a map
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (4 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 05/12] perf test: Add extra diagnostics to maps test Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 07/12] perf map: Changes to reference counting Ian Rogers
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 tools/perf/util/maps.c   | 30 ++++++++++++++++--------------
 tools/perf/util/symbol.c | 21 +++++++++++++++++----
 2 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
index 0eee27e24c33..5afed53ea0b4 100644
--- a/tools/perf/util/maps.c
+++ b/tools/perf/util/maps.c
@@ -26,6 +26,9 @@ static void __maps__free_maps_by_name(struct maps *maps)
 	/*
 	 * Free everything to try to do it from the rbtree in the next search
 	 */
+	for (unsigned int i = 0; i < maps__nr_maps(maps); i++)
+		map__put(maps__maps_by_name(maps)[i]);
+
 	zfree(&maps->maps_by_name);
 	maps->nr_maps_allocated = 0;
 }
@@ -42,7 +45,7 @@ static int __maps__insert(struct maps *maps, struct map *map)
 		return -ENOMEM;
 
 	RB_CLEAR_NODE(&new_rb_node->rb_node);
-	new_rb_node->map = map;
+	new_rb_node->map = map__get(map);
 
 	while (*p != NULL) {
 		parent = *p;
@@ -55,7 +58,6 @@ static int __maps__insert(struct maps *maps, struct map *map)
 
 	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;
 }
 
@@ -100,7 +102,7 @@ int maps__insert(struct maps *maps, struct map *map)
 			maps->maps_by_name = maps_by_name;
 			maps->nr_maps_allocated = nr_allocate;
 		}
-		maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] = map;
+		maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] = map__get(map);
 		__maps__sort_by_name(maps);
 	}
  out:
@@ -126,9 +128,9 @@ void maps__remove(struct maps *maps, struct map *map)
 	rb_node = maps__find_node(maps, map);
 	assert(rb_node->map == 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));
 }
 
@@ -136,6 +138,9 @@ static void __maps__purge(struct maps *maps)
 {
 	struct map_rb_node *pos, *next;
 
+	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)
 	}
 
 	next = first;
-	while (next) {
+	while (next && !err) {
 		struct map_rb_node *pos = rb_entry(next, struct map_rb_node, rb_node);
 		next = rb_next(&pos->rb_node);
 
@@ -331,8 +336,10 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
 
 			before->end = map__start(map);
 			err = __maps__insert(maps, before);
-			if (err)
+			if (err) {
+				map__put(before);
 				goto put_map;
+			}
 
 			if (verbose >= 2 && !use_browser)
 				map__fprintf(before, fp);
@@ -352,22 +359,17 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
 			assert(map__map_ip(pos->map, map__end(map)) ==
 				map__map_ip(after, map__end(map)));
 			err = __maps__insert(maps, after);
-			if (err)
+			if (err) {
+				map__put(after);
 				goto put_map;
-
+			}
 			if (verbose >= 2 && !use_browser)
 				map__fprintf(after, fp);
 			map__put(after);
 		}
 put_map:
 		map__put(pos->map);
-
-		if (err)
-			goto out;
 	}
-
-	err = 0;
-out:
 	up_write(maps__lock(maps));
 	return err;
 }
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 7282119c2990..91ebf93e0c20 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2053,10 +2053,23 @@ int dso__load(struct dso *dso, struct map *map)
 
 static int map__strcmp(const void *a, const void *b)
 {
-	const struct dso *dso_a = map__dso(*(const struct map **)a);
-	const struct dso *dso_b = map__dso(*(const struct map **)b);
+	const struct map *map_a = *(const struct map **)a;
+	const struct map *map_b = *(const struct map **)b;
+	const struct dso *dso_a = map__dso(map_a);
+	const struct dso *dso_b = map__dso(map_b);
+	int ret = strcmp(dso_a->short_name, dso_b->short_name);
 
-	return strcmp(dso_a->short_name, dso_b->short_name);
+	if (ret == 0 && map_a != map_b) {
+		/*
+		 * Ensure distinct but name equal maps have an order in part to
+		 * aid reference counting.
+		 */
+		ret = (int)map__start(map_a) - (int)map__start(map_b);
+		if (ret == 0)
+			ret = (int)((intptr_t)map_a - (intptr_t)map_b);
+	}
+
+	return ret;
 }
 
 static int map__strcmp_name(const void *name, const void *b)
@@ -2088,7 +2101,7 @@ static int map__groups__sort_by_name_from_rbtree(struct maps *maps)
 	maps->nr_maps_allocated = maps__nr_maps(maps);
 
 	maps__for_each_entry(maps, rb_node)
-		maps_by_name[i++] = rb_node->map;
+		maps_by_name[i++] = map__get(rb_node->map);
 
 	__maps__sort_by_name(maps);
 
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 07/12] perf map: Changes to reference counting
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (5 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 06/12] perf maps: Modify maps_by_name to hold a reference to a map Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 08/12] libperf: Add reference count checking macros Ian Rogers
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 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-reading.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 cpumode,
 	}
 	pr_debug("Bytes read match those read by objdump\n");
 out:
+	map__put(al.map);
 	return err;
 }
 
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.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)
 		}
 
 		fake_samples[i].thread = al.thread;
+		map__put(fake_samples[i].map);
 		fake_samples[i].map = al.map;
 		fake_samples[i].sym = al.sym;
 	}
@@ -147,6 +148,14 @@ static void del_hist_entries(struct hists *hists)
 	}
 }
 
+static void put_fake_samples(void)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(fake_samples); i++)
+		map__put(fake_samples[i].map);
+}
+
 typedef int (*test_fn_t)(struct evsel *, struct machine *);
 
 #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();
 
 	return err;
 }
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.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,
 			}
 
 			fake_samples[i].thread = al.thread;
+			map__put(fake_samples[i].map);
 			fake_samples[i].map = al.map;
 			fake_samples[i].sym = al.sym;
 		}
@@ -101,6 +102,14 @@ static int add_hist_entries(struct evlist *evlist,
 	return TEST_FAIL;
 }
 
+static void put_fake_samples(void)
+{
+	size_t i;
+
+	for (i = 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 = 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();
 
 	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)
 			}
 
 			fake_common_samples[k].thread = al.thread;
+			map__put(fake_common_samples[k].map);
 			fake_common_samples[k].map = al.map;
 			fake_common_samples[k].sym = al.sym;
 		}
@@ -126,11 +128,24 @@ static int add_hist_entries(struct evlist *evlist, struct machine *machine)
 	return -1;
 }
 
+static void put_fake_samples(void)
+{
+	size_t i, j;
+
+	for (i = 0; i < ARRAY_SIZE(fake_common_samples); i++)
+		map__put(fake_common_samples[i].map);
+	for (i = 0; i < ARRAY_SIZE(fake_samples); i++) {
+		for (j = 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 == t && samples->map == m &&
+		if (samples->thread == t &&
+		    samples->map == m &&
 		    samples->sym == s)
 			return 1;
 		samples++;
@@ -336,6 +351,7 @@ static int test__hists_link(struct test_suite *test __maybe_unused, int subtest
 	evlist__delete(evlist);
 	reset_output_field();
 	machines__exit(&machines);
+	put_fake_samples();
 
 	return err;
 }
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.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 machine *machine)
 		}
 
 		fake_samples[i].thread = al.thread;
+		map__put(fake_samples[i].map);
 		fake_samples[i].map = al.map;
 		fake_samples[i].sym = al.sym;
 	}
@@ -113,6 +114,14 @@ static void del_hist_entries(struct hists *hists)
 	}
 }
 
+static void put_fake_samples(void)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(fake_samples); i++)
+		map__put(fake_samples[i].map);
+}
+
 typedef int (*test_fn_t)(struct evsel *, struct machine *);
 
 #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();
 
 	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)
 		}
 
 		pr_debug("map %p, addr %" PRIx64 "\n", al.map, map__start(al.map));
+		map__put(al.map);
 	}
 
 	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 = cursor_node->ip;
 		call->ms = cursor_node->ms;
-		map__get(call->ms.map);
+		call->ms.map = map__get(call->ms.map);
 		call->srcline = cursor_node->srcline;
 
 		if (cursor_node->branch) {
@@ -1067,7 +1067,7 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
 	node->ip = ip;
 	map__zput(node->ms.map);
 	node->ms = *ms;
-	map__get(node->ms.map);
+	node->ms.map = map__get(node->ms.map);
 	node->branch = branch;
 	node->nr_loop_iter = nr_loop_iter;
 	node->iter_cycles = iter_cycles;
@@ -1115,7 +1115,8 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
 	struct machine *machine = maps__machine(node->ms.maps);
 
 	al->maps = node->ms.maps;
-	al->map = node->ms.map;
+	map__put(al->map);
+	al->map = map__get(node->ms.map);
 	al->sym = node->ms.sym;
 	al->srcline = node->srcline;
 	al->addr = node->ip;
@@ -1528,7 +1529,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
 				goto out;
 			*new = *chain;
 			new->has_children = false;
-			map__get(new->ms.map);
+			new->ms.map = map__get(new->ms.map);
 			list_add_tail(&new->list, &head);
 		}
 		parent = 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;
 
-		al.map = maps__find(machine__kernel_maps(machine), tp->addr);
+		al.map = map__get(maps__find(machine__kernel_maps(machine), tp->addr));
 		if (al.map && map__load(al.map) >= 0) {
 			al.addr = map__map_ip(al.map, tp->addr);
 			al.sym = map__find_symbol(al.map, al.addr);
 			if (al.sym)
 				ret += symbol__fprintf_symname_offs(al.sym, &al, fp);
 		}
+		map__put(al.map);
 	}
 	ret += fprintf(fp, " old len %u new len %u\n", tp->old_len, tp->new_len);
 	old = true;
@@ -614,7 +615,7 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
 		return NULL;
 	}
 
-	al->map = maps__find(maps, al->addr);
+	al->map = map__get(maps__find(maps, al->addr));
 	if (al->map != NULL) {
 		/*
 		 * Kernel maps might be changed when loading symbols so loading
@@ -773,6 +774,7 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
  */
 void addr_location__put(struct addr_location *al)
 {
+	map__zput(al->map);
 	thread__zput(al->thread);
 }
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index e494425cad06..51020da15ffc 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -450,7 +450,7 @@ static int hist_entry__init(struct hist_entry *he,
 			memset(&he->stat, 0, sizeof(he->stat));
 	}
 
-	map__get(he->ms.map);
+	he->ms.map = map__get(he->ms.map);
 
 	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));
 
-		map__get(he->branch_info->from.ms.map);
-		map__get(he->branch_info->to.ms.map);
+		he->branch_info->from.ms.map = map__get(he->branch_info->from.ms.map);
+		he->branch_info->to.ms.map = map__get(he->branch_info->to.ms.map);
 	}
 
 	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 = map__get(he->mem_info->iaddr.ms.map);
+		he->mem_info->daddr.ms.map = map__get(he->mem_info->daddr.ms.map);
 	}
 
 	if (hist_entry__has_callchains(he) && symbol_conf.use_callchain)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 1ea6f6c06bbb..25738775834e 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -881,21 +881,29 @@ static int machine__process_ksymbol_register(struct machine *machine,
 	struct symbol *sym;
 	struct dso *dso;
 	struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
+	bool put_map = false;
+	int err = 0;
 
 	if (!map) {
-		int err;
-
 		dso = dso__new(event->ksymbol.name);
-		if (dso) {
-			dso->kernel = DSO_SPACE__KERNEL;
-			map = map__new2(0, dso);
-			dso__put(dso);
-		}
 
-		if (!dso || !map) {
-			return -ENOMEM;
+		if (!dso) {
+			err = -ENOMEM;
+			goto out;
 		}
-
+		dso->kernel = DSO_SPACE__KERNEL;
+		map = map__new2(0, dso);
+		dso__put(dso);
+		if (!map) {
+			err = -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 = true;
 		if (event->ksymbol.ksym_type == PERF_RECORD_KSYMBOL_TYPE_OOL) {
 			dso->binary_type = DSO_BINARY_TYPE__OOL;
 			dso->data.file_size = event->ksymbol.len;
@@ -905,9 +913,10 @@ static int machine__process_ksymbol_register(struct machine *machine,
 		map->start = event->ksymbol.addr;
 		map->end = map__start(map) + event->ksymbol.len;
 		err = maps__insert(machine__kernel_maps(machine), map);
-		map__put(map);
-		if (err)
-			return err;
+		if (err) {
+			err = -ENOMEM;
+			goto out;
+		}
 
 		dso__set_loaded(dso);
 
@@ -922,10 +931,15 @@ static int machine__process_ksymbol_register(struct machine *machine,
 	sym = symbol__new(map__map_ip(map, map__start(map)),
 			  event->ksymbol.len,
 			  0, 0, event->ksymbol.name);
-	if (!sym)
-		return -ENOMEM;
+	if (!sym) {
+		err = -ENOMEM;
+		goto out;
+	}
 	dso__insert_symbol(dso, sym);
-	return 0;
+out:
+	if (put_map)
+		map__put(map);
+	return err;
 }
 
 static int machine__process_ksymbol_unregister(struct machine *machine,
@@ -1027,13 +1041,11 @@ static struct map *machine__addnew_module_map(struct machine *machine, u64 start
 		goto out;
 
 	err = 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 = NULL;
+	}
 out:
 	/* put the dso here, corresponding to  machine__findnew_module_dso */
 	dso__put(dso);
@@ -1325,6 +1337,7 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
 	/* In case of renewal the kernel map, destroy previous one */
 	machine__destroy_kernel_maps(machine);
 
+	map__put(machine->vmlinux_map);
 	machine->vmlinux_map = map__new2(0, kernel);
 	if (machine->vmlinux_map == NULL)
 		return -ENOMEM;
@@ -1613,7 +1626,7 @@ static int machine__create_module(void *arg, const char *name, u64 start,
 	map->end = start + size;
 
 	dso__kernel_module_get_build_id(map__dso(map), machine->root_dir);
-
+	map__put(map);
 	return 0;
 }
 
@@ -1659,16 +1672,18 @@ static void machine__set_kernel_mmap(struct machine *machine,
 static int machine__update_kernel_mmap(struct machine *machine,
 				     u64 start, u64 end)
 {
-	struct map *map = machine__kernel_map(machine);
+	struct map *orig, *updated;
 	int err;
 
-	map__get(map);
-	maps__remove(machine__kernel_maps(machine), map);
+	orig = machine->vmlinux_map;
+	updated = map__get(orig);
 
+	machine->vmlinux_map = updated;
 	machine__set_kernel_mmap(machine, start, end);
+	maps__remove(machine__kernel_maps(machine), orig);
+	err = maps__insert(machine__kernel_maps(machine), updated);
+	map__put(orig);
 
-	err = maps__insert(machine__kernel_maps(machine), map);
-	map__put(map);
 	return err;
 }
 
@@ -2295,7 +2310,7 @@ static int add_callchain_ip(struct thread *thread,
 {
 	struct map_symbol ms;
 	struct addr_location al;
-	int nr_loop_iter = 0;
+	int nr_loop_iter = 0, err;
 	u64 iter_cycles = 0;
 	const char *srcline = NULL;
 
@@ -2360,9 +2375,11 @@ static int add_callchain_ip(struct thread *thread,
 		return 0;
 
 	srcline = callchain_srcline(&ms, al.addr);
-	return callchain_cursor_append(cursor, ip, &ms,
-				       branch, flags, nr_loop_iter,
-				       iter_cycles, branch_from, srcline);
+	err = callchain_cursor_append(cursor, ip, &ms,
+				      branch, flags, nr_loop_iter,
+				      iter_cycles, branch_from, srcline);
+	map__put(al.map);
+	return err;
 }
 
 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 = memdup(from, size);
 	if (map != NULL) {
 		refcount_set(&map->refcnt, 1);
-		dso__get(dso);
+		map->dso = dso__get(dso);
 	}
 
 	return map;
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 08/12] libperf: Add reference count checking macros.
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (6 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 07/12] perf map: Changes to reference counting Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 09/12] perf cpumap: Add reference count checking Ian Rogers
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 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/include/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 <stdlib.h>
+#include <linux/zalloc.h>
+
+/*
+ * Shared reference count checking macros.
+ *
+ * Reference count checking is an approach to sanitizing the use of reference
+ * 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 reported 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 = 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 = malloc(sizeof(*result)),		\
+			result ? (result->orig = object, result)	\
+			: (result = NULL, NULL))			\
+		: (result = 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->orig : NULL))
+
+/* A put operation removing the indirection layer. */
+#define RC_CHK_PUT(object)			\
+	do {					\
+		if (object) {			\
+			object->orig = NULL;	\
+			free(object);		\
+		}				\
+	} while(0)
+
+#endif
+
+#endif /* __LIBPERF_INTERNAL_RC_CHECK_H */
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 09/12] perf cpumap: Add reference count checking
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (7 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 08/12] libperf: Add reference count checking macros Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 10/12] perf namespaces: " Ian Rogers
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 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)
 
 HDRS := bpf_perf.h core.h cpumap.h threadmap.h evlist.h evsel.h event.h mmap.h
-INTERNAL_HDRS := cpumap.h evlist.h evsel.h lib.h mmap.h threadmap.h xyarray.h
+INTERNAL_HDRS := cpumap.h evlist.h evsel.h lib.h mmap.h rc_check.h threadmap.h xyarray.h
 
 INSTALL_HDRS_PFX := $(DESTDIR)$(prefix)/include/perf
 INSTALL_HDRS := $(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 <ctype.h>
 #include <limits.h>
 
-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 = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
-
-	if (cpus != NULL) {
+	struct perf_cpu_map *result;
+	RC_STRUCT(perf_cpu_map) *cpus =
+		malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
+	if (ADD_RC_CHK(result, cpus)) {
 		cpus->nr = nr_cpus;
 		refcount_set(&cpus->refcnt, 1);
-
 	}
-	return cpus;
+	return result;
 }
 
 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 = perf_cpu_map__alloc(1);
 
 	if (cpus)
-		cpus->map[0].cpu = -1;
+		RC_CHK_ACCESS(cpus)->map[0].cpu = -1;
 
 	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) != 0,
+		WARN_ONCE(refcount_read(&RC_CHK_ACCESS(map)->refcnt) != 0,
 			  "cpu_map refcnt unbalanced\n");
-		free(map);
+		RC_CHK_FREE(map);
 	}
 }
 
 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;
 }
 
 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);
+	}
 }
 
 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;
 
 		for (i = 0; i < nr_cpus; ++i)
-			cpus->map[i].cpu = i;
+			RC_CHK_ACCESS(cpus)->map[i].cpu = i;
 	}
 
 	return cpus;
@@ -94,15 +101,16 @@ static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, const struct perf_cpu
 	int i, j;
 
 	if (cpus != 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_cpu);
 		/* Remove dups */
 		j = 0;
 		for (i = 0; i < nr_cpus; i++) {
-			if (i == 0 || cpus->map[i].cpu != cpus->map[i - 1].cpu)
-				cpus->map[j++].cpu = cpus->map[i].cpu;
+			if (i == 0 ||
+			    RC_CHK_ACCESS(cpus)->map[i].cpu != RC_CHK_ACCESS(cpus)->map[i - 1].cpu)
+				RC_CHK_ACCESS(cpus)->map[j++].cpu = RC_CHK_ACCESS(cpus)->map[i].cpu;
 		}
-		cpus->nr = j;
+		RC_CHK_ACCESS(cpus)->nr = j;
 		assert(j <= nr_cpus);
 	}
 	return cpus;
@@ -263,20 +271,20 @@ struct perf_cpu perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx)
 		.cpu = -1
 	};
 
-	if (cpus && idx < cpus->nr)
-		return cpus->map[idx];
+	if (cpus && idx < RC_CHK_ACCESS(cpus)->nr)
+		return RC_CHK_ACCESS(cpus)->map[idx];
 
 	return result;
 }
 
 int perf_cpu_map__nr(const struct perf_cpu_map *cpus)
 {
-	return cpus ? cpus->nr : 1;
+	return cpus ? RC_CHK_ACCESS(cpus)->nr : 1;
 }
 
 bool perf_cpu_map__empty(const struct perf_cpu_map *map)
 {
-	return map ? map->map[0].cpu == -1 : true;
+	return map ? RC_CHK_ACCESS(map)->map[0].cpu == -1 : true;
 }
 
 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;
 
 	low = 0;
-	high = cpus->nr;
+	high = RC_CHK_ACCESS(cpus)->nr;
 	while (low < high) {
 		int idx = (low + high) / 2;
-		struct perf_cpu cpu_at_idx = cpus->map[idx];
+		struct perf_cpu cpu_at_idx = RC_CHK_ACCESS(cpus)->map[idx];
 
 		if (cpu_at_idx.cpu == cpu.cpu)
 			return idx;
@@ -316,7 +324,9 @@ struct perf_cpu perf_cpu_map__max(const struct perf_cpu_map *map)
 	};
 
 	// cpu_map__trim_new() qsort()s it, cpu_map__default_new() sorts it as well.
-	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;
 }
 
 /** Is 'b' a subset of 'a'. */
@@ -324,15 +334,15 @@ bool perf_cpu_map__is_subset(const struct perf_cpu_map *a, const struct perf_cpu
 {
 	if (a == b || !b)
 		return true;
-	if (!a || b->nr > a->nr)
+	if (!a || RC_CHK_ACCESS(b)->nr > RC_CHK_ACCESS(a)->nr)
 		return false;
 
-	for (int i = 0, j = 0; i < a->nr; i++) {
-		if (a->map[i].cpu > b->map[j].cpu)
+	for (int i = 0, j = 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 == b->map[j].cpu) {
+		if (RC_CHK_ACCESS(a)->map[i].cpu == RC_CHK_ACCESS(b)->map[j].cpu) {
 			j++;
-			if (j == b->nr)
+			if (j == 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);
 	}
 
-	tmp_len = orig->nr + other->nr;
+	tmp_len = RC_CHK_ACCESS(orig)->nr + RC_CHK_ACCESS(other)->nr;
 	tmp_cpus = malloc(tmp_len * sizeof(struct perf_cpu));
 	if (!tmp_cpus)
 		return NULL;
 
 	/* Standard merge algorithm from wikipedia */
 	i = j = k = 0;
-	while (i < orig->nr && j < other->nr) {
-		if (orig->map[i].cpu <= other->map[j].cpu) {
-			if (orig->map[i].cpu == 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 <= RC_CHK_ACCESS(other)->map[j].cpu) {
+			if (RC_CHK_ACCESS(orig)->map[i].cpu == RC_CHK_ACCESS(other)->map[j].cpu)
 				j++;
-			tmp_cpus[k++] = orig->map[i++];
+			tmp_cpus[k++] = RC_CHK_ACCESS(orig)->map[i++];
 		} else
-			tmp_cpus[k++] = other->map[j++];
+			tmp_cpus[k++] = RC_CHK_ACCESS(other)->map[j++];
 	}
 
-	while (i < orig->nr)
-		tmp_cpus[k++] = orig->map[i++];
+	while (i < RC_CHK_ACCESS(orig)->nr)
+		tmp_cpus[k++] = RC_CHK_ACCESS(orig)->map[i++];
 
-	while (j < other->nr)
-		tmp_cpus[k++] = other->map[j++];
+	while (j < RC_CHK_ACCESS(other)->nr)
+		tmp_cpus[k++] = RC_CHK_ACCESS(other)->map[j++];
 	assert(k <= tmp_len);
 
 	merged = cpu_map__trim_new(k, tmp_cpus);
diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/include/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 @@
 
 #include <linux/refcount.h>
 #include <perf/cpumap.h>
+#include <internal/rc_check.h>
 
 /**
  * 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
 
+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 perf_cpu_map *b);
 
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 __maybe_unused,
 	TEST_ASSERT_VAL("wrong nr",  perf_cpu_map__nr(map) == 2);
 	TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 0).cpu == 1);
 	TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 1).cpu == 256);
-	TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1);
+	TEST_ASSERT_VAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(map)->refcnt) == 1);
 	perf_cpu_map__put(map);
 	return 0;
 }
@@ -94,7 +94,7 @@ static int process_event_range_cpus(struct perf_tool *tool __maybe_unused,
 	TEST_ASSERT_VAL("wrong nr",  perf_cpu_map__nr(map) == 256);
 	TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__cpu(map, 0).cpu == 1);
 	TEST_ASSERT_VAL("wrong cpu", perf_cpu_map__max(map).cpu == 256);
-	TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1);
+	TEST_ASSERT_VAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(map)->refcnt) == 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 struct perf_record_cpu_m
 			 * otherwise it would become 65535.
 			 */
 			if (data->cpus_data.cpu[i] == (u16) -1)
-				map->map[i].cpu = -1;
+				RC_CHK_ACCESS(map)->map[i].cpu = -1;
 			else
-				map->map[i].cpu = (int) data->cpus_data.cpu[i];
+				RC_CHK_ACCESS(map)->map[i].cpu = (int) data->cpus_data.cpu[i];
 		}
 	}
 
@@ -107,7 +107,7 @@ static struct perf_cpu_map *cpu_map__from_mask(const struct perf_record_cpu_map_
 
 		perf_record_cpu_map_data__read_one_mask(data, i, local_copy);
 		for_each_set_bit(cpu, local_copy, 64)
-			map->map[j++].cpu = cpu + cpus_per_i;
+		        RC_CHK_ACCESS(map)->map[j++].cpu = cpu + cpus_per_i;
 	}
 	return map;
 
@@ -124,11 +124,11 @@ static struct perf_cpu_map *cpu_map__from_range(const struct perf_record_cpu_map
 		return NULL;
 
 	if (data->range_cpu_data.any_cpu)
-		map->map[i++].cpu = -1;
+		RC_CHK_ACCESS(map)->map[i++].cpu = -1;
 
 	for (int cpu = data->range_cpu_data.start_cpu; cpu <= data->range_cpu_data.end_cpu;
 	     i++, cpu++)
-		map->map[i].cpu = cpu;
+		RC_CHK_ACCESS(map)->map[i].cpu = cpu;
 
 	return map;
 }
@@ -160,16 +160,13 @@ size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp)
 
 struct perf_cpu_map *perf_cpu_map__empty_new(int nr)
 {
-	struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int) * nr);
+	struct perf_cpu_map *cpus = perf_cpu_map__alloc(nr);
 
 	if (cpus != NULL) {
 		int i;
 
-		cpus->nr = nr;
 		for (i = 0; i < nr; i++)
-			cpus->map[i].cpu = -1;
-
-		refcount_set(&cpus->refcnt, 1);
+			RC_CHK_ACCESS(cpus)->map[i].cpu = -1;
 	}
 
 	return cpus;
@@ -239,7 +236,7 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
 {
 	int idx;
 	struct perf_cpu cpu;
-	struct cpu_aggr_map *c = cpu_aggr_map__empty_new(cpus->nr);
+	struct cpu_aggr_map *c = cpu_aggr_map__empty_new(perf_cpu_map__nr(cpus));
 
 	if (!c)
 		return NULL;
@@ -263,7 +260,7 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
 		}
 	}
 	/* Trim. */
-	if (c->nr != cpus->nr) {
+	if (c->nr != perf_cpu_map__nr(cpus)) {
 		struct cpu_aggr_map *trimmed_c =
 			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, char *buf, size_t size)
 
 #define COMMA first ? "" : ","
 
-	for (i = 0; i < map->nr + 1; i++) {
+	for (i = 0; i < perf_cpu_map__nr(map) + 1; i++) {
 		struct perf_cpu cpu = { .cpu = INT_MAX };
-		bool last = i == map->nr;
+		bool last = i == perf_cpu_map__nr(map);
 
 		if (!last)
-			cpu = map->map[i];
+			cpu = perf_cpu_map__cpu(map, i);
 
 		if (start == -1) {
 			start = i;
 			if (last) {
 				ret += snprintf(buf + ret, size - ret,
 						"%s%d", COMMA,
-						map->map[i].cpu);
+						perf_cpu_map__cpu(map, i).cpu);
 			}
-		} else if (((i - start) != (cpu.cpu - map->map[start].cpu)) || last) {
+		} else if (((i - start) != (cpu.cpu - perf_cpu_map__cpu(map, start).cpu)) || last) {
 			int end = i - 1;
 
 			if (start == end) {
 				ret += snprintf(buf + ret, size - ret,
 						"%s%d", COMMA,
-						map->map[start].cpu);
+						perf_cpu_map__cpu(map, start).cpu);
 			} else {
 				ret += 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 = false;
 			start = 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 = buf;
 	unsigned char *bitmap;
-	struct perf_cpu last_cpu = perf_cpu_map__cpu(map, map->nr - 1);
+	struct perf_cpu last_cpu = perf_cpu_map__cpu(map, perf_cpu_map__nr(map) - 1);
 
 	if (buf == 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;
 	}
 
-	for (i = 0; i < map->nr; i++) {
+	for (i = 0; i < perf_cpu_map__nr(map); i++) {
 		cpu = perf_cpu_map__cpu(map, i).cpu;
 		bitmap[cpu / 8] |= 1 << (cpu % 8);
 	}
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 78a407b42ad1..c08d42f5e2b4 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1966,13 +1966,13 @@ int perf_pmu__cpus_match(struct perf_pmu *pmu, struct perf_cpu_map *cpus,
 
 	perf_cpu_map__for_each_cpu(cpu, i, cpus) {
 		if (!perf_cpu_map__has(pmu_cpus, cpu))
-			unmatched_cpus->map[unmatched_nr++] = cpu;
+			RC_CHK_ACCESS(unmatched_cpus)->map[unmatched_nr++] = cpu;
 		else
-			matched_cpus->map[matched_nr++] = cpu;
+			RC_CHK_ACCESS(matched_cpus)->map[matched_nr++] = cpu;
 	}
 
-	unmatched_cpus->nr = unmatched_nr;
-	matched_cpus->nr = matched_nr;
+	RC_CHK_ACCESS(unmatched_cpus)->nr = unmatched_nr;
+	RC_CHK_ACCESS(matched_cpus)->nr = matched_nr;
 	*mcpus_ptr = matched_cpus;
 	*ucpus_ptr = unmatched_cpus;
 	return 0;
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 10/12] perf namespaces: Add reference count checking
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (8 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 09/12] perf cpumap: Add reference count checking Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 11/12] perf maps: " Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 12/12] perf map: " Ian Rogers
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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=fWZH20L4kv-BwVtGLwR=Em3AOOT+Q4QGivvQuYn5AsPRg@mail.gmail.com/

Signed-off-by: Ian Rogers <irogers@google.com>
---
 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;
 
-		new_name = filename_with_chroot(dso->nsinfo->pid,
+		new_name = 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 = true;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 36acdd1bd379..733051122959 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1693,7 +1693,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil
 
 		mutex_lock(&dso->lock);
 		if (access(filename, R_OK) && errno == ENOENT && dso->nsinfo) {
-			char *new_name = filename_with_chroot(dso->nsinfo->pid,
+			char *new_name = 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 != ENOENT || dso->nsinfo == NULL)
 			goto out;
 
-		new_name = filename_with_chroot(dso->nsinfo->pid, name);
+		new_name = filename_with_chroot(RC_CHK_ACCESS(dso->nsinfo)->pid, name);
 		if (!new_name)
 			goto out;
 
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	  = true;
 			pos->has_build_id = true;
 		} else if (errno == ENOENT && pos->nsinfo) {
-			char *new_name = filename_with_chroot(pos->nsinfo->pid,
+			char *new_name = filename_with_chroot(RC_CHK_ACCESS(pos->nsinfo)->pid,
 							      pos->long_name);
 
 			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);
 }
 
-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, const char *path)
 {
 	FILE *f = NULL;
 	char *statln = NULL;
@@ -74,19 +74,18 @@ static int nsinfo__get_nspid(struct nsinfo *nsi, const char *path)
 	while (getline(&statln, &linesz, f) != -1) {
 		/* Use tgid if CONFIG_PID_NS is not defined. */
 		if (strstr(statln, "Tgid:") != NULL) {
-			nsi->tgid = (pid_t)strtol(strrchr(statln, '\t'),
-						     NULL, 10);
-			nsi->nstgid = nsinfo__tgid(nsi);
+			*tgid = (pid_t)strtol(strrchr(statln, '\t'), NULL, 10);
+			*nstgid = *tgid;
 		}
 
 		if (strstr(statln, "NStgid:") != NULL) {
 			nspid = strrchr(statln, '\t');
-			nsi->nstgid = (pid_t)strtol(nspid, NULL, 10);
+			*nstgid = (pid_t)strtol(nspid, NULL, 10);
 			/*
 			 * If innermost tgid is not the first, process is in a different
 			 * PID namespace.
 			 */
-			nsi->in_pidns = (statln + sizeof("NStgid:") - 1) != nspid;
+			*in_pidns = (statln + sizeof("NStgid:") - 1) != 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 != new_stat.st_ino) {
-		nsi->need_setns = true;
-		nsi->mntns_path = newns;
+		RC_CHK_ACCESS(nsi)->need_setns = true;
+		RC_CHK_ACCESS(nsi)->mntns_path = newns;
 		newns = NULL;
 	}
 
@@ -132,13 +131,26 @@ int nsinfo__init(struct nsinfo *nsi)
 	if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsinfo__pid(nsi)) >= PATH_MAX)
 		goto out;
 
-	rv = nsinfo__get_nspid(nsi, spath);
+	rv = nsinfo__get_nspid(&RC_CHK_ACCESS(nsi)->tgid, &RC_CHK_ACCESS(nsi)->nstgid,
+			       &RC_CHK_ACCESS(nsi)->in_pidns, spath);
 
 out:
 	free(newns);
 	return rv;
 }
 
+static struct nsinfo *nsinfo__alloc(void)
+{
+	struct nsinfo *res;
+	RC_STRUCT(nsinfo) *nsi;
+
+	nsi = 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 == 0)
 		return NULL;
 
-	nsi = calloc(1, sizeof(*nsi));
-	if (nsi != NULL) {
-		nsi->pid = pid;
-		nsi->tgid = pid;
-		nsi->nstgid = pid;
-		nsi->need_setns = false;
-		nsi->in_pidns = 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) == -1)
-			nsi->need_setns = false;
+	nsi = nsinfo__alloc();
+	if (!nsi)
+		return NULL;
 
-		refcount_set(&nsi->refcnt, 1);
-	}
+	RC_CHK_ACCESS(nsi)->pid = pid;
+	RC_CHK_ACCESS(nsi)->tgid = pid;
+	RC_CHK_ACCESS(nsi)->nstgid = pid;
+	RC_CHK_ACCESS(nsi)->need_setns = false;
+	RC_CHK_ACCESS(nsi)->in_pidns = 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) == -1)
+		RC_CHK_ACCESS(nsi)->need_setns = false;
 
 	return nsi;
 }
@@ -173,21 +184,21 @@ struct nsinfo *nsinfo__copy(const struct nsinfo *nsi)
 	if (nsi == NULL)
 		return NULL;
 
-	nnsi = calloc(1, sizeof(*nnsi));
-	if (nnsi != NULL) {
-		nnsi->pid = nsinfo__pid(nsi);
-		nnsi->tgid = nsinfo__tgid(nsi);
-		nnsi->nstgid = nsinfo__nstgid(nsi);
-		nnsi->need_setns = nsinfo__need_setns(nsi);
-		nnsi->in_pidns = nsinfo__in_pidns(nsi);
-		if (nsi->mntns_path) {
-			nnsi->mntns_path = strdup(nsi->mntns_path);
-			if (!nnsi->mntns_path) {
-				free(nnsi);
-				return NULL;
-			}
+	nnsi = nsinfo__alloc();
+	if (!nnsi)
+		return NULL;
+
+	RC_CHK_ACCESS(nnsi)->pid = nsinfo__pid(nsi);
+	RC_CHK_ACCESS(nnsi)->tgid = nsinfo__tgid(nsi);
+	RC_CHK_ACCESS(nnsi)->nstgid = nsinfo__nstgid(nsi);
+	RC_CHK_ACCESS(nnsi)->need_setns = nsinfo__need_setns(nsi);
+	RC_CHK_ACCESS(nnsi)->in_pidns = nsinfo__in_pidns(nsi);
+	if (RC_CHK_ACCESS(nsi)->mntns_path) {
+		RC_CHK_ACCESS(nnsi)->mntns_path = strdup(RC_CHK_ACCESS(nsi)->mntns_path);
+		if (!RC_CHK_ACCESS(nnsi)->mntns_path) {
+			nsinfo__put(nnsi);
+			return NULL;
 		}
-		refcount_set(&nnsi->refcnt, 1);
 	}
 
 	return nnsi;
@@ -195,51 +206,60 @@ struct nsinfo *nsinfo__copy(const struct nsinfo *nsi)
 
 static void nsinfo__delete(struct nsinfo *nsi)
 {
-	zfree(&nsi->mntns_path);
-	free(nsi);
+	if (nsi) {
+		WARN_ONCE(refcount_read(&RC_CHK_ACCESS(nsi)->refcnt) != 0,
+			"nsinfo refcnt unbalanced\n");
+		zfree(&RC_CHK_ACCESS(nsi)->mntns_path);
+		RC_CHK_FREE(nsi);
+	}
 }
 
 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;
 }
 
 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);
 }
 
 bool nsinfo__need_setns(const struct nsinfo *nsi)
 {
-        return nsi->need_setns;
+	return RC_CHK_ACCESS(nsi)->need_setns;
 }
 
 void nsinfo__clear_need_setns(struct nsinfo *nsi)
 {
-        nsi->need_setns = false;
+	RC_CHK_ACCESS(nsi)->need_setns = false;
 }
 
 pid_t nsinfo__tgid(const struct nsinfo  *nsi)
 {
-        return nsi->tgid;
+	return RC_CHK_ACCESS(nsi)->tgid;
 }
 
 pid_t nsinfo__nstgid(const struct nsinfo  *nsi)
 {
-        return nsi->nstgid;
+	return RC_CHK_ACCESS(nsi)->nstgid;
 }
 
 pid_t nsinfo__pid(const struct nsinfo  *nsi)
 {
-        return nsi->pid;
+	return RC_CHK_ACCESS(nsi)->pid;
 }
 
 pid_t nsinfo__in_pidns(const struct nsinfo  *nsi)
 {
-        return nsi->in_pidns;
+	return RC_CHK_ACCESS(nsi)->in_pidns;
 }
 
 void nsinfo__mountns_enter(struct nsinfo *nsi,
@@ -256,7 +276,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,
 	nc->oldns = -1;
 	nc->newns = -1;
 
-	if (!nsi || !nsi->need_setns)
+	if (!nsi || !RC_CHK_ACCESS(nsi)->need_setns)
 		return;
 
 	if (snprintf(curpath, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX)
@@ -270,7 +290,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,
 	if (oldns < 0)
 		goto errout;
 
-	newns = open(nsi->mntns_path, O_RDONLY);
+	newns = open(RC_CHK_ACCESS(nsi)->mntns_path, O_RDONLY);
 	if (newns < 0)
 		goto errout;
 
@@ -339,9 +359,9 @@ int nsinfo__stat(const char *filename, struct stat *st, struct nsinfo *nsi)
 
 bool nsinfo__is_in_root_namespace(void)
 {
-	struct nsinfo nsi;
+	pid_t tgid = 0, nstgid = 0;
+	bool in_pidns = false;
 
-	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 <linux/perf_event.h>
 #include <linux/refcount.h>
 #include <linux/types.h>
+#include <internal/rc_check.h>
 
 #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);
 
-struct nsinfo {
+DECLARE_RC_STRUCT(nsinfo) {
 	pid_t			pid;
 	pid_t			tgid;
 	pid_t			nstgid;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 91ebf93e0c20..639343d5577c 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1963,7 +1963,7 @@ int dso__load(struct dso *dso, struct map *map)
 
 		is_reg = is_regular_file(name);
 		if (!is_reg && errno == ENOENT && dso->nsinfo) {
-			char *new_name = filename_with_chroot(dso->nsinfo->pid,
+			char *new_name = filename_with_chroot(RC_CHK_ACCESS(dso->nsinfo)->pid,
 							      name);
 			if (new_name) {
 				is_reg = is_regular_file(new_name);
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 11/12] perf maps: Add reference count checking.
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (9 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 10/12] perf namespaces: " Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  2023-04-04 20:59 ` [PATCH v6 12/12] perf map: " Ian Rogers
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 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 *test __maybe_unused, int s
 			leader && t1 && t2 && t3 && other);
 
 	maps = leader->maps;
-	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4);
+	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->refcnt), 4);
 
 	/* test the maps pointer is shared */
-	TEST_ASSERT_VAL("maps don't match", maps == t1->maps);
-	TEST_ASSERT_VAL("maps don't match", maps == t2->maps);
-	TEST_ASSERT_VAL("maps don't match", maps == t3->maps);
+	TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) == RC_CHK_ACCESS(t1->maps));
+	TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) == RC_CHK_ACCESS(t2->maps));
+	TEST_ASSERT_VAL("maps don't match", RC_CHK_ACCESS(maps) == RC_CHK_ACCESS(t3->maps));
 
 	/*
 	 * Verify the other leader was created by previous call.
@@ -71,25 +71,26 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s
 	machine__remove_thread(machine, other_leader);
 
 	other_maps = 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);
 
-	TEST_ASSERT_VAL("maps don't match", other_maps == other_leader->maps);
+	TEST_ASSERT_VAL("maps don't match",
+			RC_CHK_ACCESS(other_maps) == RC_CHK_ACCESS(other_leader->maps));
 
 	/* 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)->refcnt), 3);
 
 	thread__put(t2);
-	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1);
+	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->refcnt), 2);
 
-	thread__put(t3);
+	thread__put(t1);
+	TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&RC_CHK_ACCESS(maps)->refcnt), 1);
+
+	thread__put(leader);
 
 	/* 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);
 
 	thread__put(other);
 
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 25738775834e..2d9ce6966238 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -435,7 +435,7 @@ static struct thread *findnew_guest_code(struct machine *machine,
 		return NULL;
 
 	/* Assume maps are set up if there are any */
-	if (thread->maps->nr_maps)
+	if (RC_CHK_ACCESS(thread->maps)->nr_maps)
 		return thread;
 
 	host_thread = machine__find_thread(host_machine, -1, pid);
diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
index 5afed53ea0b4..567952587247 100644
--- a/tools/perf/util/maps.c
+++ b/tools/perf/util/maps.c
@@ -12,13 +12,13 @@
 
 static void maps__init(struct maps *maps, struct machine *machine)
 {
-	maps->entries = RB_ROOT;
+	RC_CHK_ACCESS(maps)->entries = RB_ROOT;
 	init_rwsem(maps__lock(maps));
-	maps->machine = machine;
-	maps->last_search_by_name = NULL;
-	maps->nr_maps = 0;
-	maps->maps_by_name = NULL;
-	refcount_set(&maps->refcnt, 1);
+	RC_CHK_ACCESS(maps)->machine = machine;
+	RC_CHK_ACCESS(maps)->last_search_by_name = NULL;
+	RC_CHK_ACCESS(maps)->nr_maps = 0;
+	RC_CHK_ACCESS(maps)->maps_by_name = NULL;
+	refcount_set(&RC_CHK_ACCESS(maps)->refcnt, 1);
 }
 
 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 = 0; i < maps__nr_maps(maps); i++)
 		map__put(maps__maps_by_name(maps)[i]);
 
-	zfree(&maps->maps_by_name);
-	maps->nr_maps_allocated = 0;
+	zfree(&RC_CHK_ACCESS(maps)->maps_by_name);
+	RC_CHK_ACCESS(maps)->nr_maps_allocated = 0;
 }
 
 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;
 
-	++maps->nr_maps;
+	++RC_CHK_ACCESS(maps)->nr_maps;
 
 	if (dso && dso->kernel) {
 		struct kmap *kmap = 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 = maps__nr_maps(maps) * 2;
 			struct map **maps_by_name = 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;
 			}
 
-			maps->maps_by_name = maps_by_name;
-			maps->nr_maps_allocated = nr_allocate;
+			RC_CHK_ACCESS(maps)->maps_by_name = maps_by_name;
+			RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_allocate;
 		}
 		maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] = 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;
 
 	down_write(maps__lock(maps));
-	if (maps->last_search_by_name == map)
-		maps->last_search_by_name = NULL;
+	if (RC_CHK_ACCESS(maps)->last_search_by_name == map)
+		RC_CHK_ACCESS(maps)->last_search_by_name = NULL;
 
 	rb_node = maps__find_node(maps, map);
 	assert(rb_node->map == 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));
 }
 
@@ -162,33 +162,38 @@ bool maps__empty(struct maps *maps)
 
 struct maps *maps__new(struct machine *machine)
 {
-	struct maps *maps = zalloc(sizeof(*maps));
+	struct maps *res;
+	RC_STRUCT(maps) *maps = zalloc(sizeof(*maps));
 
-	if (maps != NULL)
-		maps__init(maps, machine);
+	if (ADD_RC_CHK(res, maps))
+		maps__init(res, machine);
 
-	return maps;
+	return res;
 }
 
 void maps__delete(struct maps *maps)
 {
 	maps__exit(maps);
 	unwind__finish_access(maps);
-	free(maps);
+	RC_CHK_FREE(maps);
 }
 
 struct maps *maps__get(struct maps *maps)
 {
-	if (maps)
-		refcount_inc(&maps->refcnt);
+	struct maps *result;
 
-	return maps;
+	if (RC_CHK_GET(result, maps))
+		refcount_inc(&RC_CHK_ACCESS(maps)->refcnt);
+
+	return result;
 }
 
 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);
 }
 
 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 <stdbool.h>
 #include <linux/types.h>
 #include "rwsem.h"
+#include <internal/rc_check.h>
 
 struct ref_reloc_sym;
 struct machine;
@@ -32,7 +33,7 @@ struct map *maps__find(struct maps *maps, u64 addr);
 	for (map = maps__first(maps), next = map_rb_node__next(map); map; \
 	     map = next, next = map_rb_node__next(map))
 
-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);
 
 static inline struct rb_root *maps__entries(struct maps *maps)
 {
-	return &maps->entries;
+	return &RC_CHK_ACCESS(maps)->entries;
 }
 
 static inline struct machine *maps__machine(struct maps *maps)
 {
-	return maps->machine;
+	return RC_CHK_ACCESS(maps)->machine;
 }
 
 static inline struct rw_semaphore *maps__lock(struct maps *maps)
 {
-	return &maps->lock;
+	return &RC_CHK_ACCESS(maps)->lock;
 }
 
 static inline struct map **maps__maps_by_name(struct maps *maps)
 {
-	return maps->maps_by_name;
+	return RC_CHK_ACCESS(maps)->maps_by_name;
 }
 
 static inline unsigned int maps__nr_maps(const struct maps *maps)
 {
-	return maps->nr_maps;
+	return RC_CHK_ACCESS(maps)->nr_maps;
 }
 
 #ifdef HAVE_LIBUNWIND_SUPPORT
 static inline void *maps__addr_space(struct maps *maps)
 {
-	return maps->addr_space;
+	return RC_CHK_ACCESS(maps)->addr_space;
 }
 
 static inline const struct unwind_libunwind_ops *maps__unwind_libunwind_ops(const struct maps *maps)
 {
-	return maps->unwind_libunwind_ops;
+	return RC_CHK_ACCESS(maps)->unwind_libunwind_ops;
 }
 #endif
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 639343d5577c..6993b51b9416 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2097,8 +2097,8 @@ static int map__groups__sort_by_name_from_rbtree(struct maps *maps)
 	up_read(maps__lock(maps));
 	down_write(maps__lock(maps));
 
-	maps->maps_by_name = maps_by_name;
-	maps->nr_maps_allocated = maps__nr_maps(maps);
+	RC_CHK_ACCESS(maps)->maps_by_name = maps_by_name;
+	RC_CHK_ACCESS(maps)->nr_maps_allocated = maps__nr_maps(maps);
 
 	maps__for_each_entry(maps, rb_node)
 		maps_by_name[i++] = map__get(rb_node->map);
@@ -2133,11 +2133,12 @@ struct map *maps__find_by_name(struct maps *maps, const char *name)
 
 	down_read(maps__lock(maps));
 
-	if (maps->last_search_by_name) {
-		const struct dso *dso = map__dso(maps->last_search_by_name);
+
+	if (RC_CHK_ACCESS(maps)->last_search_by_name) {
+		const struct dso *dso = map__dso(RC_CHK_ACCESS(maps)->last_search_by_name);
 
 		if (strcmp(dso->short_name, name) == 0) {
-			map = maps->last_search_by_name;
+			map = RC_CHK_ACCESS(maps)->last_search_by_name;
 			goto out_unlock;
 		}
 	}
@@ -2157,7 +2158,7 @@ struct map *maps__find_by_name(struct maps *maps, const char *name)
 		map = rb_node->map;
 		dso = map__dso(map);
 		if (strcmp(dso->short_name, name) == 0) {
-			maps->last_search_by_name = map;
+			RC_CHK_ACCESS(maps)->last_search_by_name = 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 = {
 		.sample		= data,
 		.thread		= thread,
-		.machine	= thread->maps->machine,
+		.machine	= RC_CHK_ACCESS(thread->maps)->machine,
 		.cb		= cb,
 		.arg		= arg,
 		.max_stack	= max_stack,
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index f9a52af48de4..83dd79dcd597 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -677,7 +677,7 @@ static int _unwind__prepare_access(struct maps *maps)
 {
 	void *addr_space = unw_create_addr_space(&accessors, 0);
 
-	maps->addr_space = addr_space;
+	RC_CHK_ACCESS(maps)->addr_space = 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-libunwind.c
index 4378daaafcd3..b54968e6a4e4 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -14,7 +14,7 @@ struct unwind_libunwind_ops __weak *arm64_unwind_libunwind_ops;
 
 static void unwind__register_ops(struct maps *maps, struct unwind_libunwind_ops *ops)
 {
-	maps->unwind_libunwind_ops = ops;
+	RC_CHK_ACCESS(maps)->unwind_libunwind_ops = ops;
 }
 
 int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized)
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v6 12/12] perf map: Add reference count checking
  2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
                   ` (10 preceding siblings ...)
  2023-04-04 20:59 ` [PATCH v6 11/12] perf maps: " Ian Rogers
@ 2023-04-04 20:59 ` Ian Rogers
  11 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-04 20:59 UTC (permalink / raw)
  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, linux-kernel, Eric Dumazet,
	Dmitry Vyukov, Hao Luo
  Cc: Stephane Eranian, Ian Rogers

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 <irogers@google.com>
---
 tools/perf/arch/s390/annotate/instructions.c |  5 +-
 tools/perf/builtin-top.c                     |  4 +-
 tools/perf/tests/hists_link.c                |  2 +-
 tools/perf/tests/maps.c                      | 20 +++---
 tools/perf/tests/vmlinux-kallsyms.c          |  4 +-
 tools/perf/util/annotate.c                   | 10 +--
 tools/perf/util/machine.c                    | 25 +++----
 tools/perf/util/map.c                        | 69 +++++++++++---------
 tools/perf/util/map.h                        | 32 +++++----
 tools/perf/util/maps.c                       | 11 ++--
 tools/perf/util/symbol-elf.c                 | 26 ++++----
 tools/perf/util/symbol.c                     | 40 +++++++-----
 12 files changed, 135 insertions(+), 113 deletions(-)

diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c
index 6548933e8dc0..9953d510f7c1 100644
--- a/tools/perf/arch/s390/annotate/instructions.c
+++ b/tools/perf/arch/s390/annotate/instructions.c
@@ -39,8 +39,9 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
 	target.addr = map__objdump_2mem(map, ops->target.addr);
 
 	if (maps__find_ams(ms->maps, &target) == 0 &&
-	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
-	    ops->target.addr)
+	    map__rip_2objdump(target.ms.map,
+			      RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr)
+			     ) == ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
 	return 0;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index b803af4329d1..c0b3a98674df 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -191,7 +191,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
 	if (use_browser <= 0)
 		sleep(5);
 
-	map->erange_warned = true;
+	RC_CHK_ACCESS(map)->erange_warned = true;
 }
 
 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);
 
-		if (err == -ERANGE && !he->ms.map->erange_warned)
+		if (err == -ERANGE && !RC_CHK_ACCESS(he->ms.map)->erange_warned)
 			ui__warn_map_erange(he->ms.map, sym, ip);
 		else if (err == -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 nr_samples,
 {
 	while (nr_samples--) {
 		if (samples->thread == t &&
-		    samples->map == m &&
+		    RC_CHK_ACCESS(samples->map) == RC_CHK_ACCESS(m) &&
 		    samples->sym == 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 int size, struct maps *ma
 			if (map__start(map) != merged[i].start ||
 			    map__end(map) != merged[i].end ||
 			    strcmp(map__dso(map)->name, merged[i].name) ||
-			    refcount_read(&map->refcnt) != 1) {
+			    refcount_read(&RC_CHK_ACCESS(map)->refcnt) != 1) {
 				failed = true;
 			}
 			i++;
@@ -50,7 +50,7 @@ static int check_maps(struct map_def *merged, unsigned int 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 __maybe_unused, int subtest
 		map = dso__new_map(bpf_progs[i].name);
 		TEST_ASSERT_VAL("failed to create map", map);
 
-		map->start = bpf_progs[i].start;
-		map->end   = bpf_progs[i].end;
+		RC_CHK_ACCESS(map)->start = bpf_progs[i].start;
+		RC_CHK_ACCESS(map)->end   = bpf_progs[i].end;
 		TEST_ASSERT_VAL("failed to insert map", maps__insert(maps, map) == 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);
 
 	/* kcore1 map overlaps over all bpf maps */
-	map_kcore1->start = 100;
-	map_kcore1->end   = 1000;
+	RC_CHK_ACCESS(map_kcore1)->start = 100;
+	RC_CHK_ACCESS(map_kcore1)->end   = 1000;
 
 	/* kcore2 map hides behind bpf_prog_2 */
-	map_kcore2->start = 550;
-	map_kcore2->end   = 570;
+	RC_CHK_ACCESS(map_kcore2)->start = 550;
+	RC_CHK_ACCESS(map_kcore2)->end   = 570;
 
 	/* kcore3 map hides behind bpf_prog_3, kcore1 and adds new map */
-	map_kcore3->start = 880;
-	map_kcore3->end   = 1100;
+	RC_CHK_ACCESS(map_kcore3)->start = 880;
+	RC_CHK_ACCESS(map_kcore3)->end   = 1100;
 
 	ret = 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_suite *test __maybe_unused
 								dso->short_name :
 								dso->name));
 		if (pair) {
-			pair->priv = 1;
+			RC_CHK_ACCESS(pair)->priv = 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_suite *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 = 1;
+			RC_CHK_ACCESS(pair)->priv = 1;
 		}
 	}
 
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 733051122959..248ada119c91 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -272,8 +272,9 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s
 	target.addr = map__objdump_2mem(map, ops->target.addr);
 
 	if (maps__find_ams(ms->maps, &target) == 0 &&
-	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
-	    ops->target.addr)
+	    map__rip_2objdump(target.ms.map,
+			      RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr)
+			      ) == ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
 	return 0;
@@ -401,8 +402,9 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
 	 * the symbol searching and disassembly should be done.
 	 */
 	if (maps__find_ams(ms->maps, &target) == 0 &&
-	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
-	    ops->target.addr)
+	    map__rip_2objdump(target.ms.map,
+			      RC_CHK_ACCESS(map)->map_ip(target.ms.map, target.addr)
+			      ) == ops->target.addr)
 		ops->target.sym = target.ms.sym;
 
 	if (!ops->target.outside) {
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 2d9ce6966238..9a472ee52129 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -910,8 +910,8 @@ static int machine__process_ksymbol_register(struct machine *machine,
 			dso__set_loaded(dso);
 		}
 
-		map->start = event->ksymbol.addr;
-		map->end = map__start(map) + event->ksymbol.len;
+		RC_CHK_ACCESS(map)->start = event->ksymbol.addr;
+		RC_CHK_ACCESS(map)->end = map__start(map) + event->ksymbol.len;
 		err = maps__insert(machine__kernel_maps(machine), map);
 		if (err) {
 			err = -ENOMEM;
@@ -953,7 +953,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine,
 	if (!map)
 		return 0;
 
-	if (map != machine->vmlinux_map)
+	if (RC_CHK_ACCESS(map) != RC_CHK_ACCESS(machine->vmlinux_map))
 		maps__remove(machine__kernel_maps(machine), map);
 	else {
 		struct dso *dso = map__dso(map);
@@ -1218,8 +1218,8 @@ int machine__create_extra_kernel_map(struct machine *machine,
 	if (!map)
 		return -ENOMEM;
 
-	map->end   = xm->end;
-	map->pgoff = xm->pgoff;
+	RC_CHK_ACCESS(map)->end   = xm->end;
+	RC_CHK_ACCESS(map)->pgoff = xm->pgoff;
 
 	kmap = map__kmap(map);
 
@@ -1291,7 +1291,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,
 
 		dest_map = maps__find(kmaps, map__pgoff(map));
 		if (dest_map != map)
-			map->pgoff = map__map_ip(dest_map, map__pgoff(map));
+			RC_CHK_ACCESS(map)->pgoff = map__map_ip(dest_map, map__pgoff(map));
 		found = true;
 	}
 	if (found || machine->trampolines_mapped)
@@ -1342,7 +1342,8 @@ __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
 	if (machine->vmlinux_map == NULL)
 		return -ENOMEM;
 
-	machine->vmlinux_map->map_ip = machine->vmlinux_map->unmap_ip = identity__map_ip;
+	RC_CHK_ACCESS(machine->vmlinux_map)->map_ip = identity__map_ip;
+	RC_CHK_ACCESS(machine->vmlinux_map)->unmap_ip = identity__map_ip;
 	return maps__insert(machine__kernel_maps(machine), machine->vmlinux_map);
 }
 
@@ -1623,7 +1624,7 @@ static int machine__create_module(void *arg, const char *name, u64 start,
 	map = machine__addnew_module_map(machine, start, name);
 	if (map == NULL)
 		return -1;
-	map->end = start + size;
+	RC_CHK_ACCESS(map)->end = start + size;
 
 	dso__kernel_module_get_build_id(map__dso(map), machine->root_dir);
 	map__put(map);
@@ -1659,14 +1660,14 @@ static int machine__create_modules(struct machine *machine)
 static void machine__set_kernel_mmap(struct machine *machine,
 				     u64 start, u64 end)
 {
-	machine->vmlinux_map->start = start;
-	machine->vmlinux_map->end   = end;
+	RC_CHK_ACCESS(machine->vmlinux_map)->start = start;
+	RC_CHK_ACCESS(machine->vmlinux_map)->end   = end;
 	/*
 	 * Be a bit paranoid here, some perf.data file came with
 	 * a zero sized synthesized MMAP event for the kernel.
 	 */
 	if (start == 0 && end == 0)
-		machine->vmlinux_map->end = ~0ULL;
+		RC_CHK_ACCESS(machine->vmlinux_map)->end = ~0ULL;
 }
 
 static int machine__update_kernel_mmap(struct machine *machine,
@@ -1810,7 +1811,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
 		if (map == NULL)
 			goto out_problem;
 
-		map->end = map__start(map) + xm->end - xm->start;
+		RC_CHK_ACCESS(map)->end = map__start(map) + xm->end - xm->start;
 
 		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 *filename, char *newfilename)
 
 void map__init(struct map *map, u64 start, u64 end, u64 pgoff, struct dso *dso)
 {
-	map->start    = start;
-	map->end      = end;
-	map->pgoff    = pgoff;
-	map->reloc    = 0;
-	map->dso      = dso__get(dso);
-	map->map_ip   = map__dso_map_ip;
-	map->unmap_ip = map__dso_unmap_ip;
-	map->erange_warned = false;
-	refcount_set(&map->refcnt, 1);
+	RC_CHK_ACCESS(map)->start    = start;
+	RC_CHK_ACCESS(map)->end      = end;
+	RC_CHK_ACCESS(map)->pgoff    = pgoff;
+	RC_CHK_ACCESS(map)->reloc    = 0;
+	RC_CHK_ACCESS(map)->dso      = dso__get(dso);
+	RC_CHK_ACCESS(map)->map_ip   = map__dso_map_ip;
+	RC_CHK_ACCESS(map)->unmap_ip = map__dso_unmap_ip;
+	RC_CHK_ACCESS(map)->erange_warned = false;
+	refcount_set(&RC_CHK_ACCESS(map)->refcnt, 1);
 }
 
 struct map *map__new(struct machine *machine, u64 start, u64 len,
@@ -120,11 +120,13 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
 		     u32 prot, u32 flags, struct build_id *bid,
 		     char *filename, struct thread *thread)
 {
-	struct map *map = malloc(sizeof(*map));
+	struct map *res;
+	RC_STRUCT(map) *map;
 	struct nsinfo *nsi = NULL;
 	struct nsinfo *nnsi;
 
-	if (map != NULL) {
+	map = 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 == NULL)
 			goto out_delete;
 
-		map__init(map, start, start + len, pgoff, dso);
+		map__init(res, start, start + len, pgoff, dso);
 
 		if (anon || no_dso) {
 			map->map_ip = map->unmap_ip = identity__map_ip;
@@ -204,10 +206,10 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
 		}
 		dso__put(dso);
 	}
-	return map;
+	return res;
 out_delete:
 	nsinfo__put(nsi);
-	free(map);
+	RC_CHK_FREE(res);
 	return NULL;
 }
 
@@ -218,16 +220,18 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
  */
 struct map *map__new2(u64 start, struct dso *dso)
 {
-	struct map *map = calloc(1, (sizeof(*map) +
-				     (dso->kernel ? sizeof(struct kmap) : 0)));
-	if (map != NULL) {
+	struct map *res;
+	RC_STRUCT(map) *map;
+
+	map = 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);
 	}
 
-	return map;
+	return res;
 }
 
 bool __map__is_kernel(const struct map *map)
@@ -292,20 +296,22 @@ bool map__has_symbols(const struct map *map)
 
 static void map__exit(struct map *map)
 {
-	BUG_ON(refcount_read(&map->refcnt) != 0);
-	dso__zput(map->dso);
+	BUG_ON(refcount_read(&RC_CHK_ACCESS(map)->refcnt) != 0);
+	dso__zput(RC_CHK_ACCESS(map)->dso);
 }
 
 void map__delete(struct map *map)
 {
 	map__exit(map);
-	free(map);
+	RC_CHK_FREE(map);
 }
 
 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);
 }
 
 void map__fixup_start(struct map *map)
@@ -317,7 +323,7 @@ void map__fixup_start(struct map *map)
 	if (nd != NULL) {
 		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
 
-		map->start = sym->start;
+		RC_CHK_ACCESS(map)->start = sym->start;
 	}
 }
 
@@ -329,7 +335,7 @@ void map__fixup_end(struct map *map)
 
 	if (nd != NULL) {
 		struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
-		map->end = sym->end;
+		RC_CHK_ACCESS(map)->end = sym->end;
 	}
 }
 
@@ -400,20 +406,21 @@ struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
 
 struct map *map__clone(struct map *from)
 {
-	size_t size = sizeof(struct map);
-	struct map *map;
+	struct map *res;
+	RC_STRUCT(map) *map;
+	size_t size = sizeof(RC_STRUCT(map));
 	struct dso *dso = map__dso(from);
 
 	if (dso && dso->kernel)
 		size += sizeof(struct kmap);
 
-	map = memdup(from, size);
-	if (map != NULL) {
+	map = memdup(RC_CHK_ACCESS(from), size);
+	if (ADD_RC_CHK(res, map)) {
 		refcount_set(&map->refcnt, 1);
 		map->dso = dso__get(dso);
 	}
 
-	return map;
+	return res;
 }
 
 size_t map__fprintf(struct map *map, FILE *fp)
@@ -567,7 +574,7 @@ struct kmap *__map__kmap(struct map *map)
 
 	if (!dso || !dso->kernel)
 		return NULL;
-	return (struct kmap *)(map + 1);
+	return (struct kmap *)(&RC_CHK_ACCESS(map)[1]);
 }
 
 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 <string.h>
 #include <stdbool.h>
 #include <linux/types.h>
+#include <internal/rc_check.h>
 
 struct dso;
 struct maps;
 struct machine;
 
-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_unused, u64 ip);
 
 static inline struct dso *map__dso(const struct map *map)
 {
-	return map->dso;
+	return RC_CHK_ACCESS(map)->dso;
 }
 
 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);
 }
 
 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);
 }
 
 static inline u64 map__start(const struct map *map)
 {
-	return map->start;
+	return RC_CHK_ACCESS(map)->start;
 }
 
 static inline u64 map__end(const struct map *map)
 {
-	return map->end;
+	return RC_CHK_ACCESS(map)->end;
 }
 
 static inline u64 map__pgoff(const struct map *map)
 {
-	return map->pgoff;
+	return RC_CHK_ACCESS(map)->pgoff;
 }
 
 static inline u64 map__reloc(const struct map *map)
 {
-	return map->reloc;
+	return RC_CHK_ACCESS(map)->reloc;
 }
 
 static inline u32 map__flags(const struct map *map)
 {
-	return map->flags;
+	return RC_CHK_ACCESS(map)->flags;
 }
 
 static inline u32 map__prot(const struct map *map)
 {
-	return map->prot;
+	return RC_CHK_ACCESS(map)->prot;
 }
 
 static inline bool map__priv(const struct map *map)
 {
-	return map->priv;
+	return RC_CHK_ACCESS(map)->priv;
 }
 
 static inline size_t map__size(const struct map *map)
@@ -153,9 +154,12 @@ struct map *map__clone(struct map *map);
 
 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;
 }
 
 void map__put(struct map *map);
diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
index 567952587247..a33ae321c65a 100644
--- a/tools/perf/util/maps.c
+++ b/tools/perf/util/maps.c
@@ -126,7 +126,7 @@ void maps__remove(struct maps *maps, struct map *map)
 		RC_CHK_ACCESS(maps)->last_search_by_name = NULL;
 
 	rb_node = maps__find_node(maps, map);
-	assert(rb_node->map == map);
+	assert(rb_node->RC_CHK_ACCESS(map) == 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;
 			}
 
-			before->end = map__start(map);
+			RC_CHK_ACCESS(before)->end = map__start(map);
 			err = __maps__insert(maps, before);
 			if (err) {
 				map__put(before);
@@ -359,8 +359,9 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
 				goto put_map;
 			}
 
-			after->start = map__end(map);
-			after->pgoff += map__end(map) - map__start(pos->map);
+			RC_CHK_ACCESS(after)->start = map__end(map);
+			RC_CHK_ACCESS(after)->pgoff +=
+				map__end(map) - map__start(pos->map);
 			assert(map__map_ip(pos->map, map__end(map)) ==
 				map__map_ip(after, map__end(map)));
 			err = __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;
 
 	maps__for_each_entry(maps, rb_node) {
-		if (rb_node->map == map)
+		if (rb_node->RC_CHK_ACCESS(map) == RC_CHK_ACCESS(map))
 			return rb_node;
 	}
 	return NULL;
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index c55981116f68..302599073b5d 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1354,11 +1354,11 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
 		 */
 		if (*remap_kernel && dso->kernel && !kmodule) {
 			*remap_kernel = false;
-			map->start = shdr->sh_addr + ref_reloc(kmap);
-			map->end = map__start(map) + shdr->sh_size;
-			map->pgoff = shdr->sh_offset;
-			map->map_ip = map__dso_map_ip;
-			map->unmap_ip = map__dso_unmap_ip;
+			RC_CHK_ACCESS(map)->start = shdr->sh_addr + ref_reloc(kmap);
+			RC_CHK_ACCESS(map)->end = map__start(map) + shdr->sh_size;
+			RC_CHK_ACCESS(map)->pgoff = shdr->sh_offset;
+			RC_CHK_ACCESS(map)->map_ip = map__dso_map_ip;
+			RC_CHK_ACCESS(map)->unmap_ip = map__dso_unmap_ip;
 			/* Ensure maps are correctly ordered */
 			if (kmaps) {
 				int err;
@@ -1379,7 +1379,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
 		 */
 		if (*remap_kernel && kmodule) {
 			*remap_kernel = false;
-			map->pgoff = shdr->sh_offset;
+			RC_CHK_ACCESS(map)->pgoff = shdr->sh_offset;
 		}
 
 		*curr_mapp = map;
@@ -1414,11 +1414,13 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
 			map__kmap(curr_map)->kmaps = kmaps;
 
 		if (adjust_kernel_syms) {
-			curr_map->start  = shdr->sh_addr + ref_reloc(kmap);
-			curr_map->end	 = map__start(curr_map) + shdr->sh_size;
-			curr_map->pgoff	 = shdr->sh_offset;
+			RC_CHK_ACCESS(curr_map)->start  = shdr->sh_addr + ref_reloc(kmap);
+			RC_CHK_ACCESS(curr_map)->end	= map__start(curr_map) +
+							  shdr->sh_size;
+			RC_CHK_ACCESS(curr_map)->pgoff	= shdr->sh_offset;
 		} else {
-			curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
+			RC_CHK_ACCESS(curr_map)->map_ip = identity__map_ip;
+			RC_CHK_ACCESS(curr_map)->unmap_ip = identity__map_ip;
 		}
 		curr_dso->symtab_type = dso->symtab_type;
 		if (maps__insert(kmaps, curr_map))
@@ -1525,7 +1527,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
 			if (strcmp(elf_name, kmap->ref_reloc_sym->name))
 				continue;
 			kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
-			map->reloc = kmap->ref_reloc_sym->addr -
+			RC_CHK_ACCESS(map)->reloc = kmap->ref_reloc_sym->addr -
 				     kmap->ref_reloc_sym->unrelocated_addr;
 			break;
 		}
@@ -1536,7 +1538,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
 	 * attempted to prelink vdso to its virtual address.
 	 */
 	if (dso__is_vdso(dso))
-		map->reloc = map__start(map) - dso->text_offset;
+		RC_CHK_ACCESS(map)->reloc = map__start(map) - dso->text_offset;
 
 	dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap);
 	/*
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 6993b51b9416..42458582621b 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -279,7 +279,7 @@ void maps__fixup_end(struct maps *maps)
 
 	maps__for_each_entry(maps, curr) {
 		if (prev != NULL && !map__end(prev->map))
-			prev->map->end = map__start(curr->map);
+			RC_CHK_ACCESS(prev->map)->end = map__start(curr->map);
 
 		prev = 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 = ~0ULL;
+		RC_CHK_ACCESS(curr->map)->end = ~0ULL;
 
 	up_write(maps__lock(maps));
 }
@@ -865,7 +865,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
 			*module++ = '\0';
 			curr_map_dso = map__dso(curr_map);
 			if (strcmp(curr_map_dso->short_name, module)) {
-				if (curr_map != initial_map &&
+				if (RC_CHK_ACCESS(curr_map) != RC_CHK_ACCESS(initial_map) &&
 				    dso->kernel == DSO_SPACE__KERNEL_GUEST &&
 				    machine__is_default_guest(machine)) {
 					/*
@@ -944,7 +944,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
 				return -1;
 			}
 
-			curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
+			RC_CHK_ACCESS(curr_map)->map_ip = identity__map_ip;
+			RC_CHK_ACCESS(curr_map)->unmap_ip = 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;
 	}
 
-	list_node->map->end = map__start(list_node->map) + len;
-	list_node->map->pgoff = pgoff;
+	list_node->RC_CHK_ACCESS(map)->end = map__start(list_node->map) + len;
+	list_node->RC_CHK_ACCESS(map)->pgoff = pgoff;
 
 	list_add(&list_node->node, &md->maps);
 
@@ -1286,7 +1287,7 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map)
 				 * |new......|     -> |new..|
 				 *       |old....| ->       |old....|
 				 */
-				new_map->end = map__start(old_map);
+				RC_CHK_ACCESS(new_map)->end = 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;
 				}
 
-				m->map->end = map__start(old_map);
+
+				RC_CHK_ACCESS(m->map)->end = map__start(old_map);
 				list_add_tail(&m->node, &merged);
-				new_map->pgoff += map__end(old_map) - map__start(new_map);
-				new_map->start = map__end(old_map);
+				RC_CHK_ACCESS(new_map)->pgoff +=
+					map__end(old_map) - map__start(new_map);
+				RC_CHK_ACCESS(new_map)->start = map__end(old_map);
 			}
 		} else {
 			/*
@@ -1329,8 +1332,9 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map)
 				 *      |new......| ->         |new...|
 				 * |old....|        -> |old....|
 				 */
-				new_map->pgoff += map__end(old_map) - map__start(new_map);
-				new_map->start = map__end(old_map);
+				RC_CHK_ACCESS(new_map)->pgoff +=
+					map__end(old_map) - map__start(new_map);
+				RC_CHK_ACCESS(new_map)->start = map__end(old_map);
 			}
 		}
 	}
@@ -1456,12 +1460,12 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
 
 		list_del_init(&new_node->node);
 
-		if (new_map == replacement_map) {
-			map->start	= map__start(new_map);
-			map->end	= map__end(new_map);
-			map->pgoff	= map__pgoff(new_map);
-			map->map_ip	= new_map->map_ip;
-			map->unmap_ip	= new_map->unmap_ip;
+		if (RC_CHK_ACCESS(new_map) == RC_CHK_ACCESS(replacement_map)) {
+			RC_CHK_ACCESS(map)->start	= map__start(new_map);
+			RC_CHK_ACCESS(map)->end		= map__end(new_map);
+			RC_CHK_ACCESS(map)->pgoff	= map__pgoff(new_map);
+			RC_CHK_ACCESS(map)->map_ip	= RC_CHK_ACCESS(new_map)->map_ip;
+			RC_CHK_ACCESS(map)->unmap_ip	= RC_CHK_ACCESS(new_map)->unmap_ip;
 			/* Ensure maps are correctly ordered */
 			map__get(map);
 			maps__remove(kmaps, map);
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip
  2023-04-04 20:59 ` [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip Ian Rogers
@ 2023-04-05 13:25   ` Arnaldo Carvalho de Melo
  2023-04-05 13:32     ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-04-05 13:25 UTC (permalink / raw)
  To: Ian Rogers
  Cc: Peter Zijlstra, Ingo Molnar, 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,
	linux-kernel, Eric Dumazet, Dmitry Vyukov, Hao Luo,
	Stephane Eranian

Em Tue, Apr 04, 2023 at 01:59:43PM -0700, Ian Rogers escreveu:
> 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 <irogers@google.com>
> ---
>  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 perf_sample *sample)
>  		if (!caller) {
>  			/* found */
>  			if (node->ms.map)
> -				addr = map__unmap_ip(node->ms.map, node->ip);
> +				addr = map__dso_unmap_ip(node->ms.map, node->ip);

As we chatted, I think this is a good opportunity to make this more
clear, perhaps rename map__unmap_ip() to map__addr_offset_to_virt() and
map__map_ip() to map__addr_virt_to_offset()?

- Arnaldo

>  			else
>  				addr = node->ip;
>  
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index 1d078106abc4..af0a69c7f41f 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -1012,11 +1012,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
>  
>  		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
>  		    !map__dso(alf.map)->adjust_symbols)
> -			from = map__map_ip(alf.map, from);
> +			from = map__dso_map_ip(alf.map, from);
>  
>  		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
>  		    !map__dso(alt.map)->adjust_symbols)
> -			to = map__map_ip(alt.map, to);
> +			to = map__dso_map_ip(alt.map, to);
>  
>  		printed += fprintf(fp, " 0x%"PRIx64, from);
>  		if (PRINT_FIELD(DSO)) {
> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> index 7852b97da10a..9d24980a0a93 100644
> --- a/tools/perf/util/machine.c
> +++ b/tools/perf/util/machine.c
> @@ -3058,7 +3058,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms
>  	if (!symbol_conf.inline_name || !map || !sym)
>  		return ret;
>  
> -	addr = map__map_ip(map, ip);
> +	addr = map__dso_map_ip(map, ip);
>  	addr = map__rip_2objdump(map, addr);
>  	dso = map__dso(map);
>  
> @@ -3103,7 +3103,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
>  	 * its corresponding binary.
>  	 */
>  	if (entry->ms.map)
> -		addr = map__map_ip(entry->ms.map, entry->ip);
> +		addr = map__dso_map_ip(entry->ms.map, entry->ip);
>  
>  	srcline = 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    = pgoff;
>  	map->reloc    = 0;
>  	map->dso      = dso__get(dso);
> -	map->map_ip   = map__map_ip;
> -	map->unmap_ip = map__unmap_ip;
> +	map->map_ip   = map__dso_map_ip;
> +	map->unmap_ip = map__dso_unmap_ip;
>  	map->erange_warned = false;
>  	refcount_set(&map->refcnt, 1);
>  }
> @@ -590,12 +590,12 @@ struct maps *map__kmaps(struct map *map)
>  	return kmap->kmaps;
>  }
>  
> -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;
>  }
>  
> -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);
>  
>  /* 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);
>  
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index e715869eab8a..c55981116f68 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -1357,8 +1357,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
>  			map->start = shdr->sh_addr + ref_reloc(kmap);
>  			map->end = map__start(map) + shdr->sh_size;
>  			map->pgoff = shdr->sh_offset;
> -			map->map_ip = map__map_ip;
> -			map->unmap_ip = map__unmap_ip;
> +			map->map_ip = map__dso_map_ip;
> +			map->unmap_ip = map__dso_unmap_ip;
>  			/* Ensure maps are correctly ordered */
>  			if (kmaps) {
>  				int err;
> -- 
> 2.40.0.348.gf938b09366-goog
> 

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip
  2023-04-05 13:25   ` Arnaldo Carvalho de Melo
@ 2023-04-05 13:32     ` Arnaldo Carvalho de Melo
  2023-04-07  0:40       ` Ian Rogers
  0 siblings, 1 reply; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-04-05 13:32 UTC (permalink / raw)
  To: Ian Rogers
  Cc: Peter Zijlstra, Ingo Molnar, 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,
	linux-kernel, Eric Dumazet, Dmitry Vyukov, Hao Luo,
	Stephane Eranian

Em Wed, Apr 05, 2023 at 10:25:06AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Apr 04, 2023 at 01:59:43PM -0700, Ian Rogers escreveu:
> > 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 <irogers@google.com>
> > ---
> >  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 perf_sample *sample)
> >  		if (!caller) {
> >  			/* found */
> >  			if (node->ms.map)
> > -				addr = map__unmap_ip(node->ms.map, node->ip);
> > +				addr = map__dso_unmap_ip(node->ms.map, node->ip);
> 
> As we chatted, I think this is a good opportunity to make this more
> clear, perhaps rename map__unmap_ip() to map__addr_offset_to_virt() and
> map__map_ip() to map__addr_virt_to_offset()?

Maybe prefix both with __, i.e. __map__addr_offset_to_virt() and __map__addr_virt_to_offset(), since
then you need to wrap map->unmap_ip() to
map__map__addr_offset_to_virt(), that in some cases will map to
__map__addr_offset_to_virt(), modulo in identity maps, like with the
kernel where we use identify__map_ip().

- Arnaldo
 
> - Arnaldo
> 
> >  			else
> >  				addr = node->ip;
> >  
> > diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> > index 1d078106abc4..af0a69c7f41f 100644
> > --- a/tools/perf/builtin-script.c
> > +++ b/tools/perf/builtin-script.c
> > @@ -1012,11 +1012,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
> >  
> >  		if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
> >  		    !map__dso(alf.map)->adjust_symbols)
> > -			from = map__map_ip(alf.map, from);
> > +			from = map__dso_map_ip(alf.map, from);
> >  
> >  		if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
> >  		    !map__dso(alt.map)->adjust_symbols)
> > -			to = map__map_ip(alt.map, to);
> > +			to = map__dso_map_ip(alt.map, to);
> >  
> >  		printed += fprintf(fp, " 0x%"PRIx64, from);
> >  		if (PRINT_FIELD(DSO)) {
> > diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> > index 7852b97da10a..9d24980a0a93 100644
> > --- a/tools/perf/util/machine.c
> > +++ b/tools/perf/util/machine.c
> > @@ -3058,7 +3058,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms
> >  	if (!symbol_conf.inline_name || !map || !sym)
> >  		return ret;
> >  
> > -	addr = map__map_ip(map, ip);
> > +	addr = map__dso_map_ip(map, ip);
> >  	addr = map__rip_2objdump(map, addr);
> >  	dso = map__dso(map);
> >  
> > @@ -3103,7 +3103,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
> >  	 * its corresponding binary.
> >  	 */
> >  	if (entry->ms.map)
> > -		addr = map__map_ip(entry->ms.map, entry->ip);
> > +		addr = map__dso_map_ip(entry->ms.map, entry->ip);
> >  
> >  	srcline = 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    = pgoff;
> >  	map->reloc    = 0;
> >  	map->dso      = dso__get(dso);
> > -	map->map_ip   = map__map_ip;
> > -	map->unmap_ip = map__unmap_ip;
> > +	map->map_ip   = map__dso_map_ip;
> > +	map->unmap_ip = map__dso_unmap_ip;
> >  	map->erange_warned = false;
> >  	refcount_set(&map->refcnt, 1);
> >  }
> > @@ -590,12 +590,12 @@ struct maps *map__kmaps(struct map *map)
> >  	return kmap->kmaps;
> >  }
> >  
> > -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;
> >  }
> >  
> > -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);
> >  
> >  /* 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);
> >  
> > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> > index e715869eab8a..c55981116f68 100644
> > --- a/tools/perf/util/symbol-elf.c
> > +++ b/tools/perf/util/symbol-elf.c
> > @@ -1357,8 +1357,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
> >  			map->start = shdr->sh_addr + ref_reloc(kmap);
> >  			map->end = map__start(map) + shdr->sh_size;
> >  			map->pgoff = shdr->sh_offset;
> > -			map->map_ip = map__map_ip;
> > -			map->unmap_ip = map__unmap_ip;
> > +			map->map_ip = map__dso_map_ip;
> > +			map->unmap_ip = map__dso_unmap_ip;
> >  			/* Ensure maps are correctly ordered */
> >  			if (kmaps) {
> >  				int err;
> > -- 
> > 2.40.0.348.gf938b09366-goog
> > 
> 
> -- 
> 
> - Arnaldo

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip
  2023-04-05 13:32     ` Arnaldo Carvalho de Melo
@ 2023-04-07  0:40       ` Ian Rogers
  0 siblings, 0 replies; 19+ messages in thread
From: Ian Rogers @ 2023-04-07  0:40 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, 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,
	linux-kernel, Eric Dumazet, Dmitry Vyukov, Hao Luo,
	Stephane Eranian

On Wed, Apr 5, 2023 at 6:32 AM Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
>
> Em Wed, Apr 05, 2023 at 10:25:06AM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Tue, Apr 04, 2023 at 01:59:43PM -0700, Ian Rogers escreveu:
> > > 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 <irogers@google.com>
> > > ---
> > >  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 perf_sample *sample)
> > >             if (!caller) {
> > >                     /* found */
> > >                     if (node->ms.map)
> > > -                           addr = map__unmap_ip(node->ms.map, node->ip);
> > > +                           addr = map__dso_unmap_ip(node->ms.map, node->ip);
> >
> > As we chatted, I think this is a good opportunity to make this more
> > clear, perhaps rename map__unmap_ip() to map__addr_offset_to_virt() and
> > map__map_ip() to map__addr_virt_to_offset()?
>
> Maybe prefix both with __, i.e. __map__addr_offset_to_virt() and __map__addr_virt_to_offset(), since
> then you need to wrap map->unmap_ip() to
> map__map__addr_offset_to_virt(), that in some cases will map to
> __map__addr_offset_to_virt(), modulo in identity maps, like with the
> kernel where we use identify__map_ip().

Thanks Arnaldo, I'm not following what you are asking here. As it is a
refactor unrelated to reference count checking, could you follow up
this patch set with it?

Ian

> - Arnaldo
>
> > - Arnaldo
> >
> > >                     else
> > >                             addr = node->ip;
> > >
> > > diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> > > index 1d078106abc4..af0a69c7f41f 100644
> > > --- a/tools/perf/builtin-script.c
> > > +++ b/tools/perf/builtin-script.c
> > > @@ -1012,11 +1012,11 @@ static int perf_sample__fprintf_brstackoff(struct perf_sample *sample,
> > >
> > >             if (thread__find_map_fb(thread, sample->cpumode, from, &alf) &&
> > >                 !map__dso(alf.map)->adjust_symbols)
> > > -                   from = map__map_ip(alf.map, from);
> > > +                   from = map__dso_map_ip(alf.map, from);
> > >
> > >             if (thread__find_map_fb(thread, sample->cpumode, to, &alt) &&
> > >                 !map__dso(alt.map)->adjust_symbols)
> > > -                   to = map__map_ip(alt.map, to);
> > > +                   to = map__dso_map_ip(alt.map, to);
> > >
> > >             printed += fprintf(fp, " 0x%"PRIx64, from);
> > >             if (PRINT_FIELD(DSO)) {
> > > diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> > > index 7852b97da10a..9d24980a0a93 100644
> > > --- a/tools/perf/util/machine.c
> > > +++ b/tools/perf/util/machine.c
> > > @@ -3058,7 +3058,7 @@ static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms
> > >     if (!symbol_conf.inline_name || !map || !sym)
> > >             return ret;
> > >
> > > -   addr = map__map_ip(map, ip);
> > > +   addr = map__dso_map_ip(map, ip);
> > >     addr = map__rip_2objdump(map, addr);
> > >     dso = map__dso(map);
> > >
> > > @@ -3103,7 +3103,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
> > >      * its corresponding binary.
> > >      */
> > >     if (entry->ms.map)
> > > -           addr = map__map_ip(entry->ms.map, entry->ip);
> > > +           addr = map__dso_map_ip(entry->ms.map, entry->ip);
> > >
> > >     srcline = 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    = pgoff;
> > >     map->reloc    = 0;
> > >     map->dso      = dso__get(dso);
> > > -   map->map_ip   = map__map_ip;
> > > -   map->unmap_ip = map__unmap_ip;
> > > +   map->map_ip   = map__dso_map_ip;
> > > +   map->unmap_ip = map__dso_unmap_ip;
> > >     map->erange_warned = false;
> > >     refcount_set(&map->refcnt, 1);
> > >  }
> > > @@ -590,12 +590,12 @@ struct maps *map__kmaps(struct map *map)
> > >     return kmap->kmaps;
> > >  }
> > >
> > > -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;
> > >  }
> > >
> > > -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);
> > >
> > >  /* 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);
> > >
> > > diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> > > index e715869eab8a..c55981116f68 100644
> > > --- a/tools/perf/util/symbol-elf.c
> > > +++ b/tools/perf/util/symbol-elf.c
> > > @@ -1357,8 +1357,8 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
> > >                     map->start = shdr->sh_addr + ref_reloc(kmap);
> > >                     map->end = map__start(map) + shdr->sh_size;
> > >                     map->pgoff = shdr->sh_offset;
> > > -                   map->map_ip = map__map_ip;
> > > -                   map->unmap_ip = map__unmap_ip;
> > > +                   map->map_ip = map__dso_map_ip;
> > > +                   map->unmap_ip = map__dso_unmap_ip;
> > >                     /* Ensure maps are correctly ordered */
> > >                     if (kmaps) {
> > >                             int err;
> > > --
> > > 2.40.0.348.gf938b09366-goog
> > >
> >
> > --
> >
> > - Arnaldo
>
> --
>
> - Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v6 02/12] perf map: Add helper for map_ip and unmap_ip
  2023-04-04 20:59 ` [PATCH v6 02/12] perf map: Add helper for " Ian Rogers
@ 2023-04-07  1:06   ` Arnaldo Carvalho de Melo
  2023-04-07  1:12     ` Ian Rogers
  0 siblings, 1 reply; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-04-07  1:06 UTC (permalink / raw)
  To: Ian Rogers
  Cc: Peter Zijlstra, Ingo Molnar, 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,
	linux-kernel, Eric Dumazet, Dmitry Vyukov, Hao Luo,
	Stephane Eranian

Em Tue, Apr 04, 2023 at 01:59:44PM -0700, Ian Rogers escreveu:
> 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.

Fixing these:

⬢[acme@toolbox perf-tools-next]$ find tools/perf/ -name "*.[ch]" | xargs grep -- '->map_ip('
tools/perf/arch/s390/annotate/instructions.c:	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
tools/perf/util/cs-etm.c:	offset = al.map->map_ip(al.map, address);
tools/perf/util/annotate.c:	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
tools/perf/util/annotate.c:	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
tools/perf/util/map.c: * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
tools/perf/util/map.h:	return map->map_ip(map, ip);
⬢[acme@toolbox perf-tools-next]$

⬢[acme@toolbox perf-tools-next]$ find tools/perf/ -name "*.[ch]" | xargs grep -- '->unmap_ip('
tools/perf/arch/powerpc/util/sym-handling.c:			if (map->unmap_ip(map, sym->start) == tev->point.address) {
tools/perf/util/map.h:	return map->unmap_ip(map, ip);
⬢[acme@toolbox perf-tools-next]$
 
> Signed-off-by: Ian Rogers <irogers@google.com>
> ---
>  tools/perf/arch/s390/annotate/instructions.c     |  3 ++-
>  tools/perf/builtin-kallsyms.c                    |  2 +-
>  tools/perf/builtin-kmem.c                        |  2 +-
>  tools/perf/builtin-lock.c                        |  4 ++--
>  tools/perf/builtin-script.c                      |  2 +-
>  tools/perf/tests/vmlinux-kallsyms.c              | 10 +++++-----
>  tools/perf/util/annotate.c                       | 16 +++++++++-------
>  tools/perf/util/bpf_lock_contention.c            |  4 ++--
>  tools/perf/util/dlfilter.c                       |  2 +-
>  tools/perf/util/dso.c                            |  6 ++++--
>  tools/perf/util/event.c                          |  8 ++++----
>  tools/perf/util/evsel_fprintf.c                  |  2 +-
>  tools/perf/util/intel-pt.c                       | 10 +++++-----
>  tools/perf/util/machine.c                        | 16 ++++++++--------
>  tools/perf/util/map.c                            | 10 +++++-----
>  tools/perf/util/map.h                            | 10 ++++++++++
>  tools/perf/util/maps.c                           |  8 ++++----
>  tools/perf/util/probe-event.c                    |  8 ++++----
>  .../util/scripting-engines/trace-event-python.c  |  2 +-
>  tools/perf/util/sort.c                           | 12 ++++++------
>  tools/perf/util/symbol.c                         |  4 ++--
>  tools/perf/util/thread.c                         |  2 +-
>  tools/perf/util/unwind-libdw.c                   |  2 +-
>  tools/perf/util/unwind-libunwind-local.c         |  2 +-
>  24 files changed, 81 insertions(+), 66 deletions(-)
> 
> diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c
> index 0e136630659e..6548933e8dc0 100644
> --- a/tools/perf/arch/s390/annotate/instructions.c
> +++ b/tools/perf/arch/s390/annotate/instructions.c
> @@ -39,7 +39,8 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
>  	target.addr = map__objdump_2mem(map, ops->target.addr);
>  
>  	if (maps__find_ams(ms->maps, &target) == 0 &&
> -	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> +	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> +	    ops->target.addr)
>  		ops->target.sym = target.ms.sym;
>  
>  	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 = 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);
>  	}
>  
> 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,
>  
>  		if (sym != NULL)
>  			snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name,
> -				 addr - map->unmap_ip(map, sym->start));
> +				 addr - map__unmap_ip(map, sym->start));
>  		else
>  			snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr);
>  		printf(" %-34s |", buf);
> diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
> index 32ec58fb80e4..04345b2e7101 100644
> --- a/tools/perf/builtin-lock.c
> +++ b/tools/perf/builtin-lock.c
> @@ -900,7 +900,7 @@ static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip,
>  		return 0;
>  	}
>  
> -	offset = map->map_ip(map, ip) - sym->start;
> +	offset = map__map_ip(map, ip) - sym->start;
>  
>  	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;
>  			}
>  
> -			addrs[filters.nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
> +			addrs[filters.nr_addrs++] = map__unmap_ip(kmap, sym->start);
>  			filters.addrs = addrs;
>  		}
>  	}
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index af0a69c7f41f..8fba247b798c 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -1088,7 +1088,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
>  	/* Load maps to ensure dso->is_64_bit has been updated */
>  	map__load(al.map);
>  
> -	offset = al.map->map_ip(al.map, start);
> +	offset = map__map_ip(al.map, start);
>  	len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,
>  				    end - start + MAXINSN);
>  
> 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"
>  
> -#define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x))
> +#define UM(x) map__unmap_ip(kallsyms_map, (x))
>  
>  static bool is_ignored_symbol(const char *name, char type)
>  {
> @@ -221,8 +221,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
>  		if (sym->start == sym->end)
>  			continue;
>  
> -		mem_start = vmlinux_map->unmap_ip(vmlinux_map, sym->start);
> -		mem_end = vmlinux_map->unmap_ip(vmlinux_map, sym->end);
> +		mem_start = map__unmap_ip(vmlinux_map, sym->start);
> +		mem_end = map__unmap_ip(vmlinux_map, sym->end);
>  
>  		first_pair = machine__find_kernel_symbol(&kallsyms, mem_start, NULL);
>  		pair = first_pair;
> @@ -319,8 +319,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
>  	maps__for_each_entry(maps, rb_node) {
>  		struct map *pair, *map = rb_node->map;
>  
> -		mem_start = vmlinux_map->unmap_ip(vmlinux_map, map__start(map));
> -		mem_end = vmlinux_map->unmap_ip(vmlinux_map, map__end(map));
> +		mem_start = map__unmap_ip(vmlinux_map, map__start(map));
> +		mem_end = map__unmap_ip(vmlinux_map, map__end(map));
>  
>  		pair = maps__find(kallsyms.kmaps, mem_start);
>  		if (pair == NULL || pair->priv)
> diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> index b9cff782d7df..36acdd1bd379 100644
> --- a/tools/perf/util/annotate.c
> +++ b/tools/perf/util/annotate.c
> @@ -272,7 +272,8 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s
>  	target.addr = map__objdump_2mem(map, ops->target.addr);
>  
>  	if (maps__find_ams(ms->maps, &target) == 0 &&
> -	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> +	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> +	    ops->target.addr)
>  		ops->target.sym = target.ms.sym;
>  
>  	return 0;
> @@ -376,8 +377,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
>  	}
>  
>  	target.addr = map__objdump_2mem(map, ops->target.addr);
> -	start = map->unmap_ip(map, sym->start),
> -	end = map->unmap_ip(map, sym->end);
> +	start = map__unmap_ip(map, sym->start);
> +	end = map__unmap_ip(map, sym->end);
>  
>  	ops->target.outside = target.addr < start || target.addr > end;
>  
> @@ -400,7 +401,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
>  	 * the symbol searching and disassembly should be done.
>  	 */
>  	if (maps__find_ams(ms->maps, &target) == 0 &&
> -	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> +	    map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> +	    ops->target.addr)
>  		ops->target.sym = target.ms.sym;
>  
>  	if (!ops->target.outside) {
> @@ -881,7 +883,7 @@ static int __symbol__inc_addr_samples(struct map_symbol *ms,
>  	unsigned offset;
>  	struct sym_hist *h;
>  
> -	pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->map, addr));
> +	pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, addr));
>  
>  	if ((addr < sym->start || addr >= sym->end) &&
>  	    (addr != sym->end || sym->start != sym->end)) {
> @@ -1977,8 +1979,8 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
>  		return err;
>  
>  	pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\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));
>  
>  	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_lock_contention.c
> index 8a5d0eb44189..2b3bc544aa3e 100644
> --- a/tools/perf/util/bpf_lock_contention.c
> +++ b/tools/perf/util/bpf_lock_contention.c
> @@ -74,7 +74,7 @@ int lock_contention_prepare(struct lock_contention *con)
>  				continue;
>  			}
>  
> -			addrs[con->filters->nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
> +			addrs[con->filters->nr_addrs++] = map__unmap_ip(kmap, sym->start);
>  			con->filters->addrs = addrs;
>  		}
>  		naddrs = con->filters->nr_addrs;
> @@ -233,7 +233,7 @@ static const char *lock_contention_get_name(struct lock_contention *con,
>  	if (sym) {
>  		unsigned long offset;
>  
> -		offset = kmap->map_ip(kmap, addr) - sym->start;
> +		offset = map__map_ip(kmap, addr) - sym->start;
>  
>  		if (offset == 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)
>  
>  	map = a.map;
>  have_map:
> -	offset = map->map_ip(map, ip);
> +	offset = map__map_ip(map, ip);
>  	if (ip + len >= map__end(map))
>  		len = 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 map *map,
>  			    struct machine *machine, u64 addr,
>  			    u8 *data, ssize_t size)
>  {
> -	u64 offset = map->map_ip(map, addr);
> +	u64 offset = map__map_ip(map, addr);
> +
>  	return dso__data_read_offset(dso, machine, offset, data, size);
>  }
>  
> @@ -1162,7 +1163,8 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
>  				   struct machine *machine, u64 addr,
>  				   const u8 *data, ssize_t size)
>  {
> -	u64 offset = map->map_ip(map, addr);
> +	u64 offset = map__map_ip(map, addr);
> +
>  	return dso__data_write_cache_offs(dso, machine, offset, data, size);
>  }
>  
> 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
>  
>  		al.map = maps__find(machine__kernel_maps(machine), tp->addr);
>  		if (al.map && map__load(al.map) >= 0) {
> -			al.addr = al.map->map_ip(al.map, tp->addr);
> +			al.addr = map__map_ip(al.map, tp->addr);
>  			al.sym = map__find_symbol(al.map, al.addr);
>  			if (al.sym)
>  				ret += 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 = al->map->map_ip(al->map, al->addr);
> +		al->addr = map__map_ip(al->map, al->addr);
>  	}
>  
>  	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 = strlist__has_entry(symbol_conf.sym_list,
>  						al_addr_str);
>  		}
>  		if (!ret && symbol_conf.addr_list && al->map) {
> -			unsigned long addr = al->map->unmap_ip(al->map, al->addr);
> +			unsigned long addr = map__unmap_ip(al->map, al->addr);
>  
>  			ret = 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_fprintf.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 *sample, int left_alignment,
>  				printed += fprintf(fp, " <-");
>  
>  			if (map)
> -				addr = map->map_ip(map, node->ip);
> +				addr = map__map_ip(map, node->ip);
>  
>  			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;
>  
> -		offset = al.map->map_ip(al.map, *ip);
> +		offset = map__map_ip(al.map, *ip);
>  
>  		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;
>  
> -	offset = al.map->map_ip(al.map, ip);
> +	offset = map__map_ip(al.map, ip);
>  
>  	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, u64 *ptss_ip)
>  	for (sym = start; sym; sym = dso__next_symbol(sym)) {
>  		if (sym->binding == STB_GLOBAL &&
>  		    !strcmp(sym->name, "__switch_to")) {
> -			ip = map->unmap_ip(map, sym->start);
> +			ip = map__unmap_ip(map, sym->start);
>  			if (ip >= map__start(map) && ip < map__end(map)) {
>  				switch_ip = ip;
>  				break;
> @@ -2767,7 +2767,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
>  
>  	for (sym = start; sym; sym = dso__next_symbol(sym)) {
>  		if (!strcmp(sym->name, ptss)) {
> -			ip = map->unmap_ip(map, sym->start);
> +			ip = map__unmap_ip(map, sym->start);
>  			if (ip >= map__start(map) && ip < map__end(map)) {
>  				*ptss_ip = ip;
>  				break;
> @@ -3393,7 +3393,7 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event)
>  		if (!dso || !dso->auxtrace_cache)
>  			continue;
>  
> -		offset = al.map->map_ip(al.map, addr);
> +		offset = map__map_ip(al.map, addr);
>  
>  		e = intel_pt_cache_lookup(dso, machine, offset);
>  		if (!e)
> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> index 9d24980a0a93..d29ec4a04488 100644
> --- a/tools/perf/util/machine.c
> +++ b/tools/perf/util/machine.c
> @@ -919,7 +919,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
>  		dso = map__dso(map);
>  	}
>  
> -	sym = symbol__new(map->map_ip(map, map__start(map)),
> +	sym = symbol__new(map__map_ip(map, map__start(map)),
>  			  event->ksymbol.len,
>  			  0, 0, event->ksymbol.name);
>  	if (!sym)
> @@ -944,7 +944,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine,
>  	else {
>  		struct dso *dso = map__dso(map);
>  
> -		sym = dso__find_symbol(dso, map->map_ip(map, map__start(map)));
> +		sym = dso__find_symbol(dso, map__map_ip(map, map__start(map)));
>  		if (sym)
>  			dso__delete_symbol(dso, sym);
>  	}
> @@ -1279,7 +1279,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,
>  
>  		dest_map = maps__find(kmaps, map->pgoff);
>  		if (dest_map != map)
> -			map->pgoff = dest_map->map_ip(dest_map, map->pgoff);
> +			map->pgoff = map__map_ip(dest_map, map->pgoff);
>  		found = true;
>  	}
>  	if (found || machine->trampolines_mapped)
> @@ -3345,7 +3345,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch
>  		return NULL;
>  
>  	*modp = __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NULL;
> -	*addrp = map->unmap_ip(map, sym->start);
> +	*addrp = map__unmap_ip(map, sym->start);
>  	return sym->name;
>  }
>  
> @@ -3388,17 +3388,17 @@ bool machine__is_lock_function(struct machine *machine, u64 addr)
>  			return false;
>  		}
>  
> -		machine->sched.text_start = kmap->unmap_ip(kmap, sym->start);
> +		machine->sched.text_start = map__unmap_ip(kmap, sym->start);
>  
>  		/* should not fail from here */
>  		sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_end", &kmap);
> -		machine->sched.text_end = kmap->unmap_ip(kmap, sym->start);
> +		machine->sched.text_end = map__unmap_ip(kmap, sym->start);
>  
>  		sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_start", &kmap);
> -		machine->lock.text_start = kmap->unmap_ip(kmap, sym->start);
> +		machine->lock.text_start = map__unmap_ip(kmap, sym->start);
>  
>  		sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_end", &kmap);
> -		machine->lock.text_end = kmap->unmap_ip(kmap, sym->start);
> +		machine->lock.text_end = map__unmap_ip(kmap, sym->start);
>  	}
>  
>  	/* 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 == DSO_SPACE__USER)
>  		return rip + dso->text_offset;
>  
> -	return map->unmap_ip(map, rip) - map->reloc;
> +	return map__unmap_ip(map, rip) - map->reloc;
>  }
>  
>  /**
> @@ -539,24 +539,24 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
>  	const struct dso *dso = map__dso(map);
>  
>  	if (!dso->adjust_symbols)
> -		return map->unmap_ip(map, ip);
> +		return map__unmap_ip(map, ip);
>  
>  	if (dso->rel)
> -		return map->unmap_ip(map, ip + map->pgoff);
> +		return map__unmap_ip(map, ip + map->pgoff);
>  
>  	/*
>  	 * 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 == DSO_SPACE__USER)
> -		return map->unmap_ip(map, ip - dso->text_offset);
> +		return map__unmap_ip(map, ip - dso->text_offset);
>  
>  	return ip + map->reloc;
>  }
>  
>  bool map__contains_symbol(const struct map *map, const struct symbol *sym)
>  {
> -	u64 ip = map->unmap_ip(map, sym->start);
> +	u64 ip = map__unmap_ip(map, sym->start);
>  
>  	return ip >= 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;
>  }
>  
> +static inline u64 map__map_ip(const struct map *map, u64 ip)
> +{
> +	return map->map_ip(map, ip);
> +}
> +
> +static inline u64 map__unmap_ip(const struct map *map, u64 ip)
> +{
> +	return map->unmap_ip(map, ip);
> +}
> +
>  static inline u64 map__start(const struct map *map)
>  {
>  	return map->start;
> diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
> index 21010a2b8e16..0eee27e24c33 100644
> --- a/tools/perf/util/maps.c
> +++ b/tools/perf/util/maps.c
> @@ -194,7 +194,7 @@ struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp)
>  	if (map != NULL && map__load(map) >= 0) {
>  		if (mapp != NULL)
>  			*mapp = map;
> -		return map__find_symbol(map, map->map_ip(map, addr));
> +		return map__find_symbol(map, map__map_ip(map, addr));
>  	}
>  
>  	return NULL;
> @@ -237,7 +237,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams)
>  			return -1;
>  	}
>  
> -	ams->al_addr = ams->ms.map->map_ip(ams->ms.map, ams->addr);
> +	ams->al_addr = map__map_ip(ams->ms.map, ams->addr);
>  	ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr);
>  
>  	return ams->ms.sym ? 0 : -1;
> @@ -349,8 +349,8 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
>  
>  			after->start = map__end(map);
>  			after->pgoff += map__end(map) - map__start(pos->map);
> -			assert(pos->map->map_ip(pos->map, map__end(map)) ==
> -				after->map_ip(after, map__end(map)));
> +			assert(map__map_ip(pos->map, map__end(map)) ==
> +				map__map_ip(after, map__end(map)));
>  			err = __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 = machine__find_kernel_symbol_by_name(host_machine, name, &map);
>  		if (!sym)
>  			return -ENOENT;
> -		*addr = map->unmap_ip(map, sym->start) -
> +		*addr = 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 debuginfo *dinfo,
>  					   "Consider identifying the final function used at run time and set the probe directly on that.\n",
>  					   pp->function);
>  		} else
> -			address = map->unmap_ip(map, sym->start) - map->reloc;
> +			address = map__unmap_ip(map, sym->start) - map->reloc;
>  		break;
>  	}
>  	if (!address) {
> @@ -2249,7 +2249,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
>  		goto out;
>  
>  	pp->retprobe = tp->retprobe;
> -	pp->offset = addr - map->unmap_ip(map, sym->start);
> +	pp->offset = addr - map__unmap_ip(map, sym->start);
>  	pp->function = strdup(sym->name);
>  	ret = pp->function ? 0 : -ENOMEM;
>  
> @@ -3123,7 +3123,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>  			goto err_out;
>  		}
>  		/* Add one probe point */
> -		tp->address = map->unmap_ip(map, sym->start) + pp->offset;
> +		tp->address = map__unmap_ip(map, sym->start) + pp->offset;
>  
>  		/* 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_sample *sample,
>  				struct addr_location node_al;
>  				unsigned long offset;
>  
> -				node_al.addr = map->map_ip(map, node->ip);
> +				node_al.addr = map__map_ip(map, node->ip);
>  				node_al.map  = map;
>  				offset = get_offset(node->ms.sym, &node_al);
>  
> diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> index f161589aefda..87a3ba584af5 100644
> --- a/tools/perf/util/sort.c
> +++ b/tools/perf/util/sort.c
> @@ -364,7 +364,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
>  		u64 rip = ip;
>  
>  		if (dso && dso->kernel && dso->adjust_symbols)
> -			rip = map->unmap_ip(map, ip);
> +			rip = map__unmap_ip(map, ip);
>  
>  		ret += repsep_snprintf(bf, size, "%-#*llx %c ",
>  				       BITS_PER_LONG / 4 + 2, rip, o);
> @@ -375,7 +375,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
>  		if (sym->type == STT_OBJECT) {
>  			ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
>  			ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
> -					ip - map->unmap_ip(map, sym->start));
> +					ip - map__unmap_ip(map, sym->start));
>  		} else {
>  			ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
>  					       width - ret,
> @@ -1147,7 +1147,7 @@ static int _hist_entry__addr_snprintf(struct map_symbol *ms,
>  		if (sym->type == STT_OBJECT) {
>  			ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
>  			ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
> -					ip - map->unmap_ip(map, sym->start));
> +					ip - map__unmap_ip(map, sym->start));
>  		} else {
>  			ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
>  					       width - ret,
> @@ -2104,9 +2104,9 @@ sort__addr_cmp(struct hist_entry *left, struct hist_entry *right)
>  	struct map *right_map = right->ms.map;
>  
>  	if (left_map)
> -		left_ip = left_map->unmap_ip(left_map, left_ip);
> +		left_ip = map__unmap_ip(left_map, left_ip);
>  	if (right_map)
> -		right_ip = right_map->unmap_ip(right_map, right_ip);
> +		right_ip = map__unmap_ip(right_map, right_ip);
>  
>  	return _sort__addr_cmp(left_ip, right_ip);
>  }
> @@ -2118,7 +2118,7 @@ static int hist_entry__addr_snprintf(struct hist_entry *he, char *bf,
>  	struct map *map = he->ms.map;
>  
>  	if (map)
> -		ip = map->unmap_ip(map, ip);
> +		ip = map__unmap_ip(map, ip);
>  
>  	return repsep_snprintf(bf, size, "%-#*llx", width, ip);
>  }
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index b91deb177091..9ba49c1ef6ef 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -896,8 +896,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct 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 = curr_map->map_ip(curr_map, pos->start);
> -			pos->end   = curr_map->map_ip(curr_map, pos->end);
> +			pos->start = map__map_ip(curr_map, pos->start);
> +			pos->end   = map__map_ip(curr_map, pos->end);
>  		} else if (x86_64 && is_entry_trampoline(pos->name)) {
>  			/*
>  			 * These symbols are not needed anymore since the
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index bb7a2ce82d46..4b5bdc277baa 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -464,7 +464,7 @@ int thread__memcpy(struct thread *thread, struct machine *machine,
>  	if( !dso || dso->data.status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0)
>  		return -1;
>  
> -	offset = al.map->map_ip(al.map, ip);
> +	offset = map__map_ip(al.map, ip);
>  	if (is64bit)
>  		*is64bit = dso->is_64_bit;
>  
> 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 = 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;
>  }
>  
> diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
> index 1c13f43e7d22..f9a52af48de4 100644
> --- a/tools/perf/util/unwind-libunwind-local.c
> +++ b/tools/perf/util/unwind-libunwind-local.c
> @@ -640,7 +640,7 @@ static int entry(u64 ip, struct thread *thread,
>  	pr_debug("unwind: %s:ip = 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 cb(&e, arg);
>  }
> -- 
> 2.40.0.348.gf938b09366-goog
> 

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v6 02/12] perf map: Add helper for map_ip and unmap_ip
  2023-04-07  1:06   ` Arnaldo Carvalho de Melo
@ 2023-04-07  1:12     ` Ian Rogers
  2023-04-07  2:05       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 19+ messages in thread
From: Ian Rogers @ 2023-04-07  1:12 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, 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,
	linux-kernel, Eric Dumazet, Dmitry Vyukov, Hao Luo,
	Stephane Eranian

On Thu, Apr 6, 2023 at 6:06 PM Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
>
> Em Tue, Apr 04, 2023 at 01:59:44PM -0700, Ian Rogers escreveu:
> > 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.
>
> Fixing these:
>
> ⬢[acme@toolbox perf-tools-next]$ find tools/perf/ -name "*.[ch]" | xargs grep -- '->map_ip('
> tools/perf/arch/s390/annotate/instructions.c:       map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> tools/perf/util/cs-etm.c:       offset = al.map->map_ip(al.map, address);

Agreed on fixing these.

> tools/perf/util/annotate.c:         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> tools/perf/util/annotate.c:         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==

Here the dispatched function pointer is from map and the first
argument is target.ms.map, so the helper function doesn't apply.

> tools/perf/util/map.c: * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
> tools/perf/util/map.h:  return map->map_ip(map, ip);

This is a comment and the helper definition.

> ⬢[acme@toolbox perf-tools-next]$
>
> ⬢[acme@toolbox perf-tools-next]$ find tools/perf/ -name "*.[ch]" | xargs grep -- '->unmap_ip('
> tools/perf/arch/powerpc/util/sym-handling.c:                    if (map->unmap_ip(map, sym->start) == tev->point.address) {

Agreed on fixing this.

Thanks,
Ian

> tools/perf/util/map.h:  return map->unmap_ip(map, ip);
> ⬢[acme@toolbox perf-tools-next]$
>
> > Signed-off-by: Ian Rogers <irogers@google.com>
> > ---
> >  tools/perf/arch/s390/annotate/instructions.c     |  3 ++-
> >  tools/perf/builtin-kallsyms.c                    |  2 +-
> >  tools/perf/builtin-kmem.c                        |  2 +-
> >  tools/perf/builtin-lock.c                        |  4 ++--
> >  tools/perf/builtin-script.c                      |  2 +-
> >  tools/perf/tests/vmlinux-kallsyms.c              | 10 +++++-----
> >  tools/perf/util/annotate.c                       | 16 +++++++++-------
> >  tools/perf/util/bpf_lock_contention.c            |  4 ++--
> >  tools/perf/util/dlfilter.c                       |  2 +-
> >  tools/perf/util/dso.c                            |  6 ++++--
> >  tools/perf/util/event.c                          |  8 ++++----
> >  tools/perf/util/evsel_fprintf.c                  |  2 +-
> >  tools/perf/util/intel-pt.c                       | 10 +++++-----
> >  tools/perf/util/machine.c                        | 16 ++++++++--------
> >  tools/perf/util/map.c                            | 10 +++++-----
> >  tools/perf/util/map.h                            | 10 ++++++++++
> >  tools/perf/util/maps.c                           |  8 ++++----
> >  tools/perf/util/probe-event.c                    |  8 ++++----
> >  .../util/scripting-engines/trace-event-python.c  |  2 +-
> >  tools/perf/util/sort.c                           | 12 ++++++------
> >  tools/perf/util/symbol.c                         |  4 ++--
> >  tools/perf/util/thread.c                         |  2 +-
> >  tools/perf/util/unwind-libdw.c                   |  2 +-
> >  tools/perf/util/unwind-libunwind-local.c         |  2 +-
> >  24 files changed, 81 insertions(+), 66 deletions(-)
> >
> > diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c
> > index 0e136630659e..6548933e8dc0 100644
> > --- a/tools/perf/arch/s390/annotate/instructions.c
> > +++ b/tools/perf/arch/s390/annotate/instructions.c
> > @@ -39,7 +39,8 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
> >       target.addr = map__objdump_2mem(map, ops->target.addr);
> >
> >       if (maps__find_ams(ms->maps, &target) == 0 &&
> > -         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> > +         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> > +         ops->target.addr)
> >               ops->target.sym = target.ms.sym;
> >
> >       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 = 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);
> >       }
> >
> > 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,
> >
> >               if (sym != NULL)
> >                       snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name,
> > -                              addr - map->unmap_ip(map, sym->start));
> > +                              addr - map__unmap_ip(map, sym->start));
> >               else
> >                       snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr);
> >               printf(" %-34s |", buf);
> > diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
> > index 32ec58fb80e4..04345b2e7101 100644
> > --- a/tools/perf/builtin-lock.c
> > +++ b/tools/perf/builtin-lock.c
> > @@ -900,7 +900,7 @@ static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip,
> >               return 0;
> >       }
> >
> > -     offset = map->map_ip(map, ip) - sym->start;
> > +     offset = map__map_ip(map, ip) - sym->start;
> >
> >       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;
> >                       }
> >
> > -                     addrs[filters.nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
> > +                     addrs[filters.nr_addrs++] = map__unmap_ip(kmap, sym->start);
> >                       filters.addrs = addrs;
> >               }
> >       }
> > diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> > index af0a69c7f41f..8fba247b798c 100644
> > --- a/tools/perf/builtin-script.c
> > +++ b/tools/perf/builtin-script.c
> > @@ -1088,7 +1088,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
> >       /* Load maps to ensure dso->is_64_bit has been updated */
> >       map__load(al.map);
> >
> > -     offset = al.map->map_ip(al.map, start);
> > +     offset = map__map_ip(al.map, start);
> >       len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,
> >                                   end - start + MAXINSN);
> >
> > 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"
> >
> > -#define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x))
> > +#define UM(x) map__unmap_ip(kallsyms_map, (x))
> >
> >  static bool is_ignored_symbol(const char *name, char type)
> >  {
> > @@ -221,8 +221,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
> >               if (sym->start == sym->end)
> >                       continue;
> >
> > -             mem_start = vmlinux_map->unmap_ip(vmlinux_map, sym->start);
> > -             mem_end = vmlinux_map->unmap_ip(vmlinux_map, sym->end);
> > +             mem_start = map__unmap_ip(vmlinux_map, sym->start);
> > +             mem_end = map__unmap_ip(vmlinux_map, sym->end);
> >
> >               first_pair = machine__find_kernel_symbol(&kallsyms, mem_start, NULL);
> >               pair = first_pair;
> > @@ -319,8 +319,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
> >       maps__for_each_entry(maps, rb_node) {
> >               struct map *pair, *map = rb_node->map;
> >
> > -             mem_start = vmlinux_map->unmap_ip(vmlinux_map, map__start(map));
> > -             mem_end = vmlinux_map->unmap_ip(vmlinux_map, map__end(map));
> > +             mem_start = map__unmap_ip(vmlinux_map, map__start(map));
> > +             mem_end = map__unmap_ip(vmlinux_map, map__end(map));
> >
> >               pair = maps__find(kallsyms.kmaps, mem_start);
> >               if (pair == NULL || pair->priv)
> > diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> > index b9cff782d7df..36acdd1bd379 100644
> > --- a/tools/perf/util/annotate.c
> > +++ b/tools/perf/util/annotate.c
> > @@ -272,7 +272,8 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s
> >       target.addr = map__objdump_2mem(map, ops->target.addr);
> >
> >       if (maps__find_ams(ms->maps, &target) == 0 &&
> > -         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> > +         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> > +         ops->target.addr)
> >               ops->target.sym = target.ms.sym;
> >
> >       return 0;
> > @@ -376,8 +377,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
> >       }
> >
> >       target.addr = map__objdump_2mem(map, ops->target.addr);
> > -     start = map->unmap_ip(map, sym->start),
> > -     end = map->unmap_ip(map, sym->end);
> > +     start = map__unmap_ip(map, sym->start);
> > +     end = map__unmap_ip(map, sym->end);
> >
> >       ops->target.outside = target.addr < start || target.addr > end;
> >
> > @@ -400,7 +401,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
> >        * the symbol searching and disassembly should be done.
> >        */
> >       if (maps__find_ams(ms->maps, &target) == 0 &&
> > -         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> > +         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> > +         ops->target.addr)
> >               ops->target.sym = target.ms.sym;
> >
> >       if (!ops->target.outside) {
> > @@ -881,7 +883,7 @@ static int __symbol__inc_addr_samples(struct map_symbol *ms,
> >       unsigned offset;
> >       struct sym_hist *h;
> >
> > -     pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->map, addr));
> > +     pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, addr));
> >
> >       if ((addr < sym->start || addr >= sym->end) &&
> >           (addr != sym->end || sym->start != sym->end)) {
> > @@ -1977,8 +1979,8 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
> >               return err;
> >
> >       pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\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));
> >
> >       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_lock_contention.c
> > index 8a5d0eb44189..2b3bc544aa3e 100644
> > --- a/tools/perf/util/bpf_lock_contention.c
> > +++ b/tools/perf/util/bpf_lock_contention.c
> > @@ -74,7 +74,7 @@ int lock_contention_prepare(struct lock_contention *con)
> >                               continue;
> >                       }
> >
> > -                     addrs[con->filters->nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
> > +                     addrs[con->filters->nr_addrs++] = map__unmap_ip(kmap, sym->start);
> >                       con->filters->addrs = addrs;
> >               }
> >               naddrs = con->filters->nr_addrs;
> > @@ -233,7 +233,7 @@ static const char *lock_contention_get_name(struct lock_contention *con,
> >       if (sym) {
> >               unsigned long offset;
> >
> > -             offset = kmap->map_ip(kmap, addr) - sym->start;
> > +             offset = map__map_ip(kmap, addr) - sym->start;
> >
> >               if (offset == 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)
> >
> >       map = a.map;
> >  have_map:
> > -     offset = map->map_ip(map, ip);
> > +     offset = map__map_ip(map, ip);
> >       if (ip + len >= map__end(map))
> >               len = 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 map *map,
> >                           struct machine *machine, u64 addr,
> >                           u8 *data, ssize_t size)
> >  {
> > -     u64 offset = map->map_ip(map, addr);
> > +     u64 offset = map__map_ip(map, addr);
> > +
> >       return dso__data_read_offset(dso, machine, offset, data, size);
> >  }
> >
> > @@ -1162,7 +1163,8 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
> >                                  struct machine *machine, u64 addr,
> >                                  const u8 *data, ssize_t size)
> >  {
> > -     u64 offset = map->map_ip(map, addr);
> > +     u64 offset = map__map_ip(map, addr);
> > +
> >       return dso__data_write_cache_offs(dso, machine, offset, data, size);
> >  }
> >
> > 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
> >
> >               al.map = maps__find(machine__kernel_maps(machine), tp->addr);
> >               if (al.map && map__load(al.map) >= 0) {
> > -                     al.addr = al.map->map_ip(al.map, tp->addr);
> > +                     al.addr = map__map_ip(al.map, tp->addr);
> >                       al.sym = map__find_symbol(al.map, al.addr);
> >                       if (al.sym)
> >                               ret += 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 = al->map->map_ip(al->map, al->addr);
> > +             al->addr = map__map_ip(al->map, al->addr);
> >       }
> >
> >       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 = strlist__has_entry(symbol_conf.sym_list,
> >                                               al_addr_str);
> >               }
> >               if (!ret && symbol_conf.addr_list && al->map) {
> > -                     unsigned long addr = al->map->unmap_ip(al->map, al->addr);
> > +                     unsigned long addr = map__unmap_ip(al->map, al->addr);
> >
> >                       ret = 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_fprintf.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 *sample, int left_alignment,
> >                               printed += fprintf(fp, " <-");
> >
> >                       if (map)
> > -                             addr = map->map_ip(map, node->ip);
> > +                             addr = map__map_ip(map, node->ip);
> >
> >                       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;
> >
> > -             offset = al.map->map_ip(al.map, *ip);
> > +             offset = map__map_ip(al.map, *ip);
> >
> >               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;
> >
> > -     offset = al.map->map_ip(al.map, ip);
> > +     offset = map__map_ip(al.map, ip);
> >
> >       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, u64 *ptss_ip)
> >       for (sym = start; sym; sym = dso__next_symbol(sym)) {
> >               if (sym->binding == STB_GLOBAL &&
> >                   !strcmp(sym->name, "__switch_to")) {
> > -                     ip = map->unmap_ip(map, sym->start);
> > +                     ip = map__unmap_ip(map, sym->start);
> >                       if (ip >= map__start(map) && ip < map__end(map)) {
> >                               switch_ip = ip;
> >                               break;
> > @@ -2767,7 +2767,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
> >
> >       for (sym = start; sym; sym = dso__next_symbol(sym)) {
> >               if (!strcmp(sym->name, ptss)) {
> > -                     ip = map->unmap_ip(map, sym->start);
> > +                     ip = map__unmap_ip(map, sym->start);
> >                       if (ip >= map__start(map) && ip < map__end(map)) {
> >                               *ptss_ip = ip;
> >                               break;
> > @@ -3393,7 +3393,7 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event)
> >               if (!dso || !dso->auxtrace_cache)
> >                       continue;
> >
> > -             offset = al.map->map_ip(al.map, addr);
> > +             offset = map__map_ip(al.map, addr);
> >
> >               e = intel_pt_cache_lookup(dso, machine, offset);
> >               if (!e)
> > diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> > index 9d24980a0a93..d29ec4a04488 100644
> > --- a/tools/perf/util/machine.c
> > +++ b/tools/perf/util/machine.c
> > @@ -919,7 +919,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
> >               dso = map__dso(map);
> >       }
> >
> > -     sym = symbol__new(map->map_ip(map, map__start(map)),
> > +     sym = symbol__new(map__map_ip(map, map__start(map)),
> >                         event->ksymbol.len,
> >                         0, 0, event->ksymbol.name);
> >       if (!sym)
> > @@ -944,7 +944,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine,
> >       else {
> >               struct dso *dso = map__dso(map);
> >
> > -             sym = dso__find_symbol(dso, map->map_ip(map, map__start(map)));
> > +             sym = dso__find_symbol(dso, map__map_ip(map, map__start(map)));
> >               if (sym)
> >                       dso__delete_symbol(dso, sym);
> >       }
> > @@ -1279,7 +1279,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,
> >
> >               dest_map = maps__find(kmaps, map->pgoff);
> >               if (dest_map != map)
> > -                     map->pgoff = dest_map->map_ip(dest_map, map->pgoff);
> > +                     map->pgoff = map__map_ip(dest_map, map->pgoff);
> >               found = true;
> >       }
> >       if (found || machine->trampolines_mapped)
> > @@ -3345,7 +3345,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch
> >               return NULL;
> >
> >       *modp = __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NULL;
> > -     *addrp = map->unmap_ip(map, sym->start);
> > +     *addrp = map__unmap_ip(map, sym->start);
> >       return sym->name;
> >  }
> >
> > @@ -3388,17 +3388,17 @@ bool machine__is_lock_function(struct machine *machine, u64 addr)
> >                       return false;
> >               }
> >
> > -             machine->sched.text_start = kmap->unmap_ip(kmap, sym->start);
> > +             machine->sched.text_start = map__unmap_ip(kmap, sym->start);
> >
> >               /* should not fail from here */
> >               sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_end", &kmap);
> > -             machine->sched.text_end = kmap->unmap_ip(kmap, sym->start);
> > +             machine->sched.text_end = map__unmap_ip(kmap, sym->start);
> >
> >               sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_start", &kmap);
> > -             machine->lock.text_start = kmap->unmap_ip(kmap, sym->start);
> > +             machine->lock.text_start = map__unmap_ip(kmap, sym->start);
> >
> >               sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_end", &kmap);
> > -             machine->lock.text_end = kmap->unmap_ip(kmap, sym->start);
> > +             machine->lock.text_end = map__unmap_ip(kmap, sym->start);
> >       }
> >
> >       /* 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 == DSO_SPACE__USER)
> >               return rip + dso->text_offset;
> >
> > -     return map->unmap_ip(map, rip) - map->reloc;
> > +     return map__unmap_ip(map, rip) - map->reloc;
> >  }
> >
> >  /**
> > @@ -539,24 +539,24 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
> >       const struct dso *dso = map__dso(map);
> >
> >       if (!dso->adjust_symbols)
> > -             return map->unmap_ip(map, ip);
> > +             return map__unmap_ip(map, ip);
> >
> >       if (dso->rel)
> > -             return map->unmap_ip(map, ip + map->pgoff);
> > +             return map__unmap_ip(map, ip + map->pgoff);
> >
> >       /*
> >        * 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 == DSO_SPACE__USER)
> > -             return map->unmap_ip(map, ip - dso->text_offset);
> > +             return map__unmap_ip(map, ip - dso->text_offset);
> >
> >       return ip + map->reloc;
> >  }
> >
> >  bool map__contains_symbol(const struct map *map, const struct symbol *sym)
> >  {
> > -     u64 ip = map->unmap_ip(map, sym->start);
> > +     u64 ip = map__unmap_ip(map, sym->start);
> >
> >       return ip >= 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;
> >  }
> >
> > +static inline u64 map__map_ip(const struct map *map, u64 ip)
> > +{
> > +     return map->map_ip(map, ip);
> > +}
> > +
> > +static inline u64 map__unmap_ip(const struct map *map, u64 ip)
> > +{
> > +     return map->unmap_ip(map, ip);
> > +}
> > +
> >  static inline u64 map__start(const struct map *map)
> >  {
> >       return map->start;
> > diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
> > index 21010a2b8e16..0eee27e24c33 100644
> > --- a/tools/perf/util/maps.c
> > +++ b/tools/perf/util/maps.c
> > @@ -194,7 +194,7 @@ struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp)
> >       if (map != NULL && map__load(map) >= 0) {
> >               if (mapp != NULL)
> >                       *mapp = map;
> > -             return map__find_symbol(map, map->map_ip(map, addr));
> > +             return map__find_symbol(map, map__map_ip(map, addr));
> >       }
> >
> >       return NULL;
> > @@ -237,7 +237,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams)
> >                       return -1;
> >       }
> >
> > -     ams->al_addr = ams->ms.map->map_ip(ams->ms.map, ams->addr);
> > +     ams->al_addr = map__map_ip(ams->ms.map, ams->addr);
> >       ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr);
> >
> >       return ams->ms.sym ? 0 : -1;
> > @@ -349,8 +349,8 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
> >
> >                       after->start = map__end(map);
> >                       after->pgoff += map__end(map) - map__start(pos->map);
> > -                     assert(pos->map->map_ip(pos->map, map__end(map)) ==
> > -                             after->map_ip(after, map__end(map)));
> > +                     assert(map__map_ip(pos->map, map__end(map)) ==
> > +                             map__map_ip(after, map__end(map)));
> >                       err = __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 = machine__find_kernel_symbol_by_name(host_machine, name, &map);
> >               if (!sym)
> >                       return -ENOENT;
> > -             *addr = map->unmap_ip(map, sym->start) -
> > +             *addr = 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 debuginfo *dinfo,
> >                                          "Consider identifying the final function used at run time and set the probe directly on that.\n",
> >                                          pp->function);
> >               } else
> > -                     address = map->unmap_ip(map, sym->start) - map->reloc;
> > +                     address = map__unmap_ip(map, sym->start) - map->reloc;
> >               break;
> >       }
> >       if (!address) {
> > @@ -2249,7 +2249,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
> >               goto out;
> >
> >       pp->retprobe = tp->retprobe;
> > -     pp->offset = addr - map->unmap_ip(map, sym->start);
> > +     pp->offset = addr - map__unmap_ip(map, sym->start);
> >       pp->function = strdup(sym->name);
> >       ret = pp->function ? 0 : -ENOMEM;
> >
> > @@ -3123,7 +3123,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
> >                       goto err_out;
> >               }
> >               /* Add one probe point */
> > -             tp->address = map->unmap_ip(map, sym->start) + pp->offset;
> > +             tp->address = map__unmap_ip(map, sym->start) + pp->offset;
> >
> >               /* 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_sample *sample,
> >                               struct addr_location node_al;
> >                               unsigned long offset;
> >
> > -                             node_al.addr = map->map_ip(map, node->ip);
> > +                             node_al.addr = map__map_ip(map, node->ip);
> >                               node_al.map  = map;
> >                               offset = get_offset(node->ms.sym, &node_al);
> >
> > diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> > index f161589aefda..87a3ba584af5 100644
> > --- a/tools/perf/util/sort.c
> > +++ b/tools/perf/util/sort.c
> > @@ -364,7 +364,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
> >               u64 rip = ip;
> >
> >               if (dso && dso->kernel && dso->adjust_symbols)
> > -                     rip = map->unmap_ip(map, ip);
> > +                     rip = map__unmap_ip(map, ip);
> >
> >               ret += repsep_snprintf(bf, size, "%-#*llx %c ",
> >                                      BITS_PER_LONG / 4 + 2, rip, o);
> > @@ -375,7 +375,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
> >               if (sym->type == STT_OBJECT) {
> >                       ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
> >                       ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
> > -                                     ip - map->unmap_ip(map, sym->start));
> > +                                     ip - map__unmap_ip(map, sym->start));
> >               } else {
> >                       ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
> >                                              width - ret,
> > @@ -1147,7 +1147,7 @@ static int _hist_entry__addr_snprintf(struct map_symbol *ms,
> >               if (sym->type == STT_OBJECT) {
> >                       ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
> >                       ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
> > -                                     ip - map->unmap_ip(map, sym->start));
> > +                                     ip - map__unmap_ip(map, sym->start));
> >               } else {
> >                       ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
> >                                              width - ret,
> > @@ -2104,9 +2104,9 @@ sort__addr_cmp(struct hist_entry *left, struct hist_entry *right)
> >       struct map *right_map = right->ms.map;
> >
> >       if (left_map)
> > -             left_ip = left_map->unmap_ip(left_map, left_ip);
> > +             left_ip = map__unmap_ip(left_map, left_ip);
> >       if (right_map)
> > -             right_ip = right_map->unmap_ip(right_map, right_ip);
> > +             right_ip = map__unmap_ip(right_map, right_ip);
> >
> >       return _sort__addr_cmp(left_ip, right_ip);
> >  }
> > @@ -2118,7 +2118,7 @@ static int hist_entry__addr_snprintf(struct hist_entry *he, char *bf,
> >       struct map *map = he->ms.map;
> >
> >       if (map)
> > -             ip = map->unmap_ip(map, ip);
> > +             ip = map__unmap_ip(map, ip);
> >
> >       return repsep_snprintf(bf, size, "%-#*llx", width, ip);
> >  }
> > diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> > index b91deb177091..9ba49c1ef6ef 100644
> > --- a/tools/perf/util/symbol.c
> > +++ b/tools/perf/util/symbol.c
> > @@ -896,8 +896,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct 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 = curr_map->map_ip(curr_map, pos->start);
> > -                     pos->end   = curr_map->map_ip(curr_map, pos->end);
> > +                     pos->start = map__map_ip(curr_map, pos->start);
> > +                     pos->end   = map__map_ip(curr_map, pos->end);
> >               } else if (x86_64 && is_entry_trampoline(pos->name)) {
> >                       /*
> >                        * These symbols are not needed anymore since the
> > diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> > index bb7a2ce82d46..4b5bdc277baa 100644
> > --- a/tools/perf/util/thread.c
> > +++ b/tools/perf/util/thread.c
> > @@ -464,7 +464,7 @@ int thread__memcpy(struct thread *thread, struct machine *machine,
> >       if( !dso || dso->data.status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0)
> >               return -1;
> >
> > -     offset = al.map->map_ip(al.map, ip);
> > +     offset = map__map_ip(al.map, ip);
> >       if (is64bit)
> >               *is64bit = dso->is_64_bit;
> >
> > 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 = 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;
> >  }
> >
> > diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
> > index 1c13f43e7d22..f9a52af48de4 100644
> > --- a/tools/perf/util/unwind-libunwind-local.c
> > +++ b/tools/perf/util/unwind-libunwind-local.c
> > @@ -640,7 +640,7 @@ static int entry(u64 ip, struct thread *thread,
> >       pr_debug("unwind: %s:ip = 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 cb(&e, arg);
> >  }
> > --
> > 2.40.0.348.gf938b09366-goog
> >
>
> --
>
> - Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v6 02/12] perf map: Add helper for map_ip and unmap_ip
  2023-04-07  1:12     ` Ian Rogers
@ 2023-04-07  2:05       ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-04-07  2:05 UTC (permalink / raw)
  To: Ian Rogers
  Cc: Peter Zijlstra, Ingo Molnar, 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,
	linux-kernel, Eric Dumazet, Dmitry Vyukov, Hao Luo,
	Stephane Eranian

Em Thu, Apr 06, 2023 at 06:12:13PM -0700, Ian Rogers escreveu:
> On Thu, Apr 6, 2023 at 6:06 PM Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> >
> > Em Tue, Apr 04, 2023 at 01:59:44PM -0700, Ian Rogers escreveu:
> > > 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.
> >
> > Fixing these:
> >
> > ⬢[acme@toolbox perf-tools-next]$ find tools/perf/ -name "*.[ch]" | xargs grep -- '->map_ip('
> > tools/perf/arch/s390/annotate/instructions.c:       map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> > tools/perf/util/cs-etm.c:       offset = al.map->map_ip(al.map, address);
> 
> Agreed on fixing these.
> 
> > tools/perf/util/annotate.c:         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> > tools/perf/util/annotate.c:         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> 
> Here the dispatched function pointer is from map and the first
> argument is target.ms.map, so the helper function doesn't apply.

But they are the same (ditto for jump__parse):

static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)
{
        char *endptr, *tok, *name;
        struct map *map = ms->map;
        struct addr_map_symbol target = {
                .ms = { .map = map, },
        };

        ops->target.addr = strtoull(ops->raw, &endptr, 16);

        name = strchr(endptr, '<');
        if (name == NULL)
                goto indirect_call;

        name++;

        if (arch->objdump.skip_functions_char &&
            strchr(name, arch->objdump.skip_functions_char))
                return -1;

        tok = strchr(name, '>');
        if (tok == NULL)
                return -1;

        *tok = '\0';
        ops->target.name = strdup(name);
        *tok = '>';

        if (ops->target.name == NULL)
                return -1;
find_target:
        target.addr = map__objdump_2mem(map, ops->target.addr);

        if (maps__find_ams(ms->maps, &target) == 0 &&
            map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr)
                ops->target.sym = target.ms.sym;

        return 0;

indirect_call:
        tok = strchr(endptr, '*');
        if (tok != NULL) {
                endptr++;

                /* Indirect call can use a non-rip register and offset: callq  *0x8(%rbx).
                 * Do not parse such instruction.  */
                if (strstr(endptr, "(%r") == NULL)
                        ops->target.addr = strtoull(endptr, NULL, 16);
        }
        goto find_target;
}
 
> > tools/perf/util/map.c: * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
> > tools/perf/util/map.h:  return map->map_ip(map, ip);
> 
> This is a comment and the helper definition.
> 
> > ⬢[acme@toolbox perf-tools-next]$
> >
> > ⬢[acme@toolbox perf-tools-next]$ find tools/perf/ -name "*.[ch]" | xargs grep -- '->unmap_ip('
> > tools/perf/arch/powerpc/util/sym-handling.c:                    if (map->unmap_ip(map, sym->start) == tev->point.address) {
> 
> Agreed on fixing this.
> 
> Thanks,
> Ian
> 
> > tools/perf/util/map.h:  return map->unmap_ip(map, ip);
> > ⬢[acme@toolbox perf-tools-next]$
> >
> > > Signed-off-by: Ian Rogers <irogers@google.com>
> > > ---
> > >  tools/perf/arch/s390/annotate/instructions.c     |  3 ++-
> > >  tools/perf/builtin-kallsyms.c                    |  2 +-
> > >  tools/perf/builtin-kmem.c                        |  2 +-
> > >  tools/perf/builtin-lock.c                        |  4 ++--
> > >  tools/perf/builtin-script.c                      |  2 +-
> > >  tools/perf/tests/vmlinux-kallsyms.c              | 10 +++++-----
> > >  tools/perf/util/annotate.c                       | 16 +++++++++-------
> > >  tools/perf/util/bpf_lock_contention.c            |  4 ++--
> > >  tools/perf/util/dlfilter.c                       |  2 +-
> > >  tools/perf/util/dso.c                            |  6 ++++--
> > >  tools/perf/util/event.c                          |  8 ++++----
> > >  tools/perf/util/evsel_fprintf.c                  |  2 +-
> > >  tools/perf/util/intel-pt.c                       | 10 +++++-----
> > >  tools/perf/util/machine.c                        | 16 ++++++++--------
> > >  tools/perf/util/map.c                            | 10 +++++-----
> > >  tools/perf/util/map.h                            | 10 ++++++++++
> > >  tools/perf/util/maps.c                           |  8 ++++----
> > >  tools/perf/util/probe-event.c                    |  8 ++++----
> > >  .../util/scripting-engines/trace-event-python.c  |  2 +-
> > >  tools/perf/util/sort.c                           | 12 ++++++------
> > >  tools/perf/util/symbol.c                         |  4 ++--
> > >  tools/perf/util/thread.c                         |  2 +-
> > >  tools/perf/util/unwind-libdw.c                   |  2 +-
> > >  tools/perf/util/unwind-libunwind-local.c         |  2 +-
> > >  24 files changed, 81 insertions(+), 66 deletions(-)
> > >
> > > diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c
> > > index 0e136630659e..6548933e8dc0 100644
> > > --- a/tools/perf/arch/s390/annotate/instructions.c
> > > +++ b/tools/perf/arch/s390/annotate/instructions.c
> > > @@ -39,7 +39,8 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops,
> > >       target.addr = map__objdump_2mem(map, ops->target.addr);
> > >
> > >       if (maps__find_ams(ms->maps, &target) == 0 &&
> > > -         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> > > +         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> > > +         ops->target.addr)
> > >               ops->target.sym = target.ms.sym;
> > >
> > >       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 = 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);
> > >       }
> > >
> > > 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,
> > >
> > >               if (sym != NULL)
> > >                       snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name,
> > > -                              addr - map->unmap_ip(map, sym->start));
> > > +                              addr - map__unmap_ip(map, sym->start));
> > >               else
> > >                       snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr);
> > >               printf(" %-34s |", buf);
> > > diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
> > > index 32ec58fb80e4..04345b2e7101 100644
> > > --- a/tools/perf/builtin-lock.c
> > > +++ b/tools/perf/builtin-lock.c
> > > @@ -900,7 +900,7 @@ static int get_symbol_name_offset(struct map *map, struct symbol *sym, u64 ip,
> > >               return 0;
> > >       }
> > >
> > > -     offset = map->map_ip(map, ip) - sym->start;
> > > +     offset = map__map_ip(map, ip) - sym->start;
> > >
> > >       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;
> > >                       }
> > >
> > > -                     addrs[filters.nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
> > > +                     addrs[filters.nr_addrs++] = map__unmap_ip(kmap, sym->start);
> > >                       filters.addrs = addrs;
> > >               }
> > >       }
> > > diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> > > index af0a69c7f41f..8fba247b798c 100644
> > > --- a/tools/perf/builtin-script.c
> > > +++ b/tools/perf/builtin-script.c
> > > @@ -1088,7 +1088,7 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
> > >       /* Load maps to ensure dso->is_64_bit has been updated */
> > >       map__load(al.map);
> > >
> > > -     offset = al.map->map_ip(al.map, start);
> > > +     offset = map__map_ip(al.map, start);
> > >       len = dso__data_read_offset(dso, machine, offset, (u8 *)buffer,
> > >                                   end - start + MAXINSN);
> > >
> > > 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"
> > >
> > > -#define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x))
> > > +#define UM(x) map__unmap_ip(kallsyms_map, (x))
> > >
> > >  static bool is_ignored_symbol(const char *name, char type)
> > >  {
> > > @@ -221,8 +221,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
> > >               if (sym->start == sym->end)
> > >                       continue;
> > >
> > > -             mem_start = vmlinux_map->unmap_ip(vmlinux_map, sym->start);
> > > -             mem_end = vmlinux_map->unmap_ip(vmlinux_map, sym->end);
> > > +             mem_start = map__unmap_ip(vmlinux_map, sym->start);
> > > +             mem_end = map__unmap_ip(vmlinux_map, sym->end);
> > >
> > >               first_pair = machine__find_kernel_symbol(&kallsyms, mem_start, NULL);
> > >               pair = first_pair;
> > > @@ -319,8 +319,8 @@ static int test__vmlinux_matches_kallsyms(struct test_suite *test __maybe_unused
> > >       maps__for_each_entry(maps, rb_node) {
> > >               struct map *pair, *map = rb_node->map;
> > >
> > > -             mem_start = vmlinux_map->unmap_ip(vmlinux_map, map__start(map));
> > > -             mem_end = vmlinux_map->unmap_ip(vmlinux_map, map__end(map));
> > > +             mem_start = map__unmap_ip(vmlinux_map, map__start(map));
> > > +             mem_end = map__unmap_ip(vmlinux_map, map__end(map));
> > >
> > >               pair = maps__find(kallsyms.kmaps, mem_start);
> > >               if (pair == NULL || pair->priv)
> > > diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
> > > index b9cff782d7df..36acdd1bd379 100644
> > > --- a/tools/perf/util/annotate.c
> > > +++ b/tools/perf/util/annotate.c
> > > @@ -272,7 +272,8 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s
> > >       target.addr = map__objdump_2mem(map, ops->target.addr);
> > >
> > >       if (maps__find_ams(ms->maps, &target) == 0 &&
> > > -         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> > > +         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> > > +         ops->target.addr)
> > >               ops->target.sym = target.ms.sym;
> > >
> > >       return 0;
> > > @@ -376,8 +377,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
> > >       }
> > >
> > >       target.addr = map__objdump_2mem(map, ops->target.addr);
> > > -     start = map->unmap_ip(map, sym->start),
> > > -     end = map->unmap_ip(map, sym->end);
> > > +     start = map__unmap_ip(map, sym->start);
> > > +     end = map__unmap_ip(map, sym->end);
> > >
> > >       ops->target.outside = target.addr < start || target.addr > end;
> > >
> > > @@ -400,7 +401,8 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s
> > >        * the symbol searching and disassembly should be done.
> > >        */
> > >       if (maps__find_ams(ms->maps, &target) == 0 &&
> > > -         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) == ops->target.addr)
> > > +         map__rip_2objdump(target.ms.map, map->map_ip(target.ms.map, target.addr)) ==
> > > +         ops->target.addr)
> > >               ops->target.sym = target.ms.sym;
> > >
> > >       if (!ops->target.outside) {
> > > @@ -881,7 +883,7 @@ static int __symbol__inc_addr_samples(struct map_symbol *ms,
> > >       unsigned offset;
> > >       struct sym_hist *h;
> > >
> > > -     pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, ms->map->unmap_ip(ms->map, addr));
> > > +     pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map__unmap_ip(ms->map, addr));
> > >
> > >       if ((addr < sym->start || addr >= sym->end) &&
> > >           (addr != sym->end || sym->start != sym->end)) {
> > > @@ -1977,8 +1979,8 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
> > >               return err;
> > >
> > >       pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\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));
> > >
> > >       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_lock_contention.c
> > > index 8a5d0eb44189..2b3bc544aa3e 100644
> > > --- a/tools/perf/util/bpf_lock_contention.c
> > > +++ b/tools/perf/util/bpf_lock_contention.c
> > > @@ -74,7 +74,7 @@ int lock_contention_prepare(struct lock_contention *con)
> > >                               continue;
> > >                       }
> > >
> > > -                     addrs[con->filters->nr_addrs++] = kmap->unmap_ip(kmap, sym->start);
> > > +                     addrs[con->filters->nr_addrs++] = map__unmap_ip(kmap, sym->start);
> > >                       con->filters->addrs = addrs;
> > >               }
> > >               naddrs = con->filters->nr_addrs;
> > > @@ -233,7 +233,7 @@ static const char *lock_contention_get_name(struct lock_contention *con,
> > >       if (sym) {
> > >               unsigned long offset;
> > >
> > > -             offset = kmap->map_ip(kmap, addr) - sym->start;
> > > +             offset = map__map_ip(kmap, addr) - sym->start;
> > >
> > >               if (offset == 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)
> > >
> > >       map = a.map;
> > >  have_map:
> > > -     offset = map->map_ip(map, ip);
> > > +     offset = map__map_ip(map, ip);
> > >       if (ip + len >= map__end(map))
> > >               len = 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 map *map,
> > >                           struct machine *machine, u64 addr,
> > >                           u8 *data, ssize_t size)
> > >  {
> > > -     u64 offset = map->map_ip(map, addr);
> > > +     u64 offset = map__map_ip(map, addr);
> > > +
> > >       return dso__data_read_offset(dso, machine, offset, data, size);
> > >  }
> > >
> > > @@ -1162,7 +1163,8 @@ ssize_t dso__data_write_cache_addr(struct dso *dso, struct map *map,
> > >                                  struct machine *machine, u64 addr,
> > >                                  const u8 *data, ssize_t size)
> > >  {
> > > -     u64 offset = map->map_ip(map, addr);
> > > +     u64 offset = map__map_ip(map, addr);
> > > +
> > >       return dso__data_write_cache_offs(dso, machine, offset, data, size);
> > >  }
> > >
> > > 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
> > >
> > >               al.map = maps__find(machine__kernel_maps(machine), tp->addr);
> > >               if (al.map && map__load(al.map) >= 0) {
> > > -                     al.addr = al.map->map_ip(al.map, tp->addr);
> > > +                     al.addr = map__map_ip(al.map, tp->addr);
> > >                       al.sym = map__find_symbol(al.map, al.addr);
> > >                       if (al.sym)
> > >                               ret += 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 = al->map->map_ip(al->map, al->addr);
> > > +             al->addr = map__map_ip(al->map, al->addr);
> > >       }
> > >
> > >       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 = strlist__has_entry(symbol_conf.sym_list,
> > >                                               al_addr_str);
> > >               }
> > >               if (!ret && symbol_conf.addr_list && al->map) {
> > > -                     unsigned long addr = al->map->unmap_ip(al->map, al->addr);
> > > +                     unsigned long addr = map__unmap_ip(al->map, al->addr);
> > >
> > >                       ret = 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_fprintf.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 *sample, int left_alignment,
> > >                               printed += fprintf(fp, " <-");
> > >
> > >                       if (map)
> > > -                             addr = map->map_ip(map, node->ip);
> > > +                             addr = map__map_ip(map, node->ip);
> > >
> > >                       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;
> > >
> > > -             offset = al.map->map_ip(al.map, *ip);
> > > +             offset = map__map_ip(al.map, *ip);
> > >
> > >               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;
> > >
> > > -     offset = al.map->map_ip(al.map, ip);
> > > +     offset = map__map_ip(al.map, ip);
> > >
> > >       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, u64 *ptss_ip)
> > >       for (sym = start; sym; sym = dso__next_symbol(sym)) {
> > >               if (sym->binding == STB_GLOBAL &&
> > >                   !strcmp(sym->name, "__switch_to")) {
> > > -                     ip = map->unmap_ip(map, sym->start);
> > > +                     ip = map__unmap_ip(map, sym->start);
> > >                       if (ip >= map__start(map) && ip < map__end(map)) {
> > >                               switch_ip = ip;
> > >                               break;
> > > @@ -2767,7 +2767,7 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip)
> > >
> > >       for (sym = start; sym; sym = dso__next_symbol(sym)) {
> > >               if (!strcmp(sym->name, ptss)) {
> > > -                     ip = map->unmap_ip(map, sym->start);
> > > +                     ip = map__unmap_ip(map, sym->start);
> > >                       if (ip >= map__start(map) && ip < map__end(map)) {
> > >                               *ptss_ip = ip;
> > >                               break;
> > > @@ -3393,7 +3393,7 @@ static int intel_pt_text_poke(struct intel_pt *pt, union perf_event *event)
> > >               if (!dso || !dso->auxtrace_cache)
> > >                       continue;
> > >
> > > -             offset = al.map->map_ip(al.map, addr);
> > > +             offset = map__map_ip(al.map, addr);
> > >
> > >               e = intel_pt_cache_lookup(dso, machine, offset);
> > >               if (!e)
> > > diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
> > > index 9d24980a0a93..d29ec4a04488 100644
> > > --- a/tools/perf/util/machine.c
> > > +++ b/tools/perf/util/machine.c
> > > @@ -919,7 +919,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
> > >               dso = map__dso(map);
> > >       }
> > >
> > > -     sym = symbol__new(map->map_ip(map, map__start(map)),
> > > +     sym = symbol__new(map__map_ip(map, map__start(map)),
> > >                         event->ksymbol.len,
> > >                         0, 0, event->ksymbol.name);
> > >       if (!sym)
> > > @@ -944,7 +944,7 @@ static int machine__process_ksymbol_unregister(struct machine *machine,
> > >       else {
> > >               struct dso *dso = map__dso(map);
> > >
> > > -             sym = dso__find_symbol(dso, map->map_ip(map, map__start(map)));
> > > +             sym = dso__find_symbol(dso, map__map_ip(map, map__start(map)));
> > >               if (sym)
> > >                       dso__delete_symbol(dso, sym);
> > >       }
> > > @@ -1279,7 +1279,7 @@ int machine__map_x86_64_entry_trampolines(struct machine *machine,
> > >
> > >               dest_map = maps__find(kmaps, map->pgoff);
> > >               if (dest_map != map)
> > > -                     map->pgoff = dest_map->map_ip(dest_map, map->pgoff);
> > > +                     map->pgoff = map__map_ip(dest_map, map->pgoff);
> > >               found = true;
> > >       }
> > >       if (found || machine->trampolines_mapped)
> > > @@ -3345,7 +3345,7 @@ char *machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, ch
> > >               return NULL;
> > >
> > >       *modp = __map__is_kmodule(map) ? (char *)map__dso(map)->short_name : NULL;
> > > -     *addrp = map->unmap_ip(map, sym->start);
> > > +     *addrp = map__unmap_ip(map, sym->start);
> > >       return sym->name;
> > >  }
> > >
> > > @@ -3388,17 +3388,17 @@ bool machine__is_lock_function(struct machine *machine, u64 addr)
> > >                       return false;
> > >               }
> > >
> > > -             machine->sched.text_start = kmap->unmap_ip(kmap, sym->start);
> > > +             machine->sched.text_start = map__unmap_ip(kmap, sym->start);
> > >
> > >               /* should not fail from here */
> > >               sym = machine__find_kernel_symbol_by_name(machine, "__sched_text_end", &kmap);
> > > -             machine->sched.text_end = kmap->unmap_ip(kmap, sym->start);
> > > +             machine->sched.text_end = map__unmap_ip(kmap, sym->start);
> > >
> > >               sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_start", &kmap);
> > > -             machine->lock.text_start = kmap->unmap_ip(kmap, sym->start);
> > > +             machine->lock.text_start = map__unmap_ip(kmap, sym->start);
> > >
> > >               sym = machine__find_kernel_symbol_by_name(machine, "__lock_text_end", &kmap);
> > > -             machine->lock.text_end = kmap->unmap_ip(kmap, sym->start);
> > > +             machine->lock.text_end = map__unmap_ip(kmap, sym->start);
> > >       }
> > >
> > >       /* 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 == DSO_SPACE__USER)
> > >               return rip + dso->text_offset;
> > >
> > > -     return map->unmap_ip(map, rip) - map->reloc;
> > > +     return map__unmap_ip(map, rip) - map->reloc;
> > >  }
> > >
> > >  /**
> > > @@ -539,24 +539,24 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
> > >       const struct dso *dso = map__dso(map);
> > >
> > >       if (!dso->adjust_symbols)
> > > -             return map->unmap_ip(map, ip);
> > > +             return map__unmap_ip(map, ip);
> > >
> > >       if (dso->rel)
> > > -             return map->unmap_ip(map, ip + map->pgoff);
> > > +             return map__unmap_ip(map, ip + map->pgoff);
> > >
> > >       /*
> > >        * 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 == DSO_SPACE__USER)
> > > -             return map->unmap_ip(map, ip - dso->text_offset);
> > > +             return map__unmap_ip(map, ip - dso->text_offset);
> > >
> > >       return ip + map->reloc;
> > >  }
> > >
> > >  bool map__contains_symbol(const struct map *map, const struct symbol *sym)
> > >  {
> > > -     u64 ip = map->unmap_ip(map, sym->start);
> > > +     u64 ip = map__unmap_ip(map, sym->start);
> > >
> > >       return ip >= 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;
> > >  }
> > >
> > > +static inline u64 map__map_ip(const struct map *map, u64 ip)
> > > +{
> > > +     return map->map_ip(map, ip);
> > > +}
> > > +
> > > +static inline u64 map__unmap_ip(const struct map *map, u64 ip)
> > > +{
> > > +     return map->unmap_ip(map, ip);
> > > +}
> > > +
> > >  static inline u64 map__start(const struct map *map)
> > >  {
> > >       return map->start;
> > > diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
> > > index 21010a2b8e16..0eee27e24c33 100644
> > > --- a/tools/perf/util/maps.c
> > > +++ b/tools/perf/util/maps.c
> > > @@ -194,7 +194,7 @@ struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp)
> > >       if (map != NULL && map__load(map) >= 0) {
> > >               if (mapp != NULL)
> > >                       *mapp = map;
> > > -             return map__find_symbol(map, map->map_ip(map, addr));
> > > +             return map__find_symbol(map, map__map_ip(map, addr));
> > >       }
> > >
> > >       return NULL;
> > > @@ -237,7 +237,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams)
> > >                       return -1;
> > >       }
> > >
> > > -     ams->al_addr = ams->ms.map->map_ip(ams->ms.map, ams->addr);
> > > +     ams->al_addr = map__map_ip(ams->ms.map, ams->addr);
> > >       ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr);
> > >
> > >       return ams->ms.sym ? 0 : -1;
> > > @@ -349,8 +349,8 @@ int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
> > >
> > >                       after->start = map__end(map);
> > >                       after->pgoff += map__end(map) - map__start(pos->map);
> > > -                     assert(pos->map->map_ip(pos->map, map__end(map)) ==
> > > -                             after->map_ip(after, map__end(map)));
> > > +                     assert(map__map_ip(pos->map, map__end(map)) ==
> > > +                             map__map_ip(after, map__end(map)));
> > >                       err = __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 = machine__find_kernel_symbol_by_name(host_machine, name, &map);
> > >               if (!sym)
> > >                       return -ENOENT;
> > > -             *addr = map->unmap_ip(map, sym->start) -
> > > +             *addr = 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 debuginfo *dinfo,
> > >                                          "Consider identifying the final function used at run time and set the probe directly on that.\n",
> > >                                          pp->function);
> > >               } else
> > > -                     address = map->unmap_ip(map, sym->start) - map->reloc;
> > > +                     address = map__unmap_ip(map, sym->start) - map->reloc;
> > >               break;
> > >       }
> > >       if (!address) {
> > > @@ -2249,7 +2249,7 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
> > >               goto out;
> > >
> > >       pp->retprobe = tp->retprobe;
> > > -     pp->offset = addr - map->unmap_ip(map, sym->start);
> > > +     pp->offset = addr - map__unmap_ip(map, sym->start);
> > >       pp->function = strdup(sym->name);
> > >       ret = pp->function ? 0 : -ENOMEM;
> > >
> > > @@ -3123,7 +3123,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
> > >                       goto err_out;
> > >               }
> > >               /* Add one probe point */
> > > -             tp->address = map->unmap_ip(map, sym->start) + pp->offset;
> > > +             tp->address = map__unmap_ip(map, sym->start) + pp->offset;
> > >
> > >               /* 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_sample *sample,
> > >                               struct addr_location node_al;
> > >                               unsigned long offset;
> > >
> > > -                             node_al.addr = map->map_ip(map, node->ip);
> > > +                             node_al.addr = map__map_ip(map, node->ip);
> > >                               node_al.map  = map;
> > >                               offset = get_offset(node->ms.sym, &node_al);
> > >
> > > diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> > > index f161589aefda..87a3ba584af5 100644
> > > --- a/tools/perf/util/sort.c
> > > +++ b/tools/perf/util/sort.c
> > > @@ -364,7 +364,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
> > >               u64 rip = ip;
> > >
> > >               if (dso && dso->kernel && dso->adjust_symbols)
> > > -                     rip = map->unmap_ip(map, ip);
> > > +                     rip = map__unmap_ip(map, ip);
> > >
> > >               ret += repsep_snprintf(bf, size, "%-#*llx %c ",
> > >                                      BITS_PER_LONG / 4 + 2, rip, o);
> > > @@ -375,7 +375,7 @@ static int _hist_entry__sym_snprintf(struct map_symbol *ms,
> > >               if (sym->type == STT_OBJECT) {
> > >                       ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
> > >                       ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
> > > -                                     ip - map->unmap_ip(map, sym->start));
> > > +                                     ip - map__unmap_ip(map, sym->start));
> > >               } else {
> > >                       ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
> > >                                              width - ret,
> > > @@ -1147,7 +1147,7 @@ static int _hist_entry__addr_snprintf(struct map_symbol *ms,
> > >               if (sym->type == STT_OBJECT) {
> > >                       ret += repsep_snprintf(bf + ret, size - ret, "%s", sym->name);
> > >                       ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx",
> > > -                                     ip - map->unmap_ip(map, sym->start));
> > > +                                     ip - map__unmap_ip(map, sym->start));
> > >               } else {
> > >                       ret += repsep_snprintf(bf + ret, size - ret, "%.*s",
> > >                                              width - ret,
> > > @@ -2104,9 +2104,9 @@ sort__addr_cmp(struct hist_entry *left, struct hist_entry *right)
> > >       struct map *right_map = right->ms.map;
> > >
> > >       if (left_map)
> > > -             left_ip = left_map->unmap_ip(left_map, left_ip);
> > > +             left_ip = map__unmap_ip(left_map, left_ip);
> > >       if (right_map)
> > > -             right_ip = right_map->unmap_ip(right_map, right_ip);
> > > +             right_ip = map__unmap_ip(right_map, right_ip);
> > >
> > >       return _sort__addr_cmp(left_ip, right_ip);
> > >  }
> > > @@ -2118,7 +2118,7 @@ static int hist_entry__addr_snprintf(struct hist_entry *he, char *bf,
> > >       struct map *map = he->ms.map;
> > >
> > >       if (map)
> > > -             ip = map->unmap_ip(map, ip);
> > > +             ip = map__unmap_ip(map, ip);
> > >
> > >       return repsep_snprintf(bf, size, "%-#*llx", width, ip);
> > >  }
> > > diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> > > index b91deb177091..9ba49c1ef6ef 100644
> > > --- a/tools/perf/util/symbol.c
> > > +++ b/tools/perf/util/symbol.c
> > > @@ -896,8 +896,8 @@ static int maps__split_kallsyms(struct maps *kmaps, struct 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 = curr_map->map_ip(curr_map, pos->start);
> > > -                     pos->end   = curr_map->map_ip(curr_map, pos->end);
> > > +                     pos->start = map__map_ip(curr_map, pos->start);
> > > +                     pos->end   = map__map_ip(curr_map, pos->end);
> > >               } else if (x86_64 && is_entry_trampoline(pos->name)) {
> > >                       /*
> > >                        * These symbols are not needed anymore since the
> > > diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> > > index bb7a2ce82d46..4b5bdc277baa 100644
> > > --- a/tools/perf/util/thread.c
> > > +++ b/tools/perf/util/thread.c
> > > @@ -464,7 +464,7 @@ int thread__memcpy(struct thread *thread, struct machine *machine,
> > >       if( !dso || dso->data.status == DSO_DATA_STATUS_ERROR || map__load(al.map) < 0)
> > >               return -1;
> > >
> > > -     offset = al.map->map_ip(al.map, ip);
> > > +     offset = map__map_ip(al.map, ip);
> > >       if (is64bit)
> > >               *is64bit = dso->is_64_bit;
> > >
> > > 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 = 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;
> > >  }
> > >
> > > diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
> > > index 1c13f43e7d22..f9a52af48de4 100644
> > > --- a/tools/perf/util/unwind-libunwind-local.c
> > > +++ b/tools/perf/util/unwind-libunwind-local.c
> > > @@ -640,7 +640,7 @@ static int entry(u64 ip, struct thread *thread,
> > >       pr_debug("unwind: %s:ip = 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 cb(&e, arg);
> > >  }
> > > --
> > > 2.40.0.348.gf938b09366-goog
> > >
> >
> > --
> >
> > - Arnaldo

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2023-04-07  2:07 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-04 20:59 [PATCH v6 00/12] Reference count checker and related fixes Ian Rogers
2023-04-04 20:59 ` [PATCH v6 01/12] perf map: Rename map_ip and unmap_ip Ian Rogers
2023-04-05 13:25   ` Arnaldo Carvalho de Melo
2023-04-05 13:32     ` Arnaldo Carvalho de Melo
2023-04-07  0:40       ` Ian Rogers
2023-04-04 20:59 ` [PATCH v6 02/12] perf map: Add helper for " Ian Rogers
2023-04-07  1:06   ` Arnaldo Carvalho de Melo
2023-04-07  1:12     ` Ian Rogers
2023-04-07  2:05       ` Arnaldo Carvalho de Melo
2023-04-04 20:59 ` [PATCH v6 03/12] perf map: Add accessors for prot, priv and flags Ian Rogers
2023-04-04 20:59 ` [PATCH v6 04/12] perf map: Add accessors for pgoff and reloc Ian Rogers
2023-04-04 20:59 ` [PATCH v6 05/12] perf test: Add extra diagnostics to maps test Ian Rogers
2023-04-04 20:59 ` [PATCH v6 06/12] perf maps: Modify maps_by_name to hold a reference to a map Ian Rogers
2023-04-04 20:59 ` [PATCH v6 07/12] perf map: Changes to reference counting Ian Rogers
2023-04-04 20:59 ` [PATCH v6 08/12] libperf: Add reference count checking macros Ian Rogers
2023-04-04 20:59 ` [PATCH v6 09/12] perf cpumap: Add reference count checking Ian Rogers
2023-04-04 20:59 ` [PATCH v6 10/12] perf namespaces: " Ian Rogers
2023-04-04 20:59 ` [PATCH v6 11/12] perf maps: " Ian Rogers
2023-04-04 20:59 ` [PATCH v6 12/12] perf map: " Ian Rogers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).