linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] perf hists browser: Fix callchain print bug on TUI
  2014-09-20 16:18 [PATCHSET 0/5] perf tools: Add call-graph config options Namhyung Kim
@ 2014-09-20 16:18 ` Namhyung Kim
  0 siblings, 0 replies; 17+ messages in thread
From: Namhyung Kim @ 2014-09-20 16:18 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, David Ahern, Milian Wolff,
	LKML

Currently perf report -g graph option doesn't work as expected and
always work as same as -g fractal.  This was a bug during recent
callchain print code cleanup.

Before:
  $ perf report -g graph

    Children      Self  Command  Shared Object      Symbol
  ================================================================
  -   56.19%    35.41%  sleep    [kernel.kallsyms]  [k] page_fault
     - page_fault
        + 63.02% _dl_relocate_object
        + 36.98% clear_user

After:
    Children      Self  Command  Shared Object      Symbol
  ================================================================
  -   56.19%    35.41%  sleep    [kernel.kallsyms]  [k] page_fault
     - page_fault
        + 35.41% _dl_relocate_object
        + 20.78% clear_user

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/ui/browsers/hists.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index d4cef68176da..8f60a970404f 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -804,9 +804,6 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 			.is_current_entry = current_entry,
 		};
 
-		if (symbol_conf.cumulate_callchain)
-			total = entry->stat_acc->period;
-
 		printed += hist_browser__show_callchain(browser,
 					&entry->sorted_chain, 1, row, total,
 					hist_browser__show_callchain_entry, &arg,
-- 
2.1.0


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

* [PATCHSET 0/5] perf tools: Add call-graph config options (v2)
@ 2014-09-23  1:01 Namhyung Kim
  2014-09-23  1:01 ` [PATCH 1/5] perf hists browser: Fix callchain print bug on TUI Namhyung Kim
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Namhyung Kim @ 2014-09-23  1:01 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Paul Mackerras, Namhyung Kim,
	Namhyung Kim, LKML, Jiri Olsa, David Ahern, Milian Wolff

Hello,

This is patchset to add new callchain related config options so that
users don't need to pass their preference to the cmdline everytime.

Following config options will be added, and users can set appropriate
values to ~/.perfconfig file.  Note that the dump-size option is
meaningful only if record-mode = dwarf.

  $ cat ~/.perfconfig
  [call-graph]
    record-mode = dwarf
    dump-size = 4096
    print-type = graph
    order = callee
    threshold = 0.5
    print-limit = 128
    sort-key = function

  $ perf record -vg sleep 1
  callchain: type DWARF
  callchain: stack dump size 4096
  mmap size 528384B
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.054 MB perf.data (~2378 samples) ]
  Looking at the vmlinux_path (7 entries long)
  Using /lib/modules/3.16.3-1-ARCH/build/vmlinux for symbols


Jiri and David, I kept your Acked-by and Reviewed-by in this version.
Please take a look at the patch 4/5 which splits parser functions that
it still looks okay to you.


changes in v2)
 * use sizeof("call-graph.") instead of hardcoding the length  (Jiri)
 * split parse functions so that only handle relavant options
 * add Acked/Reviewed-by tags from David and Jiri


You can also get this from 'perf/callchain-config-v2' branch on my tree

  git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git


Any comments are welcomed, thanks
Namhyung


Namhyung Kim (5):
  perf hists browser: Fix callchain print bug on TUI
  perf tools: Move callchain config from record_opts to callchain_param
  perf tools: Move some callchain parser functions to callchain.c
  perf tools: Introduce perf_callchain_config()
  perf tools: Convert {record,top}.call-graph option to
    call-graph.record-mode

 tools/perf/builtin-record.c    | 119 ++++---------------------
 tools/perf/builtin-top.c       |   4 +-
 tools/perf/perf.h              |   3 -
 tools/perf/ui/browsers/hists.c |   3 -
 tools/perf/util/callchain.c    | 193 +++++++++++++++++++++++++++++++++++++----
 tools/perf/util/callchain.h    |   6 +-
 tools/perf/util/config.c       |   3 +
 tools/perf/util/evsel.c        |  11 ++-
 8 files changed, 203 insertions(+), 139 deletions(-)

-- 
2.1.0


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

* [PATCH 1/5] perf hists browser: Fix callchain print bug on TUI
  2014-09-23  1:01 [PATCHSET 0/5] perf tools: Add call-graph config options (v2) Namhyung Kim
@ 2014-09-23  1:01 ` Namhyung Kim
  2014-09-27  7:25   ` [tip:perf/core] " tip-bot for Namhyung Kim
  2014-09-23  1:01 ` [PATCH 2/5] perf tools: Move callchain config from record_opts to callchain_param Namhyung Kim
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Namhyung Kim @ 2014-09-23  1:01 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Paul Mackerras, Namhyung Kim,
	Namhyung Kim, LKML, Jiri Olsa, David Ahern, Milian Wolff

Currently perf report -g graph option doesn't work as expected and
always work as same as -g fractal.  This was a bug during recent
callchain print code cleanup.

Before:
  $ perf report -g graph

    Children      Self  Command  Shared Object      Symbol
  ================================================================
  -   56.19%    35.41%  sleep    [kernel.kallsyms]  [k] page_fault
     - page_fault
        + 63.02% _dl_relocate_object
        + 36.98% clear_user

After:
    Children      Self  Command  Shared Object      Symbol
  ================================================================
  -   56.19%    35.41%  sleep    [kernel.kallsyms]  [k] page_fault
     - page_fault
        + 35.41% _dl_relocate_object
        + 20.78% clear_user

Reviewed-by: David Ahern <dsahern@gmail.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/ui/browsers/hists.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index d4cef68176da..8f60a970404f 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -804,9 +804,6 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 			.is_current_entry = current_entry,
 		};
 
-		if (symbol_conf.cumulate_callchain)
-			total = entry->stat_acc->period;
-
 		printed += hist_browser__show_callchain(browser,
 					&entry->sorted_chain, 1, row, total,
 					hist_browser__show_callchain_entry, &arg,
-- 
2.1.0


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

* [PATCH 2/5] perf tools: Move callchain config from record_opts to callchain_param
  2014-09-23  1:01 [PATCHSET 0/5] perf tools: Add call-graph config options (v2) Namhyung Kim
  2014-09-23  1:01 ` [PATCH 1/5] perf hists browser: Fix callchain print bug on TUI Namhyung Kim
