Message ID | 20230328173613.555192-3-axboe@kernel.dk (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
Series | Turn single segment imports into ITER_UBUF | expand |
On Tue, Mar 28, 2023 at 11:36:07AM -0600, Jens Axboe wrote: > This returns the number of user segments in an iov_iter. The input can > either be an ITER_IOVEC, where it'll return the number of iovecs. Or it > can be an ITER_UBUF, in which case the number of segments is always 1. > > Outside of those two, no user backed iterators exist. Just return 0 for > those. Umm... Why not set ->nr_segs to 1 in iov_iter_ubuf() instead? Note that it won't be more costly; that part of struct iov_iter (8 bytes at offset 40 on amd64) is *not* left uninitialized - zero gets stored there. That way you'll get constant 1 stored there, which is just as cheap...
On Tue, Mar 28, 2023 at 11:42 AM Al Viro <viro@zeniv.linux.org.uk> wrote: > > Umm... Why not set ->nr_segs to 1 in iov_iter_ubuf() instead? Note that > it won't be more costly; that part of struct iov_iter (8 bytes at offset 40 > on amd64) is *not* left uninitialized - zero gets stored there. That way > you'll get constant 1 stored there, which is just as cheap... Ack. And with my suggestion to embed a 'struct iov' in the 'struct iov_iter' for the ITER_UBUF case (see previous email, try not to barf), we really end up with a pretty cheap "ITER_UBUF can be used almost as-is for any ITER_IOV case". Linus
On 3/28/23 12:42 PM, Al Viro wrote: > On Tue, Mar 28, 2023 at 11:36:07AM -0600, Jens Axboe wrote: >> This returns the number of user segments in an iov_iter. The input can >> either be an ITER_IOVEC, where it'll return the number of iovecs. Or it >> can be an ITER_UBUF, in which case the number of segments is always 1. >> >> Outside of those two, no user backed iterators exist. Just return 0 for >> those. > > Umm... Why not set ->nr_segs to 1 in iov_iter_ubuf() instead? Note that > it won't be more costly; that part of struct iov_iter (8 bytes at offset 40 > on amd64) is *not* left uninitialized - zero gets stored there. That way > you'll get constant 1 stored there, which is just as cheap... Good point, let's have a prep patch that does that too.
diff --git a/include/linux/uio.h b/include/linux/uio.h index 3b4403efcce1..8ba4d61e9e9b 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -168,6 +168,15 @@ static inline struct iovec iov_iter_iovec(const struct iov_iter *iter) } } +static inline int iovec_nr_user_vecs(const struct iov_iter *iter) +{ + if (iter_is_ubuf(iter)) + return 1; + else if (iter->iter_type == ITER_IOVEC) + return iter->nr_segs; + return 0; +} + size_t copy_page_from_iter_atomic(struct page *page, unsigned offset, size_t bytes, struct iov_iter *i); void iov_iter_advance(struct iov_iter *i, size_t bytes);
This returns the number of user segments in an iov_iter. The input can either be an ITER_IOVEC, where it'll return the number of iovecs. Or it can be an ITER_UBUF, in which case the number of segments is always 1. Outside of those two, no user backed iterators exist. Just return 0 for those. Signed-off-by: Jens Axboe <axboe@kernel.dk> --- include/linux/uio.h | 9 +++++++++ 1 file changed, 9 insertions(+)