[PATCH] perf: fix ordering in perf_output_sample()

From: Stephane Eranian
Date: Wed Jun 13 2012 - 10:12:51 EST



It seems like the merge of commits a7ac67ea and bce38cd5
caused an ordering problem in perf_output_sample().
The watermark check must be done at the very end of the
function and not in the middle of writing data to the buffer.

Signed-off-by: Stephane Eranian <eranian@xxxxxxxxxx>
---

diff --git a/kernel/events/core.c b/kernel/events/core.c
index f85c015..721ba28 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3979,20 +3979,6 @@ void perf_output_sample(struct perf_output_handle *handle,
}
}

- if (!event->attr.watermark) {
- int wakeup_events = event->attr.wakeup_events;
-
- if (wakeup_events) {
- struct ring_buffer *rb = handle->rb;
- int events = local_inc_return(&rb->events);
-
- if (events >= wakeup_events) {
- local_sub(wakeup_events, &rb->events);
- local_inc(&rb->wakeup);
- }
- }
- }
-
if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
if (data->br_stack) {
size_t size;
@@ -4010,6 +3996,20 @@ void perf_output_sample(struct perf_output_handle *handle,
perf_output_put(handle, nr);
}
}
+
+ if (!event->attr.watermark) {
+ int wakeup_events = event->attr.wakeup_events;
+
+ if (wakeup_events) {
+ struct ring_buffer *rb = handle->rb;
+ int events = local_inc_return(&rb->events);
+
+ if (events >= wakeup_events) {
+ local_sub(wakeup_events, &rb->events);
+ local_inc(&rb->wakeup);
+ }
+ }
+ }
}

void perf_prepare_sample(struct perf_event_header *header,
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/