perf record: Save DSO build-ID for synthesizing
authorNamhyung Kim <namhyung@kernel.org>
Tue, 20 Sep 2022 22:28:22 +0000 (15:28 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 6 Oct 2022 14:12:14 +0000 (11:12 -0300)
When synthesizing MMAP2 with build-id, it'd read the same file repeatedly as
it has no idea if it's done already.  Maintain a dsos to check that and skip
the file access if possible.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220920222822.2171056-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/synthetic-events.c

index 289ea17..cccd293 100644 (file)
@@ -364,11 +364,14 @@ static bool read_proc_maps_line(struct io *io, __u64 *start, __u64 *end,
 }
 
 static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event,
+                                            struct machine *machine,
                                             bool is_kernel)
 {
        struct build_id bid;
        struct nsinfo *nsi;
        struct nscookie nc;
+       struct dso *dso = NULL;
+       struct dso_id id;
        int rc;
 
        if (is_kernel) {
@@ -376,6 +379,18 @@ static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event,
                goto out;
        }
 
+       id.maj = event->maj;
+       id.min = event->min;
+       id.ino = event->ino;
+       id.ino_generation = event->ino_generation;
+
+       dso = dsos__findnew_id(&machine->dsos, event->filename, &id);
+       if (dso && dso->has_build_id) {
+               bid = dso->bid;
+               rc = 0;
+               goto out;
+       }
+
        nsi = nsinfo__new(event->pid);
        nsinfo__mountns_enter(nsi, &nc);
 
@@ -391,12 +406,16 @@ out:
                event->header.misc |= PERF_RECORD_MISC_MMAP_BUILD_ID;
                event->__reserved_1 = 0;
                event->__reserved_2 = 0;
+
+               if (dso && !dso->has_build_id)
+                       dso__set_build_id(dso, &bid);
        } else {
                if (event->filename[0] == '/') {
                        pr_debug2("Failed to read build ID for %s\n",
                                  event->filename);
                }
        }
+       dso__put(dso);
 }
 
 int perf_event__synthesize_mmap_events(struct perf_tool *tool,
@@ -507,7 +526,7 @@ out:
                event->mmap2.tid = pid;
 
                if (symbol_conf.buildid_mmap2)
-                       perf_record_mmap2__read_build_id(&event->mmap2, false);
+                       perf_record_mmap2__read_build_id(&event->mmap2, machine, false);
 
                if (perf_tool__process_synth_event(tool, event, machine, process) != 0) {
                        rc = -1;
@@ -690,7 +709,7 @@ int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t
                        memcpy(event->mmap2.filename, pos->dso->long_name,
                               pos->dso->long_name_len + 1);
 
-                       perf_record_mmap2__read_build_id(&event->mmap2, false);
+                       perf_record_mmap2__read_build_id(&event->mmap2, machine, false);
                } else {
                        size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
                        event->mmap.header.type = PERF_RECORD_MMAP;
@@ -1126,7 +1145,7 @@ static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
                event->mmap2.len   = map->end - event->mmap.start;
                event->mmap2.pid   = machine->pid;
 
-               perf_record_mmap2__read_build_id(&event->mmap2, true);
+               perf_record_mmap2__read_build_id(&event->mmap2, machine, true);
        } else {
                size = snprintf(event->mmap.filename, sizeof(event->mmap.filename),
                                "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1;