mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/3] perfcounter: Set the minimum percent for callchains to be displayed
@ 2009-07-02 18:14 Frederic Weisbecker
  2009-07-02 18:14 ` [PATCH 2/3] perfcounter: Provide helper to print percents color Frederic Weisbecker
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Frederic Weisbecker @ 2009-07-02 18:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras,
	Anton Blanchard, Arnaldo Carvalho de Melo, Frederic Weisbecker

Callchains output may become a burden on a trace because even
rarely hit site are exposed. This can be too much information.

Let the user set a threshold as a minimum percent of hits using
the new pattern for the -c option:

-c mode,min_percent

Example:

$ perf report -s sym -c flat,4

     8.25%  [k] copy_user_generic_string
             4.19%
                copy_user_generic_string
                generic_file_aio_read
                do_sync_read
                vfs_read
                sys_pread64
                system_call_fastpath
                pread64

     5.39%  [k] search_by_key
     4.63%  0x00000000009e0a
     2.36%  [k] memcpy_c
[...]

$ perf report -s sym -c graph,2

     8.25%  [k] copy_user_generic_string
                |
                |--4.31%-- generic_file_aio_read
                |          do_sync_read
                |          vfs_read
                |          |
                |           --4.19%-- sys_pread64
                |                     system_call_fastpath
                |                     pread64
                |
                 --3.24%-- generic_file_buffered_write
                           __generic_file_aio_write_nolock
                           generic_file_aio_write
                           do_sync_write
                           reiserfs_file_write
                           vfs_write
                           |
                            --3.14%-- sys_pwrite64
                                      system_call_fastpath
                                      __pwrite64

     5.39%  [k] search_by_key
                |
                 --2.23%-- reiserfs_update_sd_size

     4.63%  0x00000000009e0a

     2.36%  [k] memcpy_c
[...]

You can also omit it and it will default to 0.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
 tools/perf/builtin-report.c |   45 ++++++++++++++++++++++++++++++++----------
 tools/perf/util/callchain.c |   19 ++++++++++-------
 tools/perf/util/callchain.h |    6 +++-
 3 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index a3ec4bd..0e2317d 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -58,6 +58,7 @@ static regex_t		parent_regex;
 static int		exclude_other = 1;
 static int		callchain;
 static enum chain_mode	callchain_mode;
+static double		callchain_min_percent = 0.0;
 
 static u64		sample_type;
 
@@ -1219,7 +1220,7 @@ static void collapse__resort(void)
 
 static struct rb_root output_hists;
 
-static void output__insert_entry(struct hist_entry *he)
+static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
 {
 	struct rb_node **p = &output_hists.rb_node;
 	struct rb_node *parent = NULL;
@@ -1227,9 +1228,11 @@ static void output__insert_entry(struct hist_entry *he)
 
 	if (callchain) {
 		if (callchain_mode == FLAT)
-			sort_chain_flat(&he->sorted_chain, &he->callchain);
+			sort_chain_flat(&he->sorted_chain, &he->callchain,
+					min_callchain_hits);
 		else if (callchain_mode == GRAPH)
-			sort_chain_graph(&he->sorted_chain, &he->callchain);
+			sort_chain_graph(&he->sorted_chain, &he->callchain,
+					 min_callchain_hits);
 	}
 
 	while (*p != NULL) {
@@ -1246,11 +1249,14 @@ static void output__insert_entry(struct hist_entry *he)
 	rb_insert_color(&he->rb_node, &output_hists);
 }
 
-static void output__resort(void)
+static void output__resort(u64 total_samples)
 {
 	struct rb_node *next;
 	struct hist_entry *n;
 	struct rb_root *tree = &hist;
+	u64 min_callchain_hits;
+
+	min_callchain_hits = total_samples * (callchain_min_percent / 100);
 
 	if (sort__need_collapse)
 		tree = &collapse_hists;
@@ -1262,7 +1268,7 @@ static void output__resort(void)
 		next = rb_next(&n->rb_node);
 
 		rb_erase(&n->rb_node, tree);
-		output__insert_entry(n);
+		output__insert_entry(n, min_callchain_hits);
 	}
 }
 
@@ -1796,7 +1802,7 @@ done:
 		dsos__fprintf(stdout);
 
 	collapse__resort();
-	output__resort();
+	output__resort(total);
 	output__fprintf(stdout, total);
 
 	return rc;
@@ -1806,19 +1812,36 @@ static int
 parse_callchain_opt(const struct option *opt __used, const char *arg,
 		    int unset __used)
 {
+	char *tok;
+	char *endptr;
+
 	callchain = 1;
 
 	if (!arg)
 		return 0;
 
-	if (!strncmp(arg, "graph", strlen(arg)))
+	tok = strtok((char *)arg, ",");
+	if (!tok)
+		return -1;
+
+	/* get the output mode */
+	if (!strncmp(tok, "graph", strlen(arg)))
 		callchain_mode = GRAPH;
 
-	else if (!strncmp(arg, "flat", strlen(arg)))
+	else if (!strncmp(tok, "flat", strlen(arg)))
 		callchain_mode = FLAT;
 	else
 		return -1;
 
+	/* get the min percentage */
+	tok = strtok(NULL, ",");
+	if (!tok)
+		return 0;
+
+	callchain_min_percent = strtod(tok, &endptr);
+	if (tok == endptr)
+		return -1;
+
 	return 0;
 }
 
@@ -1843,9 +1866,9 @@ static const struct option options[] = {
 		   "regex filter to identify parent, see: '--sort parent'"),
 	OPT_BOOLEAN('x', "exclude-other", &exclude_other,
 		    "Only display entries with parent-match"),
-	OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type",
-		     "Display callchains with output_type: flat, graph. "
-		     "Default to flat", &parse_callchain_opt, "flat"),
+	OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type,min_percent",
+		     "Display callchains using output_type and min percent threshold. "
+		     "Default: flat,0", &parse_callchain_opt, "flat,100"),
 	OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
 		   "only consider symbols in these dsos"),
 	OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index a9873aa..c9900fe 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -57,18 +57,19 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
  * Once we get every callchains from the stream, we can now
  * sort them by hit
  */
-void sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node)
+void sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
+		     u64 min_hit)
 {
 	struct callchain_node *child;
 
 	chain_for_each_child(child, node)
-		sort_chain_flat(rb_root, child);
+		sort_chain_flat(rb_root, child, min_hit);
 
-	if (node->hit)
+	if (node->hit && node->hit >= min_hit)
 		rb_insert_callchain(rb_root, node, FLAT);
 }
 
-static void __sort_chain_graph(struct callchain_node *node)
+static void __sort_chain_graph(struct callchain_node *node, u64 min_hit)
 {
 	struct callchain_node *child;
 
@@ -76,16 +77,18 @@ static void __sort_chain_graph(struct callchain_node *node)
 	node->cumul_hit = node->hit;
 
 	chain_for_each_child(child, node) {
-		__sort_chain_graph(child);
-		rb_insert_callchain(&node->rb_root, child, GRAPH);
+		__sort_chain_graph(child, min_hit);
+		if (child->cumul_hit >= min_hit)
+			rb_insert_callchain(&node->rb_root, child, GRAPH);
 		node->cumul_hit += child->cumul_hit;
 	}
 }
 
 void
-sort_chain_graph(struct rb_root *rb_root, struct callchain_node *chain_root)
+sort_chain_graph(struct rb_root *rb_root, struct callchain_node *chain_root,
+		 u64 min_hit)
 {
-	__sort_chain_graph(chain_root);
+	__sort_chain_graph(chain_root, min_hit);
 	rb_root->rb_node = chain_root->rb_root.rb_node;
 }
 
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index dfa5600..f3e4776 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -38,6 +38,8 @@ static inline void callchain_init(struct callchain_node *node)
 
 void append_chain(struct callchain_node *root, struct ip_callchain *chain,
 		  struct symbol **syms);
-void sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node);
-void sort_chain_graph(struct rb_root *rb_root, struct callchain_node *node);
+void sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
+		     u64 min_hit);
+void sort_chain_graph(struct rb_root *rb_root, struct callchain_node *node,
+		      u64 min_hit);
 #endif
-- 
1.6.2.3


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

* [PATCH 2/3] perfcounter: Provide helper to print percents color
  2009-07-02 18:14 [PATCH 1/3] perfcounter: Set the minimum percent for callchains to be displayed Frederic Weisbecker
@ 2009-07-02 18:14 ` Frederic Weisbecker
  2009-07-02 19:42   ` [tip:perfcounters/urgent] perf_counter tools: " tip-bot for Frederic Weisbecker
  2009-07-02 18:14 ` [PATCH 3/3] perfcounter: Display percents of hits in callchain with overhead colors Frederic Weisbecker
  2009-07-02 19:42 ` [tip:perfcounters/urgent] perf_counter tools: Set the minimum percent for callchains to be displayed tip-bot for Frederic Weisbecker
  2 siblings, 1 reply; 6+ messages in thread
From: Frederic Weisbecker @ 2009-07-02 18:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras,
	Anton Blanchard, Arnaldo Carvalho de Melo, Frederic Weisbecker

Among perf annotate, perf report and perf top, we can find
the common colored printing of percents according to the
following rules:

High overhead =  > 5%, colored in red
Mid overhead =  > 0.5%, colored in green

Factorize these multiple checks in a single function named
percent_color_fprintf() and also provide a get_percent_color()
for sites which print percentages and other things at the same time.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
 tools/perf/builtin-annotate.c |   26 ++------------------------
 tools/perf/builtin-report.c   |   21 +++------------------
 tools/perf/builtin-top.c      |   15 +--------------
 tools/perf/util/color.c       |   27 +++++++++++++++++++++++++++
 tools/perf/util/color.h       |    5 +++++
 5 files changed, 38 insertions(+), 56 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 132de8b..12fc52f 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -25,10 +25,6 @@
 #define SHOW_USER	2
 #define SHOW_HV		4
 
-#define MIN_GREEN		0.5
-#define MIN_RED		5.0
-
-
 static char		const *input_name = "perf.data";
 static char		*vmlinux = "vmlinux";
 
@@ -1043,24 +1039,6 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
 	return 0;
 }
 
-static char *get_color(double percent)
-{
-	char *color = PERF_COLOR_NORMAL;
-
-	/*
-	 * We color high-overhead entries in red, mid-overhead
-	 * entries in green - and keep the low overhead places
-	 * normal:
-	 */
-	if (percent >= MIN_RED)
-		color = PERF_COLOR_RED;
-	else {
-		if (percent > MIN_GREEN)
-			color = PERF_COLOR_GREEN;
-	}
-	return color;
-}
-
 static int
 parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
 {
@@ -1122,7 +1100,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
 		} else if (sym->hist_sum)
 			percent = 100.0 * hits / sym->hist_sum;
 
-		color = get_color(percent);
+		color = get_percent_color(percent);
 
 		/*
 		 * Also color the filename and line if needed, with
@@ -1258,7 +1236,7 @@ static void print_summary(char *filename)
 
 		sym_ext = rb_entry(node, struct sym_ext, node);
 		percent = sym_ext->percent;
-		color = get_color(percent);
+		color = get_percent_color(percent);
 		path = sym_ext->path;
 
 		color_fprintf(stdout, color, " %7.2f %s", percent, path);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 0e2317d..bfca1e4 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -942,25 +942,10 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
 	if (exclude_other && !self->parent)
 		return 0;
 
-	if (total_samples) {
-		double percent = self->count * 100.0 / total_samples;
-		char *color = PERF_COLOR_NORMAL;
-
-		/*
-		 * We color high-overhead entries in red, mid-overhead
-		 * entries in green - and keep the low overhead places
-		 * normal:
-		 */
-		if (percent >= 5.0) {
-			color = PERF_COLOR_RED;
-		} else {
-			if (percent >= 0.5)
-				color = PERF_COLOR_GREEN;
-		}
-
-		ret = color_fprintf(fp, color, "   %6.2f%%",
+	if (total_samples)
+		ret = percent_color_fprintf(fp, "   %6.2f%%",
 				(self->count * 100.0) / total_samples);
-	} else
+	else
 		ret = fprintf(fp, "%12Ld ", self->count);
 
 	list_for_each_entry(se, &hist_entry__sort_list, list) {
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index cdc74cf..27c1625 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -238,7 +238,6 @@ static void print_sym_table(void)
 	for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
 		struct sym_entry *syme = rb_entry(nd, struct sym_entry, rb_node);
 		struct symbol *sym = (struct symbol *)(syme + 1);
-		char *color = PERF_COLOR_NORMAL;
 		double pcnt;
 
 		if (++printed > print_entries || syme->snap_count < count_filter)
@@ -247,24 +246,12 @@ static void print_sym_table(void)
 		pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) /
 					 sum_ksamples));
 
-		/*
-		 * We color high-overhead entries in red, mid-overhead
-		 * entries in green - and keep the low overhead places
-		 * normal:
-		 */
-		if (pcnt >= 5.0) {
-			color = PERF_COLOR_RED;
-		} else {
-			if (pcnt >= 0.5)
-				color = PERF_COLOR_GREEN;
-		}
-
 		if (nr_counters == 1)
 			printf("%20.2f - ", syme->weight);
 		else
 			printf("%9.1f %10ld - ", syme->weight, syme->snap_count);
 
-		color_fprintf(stdout, color, "%4.1f%%", pcnt);
+		percent_color_fprintf(stdout, "%4.1f%%", pcnt);
 		printf(" - %016llx : %s\n", sym->start, sym->name);
 	}
 }
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 26f8231..90a044d 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -242,4 +242,31 @@ int color_fwrite_lines(FILE *fp, const char *color,
 	return 0;
 }
 
+char *get_percent_color(double percent)
+{
+	char *color = PERF_COLOR_NORMAL;
+
+	/*
+	 * We color high-overhead entries in red, mid-overhead
+	 * entries in green - and keep the low overhead places
+	 * normal:
+	 */
+	if (percent >= MIN_RED)
+		color = PERF_COLOR_RED;
+	else {
+		if (percent > MIN_GREEN)
+			color = PERF_COLOR_GREEN;
+	}
+	return color;
+}
 
+int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
+{
+	int r;
+	char *color;
+
+	color = get_percent_color(percent);
+	r = color_fprintf(fp, color, fmt, percent);
+
+	return r;
+}
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h
index 5abfd37..706cec5 100644
--- a/tools/perf/util/color.h
+++ b/tools/perf/util/color.h
@@ -15,6 +15,9 @@
 #define PERF_COLOR_CYAN		"\033[36m"
 #define PERF_COLOR_BG_RED	"\033[41m"
 
+#define MIN_GREEN	0.5
+#define MIN_RED		5.0
+
 /*
  * This variable stores the value of color.ui
  */
@@ -32,5 +35,7 @@ void color_parse_mem(const char *value, int len, const char *var, char *dst);
 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
 int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
 int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
+int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
+char *get_percent_color(double percent);
 
 #endif /* COLOR_H */
-- 
1.6.2.3


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

* [PATCH 3/3] perfcounter: Display percents of hits in callchain with overhead colors
  2009-07-02 18:14 [PATCH 1/3] perfcounter: Set the minimum percent for callchains to be displayed Frederic Weisbecker
  2009-07-02 18:14 ` [PATCH 2/3] perfcounter: Provide helper to print percents color Frederic Weisbecker
