diff options
| -rw-r--r-- | tools/perf/util/session.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 7c5cc129207a..a765b274390e 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -732,6 +732,22 @@ static int perf_session_deliver_event(struct perf_session *session, | |||
| 732 | } | 732 | } |
| 733 | } | 733 | } |
| 734 | 734 | ||
| 735 | static int perf_session__preprocess_sample(struct perf_session *session, | ||
| 736 | event_t *event, struct sample_data *sample) | ||
| 737 | { | ||
| 738 | if (event->header.type != PERF_RECORD_SAMPLE || | ||
| 739 | !(session->sample_type & PERF_SAMPLE_CALLCHAIN)) | ||
| 740 | return 0; | ||
| 741 | |||
| 742 | if (!ip_callchain__valid(sample->callchain, event)) { | ||
| 743 | pr_debug("call-chain problem with event, skipping it.\n"); | ||
| 744 | ++session->hists.stats.nr_invalid_chains; | ||
| 745 | session->hists.stats.total_invalid_chains += sample->period; | ||
| 746 | return -EINVAL; | ||
| 747 | } | ||
| 748 | return 0; | ||
| 749 | } | ||
| 750 | |||
| 735 | static int perf_session__process_event(struct perf_session *session, | 751 | static int perf_session__process_event(struct perf_session *session, |
| 736 | event_t *event, | 752 | event_t *event, |
| 737 | struct perf_event_ops *ops, | 753 | struct perf_event_ops *ops, |
| @@ -750,24 +766,9 @@ static int perf_session__process_event(struct perf_session *session, | |||
| 750 | 766 | ||
| 751 | if (event->header.type >= PERF_RECORD_USER_TYPE_START) | 767 | if (event->header.type >= PERF_RECORD_USER_TYPE_START) |
| 752 | dump_event(session, event, file_offset, NULL); | 768 | dump_event(session, event, file_offset, NULL); |
| 753 | else | ||
| 754 | event__parse_sample(event, session, &sample); | ||
| 755 | 769 | ||
| 756 | /* These events are processed right away */ | 770 | /* These events are processed right away */ |
| 757 | switch (event->header.type) { | 771 | switch (event->header.type) { |
| 758 | case PERF_RECORD_SAMPLE: | ||
| 759 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { | ||
| 760 | if (!ip_callchain__valid(sample.callchain, event)) { | ||
| 761 | pr_debug("call-chain problem with event, " | ||
| 762 | "skipping it.\n"); | ||
| 763 | ++session->hists.stats.nr_invalid_chains; | ||
| 764 | session->hists.stats.total_invalid_chains += | ||
| 765 | sample.period; | ||
| 766 | return 0; | ||
| 767 | } | ||
| 768 | } | ||
| 769 | break; | ||
| 770 | |||
| 771 | case PERF_RECORD_HEADER_ATTR: | 772 | case PERF_RECORD_HEADER_ATTR: |
| 772 | return ops->attr(event, session); | 773 | return ops->attr(event, session); |
| 773 | case PERF_RECORD_HEADER_EVENT_TYPE: | 774 | case PERF_RECORD_HEADER_EVENT_TYPE: |
| @@ -784,6 +785,15 @@ static int perf_session__process_event(struct perf_session *session, | |||
| 784 | break; | 785 | break; |
| 785 | } | 786 | } |
| 786 | 787 | ||
| 788 | /* | ||
| 789 | * For all kernel events we get the sample data | ||
| 790 | */ | ||
| 791 | event__parse_sample(event, session, &sample); | ||
| 792 | |||
| 793 | /* Preprocess sample records - precheck callchains */ | ||
| 794 | if (perf_session__preprocess_sample(session, event, &sample)) | ||
| 795 | return 0; | ||
| 796 | |||
| 787 | if (ops->ordered_samples) { | 797 | if (ops->ordered_samples) { |
| 788 | ret = perf_session_queue_event(session, event, &sample, | 798 | ret = perf_session_queue_event(session, event, &sample, |
| 789 | file_offset); | 799 | file_offset); |