@ 2014-09-23  1:01 ` Namhyung Kim
  2014-09-27  7:25   ` [tip:perf/core] " tip-bot for Namhyung Kim
  2014-09-23  1:01 ` [PATCH 3/5] perf tools: Move some callchain parser functions to callchain.c Namhyung Kim
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Namhyung Kim @ 2014-09-23  1:01 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Paul Mackerras, Namhyung Kim,
	Namhyung Kim, LKML, Jiri Olsa, David Ahern, Milian Wolff

So that all callchain config parameters can be read/written to a single place.
It's a preparation to consolidate handling of all callchain options.

Reviewed-by: David Ahern <dsahern@gmail.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/builtin-record.c | 45 ++++++++++++++++++++-------------------------
 tools/perf/builtin-top.c    |  4 +---
 tools/perf/perf.h           |  3 ---
 tools/perf/util/callchain.h |  5 ++++-
 tools/perf/util/evsel.c     | 11 +++++------
 5 files changed, 30 insertions(+), 38 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index a1b040394170..4de632cd677b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -649,7 +649,7 @@ static int get_stack_size(char *str, unsigned long *_size)
 }
 #endif /* HAVE_DWARF_UNWIND_SUPPORT */
 
-int record_parse_callchain(const char *arg, struct record_opts *opts)
+int record_parse_callchain(const char *arg)
 {
 	char *tok, *name, *saveptr = NULL;
 	char *buf;
@@ -669,7 +669,7 @@ int record_parse_callchain(const char *arg, struct record_opts *opts)
 		/* Framepointer style */
 		if (!strncmp(name, "fp", sizeof("fp"))) {
 			if (!strtok_r(NULL, ",", &saveptr)) {
-				opts->call_graph = CALLCHAIN_FP;
+				callchain_param.record_mode = CALLCHAIN_FP;
 				ret = 0;
 			} else
 				pr_err("callchain: No more arguments "
@@ -682,15 +682,15 @@ int record_parse_callchain(const char *arg, struct record_opts *opts)
 			const unsigned long default_stack_dump_size = 8192;
 
 			ret = 0;
-			opts->call_graph = CALLCHAIN_DWARF;
-			opts->stack_dump_size = default_stack_dump_size;
+			callchain_param.record_mode = CALLCHAIN_DWARF;
+			callchain_param.dump_size = default_stack_dump_size;
 
 			tok = strtok_r(NULL, ",", &saveptr);
 			if (tok) {
 				unsigned long size = 0;
 
 				ret = get_stack_size(tok, &size);
-				opts->stack_dump_size = size;
+				callchain_param.dump_size = size;
 			}
 #endif /* HAVE_DWARF_UNWIND_SUPPORT */
 		} else {
@@ -705,61 +705,56 @@ int record_parse_callchain(const char *arg, struct record_opts *opts)
 	return ret;
 }
 
-static void callchain_debug(struct record_opts *opts)
+static void callchain_debug(void)
 {
 	static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" };
 
-	pr_debug("callchain: type %s\n", str[opts->call_graph]);
+	pr_debug("callchain: type %s\n", str[callchain_param.record_mode]);
 
-	if (opts->call_graph == CALLCHAIN_DWARF)
+	if (callchain_param.record_mode == CALLCHAIN_DWARF)
 		pr_debug("callchain: stack dump size %d\n",
-			 opts->stack_dump_size);
+			 callchain_param.dump_size);
 }
 
-int record_parse_callchain_opt(const struct option *opt,
+int record_parse_callchain_opt(const struct option *opt __maybe_unused,
 			       const char *arg,
 			       int unset)
 {
-	struct record_opts *opts = opt->value;
 	int ret;
 
-	opts->call_graph_enabled = !unset;
+	callchain_param.enabled = !unset;
 
 	/* --no-call-graph */
 	if (unset) {
-		opts->call_graph = CALLCHAIN_NONE;
+		callchain_param.record_mode = CALLCHAIN_NONE;
 		pr_debug("callchain: disabled\n");
 		return 0;
 	}
 
-	ret = record_parse_callchain(arg, opts);
+	ret = record_parse_callchain(arg);
 	if (!ret)
-		callchain_debug(opts);
+		callchain_debug();
 
 	return ret;
 }
 
-int record_callchain_opt(const struct option *opt,
+int record_callchain_opt(const struct option *opt __maybe_unused,
 			 const char *arg __maybe_unused,
 			 int unset __maybe_unused)
 {
-	struct record_opts *opts = opt->value;
+	callchain_param.enabled = true;
 
-	opts->call_graph_enabled = !unset;
+	if (callchain_param.record_mode == CALLCHAIN_NONE)
+		callchain_param.record_mode = CALLCHAIN_FP;
 
-	if (opts->call_graph == CALLCHAIN_NONE)
-		opts->call_graph = CALLCHAIN_FP;
-
-	callchain_debug(opts);
+	callchain_debug();
 	return 0;
 }
 
 static int perf_record_config(const char *var, const char *value, void *cb)
 {
-	struct record *rec = cb;
-
 	if (!strcmp(var, "record.call-graph"))
-		return record_parse_callchain(value, &rec->opts);
+		return record_parse_callchain(value);
 
 	return perf_default_config(var, value, cb);
 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index e13864be2acb..200a44b370c3 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1020,10 +1020,8 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 
 static int perf_top_config(const char *var, const char *value, void *cb)
 {
-	struct perf_top *top = cb;
-
 	if (!strcmp(var, "top.call-graph"))
-		return record_parse_callchain(value, &top->record_opts);
+		return record_parse_callchain(value);
 	if (!strcmp(var, "top.children")) {
 		symbol_conf.cumulate_callchain = perf_config_bool(var, value);
 		return 0;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 510c65f72858..220d44e44c1b 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -41,8 +41,6 @@ void pthread__unblock_sigwinch(void);
 
 struct record_opts {
 	struct target target;
-	int	     call_graph;
-	bool         call_graph_enabled;
 	bool	     group;
 	bool	     inherit_stat;
 	bool	     no_buffering;
@@ -60,7 +58,6 @@ struct record_opts {
 	u64          branch_stack;
 	u64	     default_interval;
 	u64	     user_interval;
-	u16	     stack_dump_size;
 	bool	     sample_transaction;
 	unsigned     initial_delay;
 };
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index da43619d6173..819ae4f61e08 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -54,6 +54,9 @@ enum chain_key {
 };
 
 struct callchain_param {
+	bool			enabled;
+	enum perf_call_graph_mode record_mode;
+	u32			dump_size;
 	enum chain_mode 	mode;
 	u32			print_limit;
 	double			min_percent;
@@ -154,7 +157,7 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
 struct option;
 struct hist_entry;
 
-int record_parse_callchain(const char *arg, struct record_opts *opts);
+int record_parse_callchain(const char *arg);
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index b38de5819323..e0868a901c4a 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -503,20 +503,19 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
 }
 
 static void
-perf_evsel__config_callgraph(struct perf_evsel *evsel,
-			     struct record_opts *opts)
+perf_evsel__config_callgraph(struct perf_evsel *evsel)
 {
 	bool function = perf_evsel__is_function_event(evsel);
 	struct perf_event_attr *attr = &evsel->attr;
 
 	perf_evsel__set_sample_bit(evsel, CALLCHAIN);
 
-	if (opts->call_graph == CALLCHAIN_DWARF) {
+	if (callchain_param.record_mode == CALLCHAIN_DWARF) {
 		if (!function) {
 			perf_evsel__set_sample_bit(evsel, REGS_USER);
 			perf_evsel__set_sample_bit(evsel, STACK_USER);
 			attr->sample_regs_user = PERF_REGS_MASK;
-			attr->sample_stack_user = opts->stack_dump_size;
+			attr->sample_stack_user = callchain_param.dump_size;
 			attr->exclude_callchain_user = 1;
 		} else {
 			pr_info("Cannot use DWARF unwind for function trace event,"
@@ -625,8 +624,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 		attr->mmap_data = track;
 	}
 
-	if (opts->call_graph_enabled && !evsel->no_aux_samples)
-		perf_evsel__config_callgraph(evsel, opts);
+	if (callchain_param.enabled && !evsel->no_aux_samples)
+		perf_evsel__config_callgraph(evsel);
 
 	if (target__has_cpu(&opts->target))
 		perf_evsel__set_sample_bit(evsel, CPU);
-- 
2.1.0


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

* [PATCH 3/5] perf tools: Move some callchain parser functions to callchain.c
  2014-09-23  1:01 [PATCHSET 0/5] perf tools: Add call-graph config options (v2) Namhyung Kim
  2014-09-23  1:01 ` [PATCH 1/5] perf hists browser: Fix callchain print bug on TUI Namhyung Kim
  2014-09-23  1:01 ` [PATCH 2/5] perf tools: Move callchain config from record_opts to callchain_param Namhyung Kim
@ 2014-09-23  1:01 ` Namhyung Kim
  2014-09-27  7:26   ` [tip:perf/core] perf callchain: Move some " tip-bot for Namhyung Kim
  2014-09-23  1:01 ` [PATCH 4/5] perf tools: Introduce perf_callchain_config() Namhyung Kim
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Namhyung Kim @ 2014-09-23  1:01 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Paul Mackerras, Namhyung Kim,
	Namhyung Kim, LKML, Jiri Olsa, David Ahern, Milian Wolff

And rename record_callchain_parse() to parse_callchain_record_opt() in
accordance to parse_callchain_report_opt().

Reviewed-by: David Ahern <dsahern@gmail.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/builtin-record.c | 88 ++-------------------------------------------
 tools/perf/builtin-top.c    |  2 +-
 tools/perf/util/callchain.c | 84 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/callchain.h |  2 +-
 4 files changed, 88 insertions(+), 88 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 4de632cd677b..12e1f2255f89 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -621,90 +621,6 @@ parse_branch_stack(const struct option *opt, const char *str, int unset)
 	return ret;
 }
 
-#ifdef HAVE_DWARF_UNWIND_SUPPORT
-static int get_stack_size(char *str, unsigned long *_size)
-{
-	char *endptr;
-	unsigned long size;
-	unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
-
-	size = strtoul(str, &endptr, 0);
-
-	do {
-		if (*endptr)
-			break;
-
-		size = round_up(size, sizeof(u64));
-		if (!size || size > max_size)
-			break;
-
-		*_size = size;
-		return 0;
-
-	} while (0);
-
-	pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
-	       max_size, str);
-	return -1;
-}
-#endif /* HAVE_DWARF_UNWIND_SUPPORT */
-
-int record_parse_callchain(const char *arg)
-{
-	char *tok, *name, *saveptr = NULL;
-	char *buf;
-	int ret = -1;
-
-	/* We need buffer that we know we can write to. */
-	buf = malloc(strlen(arg) + 1);
-	if (!buf)
-		return -ENOMEM;
-
-	strcpy(buf, arg);
-
-	tok = strtok_r((char *)buf, ",", &saveptr);
-	name = tok ? : (char *)buf;
-
-	do {
-		/* Framepointer style */
-		if (!strncmp(name, "fp", sizeof("fp"))) {
-			if (!strtok_r(NULL, ",", &saveptr)) {
-				callchain_param.record_mode = CALLCHAIN_FP;
-				ret = 0;
-			} else
-				pr_err("callchain: No more arguments "
-				       "needed for -g fp\n");
-			break;
-
-#ifdef HAVE_DWARF_UNWIND_SUPPORT
-		/* Dwarf style */
-		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
-			const unsigned long default_stack_dump_size = 8192;
-
-			ret = 0;
-			callchain_param.record_mode = CALLCHAIN_DWARF;
-			callchain_param.dump_size = default_stack_dump_size;
-
-			tok = strtok_r(NULL, ",", &saveptr);
-			if (tok) {
-				unsigned long size = 0;
-
-				ret = get_stack_size(tok, &size);
-				callchain_param.dump_size = size;
-			}
-#endif /* HAVE_DWARF_UNWIND_SUPPORT */
-		} else {
-			pr_err("callchain: Unknown --call-graph option "
-			       "value: %s\n", arg);
-			break;
-		}
-
-	} while (0);
-
-	free(buf);
-	return ret;
-}
-
 static void callchain_debug(void)
 {
 	static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" };
@@ -731,7 +647,7 @@ int record_parse_callchain_opt(const struct option *opt __maybe_unused,
 		return 0;
 	}
 
-	ret = record_parse_callchain(arg);
+	ret = parse_callchain_record_opt(arg);
 	if (!ret)
 		callchain_debug();
 
@@ -754,7 +670,7 @@ int record_callchain_opt(const struct option *opt __maybe_unused,
 static int perf_record_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "record.call-graph"))