@ 2009-07-02 18:14 ` Frederic Weisbecker
  2009-07-02 19:42   ` [tip:perfcounters/urgent] perf_counter tools: " tip-bot for Frederic Weisbecker
  2009-07-02 19:42 ` [tip:perfcounters/urgent] perf_counter tools: Set the minimum percent for callchains to be displayed tip-bot for Frederic Weisbecker
  2 siblings, 1 reply; 6+ messages in thread
From: Frederic Weisbecker @ 2009-07-02 18:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: LKML, Peter Zijlstra, Mike Galbraith, Paul Mackerras,
	Anton Blanchard, Arnaldo Carvalho de Melo, Frederic Weisbecker

This adds the use of colors to signal at a glance the important
overhead thresholds in callchains hit rates.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
 tools/perf/builtin-report.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index bfca1e4..01902f0 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -819,7 +819,7 @@ ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
 			double percent;
 
 			percent = hits * 100.0 / total_samples;
-			ret += fprintf(fp, "--%2.2f%%-- ", percent);
+			ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
 		} else
 			ret += fprintf(fp, "%s", "          ");
 	}
@@ -919,7 +919,8 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
 		chain = rb_entry(rb_node, struct callchain_node, rb_node);
 		percent = chain->hit * 100.0 / total_samples;
 		if (callchain_mode == FLAT) {
-			ret += fprintf(fp, "           %6.2f%%\n", percent);
+			ret += percent_color_fprintf(fp, "           %6.2f%%\n",
+						     percent);
 			ret += callchain__fprintf_flat(fp, chain, total_samples);
 		} else if (callchain_mode == GRAPH) {
 			ret += callchain__fprintf_graph(fp, chain,
-- 
1.6.2.3


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

* [tip:perfcounters/urgent] perf_counter tools: Set the minimum percent for callchains to be displayed
  2009-07-02 18:14 [PATCH 1/3] perfcounter: Set the minimum percent for callchains to be displayed Frederic Weisbecker
  2009-07-02 18:14 ` [PATCH 2/3] perfcounter: Provide helper to print percents color Frederic Weisbecker
  2009-07-02 18:14 ` [PATCH 3/3] perfcounter: Display percents of hits in callchain with overhead colors Frederic Weisbecker
@ 2009-07-02 19:42 ` tip-bot for Frederic Weisbecker
  2 siblings, 0 replies; 6+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-07-02 19:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, acme, anton, paulus, hpa, mingo, a.p.zijlstra,
	efault, fweisbec, tglx, mingo

