if (evlist) {
                perf_evlist__delete(evlist);
        } else {
-               cpu_map__delete(cpus);
+               cpu_map__put(cpus);
                thread_map__delete(threads);
        }
        machines__destroy_kernel_maps(&machines);
 
                perf_evlist__disable(evlist);
                perf_evlist__delete(evlist);
        } else {
-               cpu_map__delete(cpus);
+               cpu_map__put(cpus);
                thread_map__delete(threads);
        }
 
 
        cpus    = NULL;
        threads = NULL;
 out_free_cpus:
-       cpu_map__delete(cpus);
+       cpu_map__put(cpus);
 out_free_threads:
        thread_map__delete(threads);
        return err;
 
                perf_evlist__disable(evlist);
                perf_evlist__delete(evlist);
        } else {
-               cpu_map__delete(cpus);
+               cpu_map__put(cpus);
                thread_map__delete(threads);
        }
 
 
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "asm/bug.h"
 
 static struct cpu_map *cpu_map__default_new(void)
 {
                        cpus->map[i] = i;
 
                cpus->nr = nr_cpus;
+               atomic_set(&cpus->refcnt, 1);
        }
 
        return cpus;
        if (cpus != NULL) {
                cpus->nr = nr_cpus;
                memcpy(cpus->map, tmp_cpus, payload_size);
+               atomic_set(&cpus->refcnt, 1);
        }
 
        return cpus;
        if (cpus != NULL) {
                cpus->nr = 1;
                cpus->map[0] = -1;
+               atomic_set(&cpus->refcnt, 1);
        }
 
        return cpus;
 }
 
-void cpu_map__delete(struct cpu_map *map)
+static void cpu_map__delete(struct cpu_map *map)
 {
-       free(map);
+       if (map) {
+               WARN_ONCE(atomic_read(&map->refcnt) != 0,
+                         "cpu_map refcnt unbalanced\n");
+               free(map);
+       }
+}
+
+struct cpu_map *cpu_map__get(struct cpu_map *map)
+{
+       if (map)
+               atomic_inc(&map->refcnt);
+       return map;
+}
+
+void cpu_map__put(struct cpu_map *map)
+{
+       if (map && atomic_dec_and_test(&map->refcnt))
+               cpu_map__delete(map);
 }
 
 int cpu_map__get_socket(struct cpu_map *map, int idx)
        /* ensure we process id in increasing order */
        qsort(c->map, c->nr, sizeof(int), cmp_ids);
 
+       atomic_set(&cpus->refcnt, 1);
        *res = c;
        return 0;
 }
 
 
 #include <stdio.h>
 #include <stdbool.h>
+#include <linux/atomic.h>
 
 #include "perf.h"
 #include "util/debug.h"
 
 struct cpu_map {
+       atomic_t refcnt;
        int nr;
        int map[];
 };
 
 struct cpu_map *cpu_map__new(const char *cpu_list);
 struct cpu_map *cpu_map__dummy_new(void);
-void cpu_map__delete(struct cpu_map *map);
 struct cpu_map *cpu_map__read(FILE *file);
 size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
 int cpu_map__get_socket(struct cpu_map *map, int idx);
 int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp);
 int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep);
 
+struct cpu_map *cpu_map__get(struct cpu_map *map);
+void cpu_map__put(struct cpu_map *map);
+
 static inline int cpu_map__socket(struct cpu_map *sock, int s)
 {
        if (!sock || s > sock->nr || s < 0)
 
 {
        perf_evlist__munmap(evlist);
        perf_evlist__close(evlist);
-       cpu_map__delete(evlist->cpus);
+       cpu_map__put(evlist->cpus);
        thread_map__delete(evlist->threads);
        evlist->cpus = NULL;
        evlist->threads = NULL;
 out:
        return err;
 out_free_cpus:
-       cpu_map__delete(evlist->cpus);
+       cpu_map__put(evlist->cpus);
        evlist->cpus = NULL;
        goto out;
 }
 
        perf_evsel__free_fd(evsel);
        perf_evsel__free_id(evsel);
        close_cgroup(evsel->cgrp);
+       cpu_map__put(evsel->cpus);
        zfree(&evsel->group_name);
        zfree(&evsel->name);
        perf_evsel__object.fini(evsel);
 
 #include "parse-events-flex.h"
 #include "pmu.h"
 #include "thread_map.h"
+#include "cpumap.h"
 #include "asm/bug.h"
 
 #define MAX_NAME_LEN 100
        if (!evsel)
                return NULL;
 
-       evsel->cpus = cpus;
+       if (cpus)
+               evsel->cpus = cpu_map__get(cpus);
+
        if (name)
                evsel->name = strdup(name);
        list_add_tail(&evsel->node, list);
 
 
 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
 {
-       cpu_map__delete(pcpus->cpus);
+       cpu_map__put(pcpus->cpus);
        pcpus->ob_type->tp_free((PyObject*)pcpus);
 }
 
 
        if (!cpus)
                return false;
        cpu = cpus->map[0];
-       cpu_map__delete(cpus);
+       cpu_map__put(cpus);
 
        do {
                ret = perf_do_probe_api(fn, cpu, try[i++]);
                struct cpu_map *cpus = cpu_map__new(NULL);
 
                cpu =  cpus ? cpus->map[0] : 0;
-               cpu_map__delete(cpus);
+               cpu_map__put(cpus);
        } else {
                cpu = evlist->cpus->map[0];
        }
 
        err = 0;
 
 out_delete_map:
-       cpu_map__delete(map);
+       cpu_map__put(map);
        return err;
 }
 
 
                set_bit(c, cpumask_bits(b));
        }
 
-       cpu_map__delete(m);
+       cpu_map__put(m);
 
        return ret;
 }