-		return record_parse_callchain(value);
+		return parse_callchain_record_opt(value);
 
 	return perf_default_config(var, value, cb);
 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 200a44b370c3..45a3a461286f 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1021,7 +1021,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 static int perf_top_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "top.call-graph"))
-		return record_parse_callchain(value);
+		return parse_callchain_record_opt(value);
 	if (!strcmp(var, "top.children")) {
 		symbol_conf.cumulate_callchain = perf_config_bool(var, value);
 		return 0;
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 08f0fbf5527c..ba7297230143 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -25,6 +25,90 @@
 
 __thread struct callchain_cursor callchain_cursor;
 
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+static int get_stack_size(const char *str, unsigned long *_size)
+{
+	char *endptr;
+	unsigned long size;
+	unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
+
+	size = strtoul(str, &endptr, 0);
+
+	do {
+		if (*endptr)
+			break;
+
+		size = round_up(size, sizeof(u64));
+		if (!size || size > max_size)
+			break;
+
+		*_size = size;
+		return 0;
+
+	} while (0);
+
+	pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
+	       max_size, str);
+	return -1;
+}
+#endif /* HAVE_DWARF_UNWIND_SUPPORT */
+
+int parse_callchain_record_opt(const char *arg)
+{
+	char *tok, *name, *saveptr = NULL;
+	char *buf;
+	int ret = -1;
+
+	/* We need buffer that we know we can write to. */
+	buf = malloc(strlen(arg) + 1);
+	if (!buf)
+		return -ENOMEM;
+
+	strcpy(buf, arg);
+
+	tok = strtok_r((char *)buf, ",", &saveptr);
+	name = tok ? : (char *)buf;
+
+	do {
+		/* Framepointer style */
+		if (!strncmp(name, "fp", sizeof("fp"))) {
+			if (!strtok_r(NULL, ",", &saveptr)) {
+				callchain_param.record_mode = CALLCHAIN_FP;
+				ret = 0;
+			} else
+				pr_err("callchain: No more arguments "
+				       "needed for -g fp\n");
+			break;
+
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+		/* Dwarf style */
+		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
+			const unsigned long default_stack_dump_size = 8192;
+
+			ret = 0;
+			callchain_param.record_mode = CALLCHAIN_DWARF;
+			callchain_param.dump_size = default_stack_dump_size;
+
+			tok = strtok_r(NULL, ",", &saveptr);
+			if (tok) {
+				unsigned long size = 0;
+
+				ret = get_stack_size(tok, &size);
+				callchain_param.dump_size = size;
+			}
+#endif /* HAVE_DWARF_UNWIND_SUPPORT */
+		} else {
+			pr_err("callchain: Unknown --call-graph option "
+			       "value: %s\n", arg);
+			break;
+		}
+
+	} while (0);
+
+	free(buf);
+	return ret;
+}
+
 int
 parse_callchain_report_opt(const char *arg)
 {
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 819ae4f61e08..8adfbf0bab5c 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -157,7 +157,6 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
 struct option;
 struct hist_entry;
 
-int record_parse_callchain(const char *arg);
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 
@@ -169,6 +168,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
 			bool hide_unresolved);
 
 extern const char record_callchain_help[];
+int parse_callchain_record_opt(const char *arg);
 int parse_callchain_report_opt(const char *arg);
 
 static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
-- 
2.1.0


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

* [PATCH 4/5] perf tools: Introduce perf_callchain_config()
  2014-09-23  1:01 [PATCHSET 0/5] perf tools: Add call-graph config options (v2) Namhyung Kim
                   ` (2 preceding siblings ...)
  2014-09-23  1:01 ` [PATCH 3/5] perf tools: Move some callchain parser functions to callchain.c Namhyung Kim
@ 2014-09-23  1:01 ` Namhyung Kim
  2014-09-27  7:26   ` [tip:perf/core] " tip-bot for Namhyung Kim
  2014-09-23  1:01 ` [PATCH 5/5] perf tools: Convert {record,top}.call-graph option to call-graph.record-mode Namhyung Kim
  2014-09-23 11:56 ` [PATCH] perf tools: Fix line number in the config file error message Jiri Olsa
  5 siblings, 1 reply; 17+ messages in thread
From: Namhyung Kim @ 2014-09-23  1:01 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Paul Mackerras, Namhyung Kim,
	Namhyung Kim, LKML, Jiri Olsa, David Ahern, Milian Wolff

This patch adds support for following config options to ~/.perfconfig file.

  [call-graph]
    record-mode = dwarf
    dump-size = 8192
    print-type = fractal
    order = callee
    threshold = 0.5
    print-limit = 128
    sort-key = function

Reviewed-by: David Ahern <dsahern@gmail.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/callchain.c | 109 ++++++++++++++++++++++++++++++++++++--------
 tools/perf/util/callchain.h |   1 +
 tools/perf/util/config.c    |   3 ++
 3 files changed, 94 insertions(+), 19 deletions(-)

diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index ba7297230143..c84d3f8dcb75 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -109,6 +109,49 @@ int parse_callchain_record_opt(const char *arg)
 	return ret;
 }
 
+static int parse_callchain_mode(const char *value)
+{
+	if (!strncmp(value, "graph", strlen(value))) {
+		callchain_param.mode = CHAIN_GRAPH_ABS;
+		return 0;
+	}
+	if (!strncmp(value, "flat", strlen(value))) {
+		callchain_param.mode = CHAIN_FLAT;
+		return 0;
+	}
+	if (!strncmp(value, "fractal", strlen(value))) {
+		callchain_param.mode = CHAIN_GRAPH_REL;
+		return 0;
+	}
+	return -1;
+}
+
+static int parse_callchain_order(const char *value)
+{
+	if (!strncmp(value, "caller", strlen(value))) {
+		callchain_param.order = ORDER_CALLER;
+		return 0;
+	}
+	if (!strncmp(value, "callee", strlen(value))) {
+		callchain_param.order = ORDER_CALLEE;
+		return 0;
+	}
+	return -1;
+}
+
+static int parse_callchain_sort_key(const char *value)
+{
+	if (!strncmp(value, "function", strlen(value))) {
+		callchain_param.key = CCKEY_FUNCTION;
+		return 0;
+	}
+	if (!strncmp(value, "address", strlen(value))) {
+		callchain_param.key = CCKEY_ADDRESS;
+		return 0;
+	}
+	return -1;
+}
+
 int
 parse_callchain_report_opt(const char *arg)
 {
@@ -128,25 +171,12 @@ parse_callchain_report_opt(const char *arg)
 			return 0;
 		}
 
-		/* try to get the output mode */
-		if (!strncmp(tok, "graph", strlen(tok)))
-			callchain_param.mode = CHAIN_GRAPH_ABS;
-		else if (!strncmp(tok, "flat", strlen(tok)))
-			callchain_param.mode = CHAIN_FLAT;
-		else if (!strncmp(tok, "fractal", strlen(tok)))
-			callchain_param.mode = CHAIN_GRAPH_REL;
-		/* try to get the call chain order */
-		else if (!strncmp(tok, "caller", strlen(tok)))
-			callchain_param.order = ORDER_CALLER;
-		else if (!strncmp(tok, "callee", strlen(tok)))
-			callchain_param.order = ORDER_CALLEE;
-		/* try to get the sort key */
-		else if (!strncmp(tok, "function", strlen(tok)))
-			callchain_param.key = CCKEY_FUNCTION;
-		else if (!strncmp(tok, "address", strlen(tok)))
-			callchain_param.key = CCKEY_ADDRESS;
-		/* try to get the min percent */
-		else if (!minpcnt_set) {
+		if (!parse_callchain_mode(tok) ||
+		    !parse_callchain_order(tok) ||
+		    !parse_callchain_sort_key(tok)) {
+			/* parsing ok - move on to the next */
+		} else if (!minpcnt_set) {
+			/* try to get the min percent */
 			callchain_param.min_percent = strtod(tok, &endptr);
 			if (tok == endptr)
 				return -1;
@@ -168,6 +198,47 @@ parse_callchain_report_opt(const char *arg)
 	return 0;
 }
 
+int perf_callchain_config(const char *var, const char *value)
+{
+	char *endptr;
+
+	if (prefixcmp(var, "call-graph."))
+		return 0;
+	var += sizeof("call-graph.") - 1;
+
+	if (!strcmp(var, "record-mode"))
+		return parse_callchain_record_opt(value);
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+	if (!strcmp(var, "dump-size")) {
+		unsigned long size = 0;
+		int ret;
+
+		ret = get_stack_size(value, &size);
+		callchain_param.dump_size = size;
+
+		return ret;
+	}
+#endif
+	if (!strcmp(var, "print-type"))
+		return parse_callchain_mode(value);
+	if (!strcmp(var, "order"))
+		return parse_callchain_order(value);
+	if (!strcmp(var, "sort-key"))
+		return parse_callchain_sort_key(value);
+	if (!strcmp(var, "threshold")) {
+		callchain_param.min_percent = strtod(value, &endptr);
+		if (value == endptr)
+			return -1;
+	}
+	if (!strcmp(var, "print-limit")) {
+		callchain_param.print_limit = strtod(value, &endptr);
+		if (value == endptr)
+			return -1;
+	}
+
+	return 0;
+}
+
 static void
 rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
 		    enum chain_mode mode)
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 8adfbf0bab5c..2a1f5a46543a 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -170,6 +170,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
 extern const char record_callchain_help[];
 int parse_callchain_record_opt(const char *arg);
 int parse_callchain_report_opt(const char *arg);
