Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 182362
b: refs/heads/master
c: b7cece7
h: refs/heads/master
v: v3
  • Loading branch information
Arnaldo Carvalho de Melo authored and Ingo Molnar committed Jan 13, 2010
1 parent 014963f commit 0754b32
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 49 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ff314d3903c2843de65c2148f66f277f2440ed26
refs/heads/master: b7cece76783c68fb391f9882235b4b0c9c300c46
5 changes: 5 additions & 0 deletions trunk/tools/perf/builtin-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,11 @@ static int __cmd_kmem(void)
if (!perf_session__has_traces(session, "kmem record"))
goto out_delete;

if (perf_session__create_kernel_maps(session) < 0) {
pr_err("Problems creating kernel maps\n");
return -1;
}

setup_pager();
err = perf_session__process_events(session, &event_ops);
if (err != 0)
Expand Down
11 changes: 11 additions & 0 deletions trunk/tools/perf/builtin-record.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,11 @@ static int __cmd_record(int argc, const char **argv)
return -1;
}

if (perf_session__create_kernel_maps(session) < 0) {
pr_err("Problems creating kernel maps\n");
return -1;
}

if (!file_new) {
err = perf_header__read(&session->header, output);
if (err < 0)
Expand Down Expand Up @@ -558,6 +563,12 @@ static int __cmd_record(int argc, const char **argv)
return err;
}

err = event__synthesize_modules(process_synthesized_event, session);
if (err < 0) {
pr_err("Couldn't record kernel reference relocation symbol.\n");
return err;
}

if (!system_wide && profile_cpu == -1)
event__synthesize_thread(pid, process_synthesized_event,
session);
Expand Down
5 changes: 5 additions & 0 deletions trunk/tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,11 @@ static int __cmd_top(void)
if (session == NULL)
return -ENOMEM;

if (perf_session__create_kernel_maps(session) < 0) {
pr_err("Problems creating kernel maps\n");
return -1;
}

if (target_pid != -1)
event__synthesize_thread(target_pid, event__process, session);
else
Expand Down
106 changes: 94 additions & 12 deletions trunk/tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,36 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
return 0;
}

int event__synthesize_modules(event__handler_t process,
struct perf_session *session)
{
struct rb_node *nd;

for (nd = rb_first(&session->kmaps.maps[MAP__FUNCTION]);
nd; nd = rb_next(nd)) {
event_t ev;
size_t size;
struct map *pos = rb_entry(nd, struct map, rb_node);

if (pos->dso->kernel)
continue;

size = ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
memset(&ev, 0, sizeof(ev));
ev.mmap.header.type = PERF_RECORD_MMAP;
ev.mmap.header.size = (sizeof(ev.mmap) -
(sizeof(ev.mmap.filename) - size));
ev.mmap.start = pos->start;
ev.mmap.len = pos->end - pos->start;

memcpy(ev.mmap.filename, pos->dso->long_name,
pos->dso->long_name_len + 1);
process(&ev, session);
}

return 0;
}

int event__synthesize_thread(pid_t pid, event__handler_t process,
struct perf_session *session)
{
Expand Down Expand Up @@ -222,7 +252,9 @@ int event__synthesize_kernel_mmap(event__handler_t process,
"[kernel.kallsyms.%s]", symbol_name) + 1;
size = ALIGN(size, sizeof(u64));
ev.mmap.header.size = (sizeof(ev.mmap) - (sizeof(ev.mmap.filename) - size));
ev.mmap.start = args.start;
ev.mmap.pgoff = args.start;
ev.mmap.start = session->vmlinux_maps[MAP__FUNCTION]->start;
ev.mmap.len = session->vmlinux_maps[MAP__FUNCTION]->end - ev.mmap.start ;

return process(&ev, session);
}
Expand Down Expand Up @@ -280,7 +312,6 @@ int event__process_mmap(event_t *self, struct perf_session *session)
{
struct thread *thread;
struct map *map;
static const char kmmap_prefix[] = "[kernel.kallsyms.";

dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n",
self->mmap.pid, self->mmap.tid,
Expand All @@ -289,13 +320,61 @@ int event__process_mmap(event_t *self, struct perf_session *session)
(void *)(long)self->mmap.pgoff,
self->mmap.filename);

