On Tue, Feb 18, 2020 at 1:51 AM Andrei Vagin <avagin@xxxxxxxxx> wrote: > > This patch breaks one of CRIU tests. Here is a small reproducer: Good catch. > The quick fix looks like this: That one works, but is not really right. The things that change the number of readers or writers should simply use "wake_up_all()". I thought we did that already, but no - there _was_ one place where we did it, but that was for the pipe buffer size case, and in that case it's actually pointless. That case acts just like a "new space or data was added" So I think the right fix is the attached patch. Since you had such a lovely test-case, let me go test it too ;) Linus
fs/pipe.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index 5a34d6c22d4c..76e7f66fe2fe 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -1026,8 +1026,8 @@ static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt) static void wake_up_partner(struct pipe_inode_info *pipe) { - wake_up_interruptible(&pipe->rd_wait); - wake_up_interruptible(&pipe->wr_wait); + wake_up_interruptible_all(&pipe->rd_wait); + wake_up_interruptible_all(&pipe->wr_wait); } static int fifo_open(struct inode *inode, struct file *filp) @@ -1144,7 +1144,7 @@ static int fifo_open(struct inode *inode, struct file *filp) err_wr: if (!--pipe->writers) - wake_up_interruptible(&pipe->rd_wait); + wake_up_interruptible_all(&pipe->rd_wait); ret = -ERESTARTSYS; goto err; @@ -1271,8 +1271,8 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg) pipe->max_usage = nr_slots; pipe->tail = tail; pipe->head = head; - wake_up_interruptible_all(&pipe->rd_wait); - wake_up_interruptible_all(&pipe->wr_wait); + wake_up_interruptible(&pipe->rd_wait); + wake_up_interruptible(&pipe->wr_wait); return pipe->max_usage * PAGE_SIZE; out_revert_acct: