[3/3] btrfs: switch to kvmalloc and GFP_KERNEL in lzo/zlib alloc_workspace
diff mbox

Message ID 5e5885e05f14e5449d48b9c512c934c241f6139f.1496245064.git.dsterba@suse.com
State New
Headers show

Commit Message

David Sterba May 31, 2017, 3:41 p.m. UTC
The compression workspace buffers are larger than a page so we use
vmalloc, unconditionally. This is not always necessary as there might be
contiguous memory available.

Let's use the kvmalloc helpers that will try kmalloc first and fallback
to vmalloc. For that they require GFP_KERNEL flags. As we now have the
alloc_workspace calls protected by memalloc_nofs in the critical
contexts, we can safely use GFP_KERNEL.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/lzo.c  | 14 +++++++-------
 fs/btrfs/zlib.c |  6 +++---
 2 files changed, 10 insertions(+), 10 deletions(-)

Comments

Anand Jain June 1, 2017, 3:58 a.m. UTC | #1
> @@ -59,7 +59,7 @@ static struct list_head *zlib_alloc_workspace(void)
>
>  	workspacesize = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
>  			zlib_inflate_workspacesize());
> -	workspace->strm.workspace = vmalloc(workspacesize);
> +	workspace->strm.workspace = kvmalloc(workspacesize, GFP_KERNEL);
>  	workspace->buf = kmalloc(PAGE_SIZE, GFP_KERNEL);

  Workspace->buf can be a kvmalloc as well as in lzo? or I don't know if
  there was any purpose for not doing it for zlib.

Thanks, Anand
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Sterba June 1, 2017, 2:24 p.m. UTC | #2
On Thu, Jun 01, 2017 at 11:58:31AM +0800, Anand Jain wrote:
> 
> 
> > @@ -59,7 +59,7 @@ static struct list_head *zlib_alloc_workspace(void)
> >
> >  	workspacesize = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
> >  			zlib_inflate_workspacesize());
> > -	workspace->strm.workspace = vmalloc(workspacesize);
> > +	workspace->strm.workspace = kvmalloc(workspacesize, GFP_KERNEL);
> >  	workspace->buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
> 
>   Workspace->buf can be a kvmalloc as well as in lzo? or I don't know if
>   there was any purpose for not doing it for zlib.

Zlib is fine with PAGE_SIZE. Lzo needs potentially more than a page, and
kvmalloc does not fallback to vmalloc in that case:

http://elixir.free-electrons.com/linux/v4.12-rc3/source/mm/util.c#L378
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c
index c556f3f3fbf0..cde13cce01a0 100644
--- a/fs/btrfs/lzo.c
+++ b/fs/btrfs/lzo.c
@@ -18,7 +18,7 @@ 
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/sched.h>
@@ -41,9 +41,9 @@  static void lzo_free_workspace(struct list_head *ws)
 {
 	struct workspace *workspace = list_entry(ws, struct workspace, list);
 
-	vfree(workspace->buf);
-	vfree(workspace->cbuf);
-	vfree(workspace->mem);
+	kvfree(workspace->buf);
+	kvfree(workspace->cbuf);
+	kvfree(workspace->mem);
 	kfree(workspace);
 }
 
@@ -55,9 +55,9 @@  static struct list_head *lzo_alloc_workspace(void)
 	if (!workspace)
 		return ERR_PTR(-ENOMEM);
 
-	workspace->mem = vmalloc(LZO1X_MEM_COMPRESS);
-	workspace->buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE));
-	workspace->cbuf = vmalloc(lzo1x_worst_compress(PAGE_SIZE));
+	workspace->mem = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
+	workspace->buf = kvmalloc(lzo1x_worst_compress(PAGE_SIZE), GFP_KERNEL);
+	workspace->cbuf = kvmalloc(lzo1x_worst_compress(PAGE_SIZE), GFP_KERNEL);
 	if (!workspace->mem || !workspace->buf || !workspace->cbuf)
 		goto fail;
 
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c
index c1db7572283b..c248f9286366 100644
--- a/fs/btrfs/zlib.c
+++ b/fs/btrfs/zlib.c
@@ -24,7 +24,7 @@ 
 #include <linux/slab.h>
 #include <linux/zlib.h>
 #include <linux/zutil.h>
-#include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/sched.h>
@@ -43,7 +43,7 @@  static void zlib_free_workspace(struct list_head *ws)
 {
 	struct workspace *workspace = list_entry(ws, struct workspace, list);
 
-	vfree(workspace->strm.workspace);
+	kvfree(workspace->strm.workspace);
 	kfree(workspace->buf);
 	kfree(workspace);
 }
@@ -59,7 +59,7 @@  static struct list_head *zlib_alloc_workspace(void)
 
 	workspacesize = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
 			zlib_inflate_workspacesize());
-	workspace->strm.workspace = vmalloc(workspacesize);
+	workspace->strm.workspace = kvmalloc(workspacesize, GFP_KERNEL);
 	workspace->buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!workspace->strm.workspace || !workspace->buf)
 		goto fail;