summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/pipe.c3
-rw-r--r--kernel/watch_queue.c2
2 files changed, 3 insertions, 2 deletions
diff --git a/fs/pipe.c b/fs/pipe.c
index 8b0f6979fb49..751d5b36c84b 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -252,7 +252,8 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
*/
was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
for (;;) {
- unsigned int head = pipe->head;
+ /* Read ->head with a barrier vs post_one_notification() */
+ unsigned int head = smp_load_acquire(&pipe->head);
unsigned int tail = pipe->tail;
unsigned int mask = pipe->ring_size - 1;
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index e4d7225f539e..1a13066bf6fa 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -113,7 +113,7 @@ static bool post_one_notification(struct watch_queue *wqueue,
buf->offset = offset;
buf->len = len;
buf->flags = PIPE_BUF_FLAG_WHOLE;
- pipe->head = head + 1;
+ smp_store_release(&pipe->head, head + 1); /* vs pipe_read() */
if (!test_and_clear_bit(note, wqueue->notes_bitmap)) {
spin_unlock_irq(&pipe->rd_wait.lock);