+int perf_callchain_config(const char *var, const char *value);
 
 static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
 					     struct callchain_cursor *src)
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 9970b8b0190b..953512ed72ba 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -396,6 +396,9 @@ int perf_default_config(const char *var, const char *value,
 	if (!prefixcmp(var, "ui."))
 		return perf_ui_config(var, value);
 
+	if (!prefixcmp(var, "call-graph."))
+		return perf_callchain_config(var, value);
+
 	/* Add other config variables here. */
 	return 0;
 }
-- 
2.1.0


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

* [PATCH 5/5] perf tools: Convert {record,top}.call-graph option to call-graph.record-mode
  2014-09-23  1:01 [PATCHSET 0/5] perf tools: Add call-graph config options (v2) Namhyung Kim
                   ` (3 preceding siblings ...)
  2014-09-23  1:01 ` [PATCH 4/5] perf tools: Introduce perf_callchain_config() Namhyung Kim
@ 2014-09-23  1:01 ` Namhyung Kim
  2014-09-27  7:26   ` [tip:perf/core] perf tools: Convert {record, top}.call-graph " tip-bot for Namhyung Kim
  2014-09-23 11:56 ` [PATCH] perf tools: Fix line number in the config file error message Jiri Olsa
  5 siblings, 1 reply; 17+ messages in thread
From: Namhyung Kim @ 2014-09-23  1:01 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Peter Zijlstra, Ingo Molnar, Paul Mackerras, Namhyung Kim,
	Namhyung Kim, LKML, Jiri Olsa, David Ahern, Milian Wolff

So that it'll be passed to perf_callchain_config().

Reviewed-by: David Ahern <dsahern@gmail.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/builtin-record.c | 2 +-
 tools/perf/builtin-top.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 12e1f2255f89..86ed253fa1b8 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -670,7 +670,7 @@ int record_callchain_opt(const struct option *opt __maybe_unused,
 static int perf_record_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "record.call-graph"))
-		return parse_callchain_record_opt(value);
+		var = "call-graph.record-mode"; /* fall-through */
 
 	return perf_default_config(var, value, cb);
 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 45a3a461286f..d6cd4c3b13a0 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1021,7 +1021,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 static int perf_top_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "top.call-graph"))
-		return parse_callchain_record_opt(value);
+		var = "call-graph.record-mode"; /* fall-through */
 	if (!strcmp(var, "top.children")) {
 		symbol_conf.cumulate_callchain = perf_config_bool(var, value);
 		return 0;
-- 
2.1.0


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

* [PATCH] perf tools: Fix line number in the config file error message
  2014-09-23  1:01 [PATCHSET 0/5] perf tools: Add call-graph config options (v2) Namhyung Kim
                   ` (4 preceding siblings ...)
  2014-09-23  1:01 ` [PATCH 5/5] perf tools: Convert {record,top}.call-graph option to call-graph.record-mode Namhyung Kim
@ 2014-09-23 11:56 ` Jiri Olsa
  2014-09-24  0:21   ` Namhyung Kim
  2014-09-27  7:26   ` [tip:perf/core] " tip-bot for Jiri Olsa
  5 siblings, 2 replies; 17+ messages in thread
From: Jiri Olsa @ 2014-09-23 11:56 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Namhyung Kim, LKML, David Ahern, Milian Wolff

On Tue, Sep 23, 2014 at 10:01:39AM +0900, Namhyung Kim wrote:
> Hello,
> 
> This is patchset to add new callchain related config options so that
> users don't need to pass their preference to the cmdline everytime.
> 
> Following config options will be added, and users can set appropriate
> values to ~/.perfconfig file.  Note that the dump-size option is
> meaningful only if record-mode = dwarf.
> 
>   $ cat ~/.perfconfig
>   [call-graph]
>     record-mode = dwarf
>     dump-size = 4096
>     print-type = graph
>     order = callee
>     threshold = 0.5
>     print-limit = 128
>     sort-key = function
> 
>   $ perf record -vg sleep 1
>   callchain: type DWARF
>   callchain: stack dump size 4096
>   mmap size 528384B
>   [ perf record: Woken up 1 times to write data ]
>   [ perf record: Captured and wrote 0.054 MB perf.data (~2378 samples) ]
>   Looking at the vmlinux_path (7 entries long)
>   Using /lib/modules/3.16.3-1-ARCH/build/vmlinux for symbols
> 
> 
> Jiri and David, I kept your Acked-by and Reviewed-by in this version.
> Please take a look at the patch 4/5 which splits parser functions that
> it still looks okay to you.

looks ok to me, ACK for the patchset

During the testing I found wrong line is displayed in the parsing
error message. It's bug in the config code, attached patch should
fix it.

thanks,
jirka


---
If we fail to parse the config file within the callback function,
the line number counter 'could be' already on the next line.

This results in wrong line number report like:

  $ cat ~/.perfconfig
  [call-graph]
          sort-key = krava
  $ perf record ls
  Fatal: bad config file line 3 in /home/jolsa/.perfconfig

Fixing this by saving the current line number for this case.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/config.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 953512ed72ba..57ff826f150b 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -222,7 +222,8 @@ static int perf_parse_file(config_fn_t fn, void *data)
 	const unsigned char *bomptr = utf8_bom;
 
 	for (;;) {
-		int c = get_next_char();
+		int line, c = get_next_char();
+
 		if (bomptr && *bomptr) {
 			/* We are at the file beginning; skip UTF8-encoded BOM
 			 * if present. Sane editors won't put this in on their
@@ -261,8 +262,16 @@ static int perf_parse_file(config_fn_t fn, void *data)
 		if (!isalpha(c))
 			break;
 		var[baselen] = tolower(c);
-		if (get_value(fn, data, var, baselen+1) < 0)
+
+		/*
+		 * The get_value function might or might not reach the '\n',
+		 * so saving the current line number for error reporting.
+		 */
+		line = config_linenr;
+		if (get_value(fn, data, var, baselen+1) < 0) {
+			config_linenr = line;
 			break;
+		}
 	}
 	die("bad config file line %d in %s", config_linenr, config_file_name);
 }
-- 
1.8.3.1


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