Commit-ID:  c20ab37ef30f4a874cf27e84c12c73e584e6f5cc
Gitweb:     http://git.kernel.org/tip/c20ab37ef30f4a874cf27e84c12c73e584e6f5cc
Author:     Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Thu, 2 Jul 2009 20:14:33 +0200
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 2 Jul 2009 21:38:37 +0200

perf_counter tools: Set the minimum percent for callchains to be displayed

Callchains output may become a burden on a trace because even
rarely hit site are exposed. This can be too much information.

Let the user set a threshold as a minimum percent of hits using
the new pattern for the -c option:

    -c mode,min_percent

Example:

$ perf report -s sym -c flat,4

     8.25%  [k] copy_user_generic_string
             4.19%
                copy_user_generic_string
                generic_file_aio_read
                do_sync_read
                vfs_read
                sys_pread64
                system_call_fastpath
                pread64

     5.39%  [k] search_by_key
     4.63%  0x00000000009e0a
     2.36%  [k] memcpy_c
[...]

$ perf report -s sym -c graph,2

     8.25%  [k] copy_user_generic_string
                |
                |--4.31%-- generic_file_aio_read
                |          do_sync_read
                |          vfs_read
                |          |
                |           --4.19%-- sys_pread64
                |                     system_call_fastpath
                |                     pread64
                |
                 --3.24%-- generic_file_buffered_write
                           __generic_file_aio_write_nolock
                           generic_file_aio_write
                           do_sync_write
                           reiserfs_file_write
                           vfs_write
                           |
                            --3.14%-- sys_pwrite64
                                      system_call_fastpath
                                      __pwrite64

     5.39%  [k] search_by_key
                |
                 --2.23%-- reiserfs_update_sd_size

     4.63%  0x00000000009e0a

     2.36%  [k] memcpy_c
