summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/inode.c2
-rw-r--r--include/linux/xarray.h1
-rw-r--r--lib/xarray.c12
3 files changed, 12 insertions, 3 deletions
diff --git a/fs/inode.c b/fs/inode.c
index df6542ec3b88..2bf21e2c90fc 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -362,7 +362,7 @@ EXPORT_SYMBOL(inc_nlink);
362 362
363static void __address_space_init_once(struct address_space *mapping) 363static void __address_space_init_once(struct address_space *mapping)
364{ 364{
365 xa_init_flags(&mapping->i_pages, XA_FLAGS_LOCK_IRQ); 365 xa_init_flags(&mapping->i_pages, XA_FLAGS_LOCK_IRQ | XA_FLAGS_ACCOUNT);
366 init_rwsem(&mapping->i_mmap_rwsem); 366 init_rwsem(&mapping->i_mmap_rwsem);
367 INIT_LIST_HEAD(&mapping->private_list); 367 INIT_LIST_HEAD(&mapping->private_list);
368 spin_lock_init(&mapping->private_lock); 368 spin_lock_init(&mapping->private_lock);
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index 0e01e6129145..5921599b6dc4 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -265,6 +265,7 @@ enum xa_lock_type {
265#define XA_FLAGS_TRACK_FREE ((__force gfp_t)4U) 265#define XA_FLAGS_TRACK_FREE ((__force gfp_t)4U)
266#define XA_FLAGS_ZERO_BUSY ((__force gfp_t)8U) 266#define XA_FLAGS_ZERO_BUSY ((__force gfp_t)8U)
267#define XA_FLAGS_ALLOC_WRAPPED ((__force gfp_t)16U) 267#define XA_FLAGS_ALLOC_WRAPPED ((__force gfp_t)16U)
268#define XA_FLAGS_ACCOUNT ((__force gfp_t)32U)
268#define XA_FLAGS_MARK(mark) ((__force gfp_t)((1U << __GFP_BITS_SHIFT) << \ 269#define XA_FLAGS_MARK(mark) ((__force gfp_t)((1U << __GFP_BITS_SHIFT) << \
269 (__force unsigned)(mark))) 270 (__force unsigned)(mark)))
270 271
diff --git a/lib/xarray.c b/lib/xarray.c
index 6be3acbb861f..446b956c9188 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -298,6 +298,8 @@ bool xas_nomem(struct xa_state *xas, gfp_t gfp)
298 xas_destroy(xas); 298 xas_destroy(xas);
299 return false; 299 return false;
300 } 300 }
301 if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT)
302 gfp |= __GFP_ACCOUNT;
301 xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp); 303 xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp);
302 if (!xas->xa_alloc) 304 if (!xas->xa_alloc)
303 return false; 305 return false;
@@ -325,6 +327,8 @@ static bool __xas_nomem(struct xa_state *xas, gfp_t gfp)
325 xas_destroy(xas); 327 xas_destroy(xas);
326 return false; 328 return false;
327 } 329 }
330 if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT)
331 gfp |= __GFP_ACCOUNT;
328 if (gfpflags_allow_blocking(gfp)) { 332 if (gfpflags_allow_blocking(gfp)) {
329 xas_unlock_type(xas, lock_type); 333 xas_unlock_type(xas, lock_type);
330 xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp); 334 xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp);
@@ -358,8 +362,12 @@ static void *xas_alloc(struct xa_state *xas, unsigned int shift)
358 if (node) { 362 if (node) {
359 xas->xa_alloc = NULL; 363 xas->xa_alloc = NULL;
360 } else { 364 } else {
361 node = kmem_cache_alloc(radix_tree_node_cachep, 365 gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN;
362 GFP_NOWAIT | __GFP_NOWARN); 366
367 if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT)
368 gfp |= __GFP_ACCOUNT;
369
370 node = kmem_cache_alloc(radix_tree_node_cachep, gfp);
363 if (!node) { 371 if (!node) {
364 xas_set_err(xas, -ENOMEM); 372 xas_set_err(xas, -ENOMEM);
365 return NULL; 373 return NULL;