aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/header.c27
-rw-r--r--tools/perf/util/sort.c102
-rw-r--r--tools/perf/util/thread.c3
-rw-r--r--tools/perf/util/unwind-libunwind.c12
-rw-r--r--tools/perf/util/unwind.h3
5 files changed, 115 insertions, 32 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ce0de00399da..26f5b2fe5dc8 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -579,16 +579,12 @@ static int write_version(int fd, struct perf_header *h __maybe_unused,
579 return do_write_string(fd, perf_version_string); 579 return do_write_string(fd, perf_version_string);
580} 580}
581 581
582static int write_cpudesc(int fd, struct perf_header *h __maybe_unused, 582static int __write_cpudesc(int fd, const char *cpuinfo_proc)
583 struct perf_evlist *evlist __maybe_unused)
584{ 583{
585#ifndef CPUINFO_PROC
586#define CPUINFO_PROC NULL
587#endif
588 FILE *file; 584 FILE *file;
589 char *buf = NULL; 585 char *buf = NULL;
590 char *s, *p; 586 char *s, *p;
591 const char *search = CPUINFO_PROC; 587 const char *search = cpuinfo_proc;
592 size_t len = 0; 588 size_t len = 0;
593 int ret = -1; 589 int ret = -1;
594 590
@@ -638,6 +634,25 @@ done:
638 return ret; 634 return ret;
639} 635}
640 636
637static int write_cpudesc(int fd, struct perf_header *h __maybe_unused,
638 struct perf_evlist *evlist __maybe_unused)
639{
640#ifndef CPUINFO_PROC
641#define CPUINFO_PROC {"model name", }
642#endif
643 const char *cpuinfo_procs[] = CPUINFO_PROC;
644 unsigned int i;
645
646 for (i = 0; i < ARRAY_SIZE(cpuinfo_procs); i++) {
647 int ret;
648 ret = __write_cpudesc(fd, cpuinfo_procs[i]);
649 if (ret >= 0)
650 return ret;
651 }
652 return -1;
653}
654
655
641static int write_nrcpus(int fd, struct perf_header *h __maybe_unused, 656static int write_nrcpus(int fd, struct perf_header *h __maybe_unused,
642 struct perf_evlist *evlist __maybe_unused) 657 struct perf_evlist *evlist __maybe_unused)
643{ 658{
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 4906cd81cb56..9402885a77f3 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -373,6 +373,9 @@ struct sort_entry sort_cpu = {
373static int64_t 373static int64_t
374sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right) 374sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
375{ 375{
376 if (!left->branch_info || !right->branch_info)
377 return cmp_null(left->branch_info, right->branch_info);
378
376 return _sort__dso_cmp(left->branch_info->from.map, 379 return _sort__dso_cmp(left->branch_info->from.map,
377 right->branch_info->from.map); 380 right->branch_info->from.map);
378} 381}
@@ -380,13 +383,19 @@ sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
380static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf, 383static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
381 size_t size, unsigned int width) 384 size_t size, unsigned int width)
382{ 385{
383 return _hist_entry__dso_snprintf(he->branch_info->from.map, 386 if (he->branch_info)
384 bf, size, width); 387 return _hist_entry__dso_snprintf(he->branch_info->from.map,
388 bf, size, width);
389 else
390 return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
385} 391}
386 392
387static int64_t 393static int64_t
388sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right) 394sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
389{ 395{
396 if (!left->branch_info || !right->branch_info)
397 return cmp_null(left->branch_info, right->branch_info);
398
390 return _sort__dso_cmp(left->branch_info->to.map, 399 return _sort__dso_cmp(left->branch_info->to.map,
391 right->branch_info->to.map); 400 right->branch_info->to.map);
392} 401}
@@ -394,8 +403,11 @@ sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
394static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf, 403static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
395 size_t size, unsigned int width) 404 size_t size, unsigned int width)
396{ 405{
397 return _hist_entry__dso_snprintf(he->branch_info->to.map, 406 if (he->branch_info)
398 bf, size, width); 407 return _hist_entry__dso_snprintf(he->branch_info->to.map,
408 bf, size, width);
409 else
410 return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
399} 411}
400 412
401static int64_t 413static int64_t
@@ -404,6 +416,12 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
404 struct addr_map_symbol *from_l = &left->branch_info->from; 416 struct addr_map_symbol *from_l = &left->branch_info->from;
405 struct addr_map_symbol *from_r = &right->branch_info->from; 417 struct addr_map_symbol *from_r = &right->branch_info->from;
406 418
419 if (!left->branch_info || !right->branch_info)
420 return cmp_null(left->branch_info, right->branch_info);
421
422 from_l = &left->branch_info->from;
423 from_r = &right->branch_info->from;
424
407 if (!from_l->sym && !from_r->sym) 425 if (!from_l->sym && !from_r->sym)
408 return _sort__addr_cmp(from_l->addr, from_r->addr); 426 return _sort__addr_cmp(from_l->addr, from_r->addr);
409 427
@@ -413,8 +431,13 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
413static int64_t 431static int64_t
414sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right) 432sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
415{ 433{
416 struct addr_map_symbol *to_l = &left->branch_info->to; 434 struct addr_map_symbol *to_l, *to_r;
417 struct addr_map_symbol *to_r = &right->branch_info->to; 435
436 if (!left->branch_info || !right->branch_info)
437 return cmp_null(left->branch_info, right->branch_info);
438
439 to_l = &left->branch_info->to;
440 to_r = &right->branch_info->to;
418 441
419 if (!to_l->sym && !to_r->sym) 442 if (!to_l->sym && !to_r->sym)
420 return _sort__addr_cmp(to_l->addr, to_r->addr); 443 return _sort__addr_cmp(to_l->addr, to_r->addr);
@@ -425,19 +448,27 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
425static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf, 448static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
426 size_t size, unsigned int width) 449 size_t size, unsigned int width)
427{ 450{
428 struct addr_map_symbol *from = &he->branch_info->from; 451 if (he->branch_info) {
429 return _hist_entry__sym_snprintf(from->map, from->sym, from->addr, 452 struct addr_map_symbol *from = &he->branch_info->from;
430 he->level, bf, size, width);
431 453
454 return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
455 he->level, bf, size, width);
456 }
457
458 return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
432} 459}
433 460
434static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf, 461static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
435 size_t size, unsigned int width) 462 size_t size, unsigned int width)
436{ 463{
437 struct addr_map_symbol *to = &he->branch_info->to; 464 if (he->branch_info) {
438 return _hist_entry__sym_snprintf(to->map, to->sym, to->addr, 465 struct addr_map_symbol *to = &he->branch_info->to;
439 he->level, bf, size, width);
440 466
467 return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
468 he->level, bf, size, width);
469 }
470
471 return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
441} 472}
442 473
443struct sort_entry sort_dso_from = { 474struct sort_entry sort_dso_from = {
@@ -471,11 +502,13 @@ struct sort_entry sort_sym_to = {
471static int64_t 502static int64_t
472sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right) 503sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right)
473{ 504{
474 const unsigned char mp = left->branch_info->flags.mispred != 505 unsigned char mp, p;
475 right->branch_info->flags.mispred; 506
476 const unsigned char p = left->branch_info->flags.predicted != 507 if (!left->branch_info || !right->branch_info)
477 right->branch_info->flags.predicted; 508 return cmp_null(left->branch_info, right->branch_info);
478 509
510 mp = left->branch_info->flags.mispred != right->branch_info->flags.mispred;
511 p = left->branch_info->flags.predicted != right->branch_info->flags.predicted;
479 return mp || p; 512 return mp || p;
480} 513}
481 514
@@ -483,10 +516,12 @@ static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
483 size_t size, unsigned int width){ 516 size_t size, unsigned int width){
484 static const char *out = "N/A"; 517 static const char *out = "N/A";
485 518
486 if (he->branch_info->flags.predicted) 519 if (he->branch_info) {
487 out = "N"; 520 if (he->branch_info->flags.predicted)
488 else if (he->branch_info->flags.mispred) 521 out = "N";
489 out = "Y"; 522 else if (he->branch_info->flags.mispred)
523 out = "Y";
524 }
490 525
491 return repsep_snprintf(bf, size, "%-*.*s", width, width, out); 526 return repsep_snprintf(bf, size, "%-*.*s", width, width, out);
492} 527}
@@ -989,6 +1024,9 @@ struct sort_entry sort_mem_dcacheline = {
989static int64_t 1024static int64_t
990sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) 1025sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
991{ 1026{
1027 if (!left->branch_info || !right->branch_info)
1028 return cmp_null(left->branch_info, right->branch_info);
1029
992 return left->branch_info->flags.abort != 1030 return left->branch_info->flags.abort !=
993 right->branch_info->flags.abort; 1031 right->branch_info->flags.abort;
994} 1032}
@@ -996,10 +1034,15 @@ sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
996static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf, 1034static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf,
997 size_t size, unsigned int width) 1035 size_t size, unsigned int width)
998{ 1036{
999 static const char *out = "."; 1037 static const char *out = "N/A";
1038
1039 if (he->branch_info) {
1040 if (he->branch_info->flags.abort)
1041 out = "A";
1042 else
1043 out = ".";
1044 }
1000 1045
1001 if (he->branch_info->flags.abort)
1002 out = "A";
1003 return repsep_snprintf(bf, size, "%-*s", width, out); 1046 return repsep_snprintf(bf, size, "%-*s", width, out);
1004} 1047}
1005 1048
@@ -1013,6 +1056,9 @@ struct sort_entry sort_abort = {
1013static int64_t 1056static int64_t
1014sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right) 1057sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
1015{ 1058{
1059 if (!left->branch_info || !right->branch_info)
1060 return cmp_null(left->branch_info, right->branch_info);
1061
1016 return left->branch_info->flags.in_tx != 1062 return left->branch_info->flags.in_tx !=
1017 right->branch_info->flags.in_tx; 1063 right->branch_info->flags.in_tx;
1018} 1064}
@@ -1020,10 +1066,14 @@ sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
1020static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf, 1066static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf,
1021 size_t size, unsigned int width) 1067 size_t size, unsigned int width)
1022{ 1068{
1023 static const char *out = "."; 1069 static const char *out = "N/A";
1024 1070
1025 if (he->branch_info->flags.in_tx) 1071 if (he->branch_info) {
1026 out = "T"; 1072 if (he->branch_info->flags.in_tx)
1073 out = "T";
1074 else
1075 out = ".";
1076 }
1027 1077
1028 return repsep_snprintf(bf, size, "%-*s", width, out); 1078 return repsep_snprintf(bf, size, "%-*s", width, out);
1029} 1079}
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 2b7b2d91c016..c41411726c7a 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -117,6 +117,9 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
117 if (!new) 117 if (!new)
118 return -ENOMEM; 118 return -ENOMEM;
119 list_add(&new->list, &thread->comm_list); 119 list_add(&new->list, &thread->comm_list);
120
121 if (exec)
122 unwind__flush_access(thread);
120 } 123 }
121 124
122 thread->comm_set = true; 125 thread->comm_set = true;
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index e060386165c5..4d45c0dfe343 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -539,11 +539,23 @@ int unwind__prepare_access(struct thread *thread)
539 return -ENOMEM; 539 return -ENOMEM;
540 } 540 }
541 541
542 unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL);
542 thread__set_priv(thread, addr_space); 543 thread__set_priv(thread, addr_space);
543 544
544 return 0; 545 return 0;
545} 546}
546 547
548void unwind__flush_access(struct thread *thread)
549{
550 unw_addr_space_t addr_space;
551
552 if (callchain_param.record_mode != CALLCHAIN_DWARF)
553 return;
554
555 addr_space = thread__priv(thread);
556 unw_flush_cache(addr_space, 0, 0);
557}
558
547void unwind__finish_access(struct thread *thread) 559void unwind__finish_access(struct thread *thread)
548{ 560{
549 unw_addr_space_t addr_space; 561 unw_addr_space_t addr_space;
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index c17c4855bdbc..f50b737235eb 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -23,6 +23,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
23#ifdef HAVE_LIBUNWIND_SUPPORT 23#ifdef HAVE_LIBUNWIND_SUPPORT
24int libunwind__arch_reg_id(int regnum); 24int libunwind__arch_reg_id(int regnum);
25int unwind__prepare_access(struct thread *thread); 25int unwind__prepare_access(struct thread *thread);
26void unwind__flush_access(struct thread *thread);
26void unwind__finish_access(struct thread *thread); 27void unwind__finish_access(struct thread *thread);
27#else 28#else
28static inline int unwind__prepare_access(struct thread *thread __maybe_unused) 29static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
@@ -30,6 +31,7 @@ static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
30 return 0; 31 return 0;
31} 32}
32 33
34static inline void unwind__flush_access(struct thread *thread __maybe_unused) {}
33static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} 35static inline void unwind__finish_access(struct thread *thread __maybe_unused) {}
34#endif 36#endif
35#else 37#else
@@ -49,6 +51,7 @@ static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
49 return 0; 51 return 0;
50} 52}
51 53
54static inline void unwind__flush_access(struct thread *thread __maybe_unused) {}
52static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} 55static inline void unwind__finish_access(struct thread *thread __maybe_unused) {}
53#endif /* HAVE_DWARF_UNWIND_SUPPORT */ 56#endif /* HAVE_DWARF_UNWIND_SUPPORT */
54#endif /* __UNWIND_H */ 57#endif /* __UNWIND_H */