[...]

You can also omit it and it will default to 0.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <1246558475-10624-1-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 tools/perf/builtin-report.c |   45 ++++++++++++++++++++++++++++++++----------
 tools/perf/util/callchain.c |   19 ++++++++++-------
 tools/perf/util/callchain.h |    6 +++-
 3 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 0ca4638..e8c9817 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -60,6 +60,7 @@ static regex_t		parent_regex;
 static int		exclude_other = 1;
 static int		callchain;
 static enum chain_mode	callchain_mode;
+static double		callchain_min_percent = 0.0;
 
 static u64		sample_type;
 
@@ -1224,7 +1225,7 @@ static void collapse__resort(void)
 
 static struct rb_root output_hists;
 
-static void output__insert_entry(struct hist_entry *he)
+static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
 {
 	struct rb_node **p = &output_hists.rb_node;
 	struct rb_node *parent = NULL;
@@ -1232,9 +1233,11 @@ static void output__insert_entry(struct hist_entry *he)
 
 	if (callchain) {
 		if (callchain_mode == FLAT)
-			sort_chain_flat(&he->sorted_chain, &he->callchain);
+			sort_chain_flat(&he->sorted_chain, &he->callchain,
+					min_callchain_hits);
 		else if (callchain_mode == GRAPH)
-			sort_chain_graph(&he->sorted_chain, &he->callchain);
+			sort_chain_graph(&he->sorted_chain, &he->callchain,
+					 min_callchain_hits);
 	}
 
 	while (*p != NULL) {
@@ -1251,11 +1254,14 @@ static void output__insert_entry(struct hist_entry *he)
 	rb_insert_color(&he->rb_node, &output_hists);
 }
 
-static void output__resort(void)
+static void output__resort(u64 total_samples)
 {
 	struct rb_node *next;
 	struct hist_entry *n;
 	struct rb_root *tree = &hist;
+	u64 min_callchain_hits;
+
+	min_callchain_hits = total_samples * (callchain_min_percent / 100);
 
 	if (sort__need_collapse)
 		tree = &collapse_hists;
@@ -1267,7 +1273,7 @@ static void output__resort(void)
 		next = rb_next(&n->rb_node);
 
 		rb_erase(&n->rb_node, tree);
-		output__insert_entry(n);
+		output__insert_entry(n, min_callchain_hits);
 	}
 }
 
