diff options
| -rw-r--r-- | tools/perf/Documentation/perf-report.txt | 3 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/event.c | 12 | ||||
| -rw-r--r-- | tools/perf/util/event.h | 3 | ||||
| -rw-r--r-- | tools/perf/util/hist.c | 9 | ||||
| -rw-r--r-- | tools/perf/util/session.c | 154 | ||||
| -rw-r--r-- | tools/perf/util/symbol.c | 9 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 1 |
8 files changed, 127 insertions, 66 deletions
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 59a1f57f2bb..fefea77ec6e 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
| @@ -104,6 +104,9 @@ OPTIONS | |||
| 104 | --vmlinux=<file>:: | 104 | --vmlinux=<file>:: |
| 105 | vmlinux pathname | 105 | vmlinux pathname |
| 106 | 106 | ||
| 107 | --kallsyms=<file>:: | ||
| 108 | kallsyms pathname | ||
| 109 | |||
| 107 | -m:: | 110 | -m:: |
| 108 | --modules:: | 111 | --modules:: |
| 109 | Load module symbols. WARNING: This should only be used with -k and | 112 | Load module symbols. WARNING: This should only be used with -k and |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 904519fba43..b6a2a899aa8 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -443,6 +443,8 @@ static const struct option options[] = { | |||
| 443 | "dump raw trace in ASCII"), | 443 | "dump raw trace in ASCII"), |
| 444 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, | 444 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, |
| 445 | "file", "vmlinux pathname"), | 445 | "file", "vmlinux pathname"), |
| 446 | OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, | ||
| 447 | "file", "kallsyms pathname"), | ||
| 446 | OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), | 448 | OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), |
| 447 | OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, | 449 | OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, |
| 448 | "load module symbols - WARNING: use only with -k and LIVE kernel"), | 450 | "load module symbols - WARNING: use only with -k and LIVE kernel"), |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index e4cdc1ebe0f..183aedd4db8 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include "strlist.h" | 7 | #include "strlist.h" |
| 8 | #include "thread.h" | 8 | #include "thread.h" |
| 9 | 9 | ||
| 10 | const char *event__name[] = { | 10 | static const char *event__name[] = { |
| 11 | [0] = "TOTAL", | 11 | [0] = "TOTAL", |
| 12 | [PERF_RECORD_MMAP] = "MMAP", | 12 | [PERF_RECORD_MMAP] = "MMAP", |
| 13 | [PERF_RECORD_LOST] = "LOST", | 13 | [PERF_RECORD_LOST] = "LOST", |
| @@ -22,8 +22,18 @@ const char *event__name[] = { | |||
| 22 | [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", | 22 | [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", |
| 23 | [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", | 23 | [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", |
| 24 | [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", | 24 | [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", |
| 25 | [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", | ||
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| 28 | const char *event__get_event_name(unsigned int id) | ||
| 29 | { | ||
| 30 | if (id >= ARRAY_SIZE(event__name)) | ||
| 31 | return "INVALID"; | ||
| 32 | if (!event__name[id]) | ||
| 33 | return "UNKNOWN"; | ||
| 34 | return event__name[id]; | ||
| 35 | } | ||
| 36 | |||
| 27 | static struct sample_data synth_sample = { | 37 | static struct sample_data synth_sample = { |
| 28 | .pid = -1, | 38 | .pid = -1, |
| 29 | .tid = -1, | 39 | .tid = -1, |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index a95ab18575c..2b7e91902f1 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -85,6 +85,7 @@ struct build_id_event { | |||
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| 87 | enum perf_user_event_type { /* above any possible kernel type */ | 87 | enum perf_user_event_type { /* above any possible kernel type */ |
| 88 | PERF_RECORD_USER_TYPE_START = 64, | ||
| 88 | PERF_RECORD_HEADER_ATTR = 64, | 89 | PERF_RECORD_HEADER_ATTR = 64, |
| 89 | PERF_RECORD_HEADER_EVENT_TYPE = 65, | 90 | PERF_RECORD_HEADER_EVENT_TYPE = 65, |
| 90 | PERF_RECORD_HEADER_TRACING_DATA = 66, | 91 | PERF_RECORD_HEADER_TRACING_DATA = 66, |
| @@ -171,6 +172,6 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
| 171 | int event__parse_sample(const event_t *event, struct perf_session *session, | 172 | int event__parse_sample(const event_t *event, struct perf_session *session, |
| 172 | struct sample_data *sample); | 173 | struct sample_data *sample); |
| 173 | 174 | ||
| 174 | extern const char *event__name[]; | 175 | const char *event__get_event_name(unsigned int id); |
| 175 | 176 | ||
| 176 | #endif /* __PERF_RECORD_H */ | 177 | #endif /* __PERF_RECORD_H */ |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 2022e874099..a3b84160c42 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -1168,10 +1168,13 @@ size_t hists__fprintf_nr_events(struct hists *self, FILE *fp) | |||
| 1168 | size_t ret = 0; | 1168 | size_t ret = 0; |
| 1169 | 1169 | ||
| 1170 | for (i = 0; i < PERF_RECORD_HEADER_MAX; ++i) { | 1170 | for (i = 0; i < PERF_RECORD_HEADER_MAX; ++i) { |
| 1171 | if (!event__name[i]) | 1171 | const char *name = event__get_event_name(i); |
| 1172 | |||
| 1173 | if (!strcmp(name, "UNKNOWN")) | ||
| 1172 | continue; | 1174 | continue; |
| 1173 | ret += fprintf(fp, "%10s events: %10d\n", | 1175 | |
| 1174 | event__name[i], self->stats.nr_events[i]); | 1176 | ret += fprintf(fp, "%16s events: %10d\n", name, |
| 1177 | self->stats.nr_events[i]); | ||
| 1175 | } | 1178 | } |
| 1176 | 1179 | ||
| 1177 | return ret; | 1180 | return ret; |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 3074d38897e..b59abf5aba3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -444,6 +444,7 @@ static event__swap_op event__swap_ops[] = { | |||
| 444 | 444 | ||
| 445 | struct sample_queue { | 445 | struct sample_queue { |
| 446 | u64 timestamp; | 446 | u64 timestamp; |
| 447 | u64 file_offset; | ||
| 447 | event_t *event; | 448 | event_t *event; |
| 448 | struct list_head list; | 449 | struct list_head list; |
| 449 | }; | 450 | }; |
| @@ -464,7 +465,8 @@ static void perf_session_free_sample_buffers(struct perf_session *session) | |||
| 464 | static int perf_session_deliver_event(struct perf_session *session, | 465 | static int perf_session_deliver_event(struct perf_session *session, |
| 465 | event_t *event, | 466 | event_t *event, |
| 466 | struct sample_data *sample, | 467 | struct sample_data *sample, |
| 467 | struct perf_event_ops *ops); | 468 | struct perf_event_ops *ops, |
| 469 | u64 file_offset); | ||
| 468 | 470 | ||
| 469 | static void flush_sample_queue(struct perf_session *s, | 471 | static void flush_sample_queue(struct perf_session *s, |
| 470 | struct perf_event_ops *ops) | 472 | struct perf_event_ops *ops) |
| @@ -484,7 +486,8 @@ static void flush_sample_queue(struct perf_session *s, | |||
| 484 | break; | 486 | break; |
| 485 | 487 | ||
| 486 | event__parse_sample(iter->event, s, &sample); | 488 | event__parse_sample(iter->event, s, &sample); |
| 487 | perf_session_deliver_event(s, iter->event, &sample, ops); | 489 | perf_session_deliver_event(s, iter->event, &sample, ops, |
| 490 | iter->file_offset); | ||
| 488 | 491 | ||
| 489 | os->last_flush = iter->timestamp; | 492 | os->last_flush = iter->timestamp; |
| 490 | list_del(&iter->list); | 493 | list_del(&iter->list); |
| @@ -596,14 +599,14 @@ static void __queue_event(struct sample_queue *new, struct perf_session *s) | |||
| 596 | #define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue)) | 599 | #define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue)) |
| 597 | 600 | ||
| 598 | static int perf_session_queue_event(struct perf_session *s, event_t *event, | 601 | static int perf_session_queue_event(struct perf_session *s, event_t *event, |
| 599 | struct sample_data *data) | 602 | struct sample_data *data, u64 file_offset) |
| 600 | { | 603 | { |
| 601 | struct ordered_samples *os = &s->ordered_samples; | 604 | struct ordered_samples *os = &s->ordered_samples; |
| 602 | struct list_head *sc = &os->sample_cache; | 605 | struct list_head *sc = &os->sample_cache; |
| 603 | u64 timestamp = data->time; | 606 | u64 timestamp = data->time; |
| 604 | struct sample_queue *new; | 607 | struct sample_queue *new; |
| 605 | 608 | ||
| 606 | if (!timestamp) | 609 | if (!timestamp || timestamp == ~0ULL) |
| 607 | return -ETIME; | 610 | return -ETIME; |
| 608 | 611 | ||
| 609 | if (timestamp < s->ordered_samples.last_flush) { | 612 | if (timestamp < s->ordered_samples.last_flush) { |
| @@ -628,6 +631,7 @@ static int perf_session_queue_event(struct perf_session *s, event_t *event, | |||
| 628 | } | 631 | } |
| 629 | 632 | ||
| 630 | new->timestamp = timestamp; | 633 | new->timestamp = timestamp; |
| 634 | new->file_offset = file_offset; | ||
| 631 | new->event = event; | 635 | new->event = event; |
| 632 | 636 | ||
| 633 | __queue_event(new, s); | 637 | __queue_event(new, s); |
| @@ -635,13 +639,10 @@ static int perf_session_queue_event(struct perf_session *s, event_t *event, | |||
| 635 | return 0; | 639 | return 0; |
| 636 | } | 640 | } |
| 637 | 641 | ||
| 638 | static void callchain__dump(struct sample_data *sample) | 642 | static void callchain__printf(struct sample_data *sample) |
| 639 | { | 643 | { |
| 640 | unsigned int i; | 644 | unsigned int i; |
| 641 | 645 | ||
| 642 | if (!dump_trace) | ||
| 643 | return; | ||
| 644 | |||
| 645 | printf("... chain: nr:%Lu\n", sample->callchain->nr); | 646 | printf("... chain: nr:%Lu\n", sample->callchain->nr); |
| 646 | 647 | ||
| 647 | for (i = 0; i < sample->callchain->nr; i++) | 648 | for (i = 0; i < sample->callchain->nr; i++) |
| @@ -665,13 +666,48 @@ static void perf_session__print_tstamp(struct perf_session *session, | |||
| 665 | printf("%Lu ", sample->time); | 666 | printf("%Lu ", sample->time); |
| 666 | } | 667 | } |
| 667 | 668 | ||
| 669 | static void dump_event(struct perf_session *session, event_t *event, | ||
| 670 | u64 file_offset, struct sample_data *sample) | ||
| 671 | { | ||
| 672 | if (!dump_trace) | ||
| 673 | return; | ||
| 674 | |||
| 675 | printf("\n%#Lx [%#x]: event: %d\n", file_offset, event->header.size, | ||
| 676 | event->header.type); | ||
| 677 | |||
| 678 | trace_event(event); | ||
| 679 | |||
| 680 | if (sample) | ||
| 681 | perf_session__print_tstamp(session, event, sample); | ||
| 682 | |||
| 683 | printf("%#Lx [%#x]: PERF_RECORD_%s", file_offset, event->header.size, | ||
| 684 | event__get_event_name(event->header.type)); | ||
| 685 | } | ||
| 686 | |||
| 687 | static void dump_sample(struct perf_session *session, event_t *event, | ||
| 688 | struct sample_data *sample) | ||
| 689 | { | ||
| 690 | if (!dump_trace) | ||
| 691 | return; | ||
| 692 | |||
| 693 | printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, | ||
| 694 | sample->pid, sample->tid, sample->ip, sample->period); | ||
| 695 | |||
| 696 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) | ||
| 697 | callchain__printf(sample); | ||
| 698 | } | ||
| 699 | |||
| 668 | static int perf_session_deliver_event(struct perf_session *session, | 700 | static int perf_session_deliver_event(struct perf_session *session, |
| 669 | event_t *event, | 701 | event_t *event, |
| 670 | struct sample_data *sample, | 702 | struct sample_data *sample, |
| 671 | struct perf_event_ops *ops) | 703 | struct perf_event_ops *ops, |
| 704 | u64 file_offset) | ||
| 672 | { | 705 | { |
| 706 | dump_event(session, event, file_offset, sample); | ||
| 707 | |||
| 673 | switch (event->header.type) { | 708 | switch (event->header.type) { |
| 674 | case PERF_RECORD_SAMPLE: | 709 | case PERF_RECORD_SAMPLE: |
| 710 | dump_sample(session, event, sample); | ||
| 675 | return ops->sample(event, sample, session); | 711 | return ops->sample(event, sample, session); |
| 676 | case PERF_RECORD_MMAP: | 712 | case PERF_RECORD_MMAP: |
| 677 | return ops->mmap(event, sample, session); | 713 | return ops->mmap(event, sample, session); |
| @@ -695,54 +731,29 @@ static int perf_session_deliver_event(struct perf_session *session, | |||
| 695 | } | 731 | } |
| 696 | } | 732 | } |
| 697 | 733 | ||
| 698 | static int perf_session__process_event(struct perf_session *session, | 734 | static int perf_session__preprocess_sample(struct perf_session *session, |
| 699 | event_t *event, | 735 | event_t *event, struct sample_data *sample) |
| 700 | struct perf_event_ops *ops, | ||
| 701 | u64 file_offset) | ||
| 702 | { | 736 | { |
| 703 | struct sample_data sample; | 737 | if (event->header.type != PERF_RECORD_SAMPLE || |
| 704 | int ret; | 738 | !(session->sample_type & PERF_SAMPLE_CALLCHAIN)) |
| 705 | 739 | return 0; | |
| 706 | trace_event(event); | ||
| 707 | |||
| 708 | if (session->header.needs_swap && event__swap_ops[event->header.type]) | ||
| 709 | event__swap_ops[event->header.type](event); | ||
| 710 | 740 | ||
| 711 | if (event->header.type >= PERF_RECORD_MMAP && | 741 | if (!ip_callchain__valid(sample->callchain, event)) { |
| 712 | event->header.type <= PERF_RECORD_SAMPLE) { | 742 | pr_debug("call-chain problem with event, skipping it.\n"); |
| 713 | event__parse_sample(event, session, &sample); | 743 | ++session->hists.stats.nr_invalid_chains; |
| 714 | if (dump_trace) | 744 | session->hists.stats.total_invalid_chains += sample->period; |
| 715 | perf_session__print_tstamp(session, event, &sample); | 745 | return -EINVAL; |
| 716 | } | 746 | } |
| 747 | return 0; | ||
| 748 | } | ||
| 717 | 749 | ||
| 718 | if (event->header.type < PERF_RECORD_HEADER_MAX) { | 750 | static int perf_session__process_user_event(struct perf_session *session, event_t *event, |
| 719 | dump_printf("%#Lx [%#x]: PERF_RECORD_%s", | 751 | struct perf_event_ops *ops, u64 file_offset) |
| 720 | file_offset, event->header.size, | 752 | { |
| 721 | event__name[event->header.type]); | 753 | dump_event(session, event, file_offset, NULL); |
| 722 | hists__inc_nr_events(&session->hists, event->header.type); | ||
| 723 | } | ||
| 724 | 754 | ||
| 725 | /* These events are processed right away */ | 755 | /* These events are processed right away */ |
| 726 | switch (event->header.type) { | 756 | switch (event->header.type) { |
| 727 | case PERF_RECORD_SAMPLE: | ||
| 728 | dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", | ||
| 729 | event->header.misc, | ||
| 730 | sample.pid, sample.tid, sample.ip, sample.period); | ||
| 731 | |||
| 732 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { | ||
| 733 | if (!ip_callchain__valid(sample.callchain, event)) { | ||
| 734 | pr_debug("call-chain problem with event, " | ||
| 735 | "skipping it.\n"); | ||
| 736 | ++session->hists.stats.nr_invalid_chains; | ||
| 737 | session->hists.stats.total_invalid_chains += | ||
| 738 | sample.period; | ||
| 739 | return 0; | ||
| 740 | } | ||
| 741 | |||
| 742 | callchain__dump(&sample); | ||
| 743 | } | ||
| 744 | break; | ||
| 745 | |||
| 746 | case PERF_RECORD_HEADER_ATTR: | 757 | case PERF_RECORD_HEADER_ATTR: |
| 747 | return ops->attr(event, session); | 758 | return ops->attr(event, session); |
| 748 | case PERF_RECORD_HEADER_EVENT_TYPE: | 759 | case PERF_RECORD_HEADER_EVENT_TYPE: |
| @@ -756,16 +767,47 @@ static int perf_session__process_event(struct perf_session *session, | |||
| 756 | case PERF_RECORD_FINISHED_ROUND: | 767 | case PERF_RECORD_FINISHED_ROUND: |
| 757 | return ops->finished_round(event, session, ops); | 768 | return ops->finished_round(event, session, ops); |
| 758 | default: | 769 | default: |
| 759 | break; | 770 | return -EINVAL; |
| 760 | } | 771 | } |
| 772 | } | ||
| 773 | |||
| 774 | static int perf_session__process_event(struct perf_session *session, | ||
| 775 | event_t *event, | ||
| 776 | struct perf_event_ops *ops, | ||
| 777 | u64 file_offset) | ||
| 778 | { | ||
| 779 | struct sample_data sample; | ||
| 780 | int ret; | ||
| 781 | |||
| 782 | if (session->header.needs_swap && event__swap_ops[event->header.type]) | ||
| 783 | event__swap_ops[event->header.type](event); | ||
| 784 | |||
| 785 | if (event->header.type >= PERF_RECORD_HEADER_MAX) | ||
| 786 | return -EINVAL; | ||
| 787 | |||
| 788 | hists__inc_nr_events(&session->hists, event->header.type); | ||
| 789 | |||
| 790 | if (event->header.type >= PERF_RECORD_USER_TYPE_START) | ||
| 791 | return perf_session__process_user_event(session, event, ops, file_offset); | ||
| 792 | |||
| 793 | /* | ||
| 794 | * For all kernel events we get the sample data | ||
| 795 | */ | ||
| 796 | event__parse_sample(event, session, &sample); | ||
| 797 | |||
| 798 | /* Preprocess sample records - precheck callchains */ | ||
| 799 | if (perf_session__preprocess_sample(session, event, &sample)) | ||
| 800 | return 0; | ||
| 761 | 801 | ||
| 762 | if (ops->ordered_samples) { | 802 | if (ops->ordered_samples) { |
| 763 | ret = perf_session_queue_event(session, event, &sample); | 803 | ret = perf_session_queue_event(session, event, &sample, |
| 804 | file_offset); | ||
| 764 | if (ret != -ETIME) | 805 | if (ret != -ETIME) |
| 765 | return ret; | 806 | return ret; |
| 766 | } | 807 | } |
| 767 | 808 | ||
| 768 | return perf_session_deliver_event(session, event, &sample, ops); | 809 | return perf_session_deliver_event(session, event, &sample, ops, |
| 810 | file_offset); | ||
| 769 | } | 811 | } |
| 770 | 812 | ||
| 771 | void perf_event_header__bswap(struct perf_event_header *self) | 813 | void perf_event_header__bswap(struct perf_event_header *self) |
| @@ -870,9 +912,6 @@ more: | |||
| 870 | 912 | ||
| 871 | head += size; | 913 | head += size; |
| 872 | 914 | ||
| 873 | dump_printf("\n%#Lx [%#x]: event: %d\n", | ||
| 874 | head, event.header.size, event.header.type); | ||
| 875 | |||
| 876 | if (skip > 0) | 915 | if (skip > 0) |
| 877 | head += skip; | 916 | head += skip; |
| 878 | 917 | ||
| @@ -961,9 +1000,6 @@ more: | |||
| 961 | 1000 | ||
| 962 | size = event->header.size; | 1001 | size = event->header.size; |
| 963 | 1002 | ||
| 964 | dump_printf("\n%#Lx [%#x]: event: %d\n", | ||
| 965 | file_pos, event->header.size, event->header.type); | ||
| 966 | |||
| 967 | if (size == 0 || | 1003 | if (size == 0 || |
| 968 | perf_session__process_event(session, event, ops, file_pos) < 0) { | 1004 | perf_session__process_event(session, event, ops, file_pos) < 0) { |
| 969 | dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n", | 1005 | dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n", |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index a348906b587..f40c076aeb7 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -1830,8 +1830,8 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
| 1830 | const char *kallsyms_filename = NULL; | 1830 | const char *kallsyms_filename = NULL; |
| 1831 | char *kallsyms_allocated_filename = NULL; | 1831 | char *kallsyms_allocated_filename = NULL; |
| 1832 | /* | 1832 | /* |
| 1833 | * Step 1: if the user specified a vmlinux filename, use it and only | 1833 | * Step 1: if the user specified a kallsyms or vmlinux filename, use |
| 1834 | * it, reporting errors to the user if it cannot be used. | 1834 | * it and only it, reporting errors to the user if it cannot be used. |
| 1835 | * | 1835 | * |
| 1836 | * For instance, try to analyse an ARM perf.data file _without_ a | 1836 | * For instance, try to analyse an ARM perf.data file _without_ a |
| 1837 | * build-id, or if the user specifies the wrong path to the right | 1837 | * build-id, or if the user specifies the wrong path to the right |
| @@ -1844,6 +1844,11 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map, | |||
| 1844 | * validation in dso__load_vmlinux and will bail out if they don't | 1844 | * validation in dso__load_vmlinux and will bail out if they don't |
| 1845 | * match. | 1845 | * match. |
| 1846 | */ | 1846 | */ |
| 1847 | if (symbol_conf.kallsyms_name != NULL) { | ||
| 1848 | kallsyms_filename = symbol_conf.kallsyms_name; | ||
| 1849 | goto do_kallsyms; | ||
| 1850 | } | ||
| 1851 | |||
| 1847 | if (symbol_conf.vmlinux_name != NULL) { | 1852 | if (symbol_conf.vmlinux_name != NULL) { |
| 1848 | err = dso__load_vmlinux(self, map, | 1853 | err = dso__load_vmlinux(self, map, |
| 1849 | symbol_conf.vmlinux_name, filter); | 1854 | symbol_conf.vmlinux_name, filter); |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 038f2201ee0..12defbe18c1 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -72,6 +72,7 @@ struct symbol_conf { | |||
| 72 | show_cpu_utilization, | 72 | show_cpu_utilization, |
| 73 | initialized; | 73 | initialized; |
| 74 | const char *vmlinux_name, | 74 | const char *vmlinux_name, |
| 75 | *kallsyms_name, | ||
| 75 | *source_prefix, | 76 | *source_prefix, |
| 76 | *field_sep; | 77 | *field_sep; |
| 77 | const char *default_guest_vmlinux_name, | 78 | const char *default_guest_vmlinux_name, |
