LKML Archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] perf tools improvements and minor fixes
@ 2010-05-09 23:39 Arnaldo Carvalho de Melo
  2010-05-09 23:39 ` [PATCH 1/4] perf symbols: Consider unresolved DSOs in the dso__col_widt calculation Arnaldo Carvalho de Melo
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-05-09 23:39 UTC (permalink / raw
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Arjan van de Ven,
	Frédéric Weisbecker, Mike Galbraith, Paul Mackerras,
	Peter Zijlstra, Tom Zanussi, Zhang, Yanmin

Hi Ingo,

        Please pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 perf

Regards,

Arnaldo Carvalho de Melo (4):
  perf symbols: Consider unresolved DSOs in the dso__col_widt calculation
  perf symbols: Check if a struct machine instance was found
  perf session: Embed the host machine data on perf_session
  perf report: Allow limiting the number of entries to print in callchains

 tools/perf/builtin-report.c |    5 ++++-
 tools/perf/util/callchain.h |    1 +
 tools/perf/util/event.c     |   34 +++++++++++++++++++++++++++-------
 tools/perf/util/hist.c      |   10 ++++++++++
 tools/perf/util/map.c       |   24 ------------------------
 tools/perf/util/session.c   |    8 ++++++++
 tools/perf/util/session.h   |   14 ++++++++------
 tools/perf/util/symbol.c    |    2 +-
 tools/perf/util/symbol.h    |    2 ++
 9 files changed, 61 insertions(+), 39 deletions(-)


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] perf symbols: Consider unresolved DSOs in the dso__col_widt calculation
  2010-05-09 23:39 [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
@ 2010-05-09 23:39 ` Arnaldo Carvalho de Melo
  2010-05-09 23:39 ` [PATCH 2/4] perf symbols: Check if a struct machine instance was found Arnaldo Carvalho de Melo
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-05-09 23:39 UTC (permalink / raw
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo,
	Frédéric Weisbecker, Mike Galbraith, Paul Mackerras,
	Peter Zijlstra, Tom Zanussi

From: Arnaldo Carvalho de Melo <acme@redhat.com>

By using BITS_PER_LONG / 4, that is the number of chars that will be
used in such cases as the DSO "name".

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>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 23d5dfd..46563e1 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -676,6 +676,13 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
 			dso__calc_col_width(al->map->dso);
 
 		al->sym = map__find_symbol(al->map, al->addr, filter);
+	} else {
+		const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
+
+		if (dsos__col_width < unresolved_col_width &&
+		    !symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
+		    !symbol_conf.dso_list)
+			dsos__col_width = unresolved_col_width;
 	}
 
 	if (symbol_conf.sym_list && al->sym &&
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] perf symbols: Check if a struct machine instance was found
  2010-05-09 23:39 [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
  2010-05-09 23:39 ` [PATCH 1/4] perf symbols: Consider unresolved DSOs in the dso__col_widt calculation Arnaldo Carvalho de Melo
@ 2010-05-09 23:39 ` Arnaldo Carvalho de Melo
  2010-05-09 23:39 ` [PATCH 3/4] perf session: Embed the host machine data on perf_session Arnaldo Carvalho de Melo
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-05-09 23:39 UTC (permalink / raw
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo,
	Frédéric Weisbecker, Mike Galbraith, Paul Mackerras,
	Peter Zijlstra, Tom Zanussi

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Which can happen when processing old files that had no fake kernel MMAP,
events.

That shouldn't result in perf_session__create_kernel_maps not being
called, this will be fixed in a followup patch, for now do these checks
to avoid segfaulting.

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>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c |   17 ++++++++++-------
 1 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 46563e1..c44a5a8 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -493,8 +493,10 @@ int event__process_mmap(event_t *self, struct perf_session *session)
 		return 0;
 	}
 
-	thread = perf_session__findnew(session, self->mmap.pid);
 	machine = perf_session__find_host_machine(session);
+	if (machine == NULL)
+		goto out_problem;
+	thread = perf_session__findnew(session, self->mmap.pid);
 	map = map__new(&machine->user_dsos, self->mmap.start,
 			self->mmap.len, self->mmap.pgoff,
 			self->mmap.pid, self->mmap.filename,
@@ -552,18 +554,12 @@ void thread__find_addr_map(struct thread *self,
 	if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
 		al->level = 'k';
 		machine = perf_session__find_host_machine(session);
-		mg = &machine->kmaps;
 	} else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
 		al->level = '.';
 		machine = perf_session__find_host_machine(session);
 	} else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
 		al->level = 'g';
 		machine = perf_session__find_machine(session, pid);