@@ -1801,7 +1807,7 @@ done:
 		dsos__fprintf(stdout);
 
 	collapse__resort();
-	output__resort();
+	output__resort(total);
 	output__fprintf(stdout, total);
 
 	return rc;
@@ -1811,19 +1817,36 @@ static int
 parse_callchain_opt(const struct option *opt __used, const char *arg,
 		    int unset __used)
 {
+	char *tok;
+	char *endptr;
+
 	callchain = 1;
 
 	if (!arg)
 		return 0;
 
-	if (!strncmp(arg, "graph", strlen(arg)))
+	tok = strtok((char *)arg, ",");
+	if (!tok)
+		return -1;
+
+	/* get the output mode */
+	if (!strncmp(tok, "graph", strlen(arg)))
 		callchain_mode = GRAPH;
 
-	else if (!strncmp(arg, "flat", strlen(arg)))
+	else if (!strncmp(tok, "flat", strlen(arg)))
 		callchain_mode = FLAT;
 	else
 		return -1;
 
+	/* get the min percentage */
+	tok = strtok(NULL, ",");
+	if (!tok)
+		return 0;
+
+	callchain_min_percent = strtod(tok, &endptr);
+	if (tok == endptr)
+		return -1;
+
 	return 0;
 }
 
@@ -1850,9 +1873,9 @@ static const struct option options[] = {
 		   "regex filter to identify parent, see: '--sort parent'"),
 	OPT_BOOLEAN('x', "exclude-other", &exclude_other,
 		    "Only display entries with parent-match"),
