[PATCH 2/9] perf, tools: Add --branch-history option to report v3
From: Andi Kleen Add a --branch-history option to perf report that changes all the settings necessary for using the branches in callstacks. This is just a short cut to make this nicer to use, it does not enable any functionality by itself. v2: Change sort order. Rename option to --branch-history to be less confusing. v3: Updates Signed-off-by: Andi Kleen --- tools/perf/Documentation/perf-report.txt | 5 + tools/perf/builtin-report.c | 34 +++- tools/perf/util/machine.c| 12 +-- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 29a21b0..45f73c9 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -255,6 +255,11 @@ OPTIONS branch stacks and it will automatically switch to the branch view mode, unless --no-branch-stack is used. +--branch-history:: + Add the addresses of sampled taken branches to the callstack. + This allows to examine the path the program took to each sample. + The data collection must have used -b (or -j) and -g. + --objdump=:: Path to objdump binary. diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 4dcb4db..c2dc8f27 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -220,8 +220,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error("Selected -g but no callchain data. Did " - "you call 'perf record' without -g?\n"); + ui__error("Selected -g or --branch-history but no " + "callchain data. Did\n" + "you call 'perf record' without -g?\n"); return -1; } } else if (!rep->dont_use_callchains && @@ -544,6 +545,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, + const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt->value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -558,7 +569,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = "fractal,0.5,callee"; const char * const report_usage[] = { @@ -669,7 +680,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, "group", _conf.event_group, "Show event group information together"), OPT_CALLBACK_NOOPT('b', "branch-stack", _mode, "", - "use branch records for histogram filling", parse_branch_mode), + "use branch records for per branch histogram filling", + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, "branch-history", _call_mode, "", + "add last branch records to call history", + parse_branch_call_mode), OPT_STRING(0, "objdump", _path, "path", "objdump binary to use for disassembly and annotations"), OPT_BOOLEAN(0, "demangle", _conf.demangle, @@ -719,10 +734,19 @@ repeat: has_br_stack = perf_header__has_feat(>header, HEADER_BRANCH_STACK); - if (branch_mode == -1 && has_br_stack) { + if (branch_mode == -1 && has_br_stack && branch_call_mode == -1) { sort__mode = SORT_MODE__BRANCH; symbol_conf.cumulate_callchain = false; } + if (branch_call_mode != -1) { + callchain_param.branch_callstack = 1; + callchain_param.key = CCKEY_ADDRESS; + symbol_conf.use_callchain = true; + callchain_register_param(_param); + if (sort_order == default_sort_order) + sort_order = "srcline,symbol,dso"; + branch_mode = 0; + } if (report.mem_mode) { if (sort__mode == SORT_MODE__BRANCH) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index dee1695..ab04045 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1379,15 +1379,15 @@ static int machine__resolve_callchain_sample(struct machine *machine, * - No annotations (should annotate somehow) */ - if (branch->nr >
[PATCH 2/9] perf, tools: Add --branch-history option to report v3
From: Andi Kleen a...@linux.intel.com Add a --branch-history option to perf report that changes all the settings necessary for using the branches in callstacks. This is just a short cut to make this nicer to use, it does not enable any functionality by itself. v2: Change sort order. Rename option to --branch-history to be less confusing. v3: Updates Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/Documentation/perf-report.txt | 5 + tools/perf/builtin-report.c | 34 +++- tools/perf/util/machine.c| 12 +-- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 29a21b0..45f73c9 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -255,6 +255,11 @@ OPTIONS branch stacks and it will automatically switch to the branch view mode, unless --no-branch-stack is used. +--branch-history:: + Add the addresses of sampled taken branches to the callstack. + This allows to examine the path the program took to each sample. + The data collection must have used -b (or -j) and -g. + --objdump=path:: Path to objdump binary. diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 4dcb4db..c2dc8f27 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -220,8 +220,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error(Selected -g but no callchain data. Did - you call 'perf record' without -g?\n); + ui__error(Selected -g or --branch-history but no + callchain data. Did\n + you call 'perf record' without -g?\n); return -1; } } else if (!rep-dont_use_callchains @@ -544,6 +545,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, + const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt-value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -558,7 +569,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = fractal,0.5,callee; const char * const report_usage[] = { @@ -669,7 +680,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, group, symbol_conf.event_group, Show event group information together), OPT_CALLBACK_NOOPT('b', branch-stack, branch_mode, , - use branch records for histogram filling, parse_branch_mode), + use branch records for per branch histogram filling, + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, branch-history, branch_call_mode, , + add last branch records to call history, + parse_branch_call_mode), OPT_STRING(0, objdump, objdump_path, path, objdump binary to use for disassembly and annotations), OPT_BOOLEAN(0, demangle, symbol_conf.demangle, @@ -719,10 +734,19 @@ repeat: has_br_stack = perf_header__has_feat(session-header, HEADER_BRANCH_STACK); - if (branch_mode == -1 has_br_stack) { + if (branch_mode == -1 has_br_stack branch_call_mode == -1) { sort__mode = SORT_MODE__BRANCH; symbol_conf.cumulate_callchain = false; } + if (branch_call_mode != -1) { + callchain_param.branch_callstack = 1; + callchain_param.key = CCKEY_ADDRESS; + symbol_conf.use_callchain = true; + callchain_register_param(callchain_param); + if (sort_order == default_sort_order) + sort_order = srcline,symbol,dso; + branch_mode = 0; + } if (report.mem_mode) { if (sort__mode == SORT_MODE__BRANCH) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index dee1695..ab04045 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1379,15 +1379,15 @@ static int machine__resolve_callchain_sample(struct machine *machine, * - No annotations (should annotate somehow) */
Re: [PATCH 2/9] perf, tools: Add --branch-history option to report v3
On Fri, 23 May 2014 11:11:13 -0700, Andi Kleen wrote: >> > diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c >> > index 1a2d7fc..e6d8ed0 100644 >> > --- a/tools/perf/builtin-report.c >> > +++ b/tools/perf/builtin-report.c >> > @@ -315,8 +315,9 @@ static int report__setup_sample_type(struct report >> > *rep) >> >return -EINVAL; >> >} >> >if (symbol_conf.use_callchain) { >> > - ui__error("Selected -g but no callchain data. Did " >> > - "you call 'perf record' without -g?\n"); >> > + ui__error("Selected -g or --branch-history but no " >> > +"callchain data. Did\n" >> >> An unwanted newline in the message. > > It was intentional to make it fit onto a 80 column terminal Did you mean '\n' after the "Did" or line break after "but no"? I meant the former is weird.. The 80 column rule (in the source code) is not applied to user messages AFAIK. And ui__error() also needs to handle line breaks to fit the message on the screen in a dynamic manner. >> >> >> > +"you call 'perf record' without -g?\n"); >> >return -1; >> >} >> >} else if (!rep->dont_use_callchains && >> > @@ -631,6 +632,16 @@ parse_branch_mode(const struct option *opt >> > __maybe_unused, >> > } >> > >> > static int >> > +parse_branch_call_mode(const struct option *opt __maybe_unused, >> > +const char *str __maybe_unused, int unset) >> > +{ >> > + int *branch_mode = opt->value; >> > + >> > + *branch_mode = !unset; >> > + return 0; >> > +} >> > + >> > +static int >> > parse_percent_limit(const struct option *opt, const char *str, >> >int unset __maybe_unused) >> > { >> > @@ -645,7 +656,7 @@ int cmd_report(int argc, const char **argv, const char >> > *prefix __maybe_unused) >> >struct perf_session *session; >> >struct stat st; >> >bool has_br_stack = false; >> > - int branch_mode = -1; >> > + int branch_mode = -1, branch_call_mode = -1; >> >int ret = -1; >> >char callchain_default_opt[] = "fractal,0.5,callee"; >> >const char * const report_usage[] = { >> > @@ -754,7 +765,11 @@ int cmd_report(int argc, const char **argv, const >> > char *prefix __maybe_unused) >> >OPT_BOOLEAN(0, "group", _conf.event_group, >> >"Show event group information together"), >> >OPT_CALLBACK_NOOPT('b', "branch-stack", _mode, "", >> > - "use branch records for histogram filling", >> > parse_branch_mode), >> > + "use branch records for per branch histogram filling", >> > + parse_branch_mode), >> > + OPT_CALLBACK_NOOPT(0, "branch-history", _call_mode, "", >> > + "add last branch records to call history", >> > + parse_branch_call_mode), >> >> Looks like it can be a boolean option, or at least can share >> parse_branch_mode() callback. > > No it can't. It's a tristate. >> >> >> >OPT_STRING(0, "objdump", _path, "path", >> > "objdump binary to use for disassembly and annotations"), >> >OPT_BOOLEAN(0, "demangle", _conf.demangle, >> > @@ -804,8 +819,16 @@ repeat: >> >has_br_stack = perf_header__has_feat(>header, >> > HEADER_BRANCH_STACK); >> > >> > - if (branch_mode == -1 && has_br_stack) >> > + if (branch_mode == -1 && has_br_stack && branch_call_mode == -1) >> >sort__mode = SORT_MODE__BRANCH; >> > + if (branch_call_mode != -1) { >> >> s/-1/1/ ? > > -1 means not specified by the user. But what about --no-branch-history? Thanks, Namhyung -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add --branch-history option to report v3
On Fri, 23 May 2014 11:11:13 -0700, Andi Kleen wrote: diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1a2d7fc..e6d8ed0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -315,8 +315,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error(Selected -g but no callchain data. Did - you call 'perf record' without -g?\n); + ui__error(Selected -g or --branch-history but no +callchain data. Did\n An unwanted newline in the message. It was intentional to make it fit onto a 80 column terminal Did you mean '\n' after the Did or line break after but no? I meant the former is weird.. The 80 column rule (in the source code) is not applied to user messages AFAIK. And ui__error() also needs to handle line breaks to fit the message on the screen in a dynamic manner. +you call 'perf record' without -g?\n); return -1; } } else if (!rep-dont_use_callchains @@ -631,6 +632,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, +const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt-value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -645,7 +656,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = fractal,0.5,callee; const char * const report_usage[] = { @@ -754,7 +765,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, group, symbol_conf.event_group, Show event group information together), OPT_CALLBACK_NOOPT('b', branch-stack, branch_mode, , - use branch records for histogram filling, parse_branch_mode), + use branch records for per branch histogram filling, + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, branch-history, branch_call_mode, , + add last branch records to call history, + parse_branch_call_mode), Looks like it can be a boolean option, or at least can share parse_branch_mode() callback. No it can't. It's a tristate. OPT_STRING(0, objdump, objdump_path, path, objdump binary to use for disassembly and annotations), OPT_BOOLEAN(0, demangle, symbol_conf.demangle, @@ -804,8 +819,16 @@ repeat: has_br_stack = perf_header__has_feat(session-header, HEADER_BRANCH_STACK); - if (branch_mode == -1 has_br_stack) + if (branch_mode == -1 has_br_stack branch_call_mode == -1) sort__mode = SORT_MODE__BRANCH; + if (branch_call_mode != -1) { s/-1/1/ ? -1 means not specified by the user. But what about --no-branch-history? Thanks, Namhyung -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add --branch-history option to report v3
> > diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c > > index 1a2d7fc..e6d8ed0 100644 > > --- a/tools/perf/builtin-report.c > > +++ b/tools/perf/builtin-report.c > > @@ -315,8 +315,9 @@ static int report__setup_sample_type(struct report *rep) > > return -EINVAL; > > } > > if (symbol_conf.use_callchain) { > > - ui__error("Selected -g but no callchain data. Did " > > - "you call 'perf record' without -g?\n"); > > + ui__error("Selected -g or --branch-history but no " > > + "callchain data. Did\n" > > An unwanted newline in the message. It was intentional to make it fit onto a 80 column terminal > > > > + "you call 'perf record' without -g?\n"); > > return -1; > > } > > } else if (!rep->dont_use_callchains && > > @@ -631,6 +632,16 @@ parse_branch_mode(const struct option *opt > > __maybe_unused, > > } > > > > static int > > +parse_branch_call_mode(const struct option *opt __maybe_unused, > > + const char *str __maybe_unused, int unset) > > +{ > > + int *branch_mode = opt->value; > > + > > + *branch_mode = !unset; > > + return 0; > > +} > > + > > +static int > > parse_percent_limit(const struct option *opt, const char *str, > > int unset __maybe_unused) > > { > > @@ -645,7 +656,7 @@ int cmd_report(int argc, const char **argv, const char > > *prefix __maybe_unused) > > struct perf_session *session; > > struct stat st; > > bool has_br_stack = false; > > - int branch_mode = -1; > > + int branch_mode = -1, branch_call_mode = -1; > > int ret = -1; > > char callchain_default_opt[] = "fractal,0.5,callee"; > > const char * const report_usage[] = { > > @@ -754,7 +765,11 @@ int cmd_report(int argc, const char **argv, const char > > *prefix __maybe_unused) > > OPT_BOOLEAN(0, "group", _conf.event_group, > > "Show event group information together"), > > OPT_CALLBACK_NOOPT('b', "branch-stack", _mode, "", > > - "use branch records for histogram filling", > > parse_branch_mode), > > + "use branch records for per branch histogram filling", > > + parse_branch_mode), > > + OPT_CALLBACK_NOOPT(0, "branch-history", _call_mode, "", > > + "add last branch records to call history", > > + parse_branch_call_mode), > > Looks like it can be a boolean option, or at least can share > parse_branch_mode() callback. No it can't. It's a tristate. > > > > OPT_STRING(0, "objdump", _path, "path", > >"objdump binary to use for disassembly and annotations"), > > OPT_BOOLEAN(0, "demangle", _conf.demangle, > > @@ -804,8 +819,16 @@ repeat: > > has_br_stack = perf_header__has_feat(>header, > > HEADER_BRANCH_STACK); > > > > - if (branch_mode == -1 && has_br_stack) > > + if (branch_mode == -1 && has_br_stack && branch_call_mode == -1) > > sort__mode = SORT_MODE__BRANCH; > > + if (branch_call_mode != -1) { > > s/-1/1/ ? -1 means not specified by the user. -Andi -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add --branch-history option to report v3
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1a2d7fc..e6d8ed0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -315,8 +315,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error(Selected -g but no callchain data. Did - you call 'perf record' without -g?\n); + ui__error(Selected -g or --branch-history but no + callchain data. Did\n An unwanted newline in the message. It was intentional to make it fit onto a 80 column terminal + you call 'perf record' without -g?\n); return -1; } } else if (!rep-dont_use_callchains @@ -631,6 +632,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, + const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt-value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -645,7 +656,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = fractal,0.5,callee; const char * const report_usage[] = { @@ -754,7 +765,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, group, symbol_conf.event_group, Show event group information together), OPT_CALLBACK_NOOPT('b', branch-stack, branch_mode, , - use branch records for histogram filling, parse_branch_mode), + use branch records for per branch histogram filling, + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, branch-history, branch_call_mode, , + add last branch records to call history, + parse_branch_call_mode), Looks like it can be a boolean option, or at least can share parse_branch_mode() callback. No it can't. It's a tristate. OPT_STRING(0, objdump, objdump_path, path, objdump binary to use for disassembly and annotations), OPT_BOOLEAN(0, demangle, symbol_conf.demangle, @@ -804,8 +819,16 @@ repeat: has_br_stack = perf_header__has_feat(session-header, HEADER_BRANCH_STACK); - if (branch_mode == -1 has_br_stack) + if (branch_mode == -1 has_br_stack branch_call_mode == -1) sort__mode = SORT_MODE__BRANCH; + if (branch_call_mode != -1) { s/-1/1/ ? -1 means not specified by the user. -Andi -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/9] perf, tools: Add --branch-history option to report v3
On Fri, 16 May 2014 10:05:31 -0700, Andi Kleen wrote: > From: Andi Kleen > > Add a --branch-history option to perf report that changes all > the settings necessary for using the branches in callstacks. > > This is just a short cut to make this nicer to use, it does > not enable any functionality by itself. > > v2: Change sort order. Rename option to --branch-history to > be less confusing. > v3: Updates > Signed-off-by: Andi Kleen > --- > tools/perf/Documentation/perf-report.txt | 5 + > tools/perf/builtin-report.c | 33 > +++- > tools/perf/util/machine.c| 12 ++-- > 3 files changed, 39 insertions(+), 11 deletions(-) > > diff --git a/tools/perf/Documentation/perf-report.txt > b/tools/perf/Documentation/perf-report.txt > index 4f0f3d9..23bce9b 100644 > --- a/tools/perf/Documentation/perf-report.txt > +++ b/tools/perf/Documentation/perf-report.txt > @@ -231,6 +231,11 @@ OPTIONS > branch stacks and it will automatically switch to the branch view mode, > unless --no-branch-stack is used. > > +--branch-history:: > + Add the addresses of sampled taken branches to the callstack. > + This allows to examine the path the program took to each sample. > + The data collection must have used -b (or -j) and -g. > + > --objdump=:: > Path to objdump binary. > > diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c > index 1a2d7fc..e6d8ed0 100644 > --- a/tools/perf/builtin-report.c > +++ b/tools/perf/builtin-report.c > @@ -315,8 +315,9 @@ static int report__setup_sample_type(struct report *rep) > return -EINVAL; > } > if (symbol_conf.use_callchain) { > - ui__error("Selected -g but no callchain data. Did " > - "you call 'perf record' without -g?\n"); > + ui__error("Selected -g or --branch-history but no " > + "callchain data. Did\n" An unwanted newline in the message. > + "you call 'perf record' without -g?\n"); > return -1; > } > } else if (!rep->dont_use_callchains && > @@ -631,6 +632,16 @@ parse_branch_mode(const struct option *opt > __maybe_unused, > } > > static int > +parse_branch_call_mode(const struct option *opt __maybe_unused, > + const char *str __maybe_unused, int unset) > +{ > + int *branch_mode = opt->value; > + > + *branch_mode = !unset; > + return 0; > +} > + > +static int > parse_percent_limit(const struct option *opt, const char *str, > int unset __maybe_unused) > { > @@ -645,7 +656,7 @@ int cmd_report(int argc, const char **argv, const char > *prefix __maybe_unused) > struct perf_session *session; > struct stat st; > bool has_br_stack = false; > - int branch_mode = -1; > + int branch_mode = -1, branch_call_mode = -1; > int ret = -1; > char callchain_default_opt[] = "fractal,0.5,callee"; > const char * const report_usage[] = { > @@ -754,7 +765,11 @@ int cmd_report(int argc, const char **argv, const char > *prefix __maybe_unused) > OPT_BOOLEAN(0, "group", _conf.event_group, > "Show event group information together"), > OPT_CALLBACK_NOOPT('b', "branch-stack", _mode, "", > - "use branch records for histogram filling", > parse_branch_mode), > + "use branch records for per branch histogram filling", > + parse_branch_mode), > + OPT_CALLBACK_NOOPT(0, "branch-history", _call_mode, "", > + "add last branch records to call history", > + parse_branch_call_mode), Looks like it can be a boolean option, or at least can share parse_branch_mode() callback. > OPT_STRING(0, "objdump", _path, "path", > "objdump binary to use for disassembly and annotations"), > OPT_BOOLEAN(0, "demangle", _conf.demangle, > @@ -804,8 +819,16 @@ repeat: > has_br_stack = perf_header__has_feat(>header, >HEADER_BRANCH_STACK); > > - if (branch_mode == -1 && has_br_stack) > + if (branch_mode == -1 && has_br_stack && branch_call_mode == -1) > sort__mode = SORT_MODE__BRANCH; > + if (branch_call_mode != -1) { s/-1/1/ ? > + callchain_param.branch_callstack = 1; > + callchain_param.key = CCKEY_ADDRESS; > + symbol_conf.use_callchain = true; > + callchain_register_param(_param); Isn't it better doing this in report__setup_sample_type()? Thanks, Namhyung > + if (sort_order == default_sort_order) > + sort_order = "srcline,symbol,dso"; > + } > > /* sort__mode could be NORMAL if --no-branch-stack */ > if (sort__mode == SORT_MODE__BRANCH) { > diff --git a/tools/perf/util/machine.c
Re: [PATCH 2/9] perf, tools: Add --branch-history option to report v3
On Fri, 16 May 2014 10:05:31 -0700, Andi Kleen wrote: From: Andi Kleen a...@linux.intel.com Add a --branch-history option to perf report that changes all the settings necessary for using the branches in callstacks. This is just a short cut to make this nicer to use, it does not enable any functionality by itself. v2: Change sort order. Rename option to --branch-history to be less confusing. v3: Updates Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/Documentation/perf-report.txt | 5 + tools/perf/builtin-report.c | 33 +++- tools/perf/util/machine.c| 12 ++-- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 4f0f3d9..23bce9b 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -231,6 +231,11 @@ OPTIONS branch stacks and it will automatically switch to the branch view mode, unless --no-branch-stack is used. +--branch-history:: + Add the addresses of sampled taken branches to the callstack. + This allows to examine the path the program took to each sample. + The data collection must have used -b (or -j) and -g. + --objdump=path:: Path to objdump binary. diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1a2d7fc..e6d8ed0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -315,8 +315,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error(Selected -g but no callchain data. Did - you call 'perf record' without -g?\n); + ui__error(Selected -g or --branch-history but no + callchain data. Did\n An unwanted newline in the message. + you call 'perf record' without -g?\n); return -1; } } else if (!rep-dont_use_callchains @@ -631,6 +632,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, + const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt-value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -645,7 +656,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = fractal,0.5,callee; const char * const report_usage[] = { @@ -754,7 +765,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, group, symbol_conf.event_group, Show event group information together), OPT_CALLBACK_NOOPT('b', branch-stack, branch_mode, , - use branch records for histogram filling, parse_branch_mode), + use branch records for per branch histogram filling, + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, branch-history, branch_call_mode, , + add last branch records to call history, + parse_branch_call_mode), Looks like it can be a boolean option, or at least can share parse_branch_mode() callback. OPT_STRING(0, objdump, objdump_path, path, objdump binary to use for disassembly and annotations), OPT_BOOLEAN(0, demangle, symbol_conf.demangle, @@ -804,8 +819,16 @@ repeat: has_br_stack = perf_header__has_feat(session-header, HEADER_BRANCH_STACK); - if (branch_mode == -1 has_br_stack) + if (branch_mode == -1 has_br_stack branch_call_mode == -1) sort__mode = SORT_MODE__BRANCH; + if (branch_call_mode != -1) { s/-1/1/ ? + callchain_param.branch_callstack = 1; + callchain_param.key = CCKEY_ADDRESS; + symbol_conf.use_callchain = true; + callchain_register_param(callchain_param); Isn't it better doing this in report__setup_sample_type()? Thanks, Namhyung + if (sort_order == default_sort_order) + sort_order = srcline,symbol,dso; + } /* sort__mode could be NORMAL if --no-branch-stack */ if (sort__mode == SORT_MODE__BRANCH) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 5238506..f828c87 100644 ---
[PATCH 2/9] perf, tools: Add --branch-history option to report v3
From: Andi Kleen Add a --branch-history option to perf report that changes all the settings necessary for using the branches in callstacks. This is just a short cut to make this nicer to use, it does not enable any functionality by itself. v2: Change sort order. Rename option to --branch-history to be less confusing. v3: Updates Signed-off-by: Andi Kleen --- tools/perf/Documentation/perf-report.txt | 5 + tools/perf/builtin-report.c | 33 +++- tools/perf/util/machine.c| 12 ++-- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 4f0f3d9..23bce9b 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -231,6 +231,11 @@ OPTIONS branch stacks and it will automatically switch to the branch view mode, unless --no-branch-stack is used. +--branch-history:: + Add the addresses of sampled taken branches to the callstack. + This allows to examine the path the program took to each sample. + The data collection must have used -b (or -j) and -g. + --objdump=:: Path to objdump binary. diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1a2d7fc..e6d8ed0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -315,8 +315,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error("Selected -g but no callchain data. Did " - "you call 'perf record' without -g?\n"); + ui__error("Selected -g or --branch-history but no " + "callchain data. Did\n" + "you call 'perf record' without -g?\n"); return -1; } } else if (!rep->dont_use_callchains && @@ -631,6 +632,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, + const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt->value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -645,7 +656,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = "fractal,0.5,callee"; const char * const report_usage[] = { @@ -754,7 +765,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, "group", _conf.event_group, "Show event group information together"), OPT_CALLBACK_NOOPT('b', "branch-stack", _mode, "", - "use branch records for histogram filling", parse_branch_mode), + "use branch records for per branch histogram filling", + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, "branch-history", _call_mode, "", + "add last branch records to call history", + parse_branch_call_mode), OPT_STRING(0, "objdump", _path, "path", "objdump binary to use for disassembly and annotations"), OPT_BOOLEAN(0, "demangle", _conf.demangle, @@ -804,8 +819,16 @@ repeat: has_br_stack = perf_header__has_feat(>header, HEADER_BRANCH_STACK); - if (branch_mode == -1 && has_br_stack) + if (branch_mode == -1 && has_br_stack && branch_call_mode == -1) sort__mode = SORT_MODE__BRANCH; + if (branch_call_mode != -1) { + callchain_param.branch_callstack = 1; + callchain_param.key = CCKEY_ADDRESS; + symbol_conf.use_callchain = true; + callchain_register_param(_param); + if (sort_order == default_sort_order) + sort_order = "srcline,symbol,dso"; + } /* sort__mode could be NORMAL if --no-branch-stack */ if (sort__mode == SORT_MODE__BRANCH) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 5238506..f828c87 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1379,15 +1379,15 @@ static int machine__resolve_callchain_sample(struct machine *machine, * - No annotations (should annotate somehow) */ - if (branch->nr > PERF_MAX_BRANCH_DEPTH) { - pr_warning("corrupted branch chain. skipping...\n"); -
[PATCH 2/9] perf, tools: Add --branch-history option to report v3
From: Andi Kleen a...@linux.intel.com Add a --branch-history option to perf report that changes all the settings necessary for using the branches in callstacks. This is just a short cut to make this nicer to use, it does not enable any functionality by itself. v2: Change sort order. Rename option to --branch-history to be less confusing. v3: Updates Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/Documentation/perf-report.txt | 5 + tools/perf/builtin-report.c | 33 +++- tools/perf/util/machine.c| 12 ++-- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 4f0f3d9..23bce9b 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -231,6 +231,11 @@ OPTIONS branch stacks and it will automatically switch to the branch view mode, unless --no-branch-stack is used. +--branch-history:: + Add the addresses of sampled taken branches to the callstack. + This allows to examine the path the program took to each sample. + The data collection must have used -b (or -j) and -g. + --objdump=path:: Path to objdump binary. diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1a2d7fc..e6d8ed0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -315,8 +315,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error(Selected -g but no callchain data. Did - you call 'perf record' without -g?\n); + ui__error(Selected -g or --branch-history but no + callchain data. Did\n + you call 'perf record' without -g?\n); return -1; } } else if (!rep-dont_use_callchains @@ -631,6 +632,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, + const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt-value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -645,7 +656,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = fractal,0.5,callee; const char * const report_usage[] = { @@ -754,7 +765,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, group, symbol_conf.event_group, Show event group information together), OPT_CALLBACK_NOOPT('b', branch-stack, branch_mode, , - use branch records for histogram filling, parse_branch_mode), + use branch records for per branch histogram filling, + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, branch-history, branch_call_mode, , + add last branch records to call history, + parse_branch_call_mode), OPT_STRING(0, objdump, objdump_path, path, objdump binary to use for disassembly and annotations), OPT_BOOLEAN(0, demangle, symbol_conf.demangle, @@ -804,8 +819,16 @@ repeat: has_br_stack = perf_header__has_feat(session-header, HEADER_BRANCH_STACK); - if (branch_mode == -1 has_br_stack) + if (branch_mode == -1 has_br_stack branch_call_mode == -1) sort__mode = SORT_MODE__BRANCH; + if (branch_call_mode != -1) { + callchain_param.branch_callstack = 1; + callchain_param.key = CCKEY_ADDRESS; + symbol_conf.use_callchain = true; + callchain_register_param(callchain_param); + if (sort_order == default_sort_order) + sort_order = srcline,symbol,dso; + } /* sort__mode could be NORMAL if --no-branch-stack */ if (sort__mode == SORT_MODE__BRANCH) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 5238506..f828c87 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1379,15 +1379,15 @@ static int machine__resolve_callchain_sample(struct machine *machine, * - No annotations (should annotate somehow) */ - if (branch-nr PERF_MAX_BRANCH_DEPTH) { -
[PATCH 2/9] perf, tools: Add --branch-history option to report v3
From: Andi Kleen Add a --branch-history option to perf report that changes all the settings necessary for using the branches in callstacks. This is just a short cut to make this nicer to use, it does not enable any functionality by itself. v2: Change sort order. Rename option to --branch-history to be less confusing. v3: Updates Signed-off-by: Andi Kleen --- tools/perf/Documentation/perf-report.txt | 5 + tools/perf/builtin-report.c | 33 +++- tools/perf/util/machine.c| 12 ++-- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 349cd2a..5b270fe 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -228,6 +228,11 @@ OPTIONS branch stacks and it will automatically switch to the branch view mode, unless --no-branch-stack is used. +--branch-history:: + Add the addresses of sampled taken branches to the callstack. + This allows to examine the path the program took to each sample. + The data collection must have used -b (or -j) and -g. + --objdump=:: Path to objdump binary. diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 59e8f0a..cd6f7b2 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -295,8 +295,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error("Selected -g but no callchain data. Did " - "you call 'perf record' without -g?\n"); + ui__error("Selected -g or --branch-history but no " + "callchain data. Did\n" + "you call 'perf record' without -g?\n"); return -1; } } else if (!rep->dont_use_callchains && @@ -699,6 +700,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, + const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt->value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -713,7 +724,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = "fractal,0.5,callee"; const char * const report_usage[] = { @@ -822,7 +833,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, "group", _conf.event_group, "Show event group information together"), OPT_CALLBACK_NOOPT('b', "branch-stack", _mode, "", - "use branch records for histogram filling", parse_branch_mode), + "use branch records for per branch histogram filling", + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, "branch-history", _call_mode, "", + "add last branch records to call history", + parse_branch_call_mode), OPT_STRING(0, "objdump", _path, "path", "objdump binary to use for disassembly and annotations"), OPT_BOOLEAN(0, "demangle", _conf.demangle, @@ -870,8 +885,16 @@ repeat: has_br_stack = perf_header__has_feat(>header, HEADER_BRANCH_STACK); - if (branch_mode == -1 && has_br_stack) + if (branch_mode == -1 && has_br_stack && branch_call_mode == -1) sort__mode = SORT_MODE__BRANCH; + if (branch_call_mode != -1) { + callchain_param.branch_callstack = 1; + callchain_param.key = CCKEY_ADDRESS; + symbol_conf.use_callchain = true; + callchain_register_param(_param); + if (sort_order == default_sort_order) + sort_order = "srcline,symbol,dso"; + } /* sort__mode could be NORMAL if --no-branch-stack */ if (sort__mode == SORT_MODE__BRANCH) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index b0ff829..4e887d8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1360,15 +1360,15 @@ static int machine__resolve_callchain_sample(struct machine *machine, * - No annotations (should annotate somehow) */ - if (branch->nr > PERF_MAX_BRANCH_DEPTH) { - pr_warning("corrupted branch chain. skipping...\n"); -
[PATCH 2/9] perf, tools: Add --branch-history option to report v3
From: Andi Kleen a...@linux.intel.com Add a --branch-history option to perf report that changes all the settings necessary for using the branches in callstacks. This is just a short cut to make this nicer to use, it does not enable any functionality by itself. v2: Change sort order. Rename option to --branch-history to be less confusing. v3: Updates Signed-off-by: Andi Kleen a...@linux.intel.com --- tools/perf/Documentation/perf-report.txt | 5 + tools/perf/builtin-report.c | 33 +++- tools/perf/util/machine.c| 12 ++-- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 349cd2a..5b270fe 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -228,6 +228,11 @@ OPTIONS branch stacks and it will automatically switch to the branch view mode, unless --no-branch-stack is used. +--branch-history:: + Add the addresses of sampled taken branches to the callstack. + This allows to examine the path the program took to each sample. + The data collection must have used -b (or -j) and -g. + --objdump=path:: Path to objdump binary. diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 59e8f0a..cd6f7b2 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -295,8 +295,9 @@ static int report__setup_sample_type(struct report *rep) return -EINVAL; } if (symbol_conf.use_callchain) { - ui__error(Selected -g but no callchain data. Did - you call 'perf record' without -g?\n); + ui__error(Selected -g or --branch-history but no + callchain data. Did\n + you call 'perf record' without -g?\n); return -1; } } else if (!rep-dont_use_callchains @@ -699,6 +700,16 @@ parse_branch_mode(const struct option *opt __maybe_unused, } static int +parse_branch_call_mode(const struct option *opt __maybe_unused, + const char *str __maybe_unused, int unset) +{ + int *branch_mode = opt-value; + + *branch_mode = !unset; + return 0; +} + +static int parse_percent_limit(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -713,7 +724,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) struct perf_session *session; struct stat st; bool has_br_stack = false; - int branch_mode = -1; + int branch_mode = -1, branch_call_mode = -1; int ret = -1; char callchain_default_opt[] = fractal,0.5,callee; const char * const report_usage[] = { @@ -822,7 +833,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, group, symbol_conf.event_group, Show event group information together), OPT_CALLBACK_NOOPT('b', branch-stack, branch_mode, , - use branch records for histogram filling, parse_branch_mode), + use branch records for per branch histogram filling, + parse_branch_mode), + OPT_CALLBACK_NOOPT(0, branch-history, branch_call_mode, , + add last branch records to call history, + parse_branch_call_mode), OPT_STRING(0, objdump, objdump_path, path, objdump binary to use for disassembly and annotations), OPT_BOOLEAN(0, demangle, symbol_conf.demangle, @@ -870,8 +885,16 @@ repeat: has_br_stack = perf_header__has_feat(session-header, HEADER_BRANCH_STACK); - if (branch_mode == -1 has_br_stack) + if (branch_mode == -1 has_br_stack branch_call_mode == -1) sort__mode = SORT_MODE__BRANCH; + if (branch_call_mode != -1) { + callchain_param.branch_callstack = 1; + callchain_param.key = CCKEY_ADDRESS; + symbol_conf.use_callchain = true; + callchain_register_param(callchain_param); + if (sort_order == default_sort_order) + sort_order = srcline,symbol,dso; + } /* sort__mode could be NORMAL if --no-branch-stack */ if (sort__mode == SORT_MODE__BRANCH) { diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index b0ff829..4e887d8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1360,15 +1360,15 @@ static int machine__resolve_callchain_sample(struct machine *machine, * - No annotations (should annotate somehow) */ - if (branch-nr PERF_MAX_BRANCH_DEPTH) { -