-		if (!machine) {
-			al->map = NULL;
-			return;
-		}
-		mg = &machine->kmaps;
 	} else {
 		/*
 		 * 'u' means guest os user space.
@@ -586,6 +582,13 @@ void thread__find_addr_map(struct thread *self,
 
 		return;
 	}
+
+	if (machine == NULL) {
+		al->map = NULL;
+		return;
+	}
+
+	mg = &machine->kmaps;
 try_again:
 	al->map = map_groups__find(mg, type, al->addr);
 	if (al->map == NULL) {
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] perf session: Embed the host machine data on perf_session
  2010-05-09 23:39 [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
  2010-05-09 23:39 ` [PATCH 1/4] perf symbols: Consider unresolved DSOs in the dso__col_widt calculation Arnaldo Carvalho de Melo
  2010-05-09 23:39 ` [PATCH 2/4] perf symbols: Check if a struct machine instance was found Arnaldo Carvalho de Melo
@ 2010-05-09 23:39 ` Arnaldo Carvalho de Melo
  2010-05-09 23:39 ` [PATCH 4/4] perf report: Allow limiting the number of entries to print in callchains Arnaldo Carvalho de Melo
  2010-05-10  0:09 ` [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
  4 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-05-09 23:39 UTC (permalink / raw
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo,
	Frédéric Weisbecker, Mike Galbraith, Paul Mackerras,
	Peter Zijlstra, Tom Zanussi, Zhang, Yanmin

From: Arnaldo Carvalho de Melo <acme@redhat.com>

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>
---
 tools/perf/util/event.c   |   10 ++++++++++
 tools/perf/util/map.c     |   24 ------------------------
 tools/perf/util/session.c |    8 ++++++++
 tools/perf/util/session.h |   14 ++++++++------
 tools/perf/util/symbol.c  |    2 +-
 tools/perf/util/symbol.h  |    2 ++
 6 files changed, 29 insertions(+), 31 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index c44a5a8..4ebb51d 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -653,6 +653,16 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
 		goto out_filtered;
 
 	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,
 			      self->ip.pid, self->ip.ip, al);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 44a4df6..e672f2f 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -579,30 +579,6 @@ struct machine *machines__find(struct rb_root *self, pid_t pid)
 	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)
 {
 	char path[PATH_MAX];
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5d353e7..71bc608 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -100,6 +100,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
 	self->repipe = repipe;
 	self->ordered_samples.flush_limit = ULLONG_MAX;
 	INIT_LIST_HEAD(&self->ordered_samples.samples_head);
+	machine__init(&self->host_machine, "", HOST_KERNEL_ID);
 
 	if (mode == O_RDONLY) {
 		if (perf_session__open(self, force) < 0)
@@ -870,3 +871,10 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
 
 	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);
+}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index f2b2c6a..eb9f179 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -25,6 +25,7 @@ struct perf_session {
 	unsigned long		mmap_window;
 	struct rb_root		threads;
 	struct thread		*last_match;
+	struct machine		host_machine;
 	struct rb_root		machines;
 	struct events_stats	events_stats;
 	struct rb_root		stats_by_id;
@@ -107,18 +108,22 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
 static inline
 struct machine *perf_session__find_host_machine(struct perf_session *self)
 {
-	return machines__find_host(&self->machines);
+	return &self->host_machine;
 }
 
 static inline
 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);
 }
 
 static inline
 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);
 }
 
@@ -126,14 +131,11 @@ static inline
 void perf_session__process_machines(struct perf_session *self,
 				    machine__process_t process)
 {
+	process(&self->host_machine, self);
 	return machines__process(&self->machines, process, self);
 }
 
-static inline
-size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
-{
-	return machines__fprintf_dsos(&self->machines, fp);
-}
+size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
 
 static inline
 size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 4c0146a..994efdb 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1889,7 +1889,7 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name)
 	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;
 	size_t ret = 0;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index a517c17..edff866 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -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,
 			       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_buildid(struct rb_root *self, FILE *fp, bool with_hits);
 
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] perf report: Allow limiting the number of entries to print in callchains
  2010-05-09 23:39 [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
                   ` (2 preceding siblings ...)
  2010-05-09 23:39 ` [PATCH 3/4] perf session: Embed the host machine data on perf_session Arnaldo Carvalho de Melo
@ 2010-05-09 23:39 ` Arnaldo Carvalho de Melo
  2010-05-10  0:09 ` [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
  4 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-05-09 23:39 UTC (permalink / raw
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Arjan van de Ven,
	Frédéric Weisbecker, Mike Galbraith, Paul Mackerras,
	Peter Zijlstra, Tom Zanussi

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Works by adding a third parameter to the '-g' argument, after the graph
type and minimum percentage, for example:

[root@doppio linux-2.6-tip]# perf report -g fractal,0.5,2

Will show only the first two symbols where at least 0.5% of the samples
took place.

All the other symbols that don't fall outside these constraints will be
put together in the last entry, prefixed with "[...]" and the total
percentage for them.

Suggested-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
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>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-report.c |    5 ++++-
 tools/perf/util/callchain.h |    1 +
 tools/perf/util/hist.c      |   10 ++++++++++
 3 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 5e2f47f..642a6d8 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -343,7 +343,7 @@ static int
 parse_callchain_opt(const struct option *opt __used, const char *arg,
 		    int unset)
 {
-	char *tok;
+	char *tok, *tok2;
 	char *endptr;
 
 	/*
@@ -388,10 +388,13 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
 	if (!tok)
 		goto setup;
 
+	tok2 = strtok(NULL, ",");
 	callchain_param.min_percent = strtod(tok, &endptr);
 	if (tok == endptr)
 		return -1;
 
+	if (tok2)
+		callchain_param.print_limit = strtod(tok2, &endptr);
 setup:
 	if (register_callchain_param(&callchain_param) < 0) {
 		fprintf(stderr, "Can't register callchain params\n");
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 0f4da09..1cba1f5 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -34,6 +34,7 @@ typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *,
 
 struct callchain_param {
 	enum chain_mode 	mode;
+	u32			print_limit;
 	double			min_percent;
 	sort_chain_func_t	sort;
 };
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index e0c8a72..0f154a5 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -333,6 +333,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
 	u64 remaining;
 	size_t ret = 0;
 	int i;
+	uint entries_printed = 0;
 
 	if (callchain_param.mode == CHAIN_GRAPH_REL)
 		new_total = self->children_hit;
@@ -379,6 +380,8 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
 						  new_depth_mask | (1 << depth),
 						  left_margin);
 		node = next;
+		if (++entries_printed == callchain_param.print_limit)
+			break;
 	}
 
 	if (callchain_param.mode == CHAIN_GRAPH_REL &&
@@ -404,6 +407,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
 	bool printed = false;
 	int i = 0;
 	int ret = 0;
+	u32 entries_printed = 0;
 
 	list_for_each_entry(chain, &self->val, list) {
 		if (!i++ && sort__first_dimension == SORT_SYM)
@@ -424,6 +428,9 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
 			ret += fprintf(fp, " %s\n", chain->ms.sym->name);
 		else
 			ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
+
+		if (++entries_printed == callchain_param.print_limit)
+			break;
 	}
 
 	ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin);
@@ -462,6 +469,7 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
 	struct rb_node *rb_node;
 	struct callchain_node *chain;
 	size_t ret = 0;
+	u32 entries_printed = 0;
 
 	rb_node = rb_first(&self->sorted_chain);
 	while (rb_node) {
@@ -484,6 +492,8 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
 			break;
 		}
 		ret += fprintf(fp, "\n");
+		if (++entries_printed == callchain_param.print_limit)
+			break;
 		rb_node = rb_next(rb_node);
 	}
 
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/4] perf tools improvements and minor fixes
  2010-05-09 23:39 [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
                   ` (3 preceding siblings ...)
  2010-05-09 23:39 ` [PATCH 4/4] perf report: Allow limiting the number of entries to print in callchains Arnaldo Carvalho de Melo
@ 2010-05-10  0:09 ` Arnaldo Carvalho de Melo
  4 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-05-10  0:09 UTC (permalink / raw
  To: Ingo Molnar
  Cc: linux-kernel, Arjan van de Ven, Frédéric Weisbecker,
	Mike Galbraith, Paul Mackerras, Peter Zijlstra, Tom Zanussi,
	Yanmin, Zhang

Em Sun, May 09, 2010 at 08:39:25PM -0300, Arnaldo Carvalho de Melo escreveu:
> Hi Ingo,
> 
>         Please pull from:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 perf

Oops, retracting the pull request, I found and fixed a bug on the "check
if a struct machine instance was found" patch, v2 coming shortly.
 
> Arnaldo Carvalho de Melo (4):
>   perf symbols: Consider unresolved DSOs in the dso__col_widt calculation
>   perf symbols: Check if a struct machine instance was found
>   perf session: Embed the host machine data on perf_session
>   perf report: Allow limiting the number of entries to print in callchains

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/4] perf session: Embed the host machine data on perf_session
  2010-05-10  0:19 [GIT PULL v2 " Arnaldo Carvalho de Melo
@ 2010-05-10  0:19 ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 7+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-05-10  0:19 UTC (permalink / raw
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo,
	Frédéric Weisbecker, Mike Galbraith, Paul Mackerras,
	Peter Zijlstra, Tom Zanussi, Zhang, Yanmin

From: Arnaldo Carvalho de Melo <acme@redhat.com>

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>
---
 tools/perf/util/event.c   |   10 ++++++++++
 tools/perf/util/map.c     |   24 ------------------------
 tools/perf/util/session.c |    8 ++++++++
 tools/perf/util/session.h |   14 ++++++++------
 tools/perf/util/symbol.c  |    2 +-
 tools/perf/util/symbol.h  |    2 ++
 6 files changed, 29 insertions(+), 31 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index dfc8bf6..d2ea9dd 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -656,6 +656,16 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
 		goto out_filtered;
 
 	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,
 			      self->ip.pid, self->ip.ip, al);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 44a4df6..e672f2f 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -579,30 +579,6 @@ struct machine *machines__find(struct rb_root *self, pid_t pid)
 	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)
 {
 	char path[PATH_MAX];
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5d353e7..71bc608 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -100,6 +100,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
 	self->repipe = repipe;
 	self->ordered_samples.flush_limit = ULLONG_MAX;
 	INIT_LIST_HEAD(&self->ordered_samples.samples_head);
+	machine__init(&self->host_machine, "", HOST_KERNEL_ID);
 
 	if (mode == O_RDONLY) {
 		if (perf_session__open(self, force) < 0)
@@ -870,3 +871,10 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
 
 	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);
+}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index f2b2c6a..eb9f179 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -25,6 +25,7 @@ struct perf_session {
 	unsigned long		mmap_window;
 	struct rb_root		threads;
 	struct thread		*last_match;
+	struct machine		host_machine;
 	struct rb_root		machines;
 	struct events_stats	events_stats;
 	struct rb_root		stats_by_id;
@@ -107,18 +108,22 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
 static inline
 struct machine *perf_session__find_host_machine(struct perf_session *self)
 {
-	return machines__find_host(&self->machines);
+	return &self->host_machine;
 }
 
 static inline
 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);
 }
 
 static inline
 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);
 }
 
@@ -126,14 +131,11 @@ static inline
 void perf_session__process_machines(struct perf_session *self,
 				    machine__process_t process)
 {
+	process(&self->host_machine, self);
 	return machines__process(&self->machines, process, self);
 }
 
-static inline
-size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
-{
-	return machines__fprintf_dsos(&self->machines, fp);
-}
+size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
 
 static inline
 size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 4c0146a..994efdb 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1889,7 +1889,7 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name)
 	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;
 	size_t ret = 0;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index a517c17..edff866 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -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,
 			       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_buildid(struct rb_root *self, FILE *fp, bool with_hits);
 
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-05-10  0:20 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-09 23:39 [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
2010-05-09 23:39 ` [PATCH 1/4] perf symbols: Consider unresolved DSOs in the dso__col_widt calculation Arnaldo Carvalho de Melo
2010-05-09 23:39 ` [PATCH 2/4] perf symbols: Check if a struct machine instance was found Arnaldo Carvalho de Melo
2010-05-09 23:39 ` [PATCH 3/4] perf session: Embed the host machine data on perf_session Arnaldo Carvalho de Melo
2010-05-09 23:39 ` [PATCH 4/4] perf report: Allow limiting the number of entries to print in callchains Arnaldo Carvalho de Melo
2010-05-10  0:09 ` [PATCH 0/4] perf tools improvements and minor fixes Arnaldo Carvalho de Melo
  -- strict thread matches above, loose matches on Subject: below --
2010-05-10  0:19 [GIT PULL v2 " Arnaldo Carvalho de Melo
2010-05-10  0:19 ` [PATCH 3/4] perf session: Embed the host machine data on perf_session Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).