From: "Tobin C. Harding" <tobin@kernel.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: "Tobin C. Harding" <tobin@kernel.org>,
Roman Gushchin <guro@fb.com>,
Alexander Viro <viro@ftp.linux.org.uk>,
Christoph Hellwig <hch@infradead.org>,
Pekka Enberg <penberg@cs.helsinki.fi>,
David Rientjes <rientjes@google.com>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
Christopher Lameter <cl@linux.com>,
Miklos Szeredi <mszeredi@redhat.com>,
Andreas Dilger <adilger@dilger.ca>,
Waiman Long <longman@redhat.com>, Tycho Andersen <tycho@tycho.ws>,
Theodore Ts'o <tytso@mit.edu>, Andi Kleen <ak@linux.intel.com>,
David Chinner <david@fromorbit.com>,
Nick Piggin <npiggin@gmail.com>, Rik van Riel <riel@redhat.com>,
Hugh Dickins <hughd@google.com>, Jonathan Corbet <corbet@lwn.net>,
Matthew Wilcox <willy@infradead.org>,
linux-mm@kvack.org, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 09/15] lib: Separate radix_tree_node and xa_node slab cache
Date: Mon, 3 Jun 2019 14:26:31 +1000 [thread overview]
Message-ID: <20190603042637.2018-10-tobin@kernel.org> (raw)
In-Reply-To: <20190603042637.2018-1-tobin@kernel.org>
Earlier, Slab Movable Objects (SMO) was implemented. The XArray is now
able to take advantage of SMO in order to make xarray nodes
movable (when using the SLUB allocator).
Currently the radix tree uses the same slab cache as the XArray. Only
XArray nodes are movable _not_ radix tree nodes. We can give the radix
tree its own slab cache to overcome this.
In preparation for implementing XArray object migration (xa_node
objects) via Slab Movable Objects add a slab cache solely for XArray
nodes and make the XArray use this slab cache instead of the
radix_tree_node slab cache.
Cc: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Tobin C. Harding <tobin@kernel.org>
---
include/linux/xarray.h | 3 +++
init/main.c | 2 ++
lib/radix-tree.c | 2 +-
lib/xarray.c | 48 ++++++++++++++++++++++++++++++++++--------
4 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index 0e01e6129145..773f91f8e1db 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -42,6 +42,9 @@
#define BITS_PER_XA_VALUE (BITS_PER_LONG - 1)
+/* Called from init/main.c */
+void xarray_slabcache_init(void);
+
/**
* xa_mk_value() - Create an XArray entry from an integer.
* @v: Value to store in XArray.
diff --git a/init/main.c b/init/main.c
index 66a196c5e4c3..8c409a5dc937 100644
--- a/init/main.c
+++ b/init/main.c
@@ -107,6 +107,7 @@ static int kernel_init(void *);
extern void init_IRQ(void);
extern void radix_tree_init(void);
+extern void xarray_slabcache_init(void);
/*
* Debug helper: via this flag we know that we are in 'early bootup code'
@@ -622,6 +623,7 @@ asmlinkage __visible void __init start_kernel(void)
"Interrupts were enabled *very* early, fixing it\n"))
local_irq_disable();
radix_tree_init();
+ xarray_slabcache_init();
/*
* Set up housekeeping before setting up workqueues to allow the unbound
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 18c1dfbb1765..e6127c4c84b5 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -31,7 +31,7 @@
/*
* Radix tree node cache.
*/
-struct kmem_cache *radix_tree_node_cachep;
+static struct kmem_cache *radix_tree_node_cachep;
/*
* The radix tree is variable-height, so an insert operation not only has
diff --git a/lib/xarray.c b/lib/xarray.c
index 6be3acbb861f..861c042daa1d 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -27,6 +27,8 @@
* @entry refers to something stored in a slot in the xarray
*/
+static struct kmem_cache *xa_node_cachep;
+
static inline unsigned int xa_lock_type(const struct xarray *xa)
{
return (__force unsigned int)xa->xa_flags & 3;
@@ -244,9 +246,21 @@ void *xas_load(struct xa_state *xas)
}
EXPORT_SYMBOL_GPL(xas_load);
-/* Move the radix tree node cache here */
-extern struct kmem_cache *radix_tree_node_cachep;
-extern void radix_tree_node_rcu_free(struct rcu_head *head);
+static void xa_node_rcu_free(struct rcu_head *head)
+{
+ struct xa_node *node = container_of(head, struct xa_node, rcu_head);
+
+ /*
+ * Must only free zeroed nodes into the slab. We can be left with
+ * non-NULL entries by radix_tree_free_nodes, so clear the entries
+ * and tags here.
+ */
+ memset(node->slots, 0, sizeof(node->slots));
+ memset(node->tags, 0, sizeof(node->tags));
+ INIT_LIST_HEAD(&node->private_list);
+
+ kmem_cache_free(xa_node_cachep, node);
+}
#define XA_RCU_FREE ((struct xarray *)1)
@@ -254,7 +268,7 @@ static void xa_node_free(struct xa_node *node)
{
XA_NODE_BUG_ON(node, !list_empty(&node->private_list));
node->array = XA_RCU_FREE;
- call_rcu(&node->rcu_head, radix_tree_node_rcu_free);
+ call_rcu(&node->rcu_head, xa_node_rcu_free);
}
/*
@@ -270,7 +284,7 @@ static void xas_destroy(struct xa_state *xas)
if (!node)
return;
XA_NODE_BUG_ON(node, !list_empty(&node->private_list));
- kmem_cache_free(radix_tree_node_cachep, node);
+ kmem_cache_free(xa_node_cachep, node);
xas->xa_alloc = NULL;
}
@@ -298,7 +312,7 @@ bool xas_nomem(struct xa_state *xas, gfp_t gfp)
xas_destroy(xas);
return false;
}
- xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp);
+ xas->xa_alloc = kmem_cache_alloc(xa_node_cachep, gfp);
if (!xas->xa_alloc)
return false;
XA_NODE_BUG_ON(xas->xa_alloc, !list_empty(&xas->xa_alloc->private_list));
@@ -327,10 +341,10 @@ static bool __xas_nomem(struct xa_state *xas, gfp_t gfp)
}
if (gfpflags_allow_blocking(gfp)) {
xas_unlock_type(xas, lock_type);
- xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp);
+ xas->xa_alloc = kmem_cache_alloc(xa_node_cachep, gfp);
xas_lock_type(xas, lock_type);
} else {
- xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp);
+ xas->xa_alloc = kmem_cache_alloc(xa_node_cachep, gfp);
}
if (!xas->xa_alloc)
return false;
@@ -358,7 +372,7 @@ static void *xas_alloc(struct xa_state *xas, unsigned int shift)
if (node) {
xas->xa_alloc = NULL;
} else {
- node = kmem_cache_alloc(radix_tree_node_cachep,
+ node = kmem_cache_alloc(xa_node_cachep,
GFP_NOWAIT | __GFP_NOWARN);
if (!node) {
xas_set_err(xas, -ENOMEM);
@@ -1971,6 +1985,22 @@ void xa_destroy(struct xarray *xa)
}
EXPORT_SYMBOL(xa_destroy);
+static void xa_node_ctor(void *arg)
+{
+ struct xa_node *node = arg;
+
+ memset(node, 0, sizeof(*node));
+ INIT_LIST_HEAD(&node->private_list);
+}
+
+void __init xarray_slabcache_init(void)
+{
+ xa_node_cachep = kmem_cache_create("xarray_node",
+ sizeof(struct xa_node), 0,
+ SLAB_PANIC | SLAB_RECLAIM_ACCOUNT,
+ xa_node_ctor);
+}
+
#ifdef XA_DEBUG
void xa_dump_node(const struct xa_node *node)
{
--
2.21.0
next prev parent reply other threads:[~2019-06-03 4:28 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-03 4:26 [PATCH 00/15] Slab Movable Objects (SMO) Tobin C. Harding
2019-06-03 4:26 ` [PATCH 01/15] slub: Add isolate() and migrate() methods Tobin C. Harding
2019-06-03 4:26 ` [PATCH 02/15] tools/vm/slabinfo: Add support for -C and -M options Tobin C. Harding
2019-06-03 4:26 ` [PATCH 03/15] slub: Sort slab cache list Tobin C. Harding
2019-06-03 4:26 ` [PATCH 04/15] slub: Slab defrag core Tobin C. Harding
2019-06-03 4:26 ` [PATCH 05/15] tools/vm/slabinfo: Add remote node defrag ratio output Tobin C. Harding
2019-06-03 4:26 ` [PATCH 06/15] tools/vm/slabinfo: Add defrag_used_ratio output Tobin C. Harding
2019-06-03 4:26 ` [PATCH 07/15] tools/testing/slab: Add object migration test module Tobin C. Harding
2019-06-03 4:26 ` [PATCH 08/15] tools/testing/slab: Add object migration test suite Tobin C. Harding
2019-06-03 4:26 ` Tobin C. Harding [this message]
2019-06-03 4:26 ` [PATCH 10/15] xarray: Implement migration function for xa_node objects Tobin C. Harding
2019-06-03 4:26 ` [PATCH 11/15] tools/testing/slab: Add XArray movable objects tests Tobin C. Harding
2019-06-03 4:26 ` [PATCH 12/15] dcache: Provide a dentry constructor Tobin C. Harding
2019-06-03 4:26 ` [PATCH 13/15] dcache: Implement partial shrink via Slab Movable Objects Tobin C. Harding
2019-06-03 4:26 ` [PATCH 14/15] slub: Enable moving objects to/from specific nodes Tobin C. Harding
2019-06-03 4:26 ` [PATCH 15/15] slub: Enable balancing slabs across nodes Tobin C. Harding
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190603042637.2018-10-tobin@kernel.org \
--to=tobin@kernel.org \
--cc=adilger@dilger.ca \
--cc=ak@linux.intel.com \
--cc=akpm@linux-foundation.org \
--cc=cl@linux.com \
--cc=corbet@lwn.net \
--cc=david@fromorbit.com \
--cc=guro@fb.com \
--cc=hch@infradead.org \
--cc=hughd@google.com \
--cc=iamjoonsoo.kim@lge.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=longman@redhat.com \
--cc=mszeredi@redhat.com \
--cc=npiggin@gmail.com \
--cc=penberg@cs.helsinki.fi \
--cc=riel@redhat.com \
--cc=rientjes@google.com \
--cc=tycho@tycho.ws \
--cc=tytso@mit.edu \
--cc=viro@ftp.linux.org.uk \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).