* [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®