Skip to content

Commit aaec5a9

Browse files
oleg-nesterovbrauner
authored andcommitted
pipe_read: don't wake up the writer if the pipe is still full
wake_up(pipe->wr_wait) makes no sense if pipe_full() is still true after the reading, the writer sleeping in wait_event(wr_wait, pipe_writable()) will check the pipe_writable() == !pipe_full() condition and sleep again. Only wake the writer if we actually released a pipe buf, and the pipe was full before we did so. Signed-off-by: Oleg Nesterov <[email protected]> Link: https://lore.kernel.org/all/[email protected]/ Link: https://lore.kernel.org/r/[email protected] Reported-by: WangYuli <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent d2fc0ed commit aaec5a9

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

fs/pipe.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
253253
size_t total_len = iov_iter_count(to);
254254
struct file *filp = iocb->ki_filp;
255255
struct pipe_inode_info *pipe = filp->private_data;
256-
bool was_full, wake_next_reader = false;
256+
bool wake_writer = false, wake_next_reader = false;
257257
ssize_t ret;
258258

259259
/* Null read succeeds. */
@@ -264,14 +264,13 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
264264
mutex_lock(&pipe->mutex);
265265

266266
/*
267-
* We only wake up writers if the pipe was full when we started
268-
* reading in order to avoid unnecessary wakeups.
267+
* We only wake up writers if the pipe was full when we started reading
268+
* and it is no longer full after reading to avoid unnecessary wakeups.
269269
*
270270
* But when we do wake up writers, we do so using a sync wakeup
271271
* (WF_SYNC), because we want them to get going and generate more
272272
* data for us.
273273
*/
274-
was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
275274
for (;;) {
276275
/* Read ->head with a barrier vs post_one_notification() */
277276
unsigned int head = smp_load_acquire(&pipe->head);
@@ -340,8 +339,10 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
340339
buf->len = 0;
341340
}
342341

343-
if (!buf->len)
342+
if (!buf->len) {
343+
wake_writer |= pipe_full(head, tail, pipe->max_usage);
344344
tail = pipe_update_tail(pipe, buf, tail);
345+
}
345346
total_len -= chars;
346347
if (!total_len)
347348
break; /* common path: read succeeded */
@@ -377,7 +378,7 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
377378
* _very_ unlikely case that the pipe was full, but we got
378379
* no data.
379380
*/
380-
if (unlikely(was_full))
381+
if (unlikely(wake_writer))
381382
wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
382383
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
383384

@@ -390,15 +391,15 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
390391
if (wait_event_interruptible_exclusive(pipe->rd_wait, pipe_readable(pipe)) < 0)
391392
return -ERESTARTSYS;
392393

393-
mutex_lock(&pipe->mutex);
394-
was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
394+
wake_writer = false;
395395
wake_next_reader = true;
396+
mutex_lock(&pipe->mutex);
396397
}
397398
if (pipe_empty(pipe->head, pipe->tail))
398399
wake_next_reader = false;
399400
mutex_unlock(&pipe->mutex);
400401

401-
if (was_full)
402+
if (wake_writer)
402403
wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
403404
if (wake_next_reader)
404405
wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);

0 commit comments

Comments
 (0)