}
        pr_debug("Bytes read match those read by objdump\n");
 out:
+       map__put(al.map);
        return err;
 }
 
 
                }
 
                fake_samples[i].thread = al.thread;
+               map__put(fake_samples[i].map);
                fake_samples[i].map = al.map;
                fake_samples[i].sym = al.sym;
        }
        }
 }
 
+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))
        /* tear down everything */
        evlist__delete(evlist);
        machines__exit(&machines);
+       put_fake_samples();
 
        return err;
 }
 
                        }
 
                        fake_samples[i].thread = al.thread;
+                       map__put(fake_samples[i].map);
                        fake_samples[i].map = al.map;
                        fake_samples[i].sym = al.sym;
                }
        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;
        evlist__delete(evlist);
        reset_output_field();
        machines__exit(&machines);
+       put_fake_samples();
 
        return err;
 }
 
 #include "evsel.h"
 #include "evlist.h"
 #include "machine.h"
+#include "map.h"
 #include "parse-events.h"
 #include "hists_common.h"
 #include "util/mmap.h"
                        }
 
                        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;
                }
        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++;
        evlist__delete(evlist);
        reset_output_field();
        machines__exit(&machines);
+       put_fake_samples();
 
        return err;
 }
 
                }
 
                fake_samples[i].thread = al.thread;
+               map__put(fake_samples[i].map);
                fake_samples[i].map = al.map;
                fake_samples[i].sym = al.sym;
        }
        }
 }
 
+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))
        /* tear down everything */
        evlist__delete(evlist);
        machines__exit(&machines);
+       put_fake_samples();
 
        return err;
 }
 
                }
 
                pr_debug("map %p, addr %" PRIx64 "\n", al.map, map__start(al.map));
+               map__put(al.map);
        }
 
        machine__delete_threads(machine);
 
                }
                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) {
        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;
        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;
                                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;
 
        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;
                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
  */
 void addr_location__put(struct addr_location *al)
 {
+       map__zput(al->map);
        thread__zput(al->thread);
 }
 
 
                        memset(&he->stat, 0, sizeof(he->stat));
        }
 
-       map__get(he->ms.map);
+       he->ms.map = map__get(he->ms.map);
 
        if (he->branch_info) {
                /*
                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)
 
        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;
                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);
 
        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,
                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);
        /* 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;
        map->end = start + size;
 
        dso__kernel_module_get_build_id(map__dso(map), machine->root_dir);
-
+       map__put(map);
        return 0;
 }
 
 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;
 }
 
 {
        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;
 
                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,
 
        map = memdup(from, size);
        if (map != NULL) {
                refcount_set(&map->refcnt, 1);
-               dso__get(dso);
+               map->dso = dso__get(dso);
        }
 
        return map;