perf machine: Fix the lifetime of the VDSO temporary file
authorAdrian Hunter <adrian.hunter@intel.com>
Wed, 23 Jul 2014 11:23:00 +0000 (14:23 +0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 23 Jul 2014 20:14:39 +0000 (17:14 -0300)
The VDSO temporary file is unlinked when a session is deleted.  That
precludes the possibilities that there is no session or there is more
than one session.

Correctly the vdso belongs to the machine so put the information on
'struct machine' and get rid of the global variables.

Reviewed-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/53CF9B14.7040408@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/machine.c
tools/perf/util/machine.h
tools/perf/util/session.c
tools/perf/util/vdso.c
tools/perf/util/vdso.h

index a25f3ee1b5b37b2b5de8ef68e3531c8c9be5ff7a..65269b8ac1866da1133be1e6553c1b6f17c1c178 100644 (file)
@@ -8,6 +8,7 @@
 #include "sort.h"
 #include "strlist.h"
 #include "thread.h"
+#include "vdso.h"
 #include <stdbool.h>
 #include <symbol/kallsyms.h>
 #include "unwind.h"
@@ -23,6 +24,8 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
        INIT_LIST_HEAD(&machine->dead_threads);
        machine->last_match = NULL;
 
+       machine->vdso_info = NULL;
+
        machine->kmaps.machine = machine;
        machine->pid = pid;
 
@@ -105,6 +108,7 @@ void machine__exit(struct machine *machine)
        map_groups__exit(&machine->kmaps);
        dsos__delete(&machine->user_dsos);
        dsos__delete(&machine->kernel_dsos);
+       vdso__exit(machine);
        zfree(&machine->root_dir);
        zfree(&machine->current_tid);
 }
index 8771d0cbe9cb19d6801d3805649a82c3fb9c2252..b972824e62941fea709fdfc92dcf9bf6f80871e9 100644 (file)
@@ -20,6 +20,8 @@ union perf_event;
 
 extern const char *ref_reloc_sym_names[];
 
+struct vdso_info;
+
 struct machine {
        struct rb_node    rb_node;
        pid_t             pid;
@@ -28,6 +30,7 @@ struct machine {
        struct rb_root    threads;
        struct list_head  dead_threads;
        struct thread     *last_match;
+       struct vdso_info  *vdso_info;
        struct list_head  user_dsos;
        struct list_head  kernel_dsos;
        struct map_groups kmaps;
index d3da1055239f81924f78d727002c74b1be1dadb6..fab5838c06be3e796bdd71d733f2dacc7844135a 100644 (file)
@@ -14,7 +14,6 @@
 #include "util.h"
 #include "cpumap.h"
 #include "perf_regs.h"
-#include "vdso.h"
 
 static int perf_session__open(struct perf_session *session)
 {
@@ -156,7 +155,6 @@ void perf_session__delete(struct perf_session *session)
        if (session->file)
                perf_data_file__close(session->file);
        free(session);
-       vdso__exit();
 }
 
 static int process_event_synth_tracing_data_stub(struct perf_tool *tool
index 75245f081b600c2dd6a22d288c3430a78965c2b1..fdaccaf673712e90009c3c05f033742303dff783 100644 (file)
@@ -28,14 +28,17 @@ struct vdso_info {
        struct vdso_file vdso;
 };
 
-static struct vdso_info vdso_info_ = {
-       .vdso = {
-               .temp_file_name = VDSO__TEMP_FILE_NAME,
-               .dso_name = VDSO__MAP_NAME,
-       },
-};
-
-static struct vdso_info *vdso_info = &vdso_info_;
+static struct vdso_info *vdso_info__new(void)
+{
+       static const struct vdso_info vdso_info_init = {
+               .vdso    = {
+                       .temp_file_name = VDSO__TEMP_FILE_NAME,
+                       .dso_name = VDSO__MAP_NAME,
+               },
+       };
+
+       return memdup(&vdso_info_init, sizeof(vdso_info_init));
+}
 
 static int find_vdso_map(void **start, void **end)
 {
@@ -105,16 +108,32 @@ static char *get_file(struct vdso_file *vdso_file)
        return vdso;
 }
 
-void vdso__exit(void)
+void vdso__exit(struct machine *machine)
 {
+       struct vdso_info *vdso_info = machine->vdso_info;
+
+       if (!vdso_info)
+               return;
+
        if (vdso_info->vdso.found)
                unlink(vdso_info->vdso.temp_file_name);
+
+       zfree(&machine->vdso_info);
 }
 
 struct dso *vdso__dso_findnew(struct machine *machine)
 {
-       struct dso *dso = dsos__find(&machine->user_dsos, VDSO__MAP_NAME, true);
+       struct vdso_info *vdso_info;
+       struct dso *dso;
+
+       if (!machine->vdso_info)
+               machine->vdso_info = vdso_info__new();
+
+       vdso_info = machine->vdso_info;
+       if (!vdso_info)
+               return NULL;
 
+       dso = dsos__find(&machine->user_dsos, VDSO__MAP_NAME, true);
        if (!dso) {
                char *file;
 
index 9ab0738b6752b1fb8c9aafdd677a84c6cda11145..7cf1576863a4ccc61faf9450493a29d608e2ba29 100644 (file)
@@ -15,6 +15,6 @@ static inline bool is_vdso_map(const char *filename)
 struct machine;
 
 struct dso *vdso__dso_findnew(struct machine *machine);
-void vdso__exit(void);
+void vdso__exit(struct machine *machine);
 
 #endif /* __PERF_VDSO__ */