* Re: [PATCH] perf tools: Fix line number in the config file error message
  2014-09-23 11:56 ` [PATCH] perf tools: Fix line number in the config file error message Jiri Olsa
@ 2014-09-24  0:21   ` Namhyung Kim
  2014-09-27  7:26   ` [tip:perf/core] " tip-bot for Jiri Olsa
  1 sibling, 0 replies; 17+ messages in thread
From: Namhyung Kim @ 2014-09-24  0:21 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Namhyung Kim, LKML, David Ahern, Milian Wolff

Hi Jiri,

On Tue, 23 Sep 2014 13:56:56 +0200, Jiri Olsa wrote:
> On Tue, Sep 23, 2014 at 10:01:39AM +0900, Namhyung Kim wrote:
>> Hello,
>> 
>> This is patchset to add new callchain related config options so that
>> users don't need to pass their preference to the cmdline everytime.
>> 
>> Following config options will be added, and users can set appropriate
>> values to ~/.perfconfig file.  Note that the dump-size option is
>> meaningful only if record-mode = dwarf.
>> 
>>   $ cat ~/.perfconfig
>>   [call-graph]
>>     record-mode = dwarf
>>     dump-size = 4096
>>     print-type = graph
>>     order = callee
>>     threshold = 0.5
>>     print-limit = 128
>>     sort-key = function
>> 
>>   $ perf record -vg sleep 1
>>   callchain: type DWARF
>>   callchain: stack dump size 4096
>>   mmap size 528384B
>>   [ perf record: Woken up 1 times to write data ]
>>   [ perf record: Captured and wrote 0.054 MB perf.data (~2378 samples) ]
>>   Looking at the vmlinux_path (7 entries long)
>>   Using /lib/modules/3.16.3-1-ARCH/build/vmlinux for symbols
>> 
>> 
>> Jiri and David, I kept your Acked-by and Reviewed-by in this version.
>> Please take a look at the patch 4/5 which splits parser functions that
>> it still looks okay to you.
>
> looks ok to me, ACK for the patchset

Thanks!

>
> During the testing I found wrong line is displayed in the parsing
> error message. It's bug in the config code, attached patch should
> fix it.

Didn't notice that.. thanks for the quick fix. :)

>
>
> ---
> If we fail to parse the config file within the callback function,
> the line number counter 'could be' already on the next line.
>
> This results in wrong line number report like:
>
>   $ cat ~/.perfconfig
>   [call-graph]
>           sort-key = krava
>   $ perf record ls
>   Fatal: bad config file line 3 in /home/jolsa/.perfconfig
>
> Fixing this by saving the current line number for this case.
>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>

Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung


> ---
>  tools/perf/util/config.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
> index 953512ed72ba..57ff826f150b 100644
> --- a/tools/perf/util/config.c
> +++ b/tools/perf/util/config.c
> @@ -222,7 +222,8 @@ static int perf_parse_file(config_fn_t fn, void *data)
>  	const unsigned char *bomptr = utf8_bom;
>  
>  	for (;;) {
> -		int c = get_next_char();
> +		int line, c = get_next_char();
> +
>  		if (bomptr && *bomptr) {
>  			/* We are at the file beginning; skip UTF8-encoded BOM
>  			 * if present. Sane editors won't put this in on their
> @@ -261,8 +262,16 @@ static int perf_parse_file(config_fn_t fn, void *data)
>  		if (!isalpha(c))
>  			break;
>  		var[baselen] = tolower(c);
> -		if (get_value(fn, data, var, baselen+1) < 0)
> +
> +		/*
> +		 * The get_value function might or might not reach the '\n',
> +		 * so saving the current line number for error reporting.
> +		 */
> +		line = config_linenr;
> +		if (get_value(fn, data, var, baselen+1) < 0) {
> +			config_linenr = line;
>  			break;
> +		}
>  	}
>  	die("bad config file line %d in %s", config_linenr, config_file_name);
>  }

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

* [tip:perf/core] perf hists browser: Fix callchain print bug on TUI
  2014-09-23  1:01 ` [PATCH 1/5] perf hists browser: Fix callchain print bug on TUI Namhyung Kim
@ 2014-09-27  7:25   ` tip-bot for Namhyung Kim
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Namhyung Kim @ 2014-09-27  7:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, a.p.zijlstra, mail,
	namhyung.kim, namhyung, jolsa, dsahern, tglx

Commit-ID:  72f72ed21e56c386dd92118e5da3ce06752b1614
Gitweb:     http://git.kernel.org/tip/72f72ed21e56c386dd92118e5da3ce06752b1614
Author:     Namhyung Kim <namhyung@kernel.org>
AuthorDate: Tue, 23 Sep 2014 10:01:40 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 26 Sep 2014 12:38:02 -0300

perf hists browser: Fix callchain print bug on TUI

Currently perf report -g graph option doesn't work as expected and
always work as same as -g fractal.  This was a bug during recent
callchain print code cleanup.

Before:
  $ perf report -g graph

    Children      Self  Command  Shared Object      Symbol
  ================================================================
  -   56.19%    35.41%  sleep    [kernel.kallsyms]  [k] page_fault
     - page_fault
        + 63.02% _dl_relocate_object
        + 36.98% clear_user

After:
    Children      Self  Command  Shared Object      Symbol
  ================================================================
  -   56.19%    35.41%  sleep    [kernel.kallsyms]  [k] page_fault
     - page_fault
        + 35.41% _dl_relocate_object
        + 20.78% clear_user

Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Milian Wolff <mail@milianw.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1411434104-5307-2-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/browsers/hists.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index d4cef68..8f60a97 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -804,9 +804,6 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 			.is_current_entry = current_entry,
 		};
 
-		if (symbol_conf.cumulate_callchain)
-			total = entry->stat_acc->period;
-
 		printed += hist_browser__show_callchain(browser,
 					&entry->sorted_chain, 1, row, total,
 					hist_browser__show_callchain_entry, &arg,

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

* [tip:perf/core] perf tools: Move callchain config from record_opts to callchain_param
  2014-09-23  1:01 ` [PATCH 2/5] perf tools: Move callchain config from record_opts to callchain_param Namhyung Kim
@ 2014-09-27  7:25   ` tip-bot for Namhyung Kim
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Namhyung Kim @ 2014-09-27  7:25 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, a.p.zijlstra, mail,
	namhyung.kim, namhyung, jolsa, dsahern, tglx

Commit-ID:  72a128aa083a7f4cc4f800718aaae05d9c698e26
Gitweb:     http://git.kernel.org/tip/72a128aa083a7f4cc4f800718aaae05d9c698e26
Author:     Namhyung Kim <namhyung@kernel.org>
AuthorDate: Tue, 23 Sep 2014 10:01:41 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 26 Sep 2014 12:40:33 -0300

perf tools: Move callchain config from record_opts to callchain_param

So that all callchain config parameters can be read/written to a single
place.  It's a preparation to consolidate handling of all callchain
options.

Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Milian Wolff <mail@milianw.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1411434104-5307-3-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c | 45 ++++++++++++++++++++-------------------------
 tools/perf/builtin-top.c    |  4 +---
 tools/perf/perf.h           |  3 ---
 tools/perf/util/callchain.h |  5 ++++-
 tools/perf/util/evsel.c     | 11 +++++------
 5 files changed, 30 insertions(+), 38 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 320b198..fde0df7 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -652,7 +652,7 @@ static int get_stack_size(char *str, unsigned long *_size)
 }
 #endif /* HAVE_DWARF_UNWIND_SUPPORT */
 
-int record_parse_callchain(const char *arg, struct record_opts *opts)
+int record_parse_callchain(const char *arg)
 {
 	char *tok, *name, *saveptr = NULL;
 	char *buf;
@@ -672,7 +672,7 @@ int record_parse_callchain(const char *arg, struct record_opts *opts)
 		/* Framepointer style */
 		if (!strncmp(name, "fp", sizeof("fp"))) {
 			if (!strtok_r(NULL, ",", &saveptr)) {
-				opts->call_graph = CALLCHAIN_FP;
+				callchain_param.record_mode = CALLCHAIN_FP;
 				ret = 0;
 			} else
 				pr_err("callchain: No more arguments "
@@ -685,15 +685,15 @@ int record_parse_callchain(const char *arg, struct record_opts *opts)
 			const unsigned long default_stack_dump_size = 8192;
 
 			ret = 0;
-			opts->call_graph = CALLCHAIN_DWARF;
-			opts->stack_dump_size = default_stack_dump_size;
+			callchain_param.record_mode = CALLCHAIN_DWARF;
+			callchain_param.dump_size = default_stack_dump_size;
 
 			tok = strtok_r(NULL, ",", &saveptr);
 			if (tok) {
 				unsigned long size = 0;
 
 				ret = get_stack_size(tok, &size);
-				opts->stack_dump_size = size;
+				callchain_param.dump_size = size;
 			}
 #endif /* HAVE_DWARF_UNWIND_SUPPORT */
 		} else {
@@ -708,61 +708,56 @@ int record_parse_callchain(const char *arg, struct record_opts *opts)
 	return ret;
 }
 
-static void callchain_debug(struct record_opts *opts)
+static void callchain_debug(void)
 {
 	static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" };
 
-	pr_debug("callchain: type %s\n", str[opts->call_graph]);
+	pr_debug("callchain: type %s\n", str[callchain_param.record_mode]);
 
-	if (opts->call_graph == CALLCHAIN_DWARF)
+	if (callchain_param.record_mode == CALLCHAIN_DWARF)
 		pr_debug("callchain: stack dump size %d\n",
-			 opts->stack_dump_size);
+			 callchain_param.dump_size);
 }
 
-int record_parse_callchain_opt(const struct option *opt,
+int record_parse_callchain_opt(const struct option *opt __maybe_unused,
 			       const char *arg,
 			       int unset)
 {
-	struct record_opts *opts = opt->value;
 	int ret;
 
-	opts->call_graph_enabled = !unset;
+	callchain_param.enabled = !unset;
 
 	/* --no-call-graph */
 	if (unset) {
-		opts->call_graph = CALLCHAIN_NONE;
+		callchain_param.record_mode = CALLCHAIN_NONE;
 		pr_debug("callchain: disabled\n");
 		return 0;
 	}
 
-	ret = record_parse_callchain(arg, opts);
+	ret = record_parse_callchain(arg);
 	if (!ret)
-		callchain_debug(opts);
+		callchain_debug();
 
 	return ret;
 }
 
-int record_callchain_opt(const struct option *opt,
+int record_callchain_opt(const struct option *opt __maybe_unused,
 			 const char *arg __maybe_unused,
 			 int unset __maybe_unused)
 {
-	struct record_opts *opts = opt->value;
+	callchain_param.enabled = true;
 
-	opts->call_graph_enabled = !unset;
+	if (callchain_param.record_mode == CALLCHAIN_NONE)
+		callchain_param.record_mode = CALLCHAIN_FP;
 
-	if (opts->call_graph == CALLCHAIN_NONE)
-		opts->call_graph = CALLCHAIN_FP;
-
-	callchain_debug(opts);
+	callchain_debug();
 	return 0;
 }
 
 static int perf_record_config(const char *var, const char *value, void *cb)
 {
-	struct record *rec = cb;
-
 	if (!strcmp(var, "record.call-graph"))
-		return record_parse_callchain(value, &rec->opts);
+		return record_parse_callchain(value);
 
 	return perf_default_config(var, value, cb);
 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 5c16ba2..f7003fc 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1020,10 +1020,8 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 
 static int perf_top_config(const char *var, const char *value, void *cb)
 {
-	struct perf_top *top = cb;
-
 	if (!strcmp(var, "top.call-graph"))
-		return record_parse_callchain(value, &top->record_opts);
+		return record_parse_callchain(value);
 	if (!strcmp(var, "top.children")) {
 		symbol_conf.cumulate_callchain = perf_config_bool(var, value);
 		return 0;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 510c65f..220d44e 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -41,8 +41,6 @@ void pthread__unblock_sigwinch(void);
 
 struct record_opts {
 	struct target target;
-	int	     call_graph;
-	bool         call_graph_enabled;
 	bool	     group;
 	bool	     inherit_stat;
 	bool	     no_buffering;
@@ -60,7 +58,6 @@ struct record_opts {
 	u64          branch_stack;
 	u64	     default_interval;
 	u64	     user_interval;
-	u16	     stack_dump_size;
 	bool	     sample_transaction;
 	unsigned     initial_delay;
 };
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index da43619..819ae4f 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -54,6 +54,9 @@ enum chain_key {
 };
 
 struct callchain_param {
+	bool			enabled;
+	enum perf_call_graph_mode record_mode;
+	u32			dump_size;
 	enum chain_mode 	mode;
 	u32			print_limit;
 	double			min_percent;
@@ -154,7 +157,7 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
 struct option;
 struct hist_entry;
 
-int record_parse_callchain(const char *arg, struct record_opts *opts);
+int record_parse_callchain(const char *arg);
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index b38de58..e0868a9 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -503,20 +503,19 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
 }
 
 static void
-perf_evsel__config_callgraph(struct perf_evsel *evsel,
-			     struct record_opts *opts)
+perf_evsel__config_callgraph(struct perf_evsel *evsel)
 {
 	bool function = perf_evsel__is_function_event(evsel);
 	struct perf_event_attr *attr = &evsel->attr;
 
 	perf_evsel__set_sample_bit(evsel, CALLCHAIN);
 
-	if (opts->call_graph == CALLCHAIN_DWARF) {
+	if (callchain_param.record_mode == CALLCHAIN_DWARF) {
 		if (!function) {
 			perf_evsel__set_sample_bit(evsel, REGS_USER);
 			perf_evsel__set_sample_bit(evsel, STACK_USER);
 			attr->sample_regs_user = PERF_REGS_MASK;
-			attr->sample_stack_user = opts->stack_dump_size;
+			attr->sample_stack_user = callchain_param.dump_size;
 			attr->exclude_callchain_user = 1;
 		} else {
 			pr_info("Cannot use DWARF unwind for function trace event,"
@@ -625,8 +624,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 		attr->mmap_data = track;
 	}
 
-	if (opts->call_graph_enabled && !evsel->no_aux_samples)
-		perf_evsel__config_callgraph(evsel, opts);
+	if (callchain_param.enabled && !evsel->no_aux_samples)
+		perf_evsel__config_callgraph(evsel);
 
 	if (target__has_cpu(&opts->target))
 		perf_evsel__set_sample_bit(evsel, CPU);

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

* [tip:perf/core] perf callchain: Move some parser functions to callchain.c
  2014-09-23  1:01 ` [PATCH 3/5] perf tools: Move some callchain parser functions to callchain.c Namhyung Kim
