perf session: Free the ref_reloc_sym memory at the right place
Which is at perf_session__destroy_kernel_maps, counterpart to the
perf_session__create_kernel_maps where the kmap structure is located, just
after the vmlinux_maps.
Make it also check if the kernel maps were actually created, which may not
be the case if, for instance, perf_session__new can't complete due to
permission problems in, for instance, a 'perf report' case, when a
segfault will take place, that is how this was noticed.
The problem was introduced in d65a458
, thus post .35.
This also adds code to release guest machines as them are also created
in perf_session__create_kernel_maps, so should be deleted on this newly
introduced counterpart, perf_session__destroy_kernel_maps.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
@@ -2107,6 +2107,36 @@ int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void machine__destroy_kernel_maps(struct machine *self)
|
||||
{
|
||||
enum map_type type;
|
||||
|
||||
for (type = 0; type < MAP__NR_TYPES; ++type) {
|
||||
struct kmap *kmap;
|
||||
|
||||
if (self->vmlinux_maps[type] == NULL)
|
||||
continue;
|
||||
|
||||
kmap = map__kmap(self->vmlinux_maps[type]);
|
||||
map_groups__remove(&self->kmaps, self->vmlinux_maps[type]);
|
||||
if (kmap->ref_reloc_sym) {
|
||||
/*
|
||||
* ref_reloc_sym is shared among all maps, so free just
|
||||
* on one of them.
|
||||
*/
|
||||
if (type == MAP__FUNCTION) {
|
||||
free((char *)kmap->ref_reloc_sym->name);
|
||||
kmap->ref_reloc_sym->name = NULL;
|
||||
free(kmap->ref_reloc_sym);
|
||||
}
|
||||
kmap->ref_reloc_sym = NULL;
|
||||
}
|
||||
|
||||
map__delete(self->vmlinux_maps[type]);
|
||||
self->vmlinux_maps[type] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int machine__create_kernel_maps(struct machine *self)
|
||||
{
|
||||
struct dso *kernel = machine__create_kernel(self);
|
||||
@@ -2351,6 +2381,19 @@ failure:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void machines__destroy_guest_kernel_maps(struct rb_root *self)
|
||||
{
|
||||
struct rb_node *next = rb_first(self);
|
||||
|
||||
while (next) {
|
||||
struct machine *pos = rb_entry(next, struct machine, rb_node);
|
||||
|
||||
next = rb_next(&pos->rb_node);
|
||||
rb_erase(&pos->rb_node, self);
|
||||
machine__delete(pos);
|
||||
}
|
||||
}
|
||||
|
||||
int machine__load_kallsyms(struct machine *self, const char *filename,
|
||||
enum map_type type, symbol_filter_t filter)
|
||||
{
|
||||
|
Reference in New Issue
Block a user