-	OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type",
-		     "Display callchains with output_type: flat, graph. "
-		     "Default to flat", &parse_callchain_opt, "flat"),
+	OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type,min_percent",
+		     "Display callchains using output_type and min percent threshold. "
+		     "Default: flat,0", &parse_callchain_opt, "flat,100"),
 	OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
 		   "only consider symbols in these dsos"),
 	OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index a9873aa..c9900fe 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -57,18 +57,19 @@ rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
  * Once we get every callchains from the stream, we can now
  * sort them by hit
  */
-void sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node)
+void sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
+		     u64 min_hit)
 {
 	struct callchain_node *child;
 
 	chain_for_each_child(child, node)
-		sort_chain_flat(rb_root, child);
+		sort_chain_flat(rb_root, child, min_hit);
 
-	if (node->hit)
+	if (node->hit && node->hit >= min_hit)
 		rb_insert_callchain(rb_root, node, FLAT);
 }
 
-static void __sort_chain_graph(struct callchain_node *node)
+static void __sort_chain_graph(struct callchain_node *node, u64 min_hit)
 {
 	struct callchain_node *child;
 
@@ -76,16 +77,18 @@ static void __sort_chain_graph(struct callchain_node *node)
 	node->cumul_hit = node->hit;
 
 	chain_for_each_child(child, node) {
-		__sort_chain_graph(child);
-		rb_insert_callchain(&node->rb_root, child, GRAPH);
+		__sort_chain_graph(child, min_hit);
+		if (child->cumul_hit >= min_hit)
+			rb_insert_callchain(&node->rb_root, child, GRAPH);
 		node->cumul_hit += child->cumul_hit;
 	}
 }
 
 void
-sort_chain_graph(struct rb_root *rb_root, struct callchain_node *chain_root)
+sort_chain_graph(struct rb_root *rb_root, struct callchain_node *chain_root,
+		 u64 min_hit)
 {
-	__sort_chain_graph(chain_root);
+	__sort_chain_graph(chain_root, min_hit);
 	rb_root->rb_node = chain_root->rb_root.rb_node;
 }
 
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index dfa5600..f3e4776 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -38,6 +38,8 @@ static inline void callchain_init(struct callchain_node *node)
 
 void append_chain(struct callchain_node *root, struct ip_callchain *chain,
 		  struct symbol **syms);
-void sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node);
-void sort_chain_graph(struct rb_root *rb_root, struct callchain_node *node);
+void sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node,
+		     u64 min_hit);
+void sort_chain_graph(struct rb_root *rb_root, struct callchain_node *node,
+		      u64 min_hit);
 #endif

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

* [tip:perfcounters/urgent] perf_counter tools: Provide helper to print percents color
  2009-07-02 18:14 ` [PATCH 2/3] perfcounter: Provide helper to print percents color Frederic Weisbecker
@ 2009-07-02 19:42   ` tip-bot for Frederic Weisbecker
  0 siblings, 0 replies; 6+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-07-02 19:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, acme, anton, paulus, hpa, mingo, a.p.zijlstra,
	efault, fweisbec, tglx, mingo

Commit-ID:  1e11fd82d247e4e48a1d6c49402214434538d3fd
Gitweb:     http://git.kernel.org/tip/1e11fd82d247e4e48a1d6c49402214434538d3fd
Author:     Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Thu, 2 Jul 2009 20:14:34 +0200
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 2 Jul 2009 21:38:37 +0200

perf_counter tools: Provide helper to print percents color

