diff options
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/builtin-diff.c | 5 | ||||
| -rw-r--r-- | tools/perf/builtin-probe.c | 2 | ||||
| -rw-r--r-- | tools/perf/perf-sys.h | 30 | ||||
| -rw-r--r-- | tools/perf/util/header.c | 27 | ||||
| -rw-r--r-- | tools/perf/util/sort.c | 102 | ||||
| -rw-r--r-- | tools/perf/util/thread.c | 3 | ||||
| -rw-r--r-- | tools/perf/util/unwind-libunwind.c | 12 | ||||
| -rw-r--r-- | tools/perf/util/unwind.h | 3 |
8 files changed, 136 insertions, 48 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 8c5c11ca8c53..25114c9a6801 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -1142,6 +1142,11 @@ static int data_init(int argc, const char **argv) | |||
| 1142 | 1142 | ||
| 1143 | int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) | 1143 | int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) |
| 1144 | { | 1144 | { |
| 1145 | int ret = hists__init(); | ||
| 1146 | |||
| 1147 | if (ret < 0) | ||
| 1148 | return ret; | ||
| 1149 | |||
| 1145 | perf_config(perf_default_config, NULL); | 1150 | perf_config(perf_default_config, NULL); |
| 1146 | 1151 | ||
| 1147 | argc = parse_options(argc, argv, options, diff_usage, 0); | 1152 | argc = parse_options(argc, argv, options, diff_usage, 0); |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 04412b4770a2..7af26acf06d9 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
| @@ -375,7 +375,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 375 | OPT_CALLBACK('x', "exec", NULL, "executable|path", | 375 | OPT_CALLBACK('x', "exec", NULL, "executable|path", |
| 376 | "target executable name or path", opt_set_target), | 376 | "target executable name or path", opt_set_target), |
| 377 | OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, | 377 | OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, |
| 378 | "Disable symbol demangling"), | 378 | "Enable symbol demangling"), |
| 379 | OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, | 379 | OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, |
| 380 | "Enable kernel symbol demangling"), | 380 | "Enable kernel symbol demangling"), |
| 381 | OPT_END() | 381 | OPT_END() |
diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h index 937e4324ad94..a3b13d7dc1d4 100644 --- a/tools/perf/perf-sys.h +++ b/tools/perf/perf-sys.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #define wmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") | 13 | #define wmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") |
| 14 | #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") | 14 | #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") |
| 15 | #define cpu_relax() asm volatile("rep; nop" ::: "memory"); | 15 | #define cpu_relax() asm volatile("rep; nop" ::: "memory"); |
| 16 | #define CPUINFO_PROC "model name" | 16 | #define CPUINFO_PROC {"model name"} |
| 17 | #ifndef __NR_perf_event_open | 17 | #ifndef __NR_perf_event_open |
| 18 | # define __NR_perf_event_open 336 | 18 | # define __NR_perf_event_open 336 |
| 19 | #endif | 19 | #endif |
| @@ -30,7 +30,7 @@ | |||
| 30 | #define wmb() asm volatile("sfence" ::: "memory") | 30 | #define wmb() asm volatile("sfence" ::: "memory") |
| 31 | #define rmb() asm volatile("lfence" ::: "memory") | 31 | #define rmb() asm volatile("lfence" ::: "memory") |
| 32 | #define cpu_relax() asm volatile("rep; nop" ::: "memory"); | 32 | #define cpu_relax() asm volatile("rep; nop" ::: "memory"); |
| 33 | #define CPUINFO_PROC "model name" | 33 | #define CPUINFO_PROC {"model name"} |
| 34 | #ifndef __NR_perf_event_open | 34 | #ifndef __NR_perf_event_open |
| 35 | # define __NR_perf_event_open 298 | 35 | # define __NR_perf_event_open 298 |
| 36 | #endif | 36 | #endif |
| @@ -47,14 +47,14 @@ | |||
| 47 | #define mb() asm volatile ("sync" ::: "memory") | 47 | #define mb() asm volatile ("sync" ::: "memory") |
| 48 | #define wmb() asm volatile ("sync" ::: "memory") | 48 | #define wmb() asm volatile ("sync" ::: "memory") |
| 49 | #define rmb() asm volatile ("sync" ::: "memory") | 49 | #define rmb() asm volatile ("sync" ::: "memory") |
| 50 | #define CPUINFO_PROC "cpu" | 50 | #define CPUINFO_PROC {"cpu"} |
| 51 | #endif | 51 | #endif |
| 52 | 52 | ||
| 53 | #ifdef __s390__ | 53 | #ifdef __s390__ |
| 54 | #define mb() asm volatile("bcr 15,0" ::: "memory") | 54 | #define mb() asm volatile("bcr 15,0" ::: "memory") |
| 55 | #define wmb() asm volatile("bcr 15,0" ::: "memory") | 55 | #define wmb() asm volatile("bcr 15,0" ::: "memory") |
| 56 | #define rmb() asm volatile("bcr 15,0" ::: "memory") | 56 | #define rmb() asm volatile("bcr 15,0" ::: "memory") |
| 57 | #define CPUINFO_PROC "vendor_id" | 57 | #define CPUINFO_PROC {"vendor_id"} |
| 58 | #endif | 58 | #endif |
| 59 | 59 | ||
| 60 | #ifdef __sh__ | 60 | #ifdef __sh__ |
| @@ -67,14 +67,14 @@ | |||
| 67 | # define wmb() asm volatile("" ::: "memory") | 67 | # define wmb() asm volatile("" ::: "memory") |
| 68 | # define rmb() asm volatile("" ::: "memory") | 68 | # define rmb() asm volatile("" ::: "memory") |
| 69 | #endif | 69 | #endif |
| 70 | #define CPUINFO_PROC "cpu type" | 70 | #define CPUINFO_PROC {"cpu type"} |
| 71 | #endif | 71 | #endif |
| 72 | 72 | ||
| 73 | #ifdef __hppa__ | 73 | #ifdef __hppa__ |
| 74 | #define mb() asm volatile("" ::: "memory") | 74 | #define mb() asm volatile("" ::: "memory") |
| 75 | #define wmb() asm volatile("" ::: "memory") | 75 | #define wmb() asm volatile("" ::: "memory") |
| 76 | #define rmb() asm volatile("" ::: "memory") | 76 | #define rmb() asm volatile("" ::: "memory") |
| 77 | #define CPUINFO_PROC "cpu" | 77 | #define CPUINFO_PROC {"cpu"} |
| 78 | #endif | 78 | #endif |
| 79 | 79 | ||
| 80 | #ifdef __sparc__ | 80 | #ifdef __sparc__ |
| @@ -87,14 +87,14 @@ | |||
| 87 | #endif | 87 | #endif |
| 88 | #define wmb() asm volatile("":::"memory") | 88 | #define wmb() asm volatile("":::"memory") |
| 89 | #define rmb() asm volatile("":::"memory") | 89 | #define rmb() asm volatile("":::"memory") |
| 90 | #define CPUINFO_PROC "cpu" | 90 | #define CPUINFO_PROC {"cpu"} |
| 91 | #endif | 91 | #endif |
| 92 | 92 | ||
| 93 | #ifdef __alpha__ | 93 | #ifdef __alpha__ |
| 94 | #define mb() asm volatile("mb" ::: "memory") | 94 | #define mb() asm volatile("mb" ::: "memory") |
| 95 | #define wmb() asm volatile("wmb" ::: "memory") | 95 | #define wmb() asm volatile("wmb" ::: "memory") |
| 96 | #define rmb() asm volatile("mb" ::: "memory") | 96 | #define rmb() asm volatile("mb" ::: "memory") |
| 97 | #define CPUINFO_PROC "cpu model" | 97 | #define CPUINFO_PROC {"cpu model"} |
| 98 | #endif | 98 | #endif |
| 99 | 99 | ||
| 100 | #ifdef __ia64__ | 100 | #ifdef __ia64__ |
| @@ -102,7 +102,7 @@ | |||
| 102 | #define wmb() asm volatile ("mf" ::: "memory") | 102 | #define wmb() asm volatile ("mf" ::: "memory") |
| 103 | #define rmb() asm volatile ("mf" ::: "memory") | 103 | #define rmb() asm volatile ("mf" ::: "memory") |
| 104 | #define cpu_relax() asm volatile ("hint @pause" ::: "memory") | 104 | #define cpu_relax() asm volatile ("hint @pause" ::: "memory") |
| 105 | #define CPUINFO_PROC "model name" | 105 | #define CPUINFO_PROC {"model name"} |
| 106 | #endif | 106 | #endif |
| 107 | 107 | ||
| 108 | #ifdef __arm__ | 108 | #ifdef __arm__ |
| @@ -113,7 +113,7 @@ | |||
| 113 | #define mb() ((void(*)(void))0xffff0fa0)() | 113 | #define mb() ((void(*)(void))0xffff0fa0)() |
| 114 | #define wmb() ((void(*)(void))0xffff0fa0)() | 114 | #define wmb() ((void(*)(void))0xffff0fa0)() |
| 115 | #define rmb() ((void(*)(void))0xffff0fa0)() | 115 | #define rmb() ((void(*)(void))0xffff0fa0)() |
| 116 | #define CPUINFO_PROC "Processor" | 116 | #define CPUINFO_PROC {"model name", "Processor"} |
| 117 | #endif | 117 | #endif |
| 118 | 118 | ||
| 119 | #ifdef __aarch64__ | 119 | #ifdef __aarch64__ |
| @@ -133,28 +133,28 @@ | |||
| 133 | : "memory") | 133 | : "memory") |
| 134 | #define wmb() mb() | 134 | #define wmb() mb() |
| 135 | #define rmb() mb() | 135 | #define rmb() mb() |
| 136 | #define CPUINFO_PROC "cpu model" | 136 | #define CPUINFO_PROC {"cpu model"} |
| 137 | #endif | 137 | #endif |
| 138 | 138 | ||
| 139 | #ifdef __arc__ | 139 | #ifdef __arc__ |
| 140 | #define mb() asm volatile("" ::: "memory") | 140 | #define mb() asm volatile("" ::: "memory") |
| 141 | #define wmb() asm volatile("" ::: "memory") | 141 | #define wmb() asm volatile("" ::: "memory") |
| 142 | #define rmb() asm volatile("" ::: "memory") | 142 | #define rmb() asm volatile("" ::: "memory") |
| 143 | #define CPUINFO_PROC "Processor" | 143 | #define CPUINFO_PROC {"Processor"} |
| 144 | #endif | 144 | #endif |
| 145 | 145 | ||
| 146 | #ifdef __metag__ | 146 | #ifdef __metag__ |
| 147 | #define mb() asm volatile("" ::: "memory") | 147 | #define mb() asm volatile("" ::: "memory") |
| 148 | #define wmb() asm volatile("" ::: "memory") | 148 | #define wmb() asm volatile("" ::: "memory") |
| 149 | #define rmb() asm volatile("" ::: "memory") | 149 | #define rmb() asm volatile("" ::: "memory") |
| 150 | #define CPUINFO_PROC "CPU" | 150 | #define CPUINFO_PROC {"CPU"} |
| 151 | #endif | 151 | #endif |
| 152 | 152 | ||
| 153 | #ifdef __xtensa__ | 153 | #ifdef __xtensa__ |
| 154 | #define mb() asm volatile("memw" ::: "memory") | 154 | #define mb() asm volatile("memw" ::: "memory") |
| 155 | #define wmb() asm volatile("memw" ::: "memory") | 155 | #define wmb() asm volatile("memw" ::: "memory") |
| 156 | #define rmb() asm volatile("" ::: "memory") | 156 | #define rmb() asm volatile("" ::: "memory") |
| 157 | #define CPUINFO_PROC "core ID" | 157 | #define CPUINFO_PROC {"core ID"} |
| 158 | #endif | 158 | #endif |
| 159 | 159 | ||
| 160 | #ifdef __tile__ | 160 | #ifdef __tile__ |
| @@ -162,7 +162,7 @@ | |||
| 162 | #define wmb() asm volatile ("mf" ::: "memory") | 162 | #define wmb() asm volatile ("mf" ::: "memory") |
| 163 | #define rmb() asm volatile ("mf" ::: "memory") | 163 | #define rmb() asm volatile ("mf" ::: "memory") |
| 164 | #define cpu_relax() asm volatile ("mfspr zero, PASS" ::: "memory") | 164 | #define cpu_relax() asm volatile ("mfspr zero, PASS" ::: "memory") |
| 165 | #define CPUINFO_PROC "model name" | 165 | #define CPUINFO_PROC {"model name"} |
| 166 | #endif | 166 | #endif |
| 167 | 167 | ||
| 168 | #define barrier() asm volatile ("" ::: "memory") | 168 | #define barrier() asm volatile ("" ::: "memory") |
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 | ||
| 582 | static int write_cpudesc(int fd, struct perf_header *h __maybe_unused, | 582 | static 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 | ||
| 637 | static 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 | |||
| 641 | static int write_nrcpus(int fd, struct perf_header *h __maybe_unused, | 656 | static 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 = { | |||
| 373 | static int64_t | 373 | static int64_t |
| 374 | sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right) | 374 | sort__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) | |||
| 380 | static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf, | 383 | static 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 | ||
| 387 | static int64_t | 393 | static int64_t |
| 388 | sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right) | 394 | sort__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) | |||
| 394 | static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf, | 403 | static 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 | ||
| 401 | static int64_t | 413 | static 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) | |||
| 413 | static int64_t | 431 | static int64_t |
| 414 | sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right) | 432 | sort__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) | |||
| 425 | static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf, | 448 | static 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 | ||
| 434 | static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf, | 461 | static 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 | ||
| 443 | struct sort_entry sort_dso_from = { | 474 | struct sort_entry sort_dso_from = { |
| @@ -471,11 +502,13 @@ struct sort_entry sort_sym_to = { | |||
| 471 | static int64_t | 502 | static int64_t |
| 472 | sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right) | 503 | sort__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 = { | |||
| 989 | static int64_t | 1024 | static int64_t |
| 990 | sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) | 1025 | sort__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) | |||
| 996 | static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf, | 1034 | static 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 = { | |||
| 1013 | static int64_t | 1056 | static int64_t |
| 1014 | sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right) | 1057 | sort__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) | |||
| 1020 | static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf, | 1066 | static 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 | ||
| 548 | void 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 | |||
| 547 | void unwind__finish_access(struct thread *thread) | 559 | void 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 |
| 24 | int libunwind__arch_reg_id(int regnum); | 24 | int libunwind__arch_reg_id(int regnum); |
| 25 | int unwind__prepare_access(struct thread *thread); | 25 | int unwind__prepare_access(struct thread *thread); |
| 26 | void unwind__flush_access(struct thread *thread); | ||
| 26 | void unwind__finish_access(struct thread *thread); | 27 | void unwind__finish_access(struct thread *thread); |
| 27 | #else | 28 | #else |
| 28 | static inline int unwind__prepare_access(struct thread *thread __maybe_unused) | 29 | static 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 | ||
| 34 | static inline void unwind__flush_access(struct thread *thread __maybe_unused) {} | ||
| 33 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} | 35 | static 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 | ||
| 54 | static inline void unwind__flush_access(struct thread *thread __maybe_unused) {} | ||
| 52 | static inline void unwind__finish_access(struct thread *thread __maybe_unused) {} | 55 | static 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 */ |