@ 2014-09-27  7:26   ` tip-bot for Namhyung Kim
  2014-09-27 14:29     ` Frederic Weisbecker
  0 siblings, 1 reply; 17+ messages in thread
From: tip-bot for Namhyung Kim @ 2014-09-27  7:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, a.p.zijlstra, mail,
	namhyung.kim, namhyung, jolsa, dsahern, tglx

Commit-ID:  f7f084f4d3c29b0f9877a32fc6e2feacd47695b9
Gitweb:     http://git.kernel.org/tip/f7f084f4d3c29b0f9877a32fc6e2feacd47695b9
Author:     Namhyung Kim <namhyung@kernel.org>
AuthorDate: Tue, 23 Sep 2014 10:01:42 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 26 Sep 2014 12:41:57 -0300

perf callchain: Move some parser functions to callchain.c

And rename record_callchain_parse() to parse_callchain_record_opt() in
accordance to parse_callchain_report_opt().

Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Milian Wolff <mail@milianw.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1411434104-5307-4-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c | 88 ++-------------------------------------------
 tools/perf/builtin-top.c    |  2 +-
 tools/perf/util/callchain.c | 84 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/callchain.h |  2 +-
 4 files changed, 88 insertions(+), 88 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index fde0df7..0ee647b 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -624,90 +624,6 @@ error:
 	return ret;
 }
 
-#ifdef HAVE_DWARF_UNWIND_SUPPORT
-static int get_stack_size(char *str, unsigned long *_size)
-{
-	char *endptr;
-	unsigned long size;
-	unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
-
-	size = strtoul(str, &endptr, 0);
-
-	do {
-		if (*endptr)
-			break;
-
-		size = round_up(size, sizeof(u64));
-		if (!size || size > max_size)
-			break;
-
-		*_size = size;
-		return 0;
-
-	} while (0);
-
-	pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
-	       max_size, str);
-	return -1;
-}
-#endif /* HAVE_DWARF_UNWIND_SUPPORT */
-
-int record_parse_callchain(const char *arg)
-{
-	char *tok, *name, *saveptr = NULL;
-	char *buf;
-	int ret = -1;
-
-	/* We need buffer that we know we can write to. */
-	buf = malloc(strlen(arg) + 1);
-	if (!buf)
-		return -ENOMEM;
-
-	strcpy(buf, arg);
-
-	tok = strtok_r((char *)buf, ",", &saveptr);
-	name = tok ? : (char *)buf;
-
-	do {
-		/* Framepointer style */
-		if (!strncmp(name, "fp", sizeof("fp"))) {
-			if (!strtok_r(NULL, ",", &saveptr)) {
-				callchain_param.record_mode = CALLCHAIN_FP;
-				ret = 0;
-			} else
-				pr_err("callchain: No more arguments "
-				       "needed for -g fp\n");
-			break;
-
-#ifdef HAVE_DWARF_UNWIND_SUPPORT
-		/* Dwarf style */
-		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
-			const unsigned long default_stack_dump_size = 8192;
-
-			ret = 0;
-			callchain_param.record_mode = CALLCHAIN_DWARF;
-			callchain_param.dump_size = default_stack_dump_size;
-
-			tok = strtok_r(NULL, ",", &saveptr);
-			if (tok) {
-				unsigned long size = 0;
-
-				ret = get_stack_size(tok, &size);
-				callchain_param.dump_size = size;
-			}
-#endif /* HAVE_DWARF_UNWIND_SUPPORT */
-		} else {
-			pr_err("callchain: Unknown --call-graph option "
-			       "value: %s\n", arg);
-			break;
-		}
-
-	} while (0);
-
-	free(buf);
-	return ret;
-}
-
 static void callchain_debug(void)
 {
 	static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF" };
@@ -734,7 +650,7 @@ int record_parse_callchain_opt(const struct option *opt __maybe_unused,
 		return 0;
 	}
 
-	ret = record_parse_callchain(arg);
+	ret = parse_callchain_record_opt(arg);
 	if (!ret)
 		callchain_debug();
 
@@ -757,7 +673,7 @@ int record_callchain_opt(const struct option *opt __maybe_unused,
 static int perf_record_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "record.call-graph"))
-		return record_parse_callchain(value);
+		return parse_callchain_record_opt(value);
 
 	return perf_default_config(var, value, cb);
 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f7003fc..9d647a0 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1021,7 +1021,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 static int perf_top_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "top.call-graph"))
