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