Commit d599db3fc5dd4f1e8432fdbc6d899584b25f4dff

Authored by Arnaldo Carvalho de Melo
Committed by Ingo Molnar
1 parent c410a33887

perf report: Generalize perf_session__fprintf_hists()

Pull it out of builtin-report - further changes will be made and it
will then be reusable in 'perf diff' as well.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260914682-29652-4-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 7 changed files with 68 additions and 94 deletions Side-by-side Diff

tools/perf/builtin-report.c
... ... @@ -34,18 +34,13 @@
34 34 static char const *input_name = "perf.data";
35 35  
36 36 static int force;
37   -static bool use_callchain;
38 37  
39   -static int show_nr_samples;
40   -
41 38 static int show_threads;
42 39 static struct perf_read_values show_threads_values;
43 40  
44 41 static char default_pretty_printing_style[] = "normal";
45 42 static char *pretty_printing_style = default_pretty_printing_style;
46 43  
47   -static int exclude_other = 1;
48   -
49 44 static char callchain_default_opt[] = "fractal,0.5";
50 45  
51 46 static size_t
52 47  
53 48  
54 49  
55 50  
... ... @@ -305,23 +300,22 @@
305 300 }
306 301  
307 302 static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
308   - struct perf_session *session,
309   - u64 total_samples)
  303 + struct perf_session *session)
310 304 {
311 305 struct sort_entry *se;
312 306 size_t ret;
313 307  
314   - if (exclude_other && !self->parent)
  308 + if (symbol_conf.exclude_other && !self->parent)
315 309 return 0;
316 310  
317   - if (total_samples)
  311 + if (session->events_stats.total)
318 312 ret = percent_color_fprintf(fp,
319 313 symbol_conf.field_sep ? "%.2f" : " %6.2f%%",
320   - (self->count * 100.0) / total_samples);
  314 + (self->count * 100.0) / session->events_stats.total);
