mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] pipe: fix empty pipe check in pipe_write()
@ 2019-12-22 12:33 Jan Stancek
  2019-12-22 17:50 ` Linus Torvalds
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Stancek @ 2019-12-22 12:33 UTC (permalink / raw)
  To: torvalds, linux-fsdevel; +Cc: linux-kernel, dhowells, viro, rasibley, jstancek

LTP pipeio_1 test is hanging with v5.5-rc2-385-gb8e382a185eb,
with read side observing empty pipe and sleeping and write
side running out of space and then sleeping as well. In this
scenario there are 5 writers and 1 reader.

Problem is that after pipe_write() reacquires pipe lock, it
re-checks for empty pipe with potentially stale 'head' and
doesn't wake up read side anymore. pipe->tail can advance
beyond 'head', because there are multiple writers.

Use pipe->head for empty pipe check after reacquiring lock
to observe current state.

Testing: With patch, LTP pipeio_1 ran successfully in loop for 1 hour.
         Without patch it hanged within a minute.

Fixes: 1b6b26ae7053 ("pipe: fix and clarify pipe write wakeup logic")
Reported-by: Rachel Sibley <rasibley@redhat.com>
Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
 fs/pipe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index 04d004ee2e8c..57502c3c0fba 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -581,7 +581,7 @@ static inline bool pipe_writable(const struct pipe_inode_info *pipe)
 		}
 		wait_event_interruptible(pipe->wait, pipe_writable(pipe));
 		__pipe_lock(pipe);
-		was_empty = pipe_empty(head, pipe->tail);
+		was_empty = pipe_empty(pipe->head, pipe->tail);
 	}
 out:
 	__pipe_unlock(pipe);
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] pipe: fix empty pipe check in pipe_write()
  2019-12-22 12:33 [PATCH] pipe: fix empty pipe check in pipe_write() Jan Stancek
@ 2019-12-22 17:50 ` Linus Torvalds
  0 siblings, 0 replies; 2+ messages in thread
From: Linus Torvalds @ 2019-12-22 17:50 UTC (permalink / raw)
  To: Jan Stancek
  Cc: linux-fsdevel, Linux Kernel Mailing List, David Howells, Al Viro,
	rasibley

On Sun, Dec 22, 2019 at 4:35 AM Jan Stancek <jstancek@redhat.com> wrote:
> Problem is that after pipe_write() reacquires pipe lock, it
> re-checks for empty pipe with potentially stale 'head' and
> doesn't wake up read side anymore. pipe->tail can advance
> beyond 'head', because there are multiple writers.

Thank you. Patch is obviously correct, applied.

I wonder how much that whole "cache head/tail/mask" really helps, and
if we should strive to get rid of it entirely (and just make
"pipe_emptuy()" and friends take a 'const struct pipe_inode_info *"
argument).

Oh well.  I've apple your one-liner, but next time I might decide the
cleverness and slight code generation advantage might not be worth it.

Hopefully there won't _be_ a next time, of course ;)

             Linus

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-12-22 17:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-22 12:33 [PATCH] pipe: fix empty pipe check in pipe_write() Jan Stancek
2019-12-22 17:50 ` Linus Torvalds

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®