aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-record.c6
-rw-r--r--tools/perf/util/header.c11
-rw-r--r--tools/perf/util/symbol.c59
3 files changed, 65 insertions, 11 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 699dd21..e9be6ae 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -202,7 +202,7 @@ static void sig_atexit(void)
if (child_pid > 0)
kill(child_pid, SIGTERM);
- if (signr == -1)
+ if (signr == -1 || signr == SIGUSR1)
return;
signal(signr, SIG_DFL);
@@ -535,6 +535,7 @@ static int __cmd_record(int argc, const char **argv)
atexit(sig_atexit);
signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler);
+ signal(SIGUSR1, sig_handler);
if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
perror("failed to create pipes");
@@ -629,6 +630,7 @@ static int __cmd_record(int argc, const char **argv)
execvp(argv[0], (char **)argv);
perror(argv[0]);
+ kill(getppid(), SIGUSR1);
exit(-1);
}
@@ -789,7 +791,7 @@ static int __cmd_record(int argc, const char **argv)
}
}
- if (quiet)
+ if (quiet || signr == SIGUSR1)
return 0;
fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 76e949a..16a1602 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -971,11 +971,16 @@ perf_header__find_attr(u64 id, struct perf_header *header)
/*
* We set id to -1 if the data file doesn't contain sample
- * ids. Check for this and avoid walking through the entire
- * list of ids which may be large.
+ * ids. This can happen when the data file contains one type
+ * of event and in that case, the header can still store the
+ * event attribute information. Check for this and avoid
+ * walking through the entire list of ids which may be large.
*/
- if (id == -1ULL)
+ if (id == -1ULL) {
+ if (header->attrs > 0)
+ return &header->attr[0]->attr;
return NULL;
+ }
for (i = 0; i < header->attrs; i++) {
struct perf_header_attr *attr = header->attr[i];
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index f40c076..ceefa65 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -532,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
struct machine *machine = kmaps->machine;
struct map *curr_map = map;
struct symbol *pos;
- int count = 0;
+ int count = 0, moved = 0;
struct rb_root *root = &self->symbols[map->type];
struct rb_node *next = rb_first(root);
int kernel_range = 0;
@@ -590,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
char dso_name[PATH_MAX];
struct dso *dso;
+ if (count == 0) {
+ curr_map = map;
+ goto filter_symbol;
+ }
+
if (self->kernel == DSO_TYPE_GUEST_KERNEL)
snprintf(dso_name, sizeof(dso_name),
"[guest.kernel].%d",
@@ -615,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
map_groups__insert(kmaps, curr_map);
++kernel_range;
}
-
+filter_symbol:
if (filter && filter(curr_map, pos)) {
discard_symbol: rb_erase(&pos->rb_node, root);
symbol__delete(pos);
@@ -623,8 +628,9 @@ discard_symbol: rb_erase(&pos->rb_node, root);
if (curr_map != map) {
rb_erase(&pos->rb_node, root);
symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
- }
- count++;
+ ++moved;
+ } else
+ ++count;
}
}
@@ -634,7 +640,7 @@ discard_symbol: rb_erase(&pos->rb_node, root);
dso__set_loaded(curr_map->dso, curr_map->type);
}
- return count;
+ return count + moved;
}
int dso__load_kallsyms(struct dso *self, const char *filename,
@@ -2130,14 +2136,55 @@ static struct dso *machine__create_kernel(struct machine *self)
return kernel;
}
+struct process_args {
+ u64 start;
+};
+
+static int symbol__in_kernel(void *arg, const char *name,
+ char type __used, u64 start)
+{
+ struct process_args *args = arg;
+
+ if (strchr(name, '['))
+ return 0;
+
+ args->start = start;
+ return 1;
+}
+
+/* Figure out the start address of kernel map from /proc/kallsyms */
+static u64 machine__get_kernel_start_addr(struct machine *machine)
+{
+ const char *filename;
+ char path[PATH_MAX];
+ struct process_args args;
+
+ if (machine__is_host(machine)) {
+ filename = "/proc/kallsyms";
+ } else {
+ if (machine__is_default_guest(machine))
+ filename = (char *)symbol_conf.default_guest_kallsyms;
+ else {
+ sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+ filename = path;
+ }
+ }
+
+ if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
+ return 0;
+
+ return args.start;
+}
+
int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
{
enum map_type type;
+ u64 start = machine__get_kernel_start_addr(self);
for (type = 0; type < MAP__NR_TYPES; ++type) {
struct kmap *kmap;
- self->vmlinux_maps[type] = map__new2(0, kernel, type);
+ self->vmlinux_maps[type] = map__new2(start, kernel, type);
if (self->vmlinux_maps[type] == NULL)
return -1;