aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2011-05-23 07:06:28 -0400
committerIngo Molnar <mingo@elte.hu>2011-05-23 07:22:57 -0400
commit998bedc8c56c6869de457c845cbd328592e5e82e (patch)
treec269208d64edc1a535382601a8904e0eb96a1fcc /tools/perf
parent4eec42f392043063d0f019640b4ccc2a45570002 (diff)
perf tools: Fix ommitted mmap data update on remap
Commit eac9eacee16 "perf tools: Check we are able to read the event size on mmap" brought a check to ensure we can read the size of the event before dereferencing it, and do a remap otherwise to move the buffer forward. However that remap was ommitting all the necessary work to update the new page offset, head, and to unmap previous pages, etc... To fix this, gather all the code that fetches the event in a seperate helper which does all the necessary checks about the header/event size and tells us anytime a remap is needed. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1306148788-6179-3-git-send-email-fweisbec@gmail.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/session.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 948327d9e92b..64500fc78799 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -960,6 +960,30 @@ out_err:
960 return err; 960 return err;
961} 961}
962 962
963static union perf_event *
964fetch_mmaped_event(struct perf_session *session,
965 u64 head, size_t mmap_size, char *buf)
966{
967 union perf_event *event;
968
969 /*
970 * Ensure we have enough space remaining to read
971 * the size of the event in the headers.
972 */
973 if (head + sizeof(event->header) > mmap_size)
974 return NULL;
975
976 event = (union perf_event *)(buf + head);
977
978 if (session->header.needs_swap)
979 perf_event_header__bswap(&event->header);
980
981 if (head + event->header.size > mmap_size)
982 return NULL;
983
984 return event;
985}
986
963int __perf_session__process_events(struct perf_session *session, 987int __perf_session__process_events(struct perf_session *session,
964 u64 data_offset, u64 data_size, 988 u64 data_offset, u64 data_size,
965 u64 file_size, struct perf_event_ops *ops) 989 u64 file_size, struct perf_event_ops *ops)
@@ -1014,19 +1038,8 @@ remap:
1014 file_pos = file_offset + head; 1038 file_pos = file_offset + head;
1015 1039
1016more: 1040more:
1017 /* 1041 event = fetch_mmaped_event(session, head, mmap_size, buf);
1018 * Ensure we have enough space remaining to read 1042 if (!event) {
1019 * the size of the event in the headers.
1020 */
1021 if (head + sizeof(event->header) > mmap_size)
1022 goto remap;
1023
1024 event = (union perf_event *)(buf + head);
1025
1026 if (session->header.needs_swap)
1027 perf_event_header__bswap(&event->header);
1028
1029 if (head + event->header.size > mmap_size) {
1030 if (mmaps[map_idx]) { 1043 if (mmaps[map_idx]) {
1031 munmap(mmaps[map_idx], mmap_size); 1044 munmap(mmaps[map_idx], mmap_size);
1032 mmaps[map_idx] = NULL; 1045 mmaps[map_idx] = NULL;