diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2014-08-15 15:08:39 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-08-22 12:12:12 -0400 |
commit | fbe2af45f6bd27ee69fd775303c936c3af4a4807 (patch) | |
tree | a3592cf08457e8f6735eec760ee2ee74c06d0866 | |
parent | 4b99375b38fa137f501cfa60b70e3f0a9da39c93 (diff) |
perf tools: Add machine__kernel_ip()
Add a function to determine if an address is in the kernel. This is
based on the kernel function kernel_ip().
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/1408129739-17368-5-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/event.c | 6 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 23 | ||||
-rw-r--r-- | tools/perf/util/machine.h | 17 |
3 files changed, 43 insertions, 3 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 1398c83d896d..ed558191c0b3 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -784,9 +784,9 @@ try_again: | |||
784 | * "[vdso]" dso, but for now lets use the old trick of looking | 784 | * "[vdso]" dso, but for now lets use the old trick of looking |
785 | * in the whole kernel symbol list. | 785 | * in the whole kernel symbol list. |
786 | */ | 786 | */ |
787 | if ((long long)al->addr < 0 && | 787 | if (cpumode == PERF_RECORD_MISC_USER && machine && |
788 | cpumode == PERF_RECORD_MISC_USER && | 788 | mg != &machine->kmaps && |
789 | machine && mg != &machine->kmaps) { | 789 | machine__kernel_ip(machine, al->addr)) { |
790 | mg = &machine->kmaps; | 790 | mg = &machine->kmaps; |
791 | load_map = true; | 791 | load_map = true; |
792 | goto try_again; | 792 | goto try_again; |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 37f8dc557ec0..e00daf0d2bde 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -32,6 +32,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) | |||
32 | machine->symbol_filter = NULL; | 32 | machine->symbol_filter = NULL; |
33 | machine->id_hdr_size = 0; | 33 | machine->id_hdr_size = 0; |
34 | machine->comm_exec = false; | 34 | machine->comm_exec = false; |
35 | machine->kernel_start = 0; | ||
35 | 36 | ||
36 | machine->root_dir = strdup(root_dir); | 37 | machine->root_dir = strdup(root_dir); |
37 | if (machine->root_dir == NULL) | 38 | if (machine->root_dir == NULL) |
@@ -1559,3 +1560,25 @@ int machine__set_current_tid(struct machine *machine, int cpu, pid_t pid, | |||
1559 | 1560 | ||
1560 | return 0; | 1561 | return 0; |
1561 | } | 1562 | } |
1563 | |||
1564 | int machine__get_kernel_start(struct machine *machine) | ||
1565 | { | ||
1566 | struct map *map = machine__kernel_map(machine, MAP__FUNCTION); | ||
1567 | int err = 0; | ||
1568 | |||
1569 | /* | ||
1570 | * The only addresses above 2^63 are kernel addresses of a 64-bit | ||
1571 | * kernel. Note that addresses are unsigned so that on a 32-bit system | ||
1572 | * all addresses including kernel addresses are less than 2^32. In | ||
1573 | * that case (32-bit system), if the kernel mapping is unknown, all | ||
1574 | * addresses will be assumed to be in user space - see | ||
1575 | * machine__kernel_ip(). | ||
1576 | */ | ||
1577 | machine->kernel_start = 1ULL << 63; | ||
1578 | if (map) { | ||
1579 | err = map__load(map, machine->symbol_filter); | ||
1580 | if (map->start) | ||
1581 | machine->kernel_start = map->start; | ||
1582 | } | ||
1583 | return err; | ||
1584 | } | ||
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 61216e028319..6a6bcc1cff54 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h | |||
@@ -36,6 +36,7 @@ struct machine { | |||
36 | struct list_head kernel_dsos; | 36 | struct list_head kernel_dsos; |
37 | struct map_groups kmaps; | 37 | struct map_groups kmaps; |
38 | struct map *vmlinux_maps[MAP__NR_TYPES]; | 38 | struct map *vmlinux_maps[MAP__NR_TYPES]; |
39 | u64 kernel_start; | ||
39 | symbol_filter_t symbol_filter; | 40 | symbol_filter_t symbol_filter; |
40 | pid_t *current_tid; | 41 | pid_t *current_tid; |
41 | }; | 42 | }; |
@@ -46,6 +47,22 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type) | |||
46 | return machine->vmlinux_maps[type]; | 47 | return machine->vmlinux_maps[type]; |
47 | } | 48 | } |
48 | 49 | ||
50 | int machine__get_kernel_start(struct machine *machine); | ||
51 | |||
52 | static inline u64 machine__kernel_start(struct machine *machine) | ||
53 | { | ||
54 | if (!machine->kernel_start) | ||
55 | machine__get_kernel_start(machine); | ||
56 | return machine->kernel_start; | ||
57 | } | ||
58 | |||
59 | static inline bool machine__kernel_ip(struct machine *machine, u64 ip) | ||
60 | { | ||
61 | u64 kernel_start = machine__kernel_start(machine); | ||
62 | |||
63 | return ip >= kernel_start; | ||
64 | } | ||
65 | |||
49 | struct thread *machine__find_thread(struct machine *machine, pid_t pid, | 66 | struct thread *machine__find_thread(struct machine *machine, pid_t pid, |
50 | pid_t tid); | 67 | pid_t tid); |
51 | struct comm *machine__thread_exec_comm(struct machine *machine, | 68 | struct comm *machine__thread_exec_comm(struct machine *machine, |