mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-22 23:04:43 +00:00
perf report/top: Add option to collapse undesired parts of call graph
For example, in an application with an expensive function implemented with deeply nested recursive calls, the default call-graph presentation is dominated by the different callchains within that function. By ignoring these callees, we can collect the callchains leading into the function and compactly identify what to blame for expensive calls. For example, in this report the callers of garbage_collect() are scattered across the tree: $ perf report -d ruby 2>- | grep -m10 ^[^#]*[a-z] 22.03% ruby [.] gc_mark --- gc_mark |--59.40%-- mark_keyvalue | st_foreach | gc_mark_children | |--99.75%-- rb_gc_mark | | rb_vm_mark | | gc_mark_children | | gc_marks | | |--99.00%-- garbage_collect If we ignore the callees of garbage_collect(), its callers are coalesced: $ perf report --ignore-callees garbage_collect -d ruby 2>- | grep -m10 ^[^#]*[a-z] 72.92% ruby [.] garbage_collect --- garbage_collect vm_xmalloc |--47.08%-- ruby_xmalloc | st_insert2 | rb_hash_aset | |--98.45%-- features_index_add | | rb_provide_feature | | rb_require_safe | | vm_call_method Signed-off-by: Greg Price <price@mit.edu> Tested-by: Jiri Olsa <jolsa@redhat.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.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/20130623031720.GW22203@biohazard-cafe.mit.edu Link: http://lkml.kernel.org/r/20130708115746.GO22203@biohazard-cafe.mit.edu Cc: Fengguang Wu <fengguang.wu@intel.com> [ remove spaces at beginning of line, reported by Fengguang Wu ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
dc098b35b5
commit
b21484f1a1
9 changed files with 63 additions and 17 deletions
|
@ -1058,11 +1058,10 @@ int machine__process_event(struct machine *machine, union perf_event *event)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool symbol__match_parent_regex(struct symbol *sym)
|
||||
static bool symbol__match_regex(struct symbol *sym, regex_t *regex)
|
||||
{
|
||||
if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
|
||||
if (sym->name && !regexec(regex, sym->name, 0, NULL, 0))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1159,8 +1158,8 @@ struct branch_info *machine__resolve_bstack(struct machine *machine,
|
|||
static int machine__resolve_callchain_sample(struct machine *machine,
|
||||
struct thread *thread,
|
||||
struct ip_callchain *chain,
|
||||
struct symbol **parent)
|
||||
|
||||
struct symbol **parent,
|
||||
struct addr_location *root_al)
|
||||
{
|
||||
u8 cpumode = PERF_RECORD_MISC_USER;
|
||||
unsigned int i;
|
||||
|
@ -1211,8 +1210,15 @@ static int machine__resolve_callchain_sample(struct machine *machine,
|
|||
MAP__FUNCTION, ip, &al, NULL);
|
||||
if (al.sym != NULL) {
|
||||
if (sort__has_parent && !*parent &&
|
||||
symbol__match_parent_regex(al.sym))
|
||||
symbol__match_regex(al.sym, &parent_regex))
|
||||
*parent = al.sym;
|
||||
else if (have_ignore_callees && root_al &&
|
||||
symbol__match_regex(al.sym, &ignore_callees_regex)) {
|
||||
/* Treat this symbol as the root,
|
||||
forgetting its callees. */
|
||||
*root_al = al;
|
||||
callchain_cursor_reset(&callchain_cursor);
|
||||
}
|
||||
if (!symbol_conf.use_callchain)
|
||||
break;
|
||||
}
|
||||
|
@ -1237,13 +1243,13 @@ int machine__resolve_callchain(struct machine *machine,
|
|||
struct perf_evsel *evsel,
|
||||
struct thread *thread,
|
||||
struct perf_sample *sample,
|
||||
struct symbol **parent)
|
||||
|
||||
struct symbol **parent,
|
||||
struct addr_location *root_al)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = machine__resolve_callchain_sample(machine, thread,
|
||||
sample->callchain, parent);
|
||||
sample->callchain, parent, root_al);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue