perf session: Embed the host machine data on perf_session
We have just one host on a given session, and that is the most common setup right now, so embed a ->host_machine struct machine instance directly in the perf_session class, check if we're looking for it before going to the rb_tree. This also fixes a problem found when we try to process old perf.data files where we didn't have MMAP events for the kernel and modules and thus don't create the kernel maps, do it in event__preprocess_sample if it wasn't already. Reported-by: Ingo Molnar <mingo@elte.hu> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Tom Zanussi <tzanussi@gmail.com> Cc: Zhang, Yanmin <yanmin_zhang@linux.intel.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
4cc4945844
commit
1f626bc368
|
@ -656,6 +656,16 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
|
||||||
goto out_filtered;
|
goto out_filtered;
|
||||||
|
|
||||||
dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
|
dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
|
||||||
|
/*
|
||||||
|
* Have we already created the kernel maps for the host machine?
|
||||||
|
*
|
||||||
|
* This should have happened earlier, when we processed the kernel MMAP
|
||||||
|
* events, but for older perf.data files there was no such thing, so do
|
||||||
|
* it now.
|
||||||
|
*/
|
||||||
|
if (cpumode == PERF_RECORD_MISC_KERNEL &&
|
||||||
|
session->host_machine.vmlinux_maps[MAP__FUNCTION] == NULL)
|
||||||
|
machine__create_kernel_maps(&session->host_machine);
|
||||||
|
|
||||||
thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
|
thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
|
||||||
self->ip.pid, self->ip.ip, al);
|
self->ip.pid, self->ip.ip, al);
|
||||||
|
|
|
@ -579,30 +579,6 @@ struct machine *machines__find(struct rb_root *self, pid_t pid)
|
||||||
return default_machine;
|
return default_machine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: Why repeatedly search for this?
|
|
||||||
*/
|
|
||||||
struct machine *machines__find_host(struct rb_root *self)
|
|
||||||
{
|
|
||||||
struct rb_node **p = &self->rb_node;
|
|
||||||
struct rb_node *parent = NULL;
|
|
||||||
struct machine *machine;
|
|
||||||
pid_t pid = HOST_KERNEL_ID;
|
|
||||||
|
|
||||||
while (*p != NULL) {
|
|
||||||
parent = *p;
|
|
||||||
machine = rb_entry(parent, struct machine, rb_node);
|
|
||||||
if (pid < machine->pid)
|
|
||||||
p = &(*p)->rb_left;
|
|
||||||
else if (pid > machine->pid)
|
|
||||||
p = &(*p)->rb_right;
|
|
||||||
else
|
|
||||||
return machine;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct machine *machines__findnew(struct rb_root *self, pid_t pid)
|
struct machine *machines__findnew(struct rb_root *self, pid_t pid)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
|
|
@ -100,6 +100,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
|
||||||
self->repipe = repipe;
|
self->repipe = repipe;
|
||||||
self->ordered_samples.flush_limit = ULLONG_MAX;
|
self->ordered_samples.flush_limit = ULLONG_MAX;
|
||||||
INIT_LIST_HEAD(&self->ordered_samples.samples_head);
|
INIT_LIST_HEAD(&self->ordered_samples.samples_head);
|
||||||
|
machine__init(&self->host_machine, "", HOST_KERNEL_ID);
|
||||||
|
|
||||||
if (mode == O_RDONLY) {
|
if (mode == O_RDONLY) {
|
||||||
if (perf_session__open(self, force) < 0)
|
if (perf_session__open(self, force) < 0)
|
||||||
|
@ -870,3 +871,10 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
|
||||||
|
{
|
||||||
|
return __dsos__fprintf(&self->host_machine.kernel_dsos, fp) +
|
||||||
|
__dsos__fprintf(&self->host_machine.user_dsos, fp) +
|
||||||
|
machines__fprintf_dsos(&self->machines, fp);
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct perf_session {
|
||||||
unsigned long mmap_window;
|
unsigned long mmap_window;
|
||||||
struct rb_root threads;
|
struct rb_root threads;
|
||||||
struct thread *last_match;
|
struct thread *last_match;
|
||||||
|
struct machine host_machine;
|
||||||
struct rb_root machines;
|
struct rb_root machines;
|
||||||
struct events_stats events_stats;
|
struct events_stats events_stats;
|
||||||
struct rb_root stats_by_id;
|
struct rb_root stats_by_id;
|
||||||
|
@ -107,18 +108,22 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
|
||||||
static inline
|
static inline
|
||||||
struct machine *perf_session__find_host_machine(struct perf_session *self)
|
struct machine *perf_session__find_host_machine(struct perf_session *self)
|
||||||
{
|
{
|
||||||
return machines__find_host(&self->machines);
|
return &self->host_machine;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid)
|
struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid)
|
||||||
{
|
{
|
||||||
|
if (pid == HOST_KERNEL_ID)
|
||||||
|
return &self->host_machine;
|
||||||
return machines__find(&self->machines, pid);
|
return machines__find(&self->machines, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid)
|
struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid)
|
||||||
{
|
{
|
||||||
|
if (pid == HOST_KERNEL_ID)
|
||||||
|
return &self->host_machine;
|
||||||
return machines__findnew(&self->machines, pid);
|
return machines__findnew(&self->machines, pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,14 +131,11 @@ static inline
|
||||||
void perf_session__process_machines(struct perf_session *self,
|
void perf_session__process_machines(struct perf_session *self,
|
||||||
machine__process_t process)
|
machine__process_t process)
|
||||||
{
|
{
|
||||||
|
process(&self->host_machine, self);
|
||||||
return machines__process(&self->machines, process, self);
|
return machines__process(&self->machines, process, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
|
||||||
size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
|
|
||||||
{
|
|
||||||
return machines__fprintf_dsos(&self->machines, fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
|
size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
|
||||||
|
|
|
@ -1889,7 +1889,7 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name)
|
||||||
return dso;
|
return dso;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t __dsos__fprintf(struct list_head *head, FILE *fp)
|
size_t __dsos__fprintf(struct list_head *head, FILE *fp)
|
||||||
{
|
{
|
||||||
struct dso *pos;
|
struct dso *pos;
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
|
|
|
@ -167,6 +167,8 @@ int machine__load_kallsyms(struct machine *self, const char *filename,
|
||||||
int machine__load_vmlinux_path(struct machine *self, enum map_type type,
|
int machine__load_vmlinux_path(struct machine *self, enum map_type type,
|
||||||
symbol_filter_t filter);
|
symbol_filter_t filter);
|
||||||
|
|
||||||
|
size_t __dsos__fprintf(struct list_head *head, FILE *fp);
|
||||||
|
|
||||||
size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
|
size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
|
||||||
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
|
size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue