diff options
| -rw-r--r-- | kernel/events/ring_buffer.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 009467a60578..4b5f8d932400 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c | |||
| @@ -48,6 +48,15 @@ static void perf_output_put_handle(struct perf_output_handle *handle) | |||
| 48 | unsigned long head; | 48 | unsigned long head; |
| 49 | 49 | ||
| 50 | again: | 50 | again: |
| 51 | /* | ||
| 52 | * In order to avoid publishing a head value that goes backwards, | ||
| 53 | * we must ensure the load of @rb->head happens after we've | ||
| 54 | * incremented @rb->nest. | ||
| 55 | * | ||
| 56 | * Otherwise we can observe a @rb->head value before one published | ||
| 57 | * by an IRQ/NMI happening between the load and the increment. | ||
| 58 | */ | ||
| 59 | barrier(); | ||
| 51 | head = local_read(&rb->head); | 60 | head = local_read(&rb->head); |
| 52 | 61 | ||
| 53 | /* | 62 | /* |
