diff options
author | Jiri Olsa <jolsa@redhat.com> | 2011-06-01 15:43:46 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-08-11 07:58:03 -0400 |
commit | f57b05ed532ccf3b3e22878a5678ca10de50ad29 (patch) | |
tree | 97fed90fc6181939af5a29dfc9624163832b34e6 /tools/perf/util/symbol.c | |
parent | fc8ed7be738ffb1b3b0140ed2de6def38b9a7101 (diff) |
perf report: Use properly build_id kernel binaries
If we bring the recorded perf data together with kernel binary from another
machine using:
on server A:
perf archive
on server B:
tar xjvf perf.data.tar.bz2 -C ~/.debug
the build_id kernel dso is not properly recognized during the "perf report"
command on server B.
The reason is, that build_id dsos are added during the session initialization,
while the kernel maps are created during the sample event processing.
The machine__create_kernel_maps functions ends up creating new dso object for
kernel, but it does not check if we already have one added by build_id
processing.
Also the build_id reading ABI quirk added in commit:
- commit b25114817a73bbd2b84ce9dba02ee1ef8989a947
perf build-id: Add quirk to deal with perf.data file format breakage
populates the "struct build_id_event::pid" with 0, which
is later interpreted as DEFAULT_GUEST_KERNEL_ID.
This is not always correct, so it's better to guess the pid
value based on the "struct build_id_event::header::misc" value.
- Tested with data generated on x86 kernel version v2.6.34
and reported back on x86_64 current kernel.
- Not tested for guest kernel case.
Note the problem stays for PERF_RECORD_MMAP events recorded by perf that
does not use proper pid (HOST_KERNEL_ID/DEFAULT_GUEST_KERNEL_ID). They are
misinterpreted within the current perf code. Probably there's not much we
can do about that.
Cc: Avi Kivity <avi@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Yanmin Zhang <yanmin_zhang@linux.intel.com>
Link: http://lkml.kernel.org/r/20110601194346.GB1934@jolsa.brq.redhat.com
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r-- | tools/perf/util/symbol.c | 57 |
1 files changed, 32 insertions, 25 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a8b53714542a..e142c21ae9a5 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -2181,27 +2181,22 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *machines, | |||
2181 | return ret; | 2181 | return ret; |
2182 | } | 2182 | } |
2183 | 2183 | ||
2184 | struct dso *dso__new_kernel(const char *name) | 2184 | static struct dso* |
2185 | dso__kernel_findnew(struct machine *machine, const char *name, | ||
2186 | const char *short_name, int dso_type) | ||
2185 | { | 2187 | { |
2186 | struct dso *dso = dso__new(name ?: "[kernel.kallsyms]"); | 2188 | /* |
2187 | 2189 | * The kernel dso could be created by build_id processing. | |
2188 | if (dso != NULL) { | 2190 | */ |
2189 | dso__set_short_name(dso, "[kernel]"); | 2191 | struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); |
2190 | dso->kernel = DSO_TYPE_KERNEL; | ||
2191 | } | ||
2192 | |||
2193 | return dso; | ||
2194 | } | ||
2195 | 2192 | ||
2196 | static struct dso *dso__new_guest_kernel(struct machine *machine, | 2193 | /* |
2197 | const char *name) | 2194 | * We need to run this in all cases, since during the build_id |
2198 | { | 2195 | * processing we had no idea this was the kernel dso. |
2199 | char bf[PATH_MAX]; | 2196 | */ |
2200 | struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf, | ||
2201 | sizeof(bf))); | ||
2202 | if (dso != NULL) { | 2197 | if (dso != NULL) { |
2203 | dso__set_short_name(dso, "[guest.kernel]"); | 2198 | dso__set_short_name(dso, short_name); |
2204 | dso->kernel = DSO_TYPE_GUEST_KERNEL; | 2199 | dso->kernel = dso_type; |
2205 | } | 2200 | } |
2206 | 2201 | ||
2207 | return dso; | 2202 | return dso; |
@@ -2219,24 +2214,36 @@ void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) | |||
2219 | dso->has_build_id = true; | 2214 | dso->has_build_id = true; |
2220 | } | 2215 | } |
2221 | 2216 | ||
2222 | static struct dso *machine__create_kernel(struct machine *machine) | 2217 | static struct dso *machine__get_kernel(struct machine *machine) |
2223 | { | 2218 | { |
2224 | const char *vmlinux_name = NULL; | 2219 | const char *vmlinux_name = NULL; |
2225 | struct dso *kernel; | 2220 | struct dso *kernel; |
2226 | 2221 | ||
2227 | if (machine__is_host(machine)) { | 2222 | if (machine__is_host(machine)) { |
2228 | vmlinux_name = symbol_conf.vmlinux_name; | 2223 | vmlinux_name = symbol_conf.vmlinux_name; |
2229 | kernel = dso__new_kernel(vmlinux_name); | 2224 | if (!vmlinux_name) |
2225 | vmlinux_name = "[kernel.kallsyms]"; | ||
2226 | |||
2227 | kernel = dso__kernel_findnew(machine, vmlinux_name, | ||
2228 | "[kernel]", | ||
2229 | DSO_TYPE_KERNEL); | ||
2230 | } else { | 2230 | } else { |
2231 | char bf[PATH_MAX]; | ||
2232 | |||
2231 | if (machine__is_default_guest(machine)) | 2233 | if (machine__is_default_guest(machine)) |
2232 | vmlinux_name = symbol_conf.default_guest_vmlinux_name; | 2234 | vmlinux_name = symbol_conf.default_guest_vmlinux_name; |
2233 | kernel = dso__new_guest_kernel(machine, vmlinux_name); | 2235 | if (!vmlinux_name) |
2236 | vmlinux_name = machine__mmap_name(machine, bf, | ||
2237 | sizeof(bf)); | ||
2238 | |||
2239 | kernel = dso__kernel_findnew(machine, vmlinux_name, | ||
2240 | "[guest.kernel]", | ||
2241 | DSO_TYPE_GUEST_KERNEL); | ||
2234 | } | 2242 | } |
2235 | 2243 | ||
2236 | if (kernel != NULL) { | 2244 | if (kernel != NULL && (!kernel->has_build_id)) |
2237 | dso__read_running_kernel_build_id(kernel, machine); | 2245 | dso__read_running_kernel_build_id(kernel, machine); |
2238 | dsos__add(&machine->kernel_dsos, kernel); | 2246 | |
2239 | } | ||
2240 | return kernel; | 2247 | return kernel; |
2241 | } | 2248 | } |
2242 | 2249 | ||
@@ -2340,7 +2347,7 @@ void machine__destroy_kernel_maps(struct machine *machine) | |||
2340 | 2347 | ||
2341 | int machine__create_kernel_maps(struct machine *machine) | 2348 | int machine__create_kernel_maps(struct machine *machine) |
2342 | { | 2349 | { |
2343 | struct dso *kernel = machine__create_kernel(machine); | 2350 | struct dso *kernel = machine__get_kernel(machine); |
2344 | 2351 | ||
2345 | if (kernel == NULL || | 2352 | if (kernel == NULL || |
2346 | __machine__create_kernel_maps(machine, kernel) < 0) | 2353 | __machine__create_kernel_maps(machine, kernel) < 0) |