public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xfs: fall back to vmalloc when allocation log vector buffers
@ 2018-02-01  1:39 Dave Chinner
  2018-02-01  4:44 ` Darrick J. Wong
  0 siblings, 1 reply; 3+ messages in thread
From: Dave Chinner @ 2018-02-01  1:39 UTC (permalink / raw)
  To: linux-xfs

From: Dave Chinner <dchinner@redhat.com>

When using large directory blocks, we regularly see memory
allocations of >64k being made for the shadow log vector buffer.
When we are under memory pressure, kmalloc() may not be able to find
contiguous memory chunks large enough to satisfy these allocations
easily, and if memory is fragmented we can potentially stall here.

TO avoid this problem, switch the log vector buffer allocation to
use kmem_alloc_large(). This will allow failed allocations to fall
back to vmalloc and so remove the dependency on large contiguous
regions of memory being available. This should prevent slowdowns
and potential stalls when memory is low and/or fragmented.

Signed-Off-By: Dave Chinner <dchinner@redhat.com>
---
 fs/xfs/kmem.c        | 6 +++---
 fs/xfs/kmem.h        | 8 +++++++-
 fs/xfs/xfs_log_cil.c | 2 +-
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c
index 393b6849aeb3..7bace03dc9dc 100644
--- a/fs/xfs/kmem.c
+++ b/fs/xfs/kmem.c
@@ -46,13 +46,13 @@ kmem_alloc(size_t size, xfs_km_flags_t flags)
 }
 
 void *
-kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
+kmem_alloc_large(size_t size, xfs_km_flags_t flags)
 {
 	unsigned nofs_flag = 0;
 	void	*ptr;
 	gfp_t	lflags;
 
-	ptr = kmem_zalloc(size, flags | KM_MAYFAIL);
+	ptr = kmem_alloc(size, flags | KM_MAYFAIL);
 	if (ptr)
 		return ptr;
 
@@ -67,7 +67,7 @@ kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
 		nofs_flag = memalloc_nofs_save();
 
 	lflags = kmem_flags_convert(flags);
-	ptr = __vmalloc(size, lflags | __GFP_ZERO, PAGE_KERNEL);
+	ptr = __vmalloc(size, lflags, PAGE_KERNEL);
 
 	if (flags & KM_NOFS)
 		memalloc_nofs_restore(nofs_flag);
diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h
index 4b87472f35bc..6023b594ead7 100644
--- a/fs/xfs/kmem.h
+++ b/fs/xfs/kmem.h
@@ -71,7 +71,7 @@ kmem_flags_convert(xfs_km_flags_t flags)
 }
 
 extern void *kmem_alloc(size_t, xfs_km_flags_t);
-extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t);
+extern void *kmem_alloc_large(size_t size, xfs_km_flags_t);
 extern void *kmem_realloc(const void *, size_t, xfs_km_flags_t);
 static inline void  kmem_free(const void *ptr)
 {
@@ -85,6 +85,12 @@ kmem_zalloc(size_t size, xfs_km_flags_t flags)
 	return kmem_alloc(size, flags | KM_ZERO);
 }
 
+static inline void *
+kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
+{
+	return kmem_alloc_large(size, flags | KM_ZERO);
+}
+
 /*
  * Zone interfaces
  */
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 43aa42a3a5d3..61ab5c0a4c45 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -202,7 +202,7 @@ xlog_cil_alloc_shadow_bufs(
 			 */
 			kmem_free(lip->li_lv_shadow);
 
-			lv = kmem_alloc(buf_size, KM_SLEEP|KM_NOFS);
+			lv = kmem_alloc_large(buf_size, KM_SLEEP|KM_NOFS);
 			memset(lv, 0, xlog_cil_iovec_space(niovecs));
 
 			lv->lv_item = lip;
-- 
2.15.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] xfs: fall back to vmalloc when allocation log vector buffers
  2018-02-01  1:39 [PATCH] xfs: fall back to vmalloc when allocation log vector buffers Dave Chinner
@ 2018-02-01  4:44 ` Darrick J. Wong
  2018-02-05  0:40   ` Dave Chinner
  0 siblings, 1 reply; 3+ messages in thread
From: Darrick J. Wong @ 2018-02-01  4:44 UTC (permalink / raw)
  To: Dave Chinner; +Cc: linux-xfs

On Thu, Feb 01, 2018 at 12:39:59PM +1100, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> When using large directory blocks, we regularly see memory
> allocations of >64k being made for the shadow log vector buffer.
> When we are under memory pressure, kmalloc() may not be able to find
> contiguous memory chunks large enough to satisfy these allocations
> easily, and if memory is fragmented we can potentially stall here.
> 
> TO avoid this problem, switch the log vector buffer allocation to
> use kmem_alloc_large(). This will allow failed allocations to fall
> back to vmalloc and so remove the dependency on large contiguous
> regions of memory being available. This should prevent slowdowns
> and potential stalls when memory is low and/or fragmented.

> Signed-Off-By: Dave Chinner <dchinner@redhat.com>
> ---
>  fs/xfs/kmem.c        | 6 +++---
>  fs/xfs/kmem.h        | 8 +++++++-
>  fs/xfs/xfs_log_cil.c | 2 +-
>  3 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c
> index 393b6849aeb3..7bace03dc9dc 100644
> --- a/fs/xfs/kmem.c
> +++ b/fs/xfs/kmem.c
> @@ -46,13 +46,13 @@ kmem_alloc(size_t size, xfs_km_flags_t flags)
>  }
>  
>  void *
> -kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
> +kmem_alloc_large(size_t size, xfs_km_flags_t flags)
>  {
>  	unsigned nofs_flag = 0;
>  	void	*ptr;
>  	gfp_t	lflags;
>  
> -	ptr = kmem_zalloc(size, flags | KM_MAYFAIL);
> +	ptr = kmem_alloc(size, flags | KM_MAYFAIL);
>  	if (ptr)
>  		return ptr;
>  
> @@ -67,7 +67,7 @@ kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
>  		nofs_flag = memalloc_nofs_save();
>  
>  	lflags = kmem_flags_convert(flags);
> -	ptr = __vmalloc(size, lflags | __GFP_ZERO, PAGE_KERNEL);
> +	ptr = __vmalloc(size, lflags, PAGE_KERNEL);
>  
>  	if (flags & KM_NOFS)
>  		memalloc_nofs_restore(nofs_flag);
> diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h
> index 4b87472f35bc..6023b594ead7 100644
> --- a/fs/xfs/kmem.h
> +++ b/fs/xfs/kmem.h
> @@ -71,7 +71,7 @@ kmem_flags_convert(xfs_km_flags_t flags)
>  }
>  
>  extern void *kmem_alloc(size_t, xfs_km_flags_t);
> -extern void *kmem_zalloc_large(size_t size, xfs_km_flags_t);
> +extern void *kmem_alloc_large(size_t size, xfs_km_flags_t);
>  extern void *kmem_realloc(const void *, size_t, xfs_km_flags_t);
>  static inline void  kmem_free(const void *ptr)
>  {
> @@ -85,6 +85,12 @@ kmem_zalloc(size_t size, xfs_km_flags_t flags)
>  	return kmem_alloc(size, flags | KM_ZERO);
>  }
>  
> +static inline void *
> +kmem_zalloc_large(size_t size, xfs_km_flags_t flags)
> +{
> +	return kmem_alloc_large(size, flags | KM_ZERO);
> +}
> +
>  /*
>   * Zone interfaces
>   */
> diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
> index 43aa42a3a5d3..61ab5c0a4c45 100644
> --- a/fs/xfs/xfs_log_cil.c
> +++ b/fs/xfs/xfs_log_cil.c
> @@ -202,7 +202,7 @@ xlog_cil_alloc_shadow_bufs(
>  			 */
>  			kmem_free(lip->li_lv_shadow);
>  
> -			lv = kmem_alloc(buf_size, KM_SLEEP|KM_NOFS);
> +			lv = kmem_alloc_large(buf_size, KM_SLEEP|KM_NOFS);

"KM_SLEEP | KM_NOFS", will fix it on the way in.

I wonder about expanding the uses of vmalloc space, but otoh stalling
the log seems like a worse idea...

Looks ok enough to give it a spin,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

>  			memset(lv, 0, xlog_cil_iovec_space(niovecs));
>  
>  			lv->lv_item = lip;
> -- 
> 2.15.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] xfs: fall back to vmalloc when allocation log vector buffers
  2018-02-01  4:44 ` Darrick J. Wong
