There's nothing to synchronise post_one_notification() versus pipe_read(). Whilst posting is done under pipe->rd_wait.lock, the reader only takes pipe->mutex which cannot bar notification posting as that may need to be made from contexts that cannot sleep. Fix this by setting pipe->head with a barrier in post_one_notification() and reading pipe->head with a barrier in pipe_read(). If that's not sufficient, the rd_wait.lock will need to be taken, possibly in a ->confirm() op so that it only applies to notifications. The lock would, however, have to be dropped before copy_page_to_iter() is invoked.
Unified · Split
| @@ -253,7 +253,8 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) · 252 unmodified lines | ||
| 253 | 253 | */ |
| 254 | 254 | was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage); |
| 255 | 255 | for (;;) { |
| 256 | − unsigned int head = pipe->head; | |
| 256 | + /* Read ->head with a barrier vs post_one_notification() */ | |
| 257 | + unsigned int head = smp_load_acquire(&pipe->head); | |
| 257 | 258 | unsigned int tail = pipe->tail; |
| 258 | 259 | unsigned int mask = pipe->ring_size - 1; |
| 259 | 260 | |
| @@ -113,7 +113,7 @@ static bool post_one_notification(struct watch_queue *wqueue, · 112 unmodified lines | ||
| 113 | 113 | buf->offset = offset; |
| 114 | 114 | buf->len = len; |
| 115 | 115 | buf->flags = PIPE_BUF_FLAG_WHOLE; |
| 116 | − pipe->head = head + 1; | |
| 116 | + smp_store_release(&pipe->head, head + 1); /* vs pipe_read() */ | |
| 117 | 117 | |
| 118 | 118 | if (!test_and_clear_bit(note, wqueue->notes_bitmap)) { |
| 119 | 119 | spin_unlock_irq(&pipe->rd_wait.lock); |