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 <aryabi...@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 3427eddcfb17..83c30e51dfca 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1353,7 +1353,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;
 
@@ -1410,7 +1410,7 @@ out:
        for (; page_nr < cs.nr_segs; page_nr++)
                page_cache_release(bufs[page_nr].page);
 
-       kfree(bufs);
+       kvfree(bufs);
        return ret;
 }
 
@@ -1991,7 +1991,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;
 
@@ -2049,7 +2049,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;
 }
 
-- 
2.13.6

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to