@ 2018-02-05  0:40   ` Dave Chinner
  0 siblings, 0 replies; 3+ messages in thread
From: Dave Chinner @ 2018-02-05  0:40 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On Wed, Jan 31, 2018 at 08:44:19PM -0800, Darrick J. Wong wrote:
> On Thu, Feb 01, 2018 at 12:39:59PM +1100, Dave Chinner wrote:
> > From: Dave Chinner <dchinner@redhat.com>
> > 
> > When using large directory blocks, we regularly see memory
> > allocations of >64k being made for the shadow log vector buffer.
> > When we are under memory pressure, kmalloc() may not be able to find
> > contiguous memory chunks large enough to satisfy these allocations
> > easily, and if memory is fragmented we can potentially stall here.
> > 
> > TO avoid this problem, switch the log vector buffer allocation to
> > use kmem_alloc_large(). This will allow failed allocations to fall
> > back to vmalloc and so remove the dependency on large contiguous
> > regions of memory being available. This should prevent slowdowns
> > and potential stalls when memory is low and/or fragmented.
> 
> > Signed-Off-By: Dave Chinner <dchinner@redhat.com>
.....
> > diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
> > index 43aa42a3a5d3..61ab5c0a4c45 100644
> > --- a/fs/xfs/xfs_log_cil.c
> > +++ b/fs/xfs/xfs_log_cil.c
> > @@ -202,7 +202,7 @@ xlog_cil_alloc_shadow_bufs(
> >  			 */
> >  			kmem_free(lip->li_lv_shadow);
> >  
> > -			lv = kmem_alloc(buf_size, KM_SLEEP|KM_NOFS);
> > +			lv = kmem_alloc_large(buf_size, KM_SLEEP|KM_NOFS);
> 
> "KM_SLEEP | KM_NOFS", will fix it on the way in.

*nod*

> I wonder about expanding the uses of vmalloc space, but otoh stalling
> the log seems like a worse idea...

We'll only see this happen when memory is really low and/or
fragmented, so i don't think it's a problem at all. I could trigger
warnings without this patch - they disappear with this patch and the
system seemed more responsive under equivalent loading. That's
entirely subjective, but it's so hard to consistently drive the
system into the severe memory shortages and reclaim failures that
trigger this problem that's the best I was able to do...

> Looks ok enough to give it a spin,
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

Thanks!

-Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-02-05  0:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-01  1:39 [PATCH] xfs: fall back to vmalloc when allocation log vector buffers Dave Chinner
2018-02-01  4:44 ` Darrick J. Wong
2018-02-05  0:40   ` Dave Chinner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox