Message ID | 20230314154203.181070-3-axboe@kernel.dk (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Add FMODE_NOWAIT support to pipes | expand |
On Tue, Mar 14, 2023 at 09:42:02AM -0600, Jens Axboe wrote: > In preparation for enabling FMODE_NOWAIT for pipes, ensure that the read > and write path handle it correctly. This includes the pipe locking, > page allocation for writes, and confirming pipe buffers. > > Acked-by: Dave Chinner <dchinner@redhat.com> > Signed-off-by: Jens Axboe <axboe@kernel.dk> > --- Looks good, Reviewed-by: Christian Brauner <brauner@kernel.org>
On 3/15/23 2:23 AM, Christian Brauner wrote: > On Tue, Mar 14, 2023 at 09:42:02AM -0600, Jens Axboe wrote: >> In preparation for enabling FMODE_NOWAIT for pipes, ensure that the read >> and write path handle it correctly. This includes the pipe locking, >> page allocation for writes, and confirming pipe buffers. >> >> Acked-by: Dave Chinner <dchinner@redhat.com> >> Signed-off-by: Jens Axboe <axboe@kernel.dk> >> --- > > Looks good, > Reviewed-by: Christian Brauner <brauner@kernel.org> Thanks for the review, I'll add that. Are you OK with me carrying these patches, or do you want to stage them for 6.4?
On Wed, Mar 15, 2023 at 08:16:19AM -0600, Jens Axboe wrote: > On 3/15/23 2:23 AM, Christian Brauner wrote: > > On Tue, Mar 14, 2023 at 09:42:02AM -0600, Jens Axboe wrote: > >> In preparation for enabling FMODE_NOWAIT for pipes, ensure that the read > >> and write path handle it correctly. This includes the pipe locking, > >> page allocation for writes, and confirming pipe buffers. > >> > >> Acked-by: Dave Chinner <dchinner@redhat.com> > >> Signed-off-by: Jens Axboe <axboe@kernel.dk> > >> --- > > > > Looks good, > > Reviewed-by: Christian Brauner <brauner@kernel.org> > > Thanks for the review, I'll add that. Are you OK with me carrying > these patches, or do you want to stage them for 6.4? I'n not fuzzed. Since it's fs only I would lean towards carrying it. I can pick it up now and see if Al has any strong opinions on this one.
On 3/15/23 9:02 AM, Christian Brauner wrote: > On Wed, Mar 15, 2023 at 08:16:19AM -0600, Jens Axboe wrote: >> On 3/15/23 2:23 AM, Christian Brauner wrote: >>> On Tue, Mar 14, 2023 at 09:42:02AM -0600, Jens Axboe wrote: >>>> In preparation for enabling FMODE_NOWAIT for pipes, ensure that the read >>>> and write path handle it correctly. This includes the pipe locking, >>>> page allocation for writes, and confirming pipe buffers. >>>> >>>> Acked-by: Dave Chinner <dchinner@redhat.com> >>>> Signed-off-by: Jens Axboe <axboe@kernel.dk> >>>> --- >>> >>> Looks good, >>> Reviewed-by: Christian Brauner <brauner@kernel.org> >> >> Thanks for the review, I'll add that. Are you OK with me carrying >> these patches, or do you want to stage them for 6.4? > > I'n not fuzzed. Since it's fs only I would lean towards carrying it. I > can pick it up now and see if Al has any strong opinions on this one. Either way is fine with me - let me know if you pick it up, and I can drop it from my tree.
On 3/15/23 9:12 AM, Jens Axboe wrote: > On 3/15/23 9:02 AM, Christian Brauner wrote: >> On Wed, Mar 15, 2023 at 08:16:19AM -0600, Jens Axboe wrote: >>> On 3/15/23 2:23 AM, Christian Brauner wrote: >>>> On Tue, Mar 14, 2023 at 09:42:02AM -0600, Jens Axboe wrote: >>>>> In preparation for enabling FMODE_NOWAIT for pipes, ensure that the read >>>>> and write path handle it correctly. This includes the pipe locking, >>>>> page allocation for writes, and confirming pipe buffers. >>>>> >>>>> Acked-by: Dave Chinner <dchinner@redhat.com> >>>>> Signed-off-by: Jens Axboe <axboe@kernel.dk> >>>>> --- >>>> >>>> Looks good, >>>> Reviewed-by: Christian Brauner <brauner@kernel.org> >>> >>> Thanks for the review, I'll add that. Are you OK with me carrying >>> these patches, or do you want to stage them for 6.4? >> >> I'n not fuzzed. Since it's fs only I would lean towards carrying it. I >> can pick it up now and see if Al has any strong opinions on this one. > > Either way is fine with me - let me know if you pick it up, and > I can drop it from my tree. Oh and if you do, I should probably send out a v3. Was missing a kerneldoc in patch 1, corrected that in my tree but it's not in v2. Outside of that one-liner doc change, same patches in my tree.
diff --git a/fs/pipe.c b/fs/pipe.c index 340f253913a2..dc00b20e56c8 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -108,6 +108,16 @@ static inline void __pipe_unlock(struct pipe_inode_info *pipe) mutex_unlock(&pipe->mutex); } +static inline bool __pipe_trylock(struct pipe_inode_info *pipe, bool nonblock) +{ + if (!nonblock) { + __pipe_lock(pipe); + return true; + } + + return mutex_trylock(&pipe->mutex); +} + void pipe_double_lock(struct pipe_inode_info *pipe1, struct pipe_inode_info *pipe2) { @@ -234,6 +244,7 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) struct file *filp = iocb->ki_filp; struct pipe_inode_info *pipe = filp->private_data; bool was_full, wake_next_reader = false; + const bool nonblock = iocb->ki_flags & IOCB_NOWAIT; ssize_t ret; /* Null read succeeds. */ @@ -241,7 +252,8 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) return 0; ret = 0; - __pipe_lock(pipe); + if (!__pipe_trylock(pipe, nonblock)) + return -EAGAIN; /* * We only wake up writers if the pipe was full when we started @@ -297,7 +309,7 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) chars = total_len; } - error = pipe_buf_confirm(pipe, buf, false); + error = pipe_buf_confirm(pipe, buf, nonblock); if (error) { if (!ret) ret = error; @@ -342,7 +354,7 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to) break; if (ret) break; - if (filp->f_flags & O_NONBLOCK) { + if (filp->f_flags & O_NONBLOCK || nonblock) { ret = -EAGAIN; break; } @@ -423,12 +435,14 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) ssize_t chars; bool was_empty = false; bool wake_next_writer = false; + const bool nonblock = iocb->ki_flags & IOCB_NOWAIT; /* Null write succeeds. */ if (unlikely(total_len == 0)) return 0; - __pipe_lock(pipe); + if (!__pipe_trylock(pipe, nonblock)) + return -EAGAIN; if (!pipe->readers) { send_sig(SIGPIPE, current, 0); @@ -461,7 +475,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) if ((buf->flags & PIPE_BUF_FLAG_CAN_MERGE) && offset + chars <= PAGE_SIZE) { - ret = pipe_buf_confirm(pipe, buf, false); + ret = pipe_buf_confirm(pipe, buf, nonblock); if (ret) goto out; @@ -493,9 +507,18 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) int copied; if (!page) { - page = alloc_page(GFP_HIGHUSER | __GFP_ACCOUNT); + gfp_t gfp = __GFP_HIGHMEM | __GFP_ACCOUNT | + __GFP_HARDWALL; + int this_ret = -EAGAIN; + + if (!nonblock) { + this_ret = -ENOMEM; + gfp |= GFP_USER; + } + page = alloc_page(gfp); if (unlikely(!page)) { - ret = ret ? : -ENOMEM; + if (!ret) + ret = this_ret; break; } pipe->tmp_page = page; @@ -547,7 +570,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) continue; /* Wait for buffer space to become available. */ - if (filp->f_flags & O_NONBLOCK) { + if (filp->f_flags & O_NONBLOCK || nonblock) { if (!ret) ret = -EAGAIN; break;