summaryrefslogtreecommitdiff
path: root/tools/perf/util/machine.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/machine.c')
-rw-r--r--tools/perf/util/machine.c79
1 files changed, 48 insertions, 31 deletions
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,