summaryrefslogtreecommitdiff
path: root/tools/perf/util/vdso.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 16:09:53 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-04 16:09:53 -0700
commitef35ad26f8ff44d2c93e29952cdb336bda729d9d (patch)
treee2921072b9f4d820b18d6e5bc489b64ef2068668 /tools/perf/util/vdso.c
parent8efb90cf1e80129fad197b916714e1d01ee183d2 (diff)
parentf9b9f812235d53f774a083e88a5a23b517a69752 (diff)
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf changes from Ingo Molnar: "Kernel side changes: - Consolidate the PMU interrupt-disabled code amongst architectures (Vince Weaver) - misc fixes Tooling changes (new features, user visible changes): - Add support for pagefault tracing in 'trace', please see multiple examples in the changeset messages (Stanislav Fomichev). - Add pagefault statistics in 'trace' (Stanislav Fomichev) - Add header for columns in 'top' and 'report' TUI browsers (Jiri Olsa) - Add pagefault statistics in 'trace' (Stanislav Fomichev) - Add IO mode into timechart command (Stanislav Fomichev) - Fallback to syscalls:* when raw_syscalls:* is not available in the perl and python perf scripts. (Daniel Bristot de Oliveira) - Add --repeat global option to 'perf bench' to be used in benchmarks such as the existing 'futex' one, that was modified to use it instead of a local option. (Davidlohr Bueso) - Fix fd -> pathname resolution in 'trace', be it using /proc or a vfs_getname probe point. (Arnaldo Carvalho de Melo) - Add suggestion of how to set perf_event_paranoid sysctl, to help non-root users trying tools like 'trace' to get a working environment. (Arnaldo Carvalho de Melo) - Updates from trace-cmd for traceevent plugin_kvm plus args cleanup (Steven Rostedt, Jan Kiszka) - Support S/390 in 'perf kvm stat' (Alexander Yarygin) Tooling infrastructure changes: - Allow reserving a row for header purposes in the hists browser (Arnaldo Carvalho de Melo) - Various fixes and prep work related to supporting Intel PT (Adrian Hunter) - Introduce multiple debug variables control (Jiri Olsa) - Add callchain and additional sample information for python scripts (Joseph Schuchart) - More prep work to support Intel PT: (Adrian Hunter) - Polishing 'script' BTS output - 'inject' can specify --kallsym - VDSO is per machine, not a global var - Expose data addr lookup functions previously private to 'script' - Large mmap fixes in events processing - Include standard stringify macros in power pc code (Sukadev Bhattiprolu) Tooling cleanups: - Convert open coded equivalents to asprintf() (Andy Shevchenko) - Remove needless reassignments in 'trace' (Arnaldo Carvalho de Melo) - Cache the is_exit syscall test in 'trace) (Arnaldo Carvalho de Melo) - No need to reimplement err() in 'perf bench sched-messaging', drop barf(). (Davidlohr Bueso). - Remove ev_name argument from perf_evsel__hists_browse, can be obtained from the other parameters. (Jiri Olsa) Tooling fixes: - Fix memory leak in the 'sched-messaging' perf bench test. (Davidlohr Bueso) - The -o and -n 'perf bench mem' options are mutually exclusive, emit error when both are specified. (Davidlohr Bueso) - Fix scrollbar refresh row index in the ui browser, problem exposed now that headers will be added and will be allowed to be switched on/off. (Jiri Olsa) - Handle the num array type in python properly (Sebastian Andrzej Siewior) - Fix wrong condition for allocation failure (Jiri Olsa) - Adjust callchain based on DWARF debug info on powerpc (Sukadev Bhattiprolu) - Fix a risk for doing free on uninitialized pointer in traceevent lib (Rickard Strandqvist) - Update attr test with PERF_FLAG_FD_CLOEXEC flag (Jiri Olsa) - Enable close-on-exec flag on perf file descriptor (Yann Droneaud) - Fix build on gcc 4.4.7 (Arnaldo Carvalho de Melo) - Event ordering fixes (Jiri Olsa)" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (123 commits) Revert "perf tools: Fix jump label always changing during tracing" perf tools: Fix perf usage string leftover perf: Check permission only for parent tracepoint event perf record: Store PERF_RECORD_FINISHED_ROUND only for nonempty rounds perf record: Always force PERF_RECORD_FINISHED_ROUND event perf inject: Add --kallsyms parameter perf tools: Expose 'addr' functions so they can be reused perf session: Fix accounting of ordered samples queue perf powerpc: Include util/util.h and remove stringify macros perf tools: Fix build on gcc 4.4.7 perf tools: Add thread parameter to vdso__dso_findnew() perf tools: Add dso__type() perf tools: Separate the VDSO map name from the VDSO dso name perf tools: Add vdso__new() perf machine: Fix the lifetime of the VDSO temporary file perf tools: Group VDSO global variables into a structure perf session: Add ability to skip 4GiB or more perf session: Add ability to 'skip' a non-piped event stream perf tools: Pass machine to vdso__dso_findnew() perf tools: Add dso__data_size() ...
Diffstat (limited to 'tools/perf/util/vdso.c')
-rw-r--r--tools/perf/util/vdso.c97
1 files changed, 77 insertions, 20 deletions
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index 0ddb3b8a89ec..adca69384fcc 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -11,10 +11,34 @@
#include "vdso.h"
#include "util.h"
#include "symbol.h"
+#include "machine.h"
#include "linux/string.h"
+#include "debug.h"
-static bool vdso_found;
-static char vdso_file[] = "/tmp/perf-vdso.so-XXXXXX";
+#define VDSO__TEMP_FILE_NAME "/tmp/perf-vdso.so-XXXXXX"
+
+struct vdso_file {
+ bool found;
+ bool error;
+ char temp_file_name[sizeof(VDSO__TEMP_FILE_NAME)];
+ const char *dso_name;
+};
+
+struct vdso_info {
+ struct vdso_file vdso;
+};
+
+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 = DSO__NAME_VDSO,
+ },
+ };
+
+ return memdup(&vdso_info_init, sizeof(vdso_info_init));
+}
static int find_vdso_map(void **start, void **end)
{
@@ -47,7 +71,7 @@ static int find_vdso_map(void **start, void **end)
return !found;
}
-static char *get_file(void)
+static char *get_file(struct vdso_file *vdso_file)
{
char *vdso = NULL;
char *buf = NULL;
@@ -55,10 +79,10 @@ static char *get_file(void)
size_t size;
int fd;
- if (vdso_found)
- return vdso_file;
+ if (vdso_file->found)
+ return vdso_file->temp_file_name;
- if (find_vdso_map(&start, &end))
+ if (vdso_file->error || find_vdso_map(&start, &end))
return NULL;
size = end - start;
@@ -67,45 +91,78 @@ static char *get_file(void)
if (!buf)
return NULL;
- fd = mkstemp(vdso_file);
+ fd = mkstemp(vdso_file->temp_file_name);
if (fd < 0)
goto out;
if (size == (size_t) write(fd, buf, size))
- vdso = vdso_file;
+ vdso = vdso_file->temp_file_name;
close(fd);
out:
free(buf);
- vdso_found = (vdso != NULL);
+ vdso_file->found = (vdso != NULL);
+ vdso_file->error = !vdso_file->found;
return vdso;
}
-void vdso__exit(void)
+void vdso__exit(struct machine *machine)
{
- if (vdso_found)
- unlink(vdso_file);
+ 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 list_head *head)
+static struct dso *vdso__new(struct machine *machine, const char *short_name,
+ const char *long_name)
{
- struct dso *dso = dsos__find(head, VDSO__MAP_NAME, true);
+ struct dso *dso;
+ dso = dso__new(short_name);
+ if (dso != NULL) {
+ dsos__add(&machine->user_dsos, dso);
+ dso__set_long_name(dso, long_name, false);
+ }
+
+ return dso;
+}
+
+struct dso *vdso__dso_findnew(struct machine *machine,
+ struct thread *thread __maybe_unused)
+{
+ 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, DSO__NAME_VDSO, true);
if (!dso) {
char *file;
- file = get_file();
+ file = get_file(&vdso_info->vdso);
if (!file)
return NULL;
- dso = dso__new(VDSO__MAP_NAME);
- if (dso != NULL) {
- dsos__add(head, dso);
- dso__set_long_name(dso, file, false);
- }
+ dso = vdso__new(machine, DSO__NAME_VDSO, file);
}
return dso;
}
+
+bool dso__is_vdso(struct dso *dso)
+{
+ return !strcmp(dso->short_name, DSO__NAME_VDSO);
+}