[Devel] [PATCH RHEL7 COMMIT] fs/fuse/dev: improve ->splice() with fragmented memory

Konstantin Khorenko khorenko at virtuozzo.com
Thu Dec 7 13:57:50 MSK 2017


The commit is pushed to "branch-rh7-3.10.0-693.11.1.vz7.39.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-693.11.1.vz7.39.1
------>
commit fe4b25ff272f8e5143d8f8223dac2a8577ceb937
Author: Andrey Ryabinin <aryabinin at virtuozzo.com>
Date:   Thu Dec 7 13:57:49 2017 +0300

    fs/fuse/dev: improve ->splice() with fragmented memory
    
    fuse_dev_splice_[read,write]() temporary allocates array of pipe_buffer
    structs. Depending on pipe size it could be quite large, thus we stall
    in high order allocation request. Use kvmalloc() instead of kmalloc()
    to fallback in vmalloc() if high order page is not available at the moment.
    
    https://jira.sw.ru/browse/PSBM-77949
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 fs/fuse/dev.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 7d74782c6f43..9e77e198de60 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1354,7 +1354,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
 	if (!fud)
 		return -EPERM;
 
-	bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL);
+	bufs = kvmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL);
 	if (!bufs)
 		return -ENOMEM;
 
@@ -1411,7 +1411,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
 	for (; page_nr < cs.nr_segs; page_nr++)
 		page_cache_release(bufs[page_nr].page);
 
-	kfree(bufs);
+	kvfree(bufs);
 	return ret;
 }
 
@@ -1992,7 +1992,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
 	if (!fud)
 		return -EPERM;
 
-	bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL);
+	bufs = kvmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL);
 	if (!bufs)
 		return -ENOMEM;
 
@@ -2050,7 +2050,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
 		buf->ops->release(pipe, buf);
 	}
 out:
-	kfree(bufs);
+	kvfree(bufs);
 	return ret;
 }
 


More information about the Devel mailing list