diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index 009467a60578e4e41c345e754f0d5344dd7d8fde..4b5f8d932400c1c46a0e8bd98c4b446a39857ec2 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) unsigned long head; again: + /* + * In order to avoid publishing a head value that goes backwards, + * we must ensure the load of @rb->head happens after we've + * incremented @rb->nest. + * + * Otherwise we can observe a @rb->head value before one published + * by an IRQ/NMI happening between the load and the increment. + */ + barrier(); head = local_read(&rb->head); /*