Among perf annotate, perf report and perf top, we can find the
common colored printing of percents according to the following
rules:

    High overhead =  > 5%, colored in red
    Mid overhead =  > 0.5%, colored in green
    Low overhead =  < 0.5%, default color

Factorize these multiple checks in a single function named
percent_color_fprintf() and also provide a get_percent_color()
for sites which print percentages and other things at the same
time.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <1246558475-10624-2-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 tools/perf/builtin-annotate.c |   26 ++------------------------
 tools/perf/builtin-report.c   |   21 +++------------------
 tools/perf/builtin-top.c      |   15 +--------------
 tools/perf/util/color.c       |   27 +++++++++++++++++++++++++++
 tools/perf/util/color.h       |    5 +++++
 5 files changed, 38 insertions(+), 56 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 08ea6c5..5f9eefe 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -25,10 +25,6 @@
 #define SHOW_USER	2
 #define SHOW_HV		4
 
-#define MIN_GREEN		0.5
-#define MIN_RED		5.0
-
-
 static char		const *input_name = "perf.data";
 static char		*vmlinux = "vmlinux";
 
@@ -1047,24 +1043,6 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
 	return 0;
 }
 
-static char *get_color(double percent)
-{
-	char *color = PERF_COLOR_NORMAL;
-
-	/*
-	 * We color high-overhead entries in red, mid-overhead
-	 * entries in green - and keep the low overhead places
-	 * normal:
-	 */
-	if (percent >= MIN_RED)
-		color = PERF_COLOR_RED;
-	else {
-		if (percent > MIN_GREEN)
-			color = PERF_COLOR_GREEN;
-	}
-	return color;
-}
-
 static int
 parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
 {
@@ -1126,7 +1104,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len)
 		} else if (sym->hist_sum)
 			percent = 100.0 * hits / sym->hist_sum;
 
-		color = get_color(percent);
+		color = get_percent_color(percent);
 
 		/*
 		 * Also color the filename and line if needed, with
@@ -1262,7 +1240,7 @@ static void print_summary(char *filename)
 
 		sym_ext = rb_entry(node, struct sym_ext, node);
 		percent = sym_ext->percent;
-		color = get_color(percent);
+		color = get_percent_color(percent);
 		path = sym_ext->path;
 
 		color_fprintf(stdout, color, " %7.2f %s", percent, path);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index e8c9817..c9dbe33 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -947,25 +947,10 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
 	if (exclude_other && !self->parent)
 		return 0;
 
-	if (total_samples) {
-		double percent = self->count * 100.0 / total_samples;
-		char *color = PERF_COLOR_NORMAL;
-
-		/*
-		 * We color high-overhead entries in red, mid-overhead
-		 * entries in green - and keep the low overhead places
-		 * normal:
-		 */
-		if (percent >= 5.0) {
-			color = PERF_COLOR_RED;
-		} else {
-			if (percent >= 0.5)
-				color = PERF_COLOR_GREEN;
-		}
-
-		ret = color_fprintf(fp, color, "   %6.2f%%",
+	if (total_samples)
+		ret = percent_color_fprintf(fp, "   %6.2f%%",
 				(self->count * 100.0) / total_samples);
-	} else
+	else
 		ret = fprintf(fp, "%12Ld ", self->count);
 
 	list_for_each_entry(se, &hist_entry__sort_list, list) {
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index aa044ea..95d5c0a 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -239,7 +239,6 @@ static void print_sym_table(void)
 	for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) {
 		struct sym_entry *syme = rb_entry(nd, struct sym_entry, rb_node);
 		struct symbol *sym = (struct symbol *)(syme + 1);
-		char *color = PERF_COLOR_NORMAL;
 		double pcnt;
 
 		if (++printed > print_entries || syme->snap_count < count_filter)
@@ -248,24 +247,12 @@ static void print_sym_table(void)
 		pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) /
 					 sum_ksamples));
 
-		/*
-		 * We color high-overhead entries in red, mid-overhead
-		 * entries in green - and keep the low overhead places
-		 * normal:
-		 */
-		if (pcnt >= 5.0) {
-			color = PERF_COLOR_RED;
-		} else {
-			if (pcnt >= 0.5)
-				color = PERF_COLOR_GREEN;
-		}
-
 		if (nr_counters == 1)
 			printf("%20.2f - ", syme->weight);
 		else
 			printf("%9.1f %10ld - ", syme->weight, syme->snap_count);
 
