aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2014-08-15 15:08:39 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-08-22 12:12:12 -0400
commitfbe2af45f6bd27ee69fd775303c936c3af4a4807 (patch)
treea3592cf08457e8f6735eec760ee2ee74c06d0866
parent4b99375b38fa137f501cfa60b70e3f0a9da39c93 (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.c6
-rw-r--r--tools/perf/util/machine.c23
-rw-r--r--tools/perf/util/machine.h17
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
1564int 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
50int machine__get_kernel_start(struct machine *machine);
51
52static 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
59static 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
49struct thread *machine__find_thread(struct machine *machine, pid_t pid, 66struct thread *machine__find_thread(struct machine *machine, pid_t pid,
50 pid_t tid); 67 pid_t tid);
51struct comm *machine__thread_exec_comm(struct machine *machine, 68struct comm *machine__thread_exec_comm(struct machine *machine,