-		return record_parse_callchain(value);
+		return parse_callchain_record_opt(value);
 	if (!strcmp(var, "top.children")) {
 		symbol_conf.cumulate_callchain = perf_config_bool(var, value);
 		return 0;
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 08f0fbf..ba72972 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -25,6 +25,90 @@
 
 __thread struct callchain_cursor callchain_cursor;
 
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+static int get_stack_size(const char *str, unsigned long *_size)
+{
+	char *endptr;
+	unsigned long size;
+	unsigned long max_size = round_down(USHRT_MAX, sizeof(u64));
+
+	size = strtoul(str, &endptr, 0);
+
+	do {
+		if (*endptr)
+			break;
+
+		size = round_up(size, sizeof(u64));
+		if (!size || size > max_size)
+			break;
+
+		*_size = size;
+		return 0;
+
+	} while (0);
+
+	pr_err("callchain: Incorrect stack dump size (max %ld): %s\n",
+	       max_size, str);
+	return -1;
+}
+#endif /* HAVE_DWARF_UNWIND_SUPPORT */
+
+int parse_callchain_record_opt(const char *arg)
+{
+	char *tok, *name, *saveptr = NULL;
+	char *buf;
+	int ret = -1;
+
+	/* We need buffer that we know we can write to. */
+	buf = malloc(strlen(arg) + 1);
+	if (!buf)
+		return -ENOMEM;
+
+	strcpy(buf, arg);
+
+	tok = strtok_r((char *)buf, ",", &saveptr);
+	name = tok ? : (char *)buf;
+
+	do {
+		/* Framepointer style */
+		if (!strncmp(name, "fp", sizeof("fp"))) {
+			if (!strtok_r(NULL, ",", &saveptr)) {
+				callchain_param.record_mode = CALLCHAIN_FP;
+				ret = 0;
+			} else
+				pr_err("callchain: No more arguments "
+				       "needed for -g fp\n");
+			break;
+
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+		/* Dwarf style */
+		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
+			const unsigned long default_stack_dump_size = 8192;
+
+			ret = 0;
+			callchain_param.record_mode = CALLCHAIN_DWARF;
+			callchain_param.dump_size = default_stack_dump_size;
+
+			tok = strtok_r(NULL, ",", &saveptr);
+			if (tok) {
+				unsigned long size = 0;
+
+				ret = get_stack_size(tok, &size);
+				callchain_param.dump_size = size;
+			}
+#endif /* HAVE_DWARF_UNWIND_SUPPORT */
+		} else {
+			pr_err("callchain: Unknown --call-graph option "
+			       "value: %s\n", arg);
+			break;
+		}
+
+	} while (0);
+
+	free(buf);
+	return ret;
+}
+
 int
 parse_callchain_report_opt(const char *arg)
 {
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 819ae4f..8adfbf0 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -157,7 +157,6 @@ static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
 struct option;
 struct hist_entry;
 
-int record_parse_callchain(const char *arg);
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 
@@ -169,6 +168,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
 			bool hide_unresolved);
 
 extern const char record_callchain_help[];
+int parse_callchain_record_opt(const char *arg);
 int parse_callchain_report_opt(const char *arg);
 
 static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,

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

* [tip:perf/core] perf tools: Introduce perf_callchain_config()
  2014-09-23  1:01 ` [PATCH 4/5] perf tools: Introduce perf_callchain_config() Namhyung Kim
@ 2014-09-27  7:26   ` tip-bot for Namhyung Kim
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Namhyung Kim @ 2014-09-27  7:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, a.p.zijlstra, mail,
	namhyung.kim, namhyung, jolsa, dsahern, tglx

Commit-ID:  2b9240cafe9780f77b257321b13c4c4d2c2d0dc8
Gitweb:     http://git.kernel.org/tip/2b9240cafe9780f77b257321b13c4c4d2c2d0dc8
Author:     Namhyung Kim <namhyung@kernel.org>
AuthorDate: Tue, 23 Sep 2014 10:01:43 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 26 Sep 2014 12:43:24 -0300

perf tools: Introduce perf_callchain_config()

This patch adds support for following config options to ~/.perfconfig file.

  [call-graph]
    record-mode = dwarf
    dump-size = 8192
    print-type = fractal
    order = callee
    threshold = 0.5
    print-limit = 128
    sort-key = function

Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Milian Wolff <mail@milianw.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1411434104-5307-5-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/callchain.c | 109 ++++++++++++++++++++++++++++++++++++--------
 tools/perf/util/callchain.h |   1 +
 tools/perf/util/config.c    |   3 ++
 3 files changed, 94 insertions(+), 19 deletions(-)

diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index ba72972..c84d3f8 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -109,6 +109,49 @@ int parse_callchain_record_opt(const char *arg)
 	return ret;
 }
 
+static int parse_callchain_mode(const char *value)
+{
+	if (!strncmp(value, "graph", strlen(value))) {
+		callchain_param.mode = CHAIN_GRAPH_ABS;
+		return 0;
+	}
+	if (!strncmp(value, "flat", strlen(value))) {
+		callchain_param.mode = CHAIN_FLAT;
+		return 0;
+	}
+	if (!strncmp(value, "fractal", strlen(value))) {
+		callchain_param.mode = CHAIN_GRAPH_REL;
+		return 0;
+	}
+	return -1;
+}
+
+static int parse_callchain_order(const char *value)
+{
+	if (!strncmp(value, "caller", strlen(value))) {
+		callchain_param.order = ORDER_CALLER;
+		return 0;
+	}
+	if (!strncmp(value, "callee", strlen(value))) {
+		callchain_param.order = ORDER_CALLEE;
+		return 0;
+	}
+	return -1;
+}
+
+static int parse_callchain_sort_key(const char *value)
+{
+	if (!strncmp(value, "function", strlen(value))) {
+		callchain_param.key = CCKEY_FUNCTION;
+		return 0;
+	}
+	if (!strncmp(value, "address", strlen(value))) {
+		callchain_param.key = CCKEY_ADDRESS;
+		return 0;
+	}
+	return -1;
+}
+
 int
 parse_callchain_report_opt(const char *arg)
 {
@@ -128,25 +171,12 @@ parse_callchain_report_opt(const char *arg)
 			return 0;
 		}
 
-		/* try to get the output mode */
-		if (!strncmp(tok, "graph", strlen(tok)))
-			callchain_param.mode = CHAIN_GRAPH_ABS;
-		else if (!strncmp(tok, "flat", strlen(tok)))
-			callchain_param.mode = CHAIN_FLAT;
-		else if (!strncmp(tok, "fractal", strlen(tok)))
-			callchain_param.mode = CHAIN_GRAPH_REL;
-		/* try to get the call chain order */
-		else if (!strncmp(tok, "caller", strlen(tok)))
-			callchain_param.order = ORDER_CALLER;
-		else if (!strncmp(tok, "callee", strlen(tok)))
-			callchain_param.order = ORDER_CALLEE;
-		/* try to get the sort key */
-		else if (!strncmp(tok, "function", strlen(tok)))
-			callchain_param.key = CCKEY_FUNCTION;
-		else if (!strncmp(tok, "address", strlen(tok)))
-			callchain_param.key = CCKEY_ADDRESS;
-		/* try to get the min percent */
-		else if (!minpcnt_set) {
+		if (!parse_callchain_mode(tok) ||
+		    !parse_callchain_order(tok) ||
+		    !parse_callchain_sort_key(tok)) {
+			/* parsing ok - move on to the next */
+		} else if (!minpcnt_set) {
+			/* try to get the min percent */
 			callchain_param.min_percent = strtod(tok, &endptr);
 			if (tok == endptr)
 				return -1;
@@ -168,6 +198,47 @@ parse_callchain_report_opt(const char *arg)
 	return 0;
 }
 
+int perf_callchain_config(const char *var, const char *value)
+{
+	char *endptr;
+
+	if (prefixcmp(var, "call-graph."))
+		return 0;
+	var += sizeof("call-graph.") - 1;
+
+	if (!strcmp(var, "record-mode"))
+		return parse_callchain_record_opt(value);
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+	if (!strcmp(var, "dump-size")) {
+		unsigned long size = 0;
+		int ret;
+
+		ret = get_stack_size(value, &size);
+		callchain_param.dump_size = size;
+
+		return ret;
+	}
+#endif
+	if (!strcmp(var, "print-type"))
+		return parse_callchain_mode(value);
+	if (!strcmp(var, "order"))
+		return parse_callchain_order(value);
+	if (!strcmp(var, "sort-key"))
+		return parse_callchain_sort_key(value);
+	if (!strcmp(var, "threshold")) {
+		callchain_param.min_percent = strtod(value, &endptr);
+		if (value == endptr)
+			return -1;
+	}
+	if (!strcmp(var, "print-limit")) {
+		callchain_param.print_limit = strtod(value, &endptr);
+		if (value == endptr)
+			return -1;
+	}
+
+	return 0;
+}
+
 static void
 rb_insert_callchain(struct rb_root *root, struct callchain_node *chain,
 		    enum chain_mode mode)
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 8adfbf0..2a1f5a4 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -170,6 +170,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *
 extern const char record_callchain_help[];
 int parse_callchain_record_opt(const char *arg);
 int parse_callchain_report_opt(const char *arg);
+int perf_callchain_config(const char *var, const char *value);
 
 static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
 					     struct callchain_cursor *src)
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 9970b8b..953512e 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -396,6 +396,9 @@ int perf_default_config(const char *var, const char *value,
 	if (!prefixcmp(var, "ui."))
 		return perf_ui_config(var, value);
 
+	if (!prefixcmp(var, "call-graph."))
+		return perf_callchain_config(var, value);
+
 	/* Add other config variables here. */
 	return 0;
 }

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

* [tip:perf/core] perf tools: Convert {record, top}.call-graph option to call-graph.record-mode
  2014-09-23  1:01 ` [PATCH 5/5] perf tools: Convert {record,top}.call-graph option to call-graph.record-mode Namhyung Kim
@ 2014-09-27  7:26   ` tip-bot for Namhyung Kim
  0 siblings, 0 replies; 17+ messages in thread
From: tip-bot for Namhyung Kim @ 2014-09-27  7:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, a.p.zijlstra, mail,
	namhyung.kim, namhyung, jolsa, dsahern, tglx

