Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Zhouyi Zhou and committed by
Arnaldo Carvalho de Melo
8e50d384 ae779a63

+49 -16
+7
tools/perf/builtin-kvm.c
··· 888 888 while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) { 889 889 err = perf_evlist__parse_sample(kvm->evlist, event, &sample); 890 890 if (err) { 891 + perf_evlist__mmap_consume(kvm->evlist, idx); 891 892 pr_err("Failed to parse sample\n"); 892 893 return -1; 893 894 } 894 895 895 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 903 if (err) { 897 904 pr_err("Failed to enqueue sample: %d\n", err); 898 905 return -1;
+6 -4
tools/perf/builtin-top.c
··· 810 810 ret = perf_evlist__parse_sample(top->evlist, event, &sample); 811 811 if (ret) { 812 812 pr_err("Can't parse sample, err = %d\n", ret); 813 - continue; 813 + goto next_event; 814 814 } 815 815 816 816 evsel = perf_evlist__id2evsel(session->evlist, sample.id); ··· 825 825 case PERF_RECORD_MISC_USER: 826 826 ++top->us_samples; 827 827 if (top->hide_user_symbols) 828 - continue; 828 + goto next_event; 829 829 machine = &session->machines.host; 830 830 break; 831 831 case PERF_RECORD_MISC_KERNEL: 832 832 ++top->kernel_samples; 833 833 if (top->hide_kernel_symbols) 834 - continue; 834 + goto next_event; 835 835 machine = &session->machines.host; 836 836 break; 837 837 case PERF_RECORD_MISC_GUEST_KERNEL: ··· 847 847 */ 848 848 /* Fall thru */ 849 849 default: 850 - continue; 850 + goto next_event; 851 851 } 852 852 853 853 ··· 859 859 machine__process_event(machine, event); 860 860 } else 861 861 ++session->stats.nr_unknown_events; 862 + next_event: 863 + perf_evlist__mmap_consume(top->evlist, idx); 862 864 } 863 865 } 864 866
+5 -3
tools/perf/builtin-trace.c
··· 987 987 err = perf_evlist__parse_sample(evlist, event, &sample); 988 988 if (err) { 989 989 fprintf(trace->output, "Can't parse sample, err = %d, skipping...\n", err); 990 - continue; 990 + goto next_event; 991 991 } 992 992 993 993 if (trace->base_time == 0) ··· 1001 1001 evsel = perf_evlist__id2evsel(evlist, sample.id); 1002 1002 if (evsel == NULL) { 1003 1003 fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); 1004 - continue; 1004 + goto next_event; 1005 1005 } 1006 1006 1007 1007 if (sample.raw_data == NULL) { 1008 1008 fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", 1009 1009 perf_evsel__name(evsel), sample.tid, 1010 1010 sample.cpu, sample.raw_size); 1011 - continue; 1011 + goto next_event; 1012 1012 } 1013 1013 1014 1014 handler = evsel->handler.func; 1015 1015 handler(trace, evsel, &sample); 1016 + next_event: 1017 + perf_evlist__mmap_consume(evlist, i); 1016 1018 1017 1019 if (done) 1018 1020 goto out_unmap_evlist;
+1
tools/perf/tests/code-reading.c
··· 290 290 for (i = 0; i < evlist->nr_mmaps; i++) { 291 291 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { 292 292 ret = process_event(machine, evlist, event, state); 293 + perf_evlist__mmap_consume(evlist, i); 293 294 if (ret < 0) 294 295 return ret; 295 296 }
+1
tools/perf/tests/keep-tracking.c
··· 36 36 (pid_t)event->comm.tid == getpid() && 37 37 strcmp(event->comm.comm, comm) == 0) 38 38 found += 1; 39 + perf_evlist__mmap_consume(evlist, i); 39 40 } 40 41 } 41 42 return found;
+1
tools/perf/tests/mmap-basic.c
··· 122 122 goto out_munmap; 123 123 } 124 124 nr_events[evsel->idx]++; 125 + perf_evlist__mmap_consume(evlist, 0); 125 126 } 126 127 127 128 err = 0;
+3 -1
tools/perf/tests/open-syscall-tp-fields.c
··· 77 77 78 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 82 continue; 83 + } 82 84 83 85 err = perf_evsel__parse_sample(evsel, event, &sample); 84 86 if (err) {
+2
tools/perf/tests/perf-record.c
··· 263 263 type); 264 264 ++errs; 265 265 } 266 + 267 + perf_evlist__mmap_consume(evlist, i); 266 268 } 267 269 } 268 270
+3 -1
tools/perf/tests/perf-time-to-tsc.c
··· 122 122 if (event->header.type != PERF_RECORD_COMM || 123 123 (pid_t)event->comm.pid != getpid() || 124 124 (pid_t)event->comm.tid != getpid()) 125 - continue; 125 + goto next_event; 126 126 127 127 if (strcmp(event->comm.comm, comm1) == 0) { 128 128 CHECK__(perf_evsel__parse_sample(evsel, event, ··· 134 134 &sample)); 135 135 comm2_time = sample.time; 136 136 } 137 + next_event: 138 + perf_evlist__mmap_consume(evlist, i); 137 139 } 138 140 } 139 141
+3 -1
tools/perf/tests/sw-clock.c
··· 78 78 struct perf_sample sample; 79 79 80 80 if (event->header.type != PERF_RECORD_SAMPLE) 81 - continue; 81 + goto next_event; 82 82 83 83 err = perf_evlist__parse_sample(evlist, event, &sample); 84 84 if (err < 0) { ··· 88 88 89 89 total_periods += sample.period; 90 90 nr_samples++; 91 + next_event: 92 + perf_evlist__mmap_consume(evlist, 0); 91 93 } 92 94 93 95 if ((u64) nr_samples == total_periods) {
+3 -3
tools/perf/tests/task-exit.c
··· 96 96 97 97 retry: 98 98 while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { 99 - if (event->header.type != PERF_RECORD_EXIT) 100 - continue; 99 + if (event->header.type == PERF_RECORD_EXIT) 100 + nr_exit++; 101 101 102 - nr_exit++; 102 + perf_evlist__mmap_consume(evlist, 0); 103 103 } 104 104 105 105 if (!exited || !nr_exit) {
+10 -3
tools/perf/util/evlist.c
··· 545 545 546 546 md->prev = old; 547 547 548 - if (!evlist->overwrite) 549 - perf_mmap__write_tail(md, old); 550 - 551 548 return event; 549 + } 550 + 551 + void 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 + } 552 559 } 553 560 554 561 static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
+2
tools/perf/util/evlist.h
··· 89 89 90 90 union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); 91 91 92 + void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx); 93 + 92 94 int perf_evlist__open(struct perf_evlist *evlist); 93 95 void perf_evlist__close(struct perf_evlist *evlist); 94 96
+2
tools/perf/util/python.c
··· 822 822 PyObject *pyevent = pyrf_event__new(event); 823 823 struct pyrf_event *pevent = (struct pyrf_event *)pyevent; 824 824 825 + perf_evlist__mmap_consume(evlist, cpu); 826 + 825 827 if (pyevent == NULL) 826 828 return PyErr_NoMemory(); 827 829