On Fri, Dec 6, 2019 at 5:56 AM David Sterba <dsterba@xxxxxxx> wrote: > > For reference, I've retested current master (b0d4beaa5a4b7d), that > incldes the 2 pipe fixes, the test still hangs. I think I found it. TOTALLY UNTESTED patch appended. It's whitespace-damaged and may be completely wrong. And might not fix it. The first hunk is purely syntactic sugar - use the normal head/tail order. The second/third hunk is what I think fixes the problem: iter_file_splice_write() had the same buggy "let's cache head/tail/mask" pattern as pipe_write() had. You can't cache them over a 'pipe_wait()' that drops the pipe lock, and there's one in splice_from_pipe_next(). Linus --- snip snip -- diff --git a/fs/splice.c b/fs/splice.c index f2400ce7d528..fa1f3773c8cd 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -495,7 +495,7 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des unsigned int mask = pipe->ring_size - 1; int ret; - while (!pipe_empty(tail, head)) { + while (!pipe_empty(head, tail)) { struct pipe_buffer *buf = &pipe->bufs[tail & mask]; sd->len = buf->len; @@ -711,9 +711,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, splice_from_pipe_begin(&sd); while (sd.total_len) { struct iov_iter from; - unsigned int head = pipe->head; - unsigned int tail = pipe->tail; - unsigned int mask = pipe->ring_size - 1; + unsigned int head, tail, mask; size_t left; int n; @@ -732,6 +730,10 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, } } + head = pipe->head; + tail = pipe->tail; + mask = pipe->ring_size - 1; + /* build the vector */ left = sd.total_len; for (n = 0; !pipe_empty(head, tail) && left && n < nbufs; tail++, n++) {