Commit-ID:  5a2e5e85989025a3bb23ea5571fdac0cc5787807
Gitweb:     http://git.kernel.org/tip/5a2e5e85989025a3bb23ea5571fdac0cc5787807
Author:     Namhyung Kim <namhyung@kernel.org>
AuthorDate: Tue, 23 Sep 2014 10:01:44 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 26 Sep 2014 12:43:53 -0300

perf tools: Convert {record,top}.call-graph option to call-graph.record-mode

So that it'll be passed to perf_callchain_config().

Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Milian Wolff <mail@milianw.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1411434104-5307-6-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c | 2 +-
 tools/perf/builtin-top.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 0ee647b..44c6f3d 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -673,7 +673,7 @@ int record_callchain_opt(const struct option *opt __maybe_unused,
 static int perf_record_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "record.call-graph"))
-		return parse_callchain_record_opt(value);
+		var = "call-graph.record-mode"; /* fall-through */
 
 	return perf_default_config(var, value, cb);
 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 9d647a0..fc3d55f 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1021,7 +1021,7 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
 static int perf_top_config(const char *var, const char *value, void *cb)
 {
 	if (!strcmp(var, "top.call-graph"))
-		return parse_callchain_record_opt(value);
+		var = "call-graph.record-mode"; /* fall-through */
 	if (!strcmp(var, "top.children")) {
 		symbol_conf.cumulate_callchain = perf_config_bool(var, value);
 		return 0;

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

* [tip:perf/core] perf tools: Fix line number in the config file error message
  2014-09-23 11:56 ` [PATCH] perf tools: Fix line number in the config file error message Jiri Olsa
  2014-09-24  0:21   ` Namhyung Kim
@ 2014-09-27  7:26   ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Jiri Olsa @ 2014-09-27  7:26 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, jolsa, a.p.zijlstra, mail,
	namhyung.kim, namhyung, jolsa, dsahern, tglx, cjashfor

Commit-ID:  49757c9cc7887bc79f742eb8aacf16e464ca5f0b
Gitweb:     http://git.kernel.org/tip/49757c9cc7887bc79f742eb8aacf16e464ca5f0b
Author:     Jiri Olsa <jolsa@redhat.com>
AuthorDate: Tue, 23 Sep 2014 13:56:56 +0200
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 26 Sep 2014 12:45:23 -0300

perf tools: Fix line number in the config file error message

If we fail to parse the config file within the callback function,
the line number counter 'could be' already on the next line.

This results in wrong line number report like:

  $ cat ~/.perfconfig
  [call-graph]
          sort-key = krava
  $ perf record ls
  Fatal: bad config file line 3 in /home/jolsa/.perfconfig

Fixing this by saving the current line number for this case.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Milian Wolff <mail@milianw.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20140923115656.GC2979@krava.brq.redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/config.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 953512e..57ff826 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -222,7 +222,8 @@ static int perf_parse_file(config_fn_t fn, void *data)
 	const unsigned char *bomptr = utf8_bom;
 
 	for (;;) {
-		int c = get_next_char();
+		int line, c = get_next_char();
+
 		if (bomptr && *bomptr) {
 			/* We are at the file beginning; skip UTF8-encoded BOM
 			 * if present. Sane editors won't put this in on their
@@ -261,8 +262,16 @@ static int perf_parse_file(config_fn_t fn, void *data)
 		if (!isalpha(c))
 			break;
 		var[baselen] = tolower(c);
-		if (get_value(fn, data, var, baselen+1) < 0)
+
+		/*
+		 * The get_value function might or might not reach the '\n',
+		 * so saving the current line number for error reporting.
+		 */
+		line = config_linenr;
+		if (get_value(fn, data, var, baselen+1) < 0) {
+			config_linenr = line;
 			break;
+		}
 	}
 	die("bad config file line %d in %s", config_linenr, config_file_name);
 }

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

* Re: [tip:perf/core] perf callchain: Move some parser functions to callchain.c
  2014-09-27  7:26   ` [tip:perf/core] perf callchain: Move some " tip-bot for Namhyung Kim
@ 2014-09-27 14:29     ` Frederic Weisbecker
  2014-09-29  4:18       ` Namhyung Kim
  0 siblings, 1 reply; 17+ messages in thread
From: Frederic Weisbecker @ 2014-09-27 14:29 UTC (permalink / raw)
  To: Ingo Molnar, H. Peter Anvin, Paul Mackerras, LKML,
	Arnaldo Carvalho de Melo, Peter Zijlstra, mail, Namhyung Kim,
	Namhyung Kim, Jiri Olsa, David Ahern, Thomas Gleixner
  Cc: linux-tip-commits

Hi Namhyung,

2014-09-27 9:26 GMT+02:00 tip-bot for Namhyung Kim <tipbot@zytor.com>:
> Commit-ID:  f7f084f4d3c29b0f9877a32fc6e2feacd47695b9
> Gitweb:     http://git.kernel.org/tip/f7f084f4d3c29b0f9877a32fc6e2feacd47695b9
> Author:     Namhyung Kim <namhyung@kernel.org>
> AuthorDate: Tue, 23 Sep 2014 10:01:42 +0900
> Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
> CommitDate: Fri, 26 Sep 2014 12:41:57 -0300
>
> perf callchain: Move some parser functions to callchain.c

Please Cc me on callchain stuff. I may not be very verbose but I still
keep an eye on evolutions there.

Thanks.

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

* Re: [tip:perf/core] perf callchain: Move some parser functions to callchain.c
  2014-09-27 14:29     ` Frederic Weisbecker
@ 2014-09-29  4:18       ` Namhyung Kim
  0 siblings, 0 replies; 17+ messages in thread
From: Namhyung Kim @ 2014-09-29  4:18 UTC (permalink / raw)
  To: Frederic Weisbecker
  Cc: Ingo Molnar, H. Peter Anvin, Paul Mackerras, LKML,
	Arnaldo Carvalho de Melo, Peter Zijlstra, mail, Namhyung Kim,
	Jiri Olsa, David Ahern, Thomas Gleixner, linux-tip-commits

Hi Frederic,

On Sat, 27 Sep 2014 16:29:13 +0200, Frederic Weisbecker wrote:
> Hi Namhyung,
>
> 2014-09-27 9:26 GMT+02:00 tip-bot for Namhyung Kim <tipbot@zytor.com>:
>> Commit-ID:  f7f084f4d3c29b0f9877a32fc6e2feacd47695b9
>> Gitweb:     http://git.kernel.org/tip/f7f084f4d3c29b0f9877a32fc6e2feacd47695b9
>> Author:     Namhyung Kim <namhyung@kernel.org>
>> AuthorDate: Tue, 23 Sep 2014 10:01:42 +0900
>> Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
>> CommitDate: Fri, 26 Sep 2014 12:41:57 -0300
>>
>> perf callchain: Move some parser functions to callchain.c
>
> Please Cc me on callchain stuff. I may not be very verbose but I still
> keep an eye on evolutions there.

Oops, my bad.  I'll CC you when I send callchain patches later.

Thanks,
Namhyung

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

end of thread, other threads:[~2014-09-29  4:18 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-23  1:01 [PATCHSET 0/5] perf tools: Add call-graph config options (v2) Namhyung Kim
2014-09-23  1:01 ` [PATCH 1/5] perf hists browser: Fix callchain print bug on TUI Namhyung Kim
2014-09-27  7:25   ` [tip:perf/core] " tip-bot for Namhyung Kim
2014-09-23  1:01 ` [PATCH 2/5] perf tools: Move callchain config from record_opts to callchain_param Namhyung Kim
2014-09-27  7:25   ` [tip:perf/core] " tip-bot for Namhyung Kim
2014-09-23  1:01 ` [PATCH 3/5] perf tools: Move some callchain parser functions to callchain.c Namhyung Kim
2014-09-27  7:26   ` [tip:perf/core] perf callchain: Move some " tip-bot for Namhyung Kim
2014-09-27 14:29     ` Frederic Weisbecker
2014-09-29  4:18       ` Namhyung Kim
2014-09-23  1:01 ` [PATCH 4/5] perf tools: Introduce perf_callchain_config() Namhyung Kim
2014-09-27  7:26   ` [tip:perf/core] " tip-bot for Namhyung Kim
2014-09-23  1:01 ` [PATCH 5/5] perf tools: Convert {record,top}.call-graph option to call-graph.record-mode Namhyung Kim
2014-09-27  7:26   ` [tip:perf/core] perf tools: Convert {record, top}.call-graph " tip-bot for Namhyung Kim
2014-09-23 11:56 ` [PATCH] perf tools: Fix line number in the config file error message Jiri Olsa
2014-09-24  0:21   ` Namhyung Kim
2014-09-27  7:26   ` [tip:perf/core] " tip-bot for Jiri Olsa
  -- strict thread matches above, loose matches on Subject: below --
2014-09-20 16:18 [PATCHSET 0/5] perf tools: Add call-graph config options Namhyung Kim
2014-09-20 16:18 ` [PATCH 1/5] perf hists browser: Fix callchain print bug on TUI Namhyung Kim

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 NNTP newsgroup(s).