Message ID | 20240228144126.2864064-2-houtao@huaweicloud.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | virtiofs: fix the warning for ITER_KVEC dio | expand |
On Wed, 28 Feb 2024 at 15:40, Hou Tao <houtao@huaweicloud.com> wrote: > So instead of limiting both the values of max_read and max_write in > kernel, capping the maximal length of kvec iter IO by using max_pages in > fuse_direct_io() just like it does for ubuf/iovec iter IO. Now the max > value for max_pages is 256, so on host with 4KB page size, the maximal > size passed to kmalloc() in copy_args_to_argbuf() is about 1MB+40B. The > allocation of 2MB of physically contiguous memory will still incur > significant stress on the memory subsystem, but the warning is fixed. > Additionally, the requirement for huge physically contiguous memory will > be removed in the following patch. So the issue will be fixed properly by following patches? In that case this patch could be omitted, right? Thanks, Miklos
Hi, On 3/1/2024 9:42 PM, Miklos Szeredi wrote: > On Wed, 28 Feb 2024 at 15:40, Hou Tao <houtao@huaweicloud.com> wrote: > >> So instead of limiting both the values of max_read and max_write in >> kernel, capping the maximal length of kvec iter IO by using max_pages in >> fuse_direct_io() just like it does for ubuf/iovec iter IO. Now the max >> value for max_pages is 256, so on host with 4KB page size, the maximal >> size passed to kmalloc() in copy_args_to_argbuf() is about 1MB+40B. The >> allocation of 2MB of physically contiguous memory will still incur >> significant stress on the memory subsystem, but the warning is fixed. >> Additionally, the requirement for huge physically contiguous memory will >> be removed in the following patch. > So the issue will be fixed properly by following patches? > > In that case this patch could be omitted, right? Sorry for the late reply. Being busy with off-site workshop these days. No, this patch is still necessary and it is used to limit the number of scatterlist used for fuse request and reply in virtio-fs. If the length of out_args[0].size is not limited, the number of scatterlist used to map the fuse request may be greater than the queue size of virtio-queue and the fuse request may hang forever. > > Thanks, > Miklos
On 3/9/24 05:26, Hou Tao wrote: > Hi, > > On 3/1/2024 9:42 PM, Miklos Szeredi wrote: >> On Wed, 28 Feb 2024 at 15:40, Hou Tao <houtao@huaweicloud.com> wrote: >> >>> So instead of limiting both the values of max_read and max_write in >>> kernel, capping the maximal length of kvec iter IO by using max_pages in >>> fuse_direct_io() just like it does for ubuf/iovec iter IO. Now the max >>> value for max_pages is 256, so on host with 4KB page size, the maximal >>> size passed to kmalloc() in copy_args_to_argbuf() is about 1MB+40B. The >>> allocation of 2MB of physically contiguous memory will still incur >>> significant stress on the memory subsystem, but the warning is fixed. >>> Additionally, the requirement for huge physically contiguous memory will >>> be removed in the following patch. >> So the issue will be fixed properly by following patches? >> >> In that case this patch could be omitted, right? > > Sorry for the late reply. Being busy with off-site workshop these days. > > No, this patch is still necessary and it is used to limit the number of > scatterlist used for fuse request and reply in virtio-fs. If the length > of out_args[0].size is not limited, the number of scatterlist used to > map the fuse request may be greater than the queue size of virtio-queue > and the fuse request may hang forever. I'm currently also totally busy and didn't carefully check, but isn't there something missing that limits fc->max_write/fc->max_read? Thanks, Bernd
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 148a71b8b4d0e..f90ea25e366f0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1423,6 +1423,16 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii, return ret < 0 ? ret : 0; } +static size_t fuse_max_dio_rw_size(const struct fuse_conn *fc, + const struct iov_iter *iter, int write) +{ + unsigned int nmax = write ? fc->max_write : fc->max_read; + + if (iov_iter_is_kvec(iter)) + nmax = min(nmax, fc->max_pages << PAGE_SHIFT); + return nmax; +} + ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, loff_t *ppos, int flags) { @@ -1433,7 +1443,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, struct inode *inode = mapping->host; struct fuse_file *ff = file->private_data; struct fuse_conn *fc = ff->fm->fc; - size_t nmax = write ? fc->max_write : fc->max_read; + size_t nmax = fuse_max_dio_rw_size(fc, iter, write); loff_t pos = *ppos; size_t count = iov_iter_count(iter); pgoff_t idx_from = pos >> PAGE_SHIFT;