if (self->mmap.pid == 0 &&
memcmp(self->mmap.filename, kmmap_prefix,
sizeof(kmmap_prefix) - 1) == 0) {
const char *symbol_name = (self->mmap.filename +
sizeof(kmmap_prefix) - 1);
perf_session__set_kallsyms_ref_reloc_sym(session, symbol_name,
self->mmap.start);
if (self->mmap.pid == 0) {
static const char kmmap_prefix[] = "[kernel.kallsyms.";

if (self->mmap.filename[0] == '/') {
char short_module_name[1024];
char *name = strrchr(self->mmap.filename, '/'), *dot;

if (name == NULL)
goto out_problem;

++name; /* skip / */
dot = strrchr(name, '.');
if (dot == NULL)
goto out_problem;

snprintf(short_module_name, sizeof(short_module_name),
"[%.*s]", (int)(dot - name), name);
strxfrchar(short_module_name, '-', '_');

map = perf_session__new_module_map(session,
self->mmap.start,
short_module_name);
if (map == NULL)
goto out_problem;

name = strdup(self->mmap.filename);
if (name == NULL)
goto out_problem;

dso__set_long_name(map->dso, name);
map->end = map->start + self->mmap.len;
} else if (memcmp(self->mmap.filename, kmmap_prefix,
sizeof(kmmap_prefix) - 1) == 0) {
const char *symbol_name = (self->mmap.filename +
sizeof(kmmap_prefix) - 1);
/*
* Should be there already, from the build-id table in
* the header.
*/
struct dso *kernel = __dsos__findnew(&dsos__kernel,
"[kernel.kallsyms]");
if (kernel == NULL)
goto out_problem;

if (__map_groups__create_kernel_maps(&session->kmaps,
session->vmlinux_maps,
kernel) < 0)
goto out_problem;

session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start;
session->vmlinux_maps[MAP__FUNCTION]->end = self->mmap.start + self->mmap.len;

perf_session__set_kallsyms_ref_reloc_sym(session, symbol_name,
self->mmap.pgoff);
}
return 0;
}

Expand All @@ -304,10 +383,13 @@ int event__process_mmap(event_t *self, struct perf_session *session)
session->cwd, session->cwdlen);

if (thread == NULL || map == NULL)
dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
else
thread__insert_map(thread, map);
goto out_problem;

thread__insert_map(thread, map);
return 0;

out_problem:
dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions trunk/tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ void event__synthesize_threads(event__handler_t process,
int event__synthesize_kernel_mmap(event__handler_t process,
struct perf_session *session,
const char *symbol_name);
int event__synthesize_modules(event__handler_t process,
struct perf_session *session);

int event__process_comm(event_t *self, struct perf_session *session);
int event__process_lost(event_t *self, struct perf_session *session);
Expand Down
8 changes: 4 additions & 4 deletions trunk/tools/perf/util/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
self->unknown_events = 0;
map_groups__init(&self->kmaps);

if (perf_session__create_kernel_maps(self) < 0)
goto out_delete;

if (mode == O_RDONLY && perf_session__open(self, force) < 0)
goto out_delete;

Expand Down Expand Up @@ -268,8 +265,11 @@ int perf_header__read_build_ids(int input, u64 offset, u64 size)
head = &dsos__kernel;

dso = __dsos__findnew(head, filename);
if (dso != NULL)
if (dso != NULL) {
dso__set_build_id(dso, &bev.build_id);
if (head == &dsos__kernel && filename[0] == '[')
dso->kernel = 1;
}

offset += bev.header.size;
}
Expand Down
Loading

0 comments on commit 0754b32

Please sign in to comment.