diff options
| author | Zhouyi Zhou <zhouzhouyi@gmail.com> | 2013-10-24 03:43:33 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-10-28 15:06:00 -0400 |
| commit | 8e50d384cc1d5afd2989cf0f7093756ed7164eb2 (patch) | |
| tree | 87e34b49783a32d8552eaad510d0b5fba94ee08e /tools | |
| parent | ae779a630977d93fbebfa06216ea47df5b5c62c8 (diff) | |
perf tools: Fixup mmap event consumption
The tail position of the event buffer should only be modified after
actually use that event.
If not the event buffer could be invalid before use, and segment fault
occurs when invoking perf top -G.
Signed-off-by: Zhouyi Zhou <yizhouzhou@ict.ac.cn>
Cc: David Ahern <dsahern@gmail.com>
Cc: Zhouyi Zhou <yizhouzhou@ict.ac.cn>
Link: http://lkml.kernel.org/r/1382600613-32177-1-git-send-email-zhouzhouyi@gmail.com
[ Simplified the logic using exit gotos and renamed write_tail method to mmap_consume ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/perf/builtin-kvm.c | 7 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 10 | ||||
| -rw-r--r-- | tools/perf/builtin-trace.c | 8 | ||||
| -rw-r--r-- | tools/perf/tests/code-reading.c | 1 | ||||
| -rw-r--r-- | tools/perf/tests/keep-tracking.c | 1 | ||||
| -rw-r--r-- | tools/perf/tests/mmap-basic.c | 1 | ||||
| -rw-r--r-- | tools/perf/tests/open-syscall-tp-fields.c | 4 | ||||
| -rw-r--r-- | tools/perf/tests/perf-record.c | 2 | ||||
| -rw-r--r-- | tools/perf/tests/perf-time-to-tsc.c | 4 | ||||
| -rw-r--r-- | tools/perf/tests/sw-clock.c | 4 | ||||
| -rw-r--r-- | tools/perf/tests/task-exit.c | 6 | ||||
| -rw-r--r-- | tools/perf/util/evlist.c | 13 | ||||
| -rw-r--r-- | tools/perf/util/evlist.h | 2 | ||||
| -rw-r--r-- | tools/perf/util/python.c | 2 |
14 files changed, 49 insertions, 16 deletions
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 935d52216c89..fbc2888d6495 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
| @@ -888,11 +888,18 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx, | |||
| 888 | while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) { | 888 | while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) { |
| 889 | err = perf_evlist__parse_sample(kvm->evlist, event, &sample); | 889 | err = perf_evlist__parse_sample(kvm->evlist, event, &sample); |
| 890 | if (err) { | 890 | if (err) { |
| 891 | perf_evlist__mmap_consume(kvm->evlist, idx); | ||
| 891 | pr_err("Failed to parse sample\n"); | 892 | pr_err("Failed to parse sample\n"); |
| 892 | return -1; | 893 | return -1; |
| 893 | } | 894 | } |
| 894 | 895 | ||
| 895 | err = perf_session_queue_event(kvm->session, event, &sample, 0); | 896 | err = perf_session_queue_event(kvm->session, event, &sample, 0); |
| 897 | /* | ||
| 898 | * FIXME: Here we can't consume the event, as perf_session_queue_event will | ||
| 899 | * point to it, and it'll get possibly overwritten by the kernel. | ||
| 900 | */ | ||
| 901 | perf_evlist__mmap_consume(kvm->evlist, idx); | ||
| 902 | |||
| 896 | if (err) { | 903 | if (err) { |
| 897 | pr_err("Failed to enqueue sample: %d\n", err); | 904 | pr_err("Failed to enqueue sample: %d\n", err); |
| 898 | return -1; | 905 | return -1; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0df298a0e946..5a11f13e56f9 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -810,7 +810,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
| 810 | ret = perf_evlist__parse_sample(top->evlist, event, &sample); | 810 | ret = perf_evlist__parse_sample(top->evlist, event, &sample); |
| 811 | if (ret) { | 811 | if (ret) { |
| 812 | pr_err("Can't parse sample, err = %d\n", ret); | 812 | pr_err("Can't parse sample, err = %d\n", ret); |
| 813 | continue; | 813 | goto next_event; |
| 814 | } | 814 | } |
| 815 | 815 | ||
| 816 | evsel = perf_evlist__id2evsel(session->evlist, sample.id); | 816 | evsel = perf_evlist__id2evsel(session->evlist, sample.id); |
| @@ -825,13 +825,13 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
| 825 | case PERF_RECORD_MISC_USER: | 825 | case PERF_RECORD_MISC_USER: |
| 826 | ++top->us_samples; | 826 | ++top->us_samples; |
| 827 | if (top->hide_user_symbols) | 827 | if (top->hide_user_symbols) |
| 828 | continue; | 828 | goto next_event; |
| 829 | machine = &session->machines.host; | 829 | machine = &session->machines.host; |
| 830 | break; | 830 | break; |
| 831 | case PERF_RECORD_MISC_KERNEL: | 831 | case PERF_RECORD_MISC_KERNEL: |
| 832 | ++top->kernel_samples; | 832 | ++top->kernel_samples; |
| 833 | if (top->hide_kernel_symbols) | 833 | if (top->hide_kernel_symbols) |
| 834 | continue; | 834 | goto next_event; |
| 835 | machine = &session->machines.host; | 835 | machine = &session->machines.host; |
| 836 | break; | 836 | break; |
| 837 | case PERF_RECORD_MISC_GUEST_KERNEL: | 837 | case PERF_RECORD_MISC_GUEST_KERNEL: |
| @@ -847,7 +847,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
| 847 | */ | 847 | */ |
| 848 | /* Fall thru */ | 848 | /* Fall thru */ |
| 849 | default: | 849 | default: |
| 850 | continue; | 850 | goto next_event; |
| 851 | } | 851 | } |
| 852 | 852 | ||
| 853 | 853 | ||
| @@ -859,6 +859,8 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
| 859 | machine__process_event(machine, event); | 859 | machine__process_event(machine, event); |
| 860 | } else | 860 | } else |
| 861 | ++session->stats.nr_unknown_events; | 861 | ++session->stats.nr_unknown_events; |
| 862 | next_event: | ||
| 863 | perf_evlist__mmap_consume(top->evlist, idx); | ||
| 862 | } | 864 | } |
| 863 | } | 865 | } |
| 864 | 866 | ||
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 71aa3e35406b..99c8d9ad6729 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -987,7 +987,7 @@ again: | |||
| 987 | err = perf_evlist__parse_sample(evlist, event, &sample); | 987 | err = perf_evlist__parse_sample(evlist, event, &sample); |
| 988 | if (err) { | 988 | if (err) { |
| 989 | fprintf(trace->output, "Can't parse sample, err = %d, skipping...\n", err); | 989 | fprintf(trace->output, "Can't parse sample, err = %d, skipping...\n", err); |
| 990 | continue; | 990 | goto next_event; |
| 991 | } | 991 | } |
| 992 | 992 | ||
| 993 | if (trace->base_time == 0) | 993 | if (trace->base_time == 0) |
| @@ -1001,18 +1001,20 @@ again: | |||
| 1001 | evsel = perf_evlist__id2evsel(evlist, sample.id); | 1001 | evsel = perf_evlist__id2evsel(evlist, sample.id); |
| 1002 | if (evsel == NULL) { | 1002 | if (evsel == NULL) { |
| 1003 | fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); | 1003 | fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); |
| 1004 | continue; | 1004 | goto next_event; |
| 1005 | } | 1005 | } |
| 1006 | 1006 | ||
| 1007 | if (sample.raw_data == NULL) { | 1007 | if (sample.raw_data == NULL) { |
| 1008 | fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", | 1008 | fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", |
| 1009 | perf_evsel__name(evsel), sample.tid, | 1009 | perf_evsel__name(evsel), sample.tid, |
| 1010 | sample.cpu, sample.raw_size); | 1010 | sample.cpu, sample.raw_size); |
| 1011 | continue; | 1011 | goto next_event; |
| 1012 | } | 1012 | } |
| 1013 | 1013 | ||
| 1014 | handler = evsel->handler.func; | 1014 | handler = evsel->handler.func; |
| 1015 | handler(trace, evsel, &sample); | 1015 | handler(trace, evsel, &sample); |
| 1016 | next_event: | ||
| 1017 | perf_evlist__mmap_consume(evlist, i); | ||
| 1016 | 1018 | ||
| 1017 | if (done) | 1019 | if (done) |
| 1018 | goto out_unmap_evlist; | 1020 | goto out_unmap_evlist; |
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 6fb781d5586c..e3fedfa2906e 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c | |||
| @@ -290,6 +290,7 @@ static int process_events(struct machine *machine, struct perf_evlist *evlist, | |||
| 290 | for (i = 0; i < evlist->nr_mmaps; i++) { | 290 | for (i = 0; i < evlist->nr_mmaps; i++) { |
| 291 | while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { | 291 | while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { |
| 292 | ret = process_event(machine, evlist, event, state); | 292 | ret = process_event(machine, evlist, event, state); |
| 293 | perf_evlist__mmap_consume(evlist, i); | ||
| 293 | if (ret < 0) | 294 | if (ret < 0) |
| 294 | return ret; | 295 | return ret; |
| 295 | } | 296 | } |
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index d444ea2c47d9..376c35608534 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c | |||
| @@ -36,6 +36,7 @@ static int find_comm(struct perf_evlist *evlist, const char *comm) | |||
| 36 | (pid_t)event->comm.tid == getpid() && | 36 | (pid_t)event->comm.tid == getpid() && |
| 37 | strcmp(event->comm.comm, comm) == 0) | 37 | strcmp(event->comm.comm, comm) == 0) |
| 38 | found += 1; | 38 | found += 1; |
| 39 | perf_evlist__mmap_consume(evlist, i); | ||
| 39 | } | 40 | } |
| 40 | } | 41 | } |
| 41 | return found; | 42 | return found; |
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index c4185b9aeb80..a7232c204eb9 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c | |||
| @@ -122,6 +122,7 @@ int test__basic_mmap(void) | |||
| 122 | goto out_munmap; | 122 | goto out_munmap; |
| 123 | } | 123 | } |
| 124 | nr_events[evsel->idx]++; | ||