-		color_fprintf(stdout, color, "%4.1f%%", pcnt);
+		percent_color_fprintf(stdout, "%4.1f%%", pcnt);
 		printf(" - %016llx : %s", sym->start, sym->name);
 		if (sym->module)
 			printf("\t[%s]", sym->module->name);
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c
index 26f8231..90a044d 100644
--- a/tools/perf/util/color.c
+++ b/tools/perf/util/color.c
@@ -242,4 +242,31 @@ int color_fwrite_lines(FILE *fp, const char *color,
 	return 0;
 }
 
+char *get_percent_color(double percent)
+{
+	char *color = PERF_COLOR_NORMAL;
+
+	/*
+	 * We color high-overhead entries in red, mid-overhead
+	 * entries in green - and keep the low overhead places
+	 * normal:
+	 */
+	if (percent >= MIN_RED)
+		color = PERF_COLOR_RED;
+	else {
+		if (percent > MIN_GREEN)
+			color = PERF_COLOR_GREEN;
+	}
+	return color;
+}
 
+int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
+{
+	int r;
+	char *color;
+
+	color = get_percent_color(percent);
+	r = color_fprintf(fp, color, fmt, percent);
+
+	return r;
+}
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h
index 5abfd37..706cec5 100644
--- a/tools/perf/util/color.h
+++ b/tools/perf/util/color.h
@@ -15,6 +15,9 @@
 #define PERF_COLOR_CYAN		"\033[36m"
 #define PERF_COLOR_BG_RED	"\033[41m"
 
+#define MIN_GREEN	0.5
+#define MIN_RED		5.0
+
 /*
  * This variable stores the value of color.ui
  */
@@ -32,5 +35,7 @@ void color_parse_mem(const char *value, int len, const char *var, char *dst);
 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
 int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
 int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
+int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
+char *get_percent_color(double percent);
 
 #endif /* COLOR_H */

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

* [tip:perfcounters/urgent] perf_counter tools: Display percents of hits in callchain with overhead colors
  2009-07-02 18:14 ` [PATCH 3/3] perfcounter: Display percents of hits in callchain with overhead colors Frederic Weisbecker
@ 2009-07-02 19:42   ` tip-bot for Frederic Weisbecker
  0 siblings, 0 replies; 6+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-07-02 19:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, acme, anton, paulus, hpa, mingo, a.p.zijlstra,
	efault, fweisbec, tglx, mingo

Commit-ID:  24b57c6988c5791628c89a8838910991abc9cc1e
Gitweb:     http://git.kernel.org/tip/24b57c6988c5791628c89a8838910991abc9cc1e
Author:     Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Thu, 2 Jul 2009 20:14:35 +0200
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 2 Jul 2009 21:38:38 +0200

perf_counter tools: Display percents of hits in callchain with overhead colors

This adds the use of colors to signal at a glance the important
overhead thresholds in callchains hit rates.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <1246558475-10624-3-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 tools/perf/builtin-report.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c9dbe33..283773d 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -824,7 +824,7 @@ ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
 			double percent;
 
 			percent = hits * 100.0 / total_samples;
-			ret += fprintf(fp, "--%2.2f%%-- ", percent);
+			ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
 		} else
 			ret += fprintf(fp, "%s", "          ");
 	}
@@ -924,7 +924,8 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
 		chain = rb_entry(rb_node, struct callchain_node, rb_node);
 		percent = chain->hit * 100.0 / total_samples;
 		if (callchain_mode == FLAT) {
-			ret += fprintf(fp, "           %6.2f%%\n", percent);
+			ret += percent_color_fprintf(fp, "           %6.2f%%\n",
+						     percent);
 			ret += callchain__fprintf_flat(fp, chain, total_samples);
 		} else if (callchain_mode == GRAPH) {
 			ret += callchain__fprintf_graph(fp, chain,

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

end of thread, other threads:[~2009-07-02 19:43 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-02 18:14 [PATCH 1/3] perfcounter: Set the minimum percent for callchains to be displayed Frederic Weisbecker
2009-07-02 18:14 ` [PATCH 2/3] perfcounter: Provide helper to print percents color Frederic Weisbecker
2009-07-02 19:42   ` [tip:perfcounters/urgent] perf_counter tools: " tip-bot for Frederic Weisbecker
2009-07-02 18:14 ` [PATCH 3/3] perfcounter: Display percents of hits in callchain with overhead colors Frederic Weisbecker
2009-07-02 19:42   ` [tip:perfcounters/urgent] perf_counter tools: " tip-bot for Frederic Weisbecker
2009-07-02 19:42 ` [tip:perfcounters/urgent] perf_counter tools: Set the minimum percent for callchains to be displayed tip-bot for Frederic Weisbecker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome