aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorZhouyi Zhou <zhouzhouyi@gmail.com>2013-10-24 03:43:33 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-10-28 15:06:00 -0400
commit8e50d384cc1d5afd2989cf0f7093756ed7164eb2 (patch)
tree87e34b49783a32d8552eaad510d0b5fba94ee08e /tools
parentae779a630977d93fbebfa06216ea47df5b5c62c8 (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.c7
-rw-r--r--tools/perf/builtin-top.c10
-rw-r--r--tools/perf/builtin-trace.c8
-rw-r--r--tools/perf/tests/code-reading.c1
-rw-r--r--tools/perf/tests/keep-tracking.c1
-rw-r--r--tools/perf/tests/mmap-basic.c1
-rw-r--r--tools/perf/tests/open-syscall-tp-fields.c4
-rw-r--r--tools/perf/tests/perf-record.c2
-rw-r--r--tools/perf/tests/perf-time-to-tsc.c4
-rw-r--r--tools/perf/tests/sw-clock.c4
-rw-r--r--tools/perf/tests/task-exit.c6
-rw-r--r--tools/perf/util/evlist.c13
-rw-r--r--tools/perf/util/evlist.h2
-rw-r--r--tools/perf/util/python.c2
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;
862next_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);
1016next_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]++; 124 nr_events[evsel->idx]++;
125 perf_evlist__mmap_consume(evlist, 0);
125 } 126 }
126 127
127 err = 0; 128 err = 0;
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
index fc5b9fca8b47..524b221b829b 100644
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ b/tools/perf/tests/open-syscall-tp-fields.c
@@ -77,8 +77,10 @@ int test__syscall_open_tp_fields(void)
77 77
78 ++nr_events; 78 ++nr_events;
79 79
80 if (type != PERF_RECORD_SAMPLE) 80 if (type != PERF_RECORD_SAMPLE) {
81 perf_evlist__mmap_consume(evlist, i);
81 continue; 82 continue;
83 }
82 84
83 err = perf_evsel__parse_sample(evsel, event, &sample); 85 err = perf_evsel__parse_sample(evsel, event, &sample);
84 if (err) { 86 if (err) {
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index b8a7056519ac..7923b06ffc91 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -263,6 +263,8 @@ int test__PERF_RECORD(void)
263 type); 263 type);
264 ++errs; 264 ++errs;
265 } 265 }
266
267 perf_evlist__mmap_consume(evlist, i);
266 } 268 }
267 } 269 }
268 270
diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c
index 0ab61b1f408e..4ca1b938f6a6 100644
--- a/tools/perf/tests/perf-time-to-tsc.c
+++ b/tools/perf/tests/perf-time-to-tsc.c
@@ -122,7 +122,7 @@ int test__perf_time_to_tsc(void)
122 if (event->header.type != PERF_RECORD_COMM || 122 if (event->header.type != PERF_RECORD_COMM ||
123 (pid_t)event->comm.pid != getpid() || 123 (pid_t)event->comm.pid != getpid() ||
124 (pid_t)event->comm.tid != getpid()) 124 (pid_t)event->comm.tid != getpid())
125 continue; 125 goto next_event;
126 126
127 if (strcmp(event->comm.comm, comm1) == 0) { 127 if (strcmp(event->comm.comm, comm1) == 0) {
128 CHECK__(perf_evsel__parse_sample(evsel, event, 128 CHECK__(perf_evsel__parse_sample(evsel, event,
@@ -134,6 +134,8 @@ int test__perf_time_to_tsc(void)
134 &sample)); 134 &sample));
135 comm2_time = sample.time; 135 comm2_time = sample.time;
136 } 136 }
137next_event:
138 perf_evlist__mmap_consume(evlist, i);
137 } 139 }
138 } 140 }
139 141
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c
index 2e41e2d32ccc..6e2b44ec0749 100644
--- a/tools/perf/tests/sw-clock.c
+++ b/tools/perf/tests/sw-clock.c
@@ -78,7 +78,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
78 struct perf_sample sample; 78 struct perf_sample sample;
79 79
80 if (event->header.type != PERF_RECORD_SAMPLE) 80 if (event->header.type != PERF_RECORD_SAMPLE)
81 continue; 81 goto next_event;
82 82
83 err = perf_evlist__parse_sample(evlist, event, &sample); 83 err = perf_evlist__parse_sample(evlist, event, &sample);
84 if (err < 0) { 84 if (err < 0) {
@@ -88,6 +88,8 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
88 88
89 total_periods += sample.period; 89 total_periods += sample.period;
90 nr_samples++; 90 nr_samples++;
91next_event:
92 perf_evlist__mmap_consume(evlist, 0);
91 } 93 }
92 94
93 if ((u64) nr_samples == total_periods) { 95 if ((u64) nr_samples == total_periods) {
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c
index 28fe5894b061..a3e64876e940 100644
--- a/tools/perf/tests/task-exit.c
+++ b/tools/perf/tests/task-exit.c
@@ -96,10 +96,10 @@ int test__task_exit(void)
96 96
97retry: 97retry:
98 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { 98 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
99 if (event->header.type != PERF_RECORD_EXIT) 99 if (event->header.type == PERF_RECORD_EXIT)
100 continue; 100 nr_exit++;
101 101
102 nr_exit++; 102 perf_evlist__mmap_consume(evlist, 0);
103 } 103 }
104 104
105 if (!exited || !nr_exit) { 105 if (!exited || !nr_exit) {
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index f9f77bee0b1b..e584cd30b0f2 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -545,12 +545,19 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
545 545
546 md->prev = old; 546 md->prev = old;
547 547
548 if (!evlist->overwrite)
549 perf_mmap__write_tail(md, old);
550
551 return event; 548 return event;
552} 549}
553 550
551void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
552{
553 if (!evlist->overwrite) {
554 struct perf_mmap *md = &evlist->mmap[idx];
555 unsigned int old = md->prev;
556
557 perf_mmap__write_tail(md, old);
558 }
559}
560
554static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx) 561static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
555{ 562{
556 if (evlist->mmap[idx].base != NULL) { 563 if (evlist->mmap[idx].base != NULL) {
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 880d7139d2fb..206d09339306 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -89,6 +89,8 @@ struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
89 89
90union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); 90union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
91 91
92void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
93
92int perf_evlist__open(struct perf_evlist *evlist); 94int perf_evlist__open(struct perf_evlist *evlist);
93void perf_evlist__close(struct perf_evlist *evlist); 95void perf_evlist__close(struct perf_evlist *evlist);
94 96
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 71b5412bbbb9..2ac4bc92bb1f 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -822,6 +822,8 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
822 PyObject *pyevent = pyrf_event__new(event); 822 PyObject *pyevent = pyrf_event__new(event);
823 struct pyrf_event *pevent = (struct pyrf_event *)pyevent; 823 struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
824 824
825 perf_evlist__mmap_consume(evlist, cpu);
826
825 if (pyevent == NULL) 827 if (pyevent == NULL)
826 return PyErr_NoMemory(); 828 return PyErr_NoMemory();
827 829