321 315 else
322 316 ret = fprintf(fp, symbol_conf.field_sep ? "%lld" : "%12lld ", self->count);
323 317  
324   - if (show_nr_samples) {
  318 + if (symbol_conf.show_nr_samples) {
325 319 if (symbol_conf.field_sep)
326 320 fprintf(fp, "%c%lld", *symbol_conf.field_sep, self->count);
327 321 else
... ... @@ -338,7 +332,7 @@
338 332  
339 333 ret += fprintf(fp, "\n");
340 334  
341   - if (session->use_callchain) {
  335 + if (symbol_conf.use_callchain) {
342 336 int left_margin = 0;
343 337  
344 338 if (sort__first_dimension == SORT_COMM) {
345 339  
... ... @@ -348,41 +342,13 @@
348 342 left_margin -= thread__comm_len(self->thread);
349 343 }
350 344  
351   - hist_entry_callchain__fprintf(fp, self, total_samples,
  345 + hist_entry_callchain__fprintf(fp, self, session->events_stats.total,
352 346 left_margin);
353 347 }
354 348  
355 349 return ret;
356 350 }
357 351  
358   -static void thread__comm_adjust(struct thread *self)
359   -{
360   - char *comm = self->comm;
361   -
362   - if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
363   - (!symbol_conf.comm_list ||
364   - strlist__has_entry(symbol_conf.comm_list, comm))) {
365   - unsigned int slen = strlen(comm);
366   -
367   - if (slen > comms__col_width) {
368   - comms__col_width = slen;
369   - threads__col_width = slen + 6;
370   - }
371   - }
372   -}
373   -
374   -static int thread__set_comm_adjust(struct thread *self, const char *comm)
375   -{
376   - int ret = thread__set_comm(self, comm);
377   -
378   - if (ret)
379   - return ret;
380   -
381   - thread__comm_adjust(self);
382   -
383   - return 0;
384   -}
385   -
386 352 /*
387 353 * collect histogram counts
388 354 */
... ... @@ -395,7 +361,7 @@
395 361 bool hit;
396 362 struct hist_entry *he;
397 363  
398   - if ((sort__has_parent || self->use_callchain) && chain)
  364 + if ((sort__has_parent || symbol_conf.use_callchain) && chain)
399 365 syms = perf_session__resolve_callchain(self, al->thread,
400 366 chain, &parent);
401 367 he = __perf_session__add_hist_entry(self, al, parent, count, &hit);
... ... @@ -405,7 +371,7 @@
405 371 if (hit)
406 372 he->count += count;
407 373  
408   - if (self->use_callchain) {
  374 + if (symbol_conf.use_callchain) {
409 375 if (!hit)
410 376 callchain_init(&he->callchain);
411 377 append_chain(&he->callchain, chain, syms);
... ... @@ -415,8 +381,7 @@
415 381 return 0;
416 382 }
417 383  
418   -static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
419   - u64 total_samples, FILE *fp)
  384 +static size_t perf_session__fprintf_hists(struct perf_session *self, FILE *fp)
420 385 {
421 386 struct hist_entry *pos;
422 387 struct sort_entry *se;
423 388  
424 389  
425 390  
... ... @@ -424,17 +389,14 @@
424 389 size_t ret = 0;
425 390 unsigned int width;
426 391 char *col_width = symbol_conf.col_width_list_str;
427   - int raw_printing_style;
428 392  
429   - raw_printing_style = !strcmp(pretty_printing_style, "raw");
430   -
431 393 init_rem_hits();
432 394  
433   - fprintf(fp, "# Samples: %Ld\n", (u64)total_samples);
  395 + fprintf(fp, "# Samples: %ld\n", self->events_stats.total);
434 396 fprintf(fp, "#\n");
435 397  
436 398 fprintf(fp, "# Overhead");
437   - if (show_nr_samples) {
  399 + if (symbol_conf.show_nr_samples) {
438 400 if (symbol_conf.field_sep)
439 401 fprintf(fp, "%cSamples", *symbol_conf.field_sep);
440 402 else
... ... @@ -467,7 +429,7 @@
467 429 goto print_entries;
468 430  
469 431 fprintf(fp, "# ........");
470   - if (show_nr_samples)
  432 + if (symbol_conf.show_nr_samples)
471 433 fprintf(fp, " ..........");
472 434 list_for_each_entry(se, &hist_entry__sort_list, list) {
473 435 unsigned int i;
... ... @@ -490,7 +452,7 @@
490 452 print_entries:
491 453 for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
492 454 pos = rb_entry(nd, struct hist_entry, rb_node);
493   - ret += hist_entry__fprintf(fp, pos, self, total_samples);
  455 + ret += hist_entry__fprintf(fp, pos, self);
494 456 }
495 457  
496 458 if (sort_order == default_sort_order &&
... ... @@ -503,10 +465,6 @@
503 465  
504 466 free(rem_sq_bracket);
505 467  
506   - if (show_threads)
507   - perf_read_values_display(fp, &show_threads_values,
508   - raw_printing_style);
509   -
510 468 return ret;
511 469 }
512 470  
... ... @@ -572,21 +530,6 @@
572 530 return 0;
573 531 }
574 532  
575   -static int process_comm_event(event_t *event, struct perf_session *session)
576   -{
577   - struct thread *thread = perf_session__findnew(session, event->comm.pid);
578   -
579   - dump_printf(": %s:%d\n", event->comm.comm, event->comm.pid);
580   -
581   - if (thread == NULL ||
582   - thread__set_comm_adjust(thread, event->comm.comm)) {
583   - dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
584   - return -1;
585   - }
586   -
587   - return 0;
588   -}
589   -
590 533 static int process_read_event(event_t *event, struct perf_session *session __used)
591 534 {
592 535 struct perf_event_attr *attr;
593 536  
... ... @@ -619,14 +562,14 @@
619 562 " perf record without -g?\n");
620 563 return -1;
621 564 }
622   - if (session->use_callchain) {
  565 + if (symbol_conf.use_callchain) {
623 566 fprintf(stderr, "selected -g but no callchain data."
624 567 " Did you call perf record without"
625 568 " -g?\n");
626 569 return -1;
627 570 }
628   - } else if (callchain_param.mode != CHAIN_NONE && !session->use_callchain) {
629   - session->use_callchain = true;
  571 + } else if (callchain_param.mode != CHAIN_NONE && !symbol_conf.use_callchain) {
  572 + symbol_conf.use_callchain = true;
630 573 if (register_callchain_param(&callchain_param) < 0) {
631 574 fprintf(stderr, "Can't register callchain"
632 575 " params\n");
... ... @@ -640,7 +583,7 @@
640 583 static struct perf_event_ops event_ops = {
641 584 .process_sample_event = process_sample_event,
642 585 .process_mmap_event = event__process_mmap,
643   - .process_comm_event = process_comm_event,
  586 + .process_comm_event = event__process_mmap,
644 587 .process_exit_event = event__process_task,
645 588 .process_fork_event = event__process_task,
646 589 .process_lost_event = event__process_lost,
... ... @@ -658,8 +601,6 @@
658 601 if (session == NULL)
659 602 return -ENOMEM;
660 603  
661   - session->use_callchain = use_callchain;
662   -
663 604 if (show_threads)
664 605 perf_read_values_init(&show_threads_values);
665 606  
666 607  
... ... @@ -680,10 +621,13 @@
680 621  
681 622 perf_session__collapse_resort(session);
682 623 perf_session__output_resort(session, session->events_stats.total);
683   - perf_session__fprintf_hist_entries(session, session->events_stats.total, stdout);
684   -
685   - if (show_threads)
  624 + perf_session__fprintf_hists(session, stdout);
  625 + if (show_threads) {
  626 + bool raw_printing_style = !strcmp(pretty_printing_style, "raw");
  627 + perf_read_values_display(stdout, &show_threads_values,
  628 + raw_printing_style);
686 629 perf_read_values_destroy(&show_threads_values);
  630 + }
687 631 out_delete:
688 632 perf_session__delete(session);
689 633 return ret;
... ... @@ -696,7 +640,7 @@
696 640 char *tok;
697 641 char *endptr;
698 642  
699   - use_callchain = true;
  643 + symbol_conf.use_callchain = true;
700 644  
701 645 if (!arg)
702 646 return 0;
... ... @@ -717,7 +661,7 @@
717 661  
718 662 else if (!strncmp(tok, "none", strlen(arg))) {
719 663 callchain_param.mode = CHAIN_NONE;
720   - use_callchain = true;
  664 + symbol_conf.use_callchain = true;
721 665  
722 666 return 0;
723 667 }
... ... @@ -760,7 +704,7 @@
760 704 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
761 705 OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
762 706 "load module symbols - WARNING: use only with -k and LIVE kernel"),
763   - OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples,
  707 + OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
764 708 "Show a column with the number of samples"),
765 709 OPT_BOOLEAN('T', "threads", &show_threads,
766 710 "Show per-thread event counters"),
... ... @@ -772,7 +716,7 @@
772 716 "Don't shorten the pathnames taking into account the cwd"),
773 717 OPT_STRING('p', "parent", &parent_pattern, "regex",
774 718 "regex filter to identify parent, see: '--sort parent'"),
775   - OPT_BOOLEAN('x', "exclude-other", &exclude_other,
  719 + OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
776 720 "Only display entries with parent-match"),
777 721 OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
778 722 "Display callchains using output_type and min percent threshold. "
... ... @@ -817,7 +761,7 @@
817 761 sort_dimension__add("parent");
818 762 sort_parent.elide = 1;
819 763 } else
820   - exclude_other = 0;
  764 + symbol_conf.exclude_other = false;
821 765  
822 766 /*
823 767 * Any (unrecognized) arguments left?
tools/perf/util/event.c
... ... @@ -189,13 +189,41 @@
189 189 closedir(proc);
190 190 }
191 191  
  192 +static void thread__comm_adjust(struct thread *self)
  193 +{
  194 + char *comm = self->comm;
  195 +
  196 + if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
  197 + (!symbol_conf.comm_list ||
  198 + strlist__has_entry(symbol_conf.comm_list, comm))) {
  199 + unsigned int slen = strlen(comm);
  200 +
  201 + if (slen > comms__col_width) {
  202 + comms__col_width = slen;
  203 + threads__col_width = slen + 6;
  204 + }
  205 + }
  206 +}
  207 +
  208 +static int thread__set_comm_adjust(struct thread *self, const char *comm)
  209 +{
  210 + int ret = thread__set_comm(self, comm);
  211 +
  212 + if (ret)
  213 + return ret;
  214 +
  215 + thread__comm_adjust(self);
  216 +
  217 + return 0;
  218 +}
  219 +
192 220 int event__process_comm(event_t *self, struct perf_session *session)
193 221 {
194 222 struct thread *thread = perf_session__findnew(session, self->comm.pid);
195 223  
196 224 dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid);
197 225  
198   - if (thread == NULL || thread__set_comm(thread, self->comm.comm)) {
  226 + if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) {
199 227 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
200 228 return -1;
201 229 }
tools/perf/util/hist.c
... ... @@ -156,8 +156,7 @@
156 156 * reverse the map, sort on count.
157 157 */
158 158  
159   -static void perf_session__insert_output_hist_entry(struct perf_session *self,
160   - struct rb_root *root,
  159 +static void perf_session__insert_output_hist_entry(struct rb_root *root,
161 160 struct hist_entry *he,
162 161 u64 min_callchain_hits)
163 162 {
... ... @@ -165,7 +164,7 @@
165 164 struct rb_node *parent = NULL;
166 165 struct hist_entry *iter;
167 166  
168   - if (self->use_callchain)
  167 + if (symbol_conf.use_callchain)
169 168 callchain_param.sort(&he->sorted_chain, &he->callchain,
170 169 min_callchain_hits, &callchain_param);
171 170  
... ... @@ -201,7 +200,7 @@
201 200 next = rb_next(&n->rb_node);
202 201  
203 202 rb_erase(&n->rb_node, &self->hists);
204   - perf_session__insert_output_hist_entry(self, &tmp, n,
  203 + perf_session__insert_output_hist_entry(&tmp, n,
205 204 min_callchain_hits);
206 205 }
207 206  
tools/perf/util/session.c
... ... @@ -108,7 +108,7 @@
108 108 struct symbol **syms = NULL;
109 109 unsigned int i;
110 110  
111   - if (self->use_callchain) {
  111 + if (symbol_conf.use_callchain) {
112 112 syms = calloc(chain->nr, sizeof(*syms));
113 113 if (!syms) {
114 114 fprintf(stderr, "Can't allocate memory for symbols\n");
... ... @@ -140,7 +140,7 @@
140 140 if (sort__has_parent && !*parent &&
141 141 symbol__match_parent_regex(al.sym))
142 142 *parent = al.sym;
143   - if (!self->use_callchain)
  143 + if (!symbol_conf.use_callchain)
144 144 break;
145 145 syms[i] = al.sym;
146 146 }
tools/perf/util/session.h
... ... @@ -25,7 +25,6 @@
25 25 int fd;
26 26 int cwdlen;
27 27 char *cwd;
28   - bool use_callchain;
29 28 char filename[0];
30 29 };
31 30  
tools/perf/util/symbol.c
... ... @@ -38,6 +38,7 @@
38 38 static char **vmlinux_path;
39 39  
40 40 struct symbol_conf symbol_conf = {
  41 + .exclude_other = true,
41 42 .use_modules = true,
42 43 .try_vmlinux_path = true,
43 44 };
tools/perf/util/symbol.h
... ... @@ -55,7 +55,10 @@
55 55 unsigned short priv_size;
56 56 bool try_vmlinux_path,
57 57 use_modules,
58   - sort_by_name;
  58 + sort_by_name,
  59 + show_nr_samples,
  60 + use_callchain,
  61 + exclude_other;
59 62 const char *vmlinux_name,
60 63 *field_sep;
61 64 char *dso_list_str,