perf report: Allow limiting the number of entries to print in callchains
Works by adding a third parameter to the '-g' argument, after the graph type and minimum percentage, for example: [root@doppio linux-2.6-tip]# perf report -g fractal,0.5,2 Will show only the first two symbols where at least 0.5% of the samples took place. All the other symbols that don't fall outside these constraints will be put together in the last entry, prefixed with "[...]" and the total percentage for them. Suggested-by: Arjan van de Ven <arjan@linux.intel.com> Acked-by: Arjan van de Ven <arjan@linux.intel.com> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Родитель
1f626bc368
Коммит
232a5c948d
|
@ -343,7 +343,7 @@ static int
|
||||||
parse_callchain_opt(const struct option *opt __used, const char *arg,
|
parse_callchain_opt(const struct option *opt __used, const char *arg,
|
||||||
int unset)
|
int unset)
|
||||||
{
|
{
|
||||||
char *tok;
|
char *tok, *tok2;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -388,10 +388,13 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
|
||||||
if (!tok)
|
if (!tok)
|
||||||
goto setup;
|
goto setup;
|
||||||
|
|
||||||
|
tok2 = strtok(NULL, ",");
|
||||||
callchain_param.min_percent = strtod(tok, &endptr);
|
callchain_param.min_percent = strtod(tok, &endptr);
|
||||||
if (tok == endptr)
|
if (tok == endptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (tok2)
|
||||||
|
callchain_param.print_limit = strtod(tok2, &endptr);
|
||||||
setup:
|
setup:
|
||||||
if (register_callchain_param(&callchain_param) < 0) {
|
if (register_callchain_param(&callchain_param) < 0) {
|
||||||
fprintf(stderr, "Can't register callchain params\n");
|
fprintf(stderr, "Can't register callchain params\n");
|
||||||
|
|
|
@ -34,6 +34,7 @@ typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *,
|
||||||
|
|
||||||
struct callchain_param {
|
struct callchain_param {
|
||||||
enum chain_mode mode;
|
enum chain_mode mode;
|
||||||
|
u32 print_limit;
|
||||||
double min_percent;
|
double min_percent;
|
||||||
sort_chain_func_t sort;
|
sort_chain_func_t sort;
|
||||||
};
|
};
|
||||||
|
|
|
@ -333,6 +333,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
|
||||||
u64 remaining;
|
u64 remaining;
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
int i;
|
int i;
|
||||||
|
uint entries_printed = 0;
|
||||||
|
|
||||||
if (callchain_param.mode == CHAIN_GRAPH_REL)
|
if (callchain_param.mode == CHAIN_GRAPH_REL)
|
||||||
new_total = self->children_hit;
|
new_total = self->children_hit;
|
||||||
|
@ -379,6 +380,8 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
|
||||||
new_depth_mask | (1 << depth),
|
new_depth_mask | (1 << depth),
|
||||||
left_margin);
|
left_margin);
|
||||||
node = next;
|
node = next;
|
||||||
|
if (++entries_printed == callchain_param.print_limit)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callchain_param.mode == CHAIN_GRAPH_REL &&
|
if (callchain_param.mode == CHAIN_GRAPH_REL &&
|
||||||
|
@ -404,6 +407,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
|
||||||
bool printed = false;
|
bool printed = false;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
u32 entries_printed = 0;
|
||||||
|
|
||||||
list_for_each_entry(chain, &self->val, list) {
|
list_for_each_entry(chain, &self->val, list) {
|
||||||
if (!i++ && sort__first_dimension == SORT_SYM)
|
if (!i++ && sort__first_dimension == SORT_SYM)
|
||||||
|
@ -424,6 +428,9 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
|
||||||
ret += fprintf(fp, " %s\n", chain->ms.sym->name);
|
ret += fprintf(fp, " %s\n", chain->ms.sym->name);
|
||||||
else
|
else
|
||||||
ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
|
ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
|
||||||
|
|
||||||
|
if (++entries_printed == callchain_param.print_limit)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin);
|
ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin);
|
||||||
|
@ -462,6 +469,7 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
|
||||||
struct rb_node *rb_node;
|
struct rb_node *rb_node;
|
||||||
struct callchain_node *chain;
|
struct callchain_node *chain;
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
|
u32 entries_printed = 0;
|
||||||
|
|
||||||
rb_node = rb_first(&self->sorted_chain);
|
rb_node = rb_first(&self->sorted_chain);
|
||||||
while (rb_node) {
|
while (rb_node) {
|
||||||
|
@ -484,6 +492,8 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret += fprintf(fp, "\n");
|
ret += fprintf(fp, "\n");
|
||||||
|
if (++entries_printed == callchain_param.print_limit)
|
||||||
|
break;
|
||||||
rb_node = rb_next(rb_node);
|
rb_node = rb_next(rb_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче