Could you test this patch and see if it does the correct thing on a memory
hotplug system?
Fix the bringup of a new memory node that used to simply alloate a management
structure from a foreign node to use the bootstrap functions to allocate
the kmem_cache_node structure from the correct node.
Signed-off-by: Christoph Lameter <cl@xxxxxxxxx>
---
mm/slub.c | 40 +++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
Index: linux-2.6/mm/slub.c
===================================================================
--- linux-2.6.orig/mm/slub.c 2012-04-27 02:40:50.000000000 -0500
+++ linux-2.6/mm/slub.c 2012-04-27 04:19:02.183694195 -0500
@@ -1021,7 +1021,7 @@ static inline void inc_slabs_node(struct
* May be called early in order to allocate a slab for the
* kmem_cache_node structure. Solve the chicken-egg
* dilemma by deferring the increment of the count during
- * bootstrap (see early_kmem_cache_node_alloc).
+ * bootstrap (see kmem_cache_node_first_alloc).
*/
if (n) {
atomic_long_inc(&n->nr_slabs);
@@ -2801,15 +2801,23 @@ static inline int alloc_kmem_cache_cpus(
static struct kmem_cache *kmem_cache_node;
/*
- * No kmalloc_node yet so do it by hand. We know that this is the first
- * slab on the node for this slabcache. There are no concurrent accesses
- * possible.
+ * Solve the chicken egg dilemma of needing a per node structure from
+ * the kmem_cache_node slab cache from the node that we want the structure for.
+ *
+ * We cannot allocate from the slab since the kmem_cache_node structure is
+ * missing. So allocate a slab page and manually configure it so that the first
+ * object can be used for the kmem_cache_node structure of the kmem_cache_node
+ * slabcache. Then initialize the kmem_cache_node structure to have the correct
+ * values and make it usable. After that additional kmem_cache_node structures
+ * can be allocated via the regular allocator functions.
*
* Note that this function only works on the kmalloc_node_cache
- * when allocating for the kmalloc_node_cache. This is used for bootstrapping
- * memory on a fresh node that has no slab structures yet.
+ * when performing an initial allocation for kmalloc_node_cache.
+ *
+ * This function is required for bootstrapping
+ * slab caches on a fresh node that has no slab structures yet.
*/
-static void early_kmem_cache_node_alloc(int node)
+static void kmem_cache_node_first_alloc(int node)
{
struct page *page;
struct kmem_cache_node *n;
@@ -2864,7 +2872,7 @@ static int init_kmem_cache_nodes(struct
struct kmem_cache_node *n;
if (slab_state == DOWN) {
- early_kmem_cache_node_alloc(node);
+ kmem_cache_node_first_alloc(node);
continue;
}
n = kmem_cache_alloc_node(kmem_cache_node,
@@ -3614,12 +3622,18 @@ static int slab_mem_going_online_callbac
* online.
*/
down_read(&slub_lock);
+
+ /*
+ * Must have a kmem_cache_node structure for the kmem_cache_node
+ * structure first on the target node otherwise we cannot allocate
+ * kmem_cache_node structures for other slab caches on the new node.
+ */
+ kmem_cache_node_first_alloc(nid);
+
list_for_each_entry(s, &slab_caches, list) {
- /*
- * XXX: kmem_cache_alloc_node will fallback to other nodes
- * since memory is not yet available from the node that
- * is brought up.
- */
+ if (s == kmem_cache_node)
+ continue;
+
n = kmem_cache_alloc(kmem_cache_node, GFP_KERNEL);
if (!n) {
ret = -ENOMEM;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxx. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>
[Site Home]
[Linux ARM Kernel]
[Linux ARM]
[Linux Omap]
[Fedora ARM]
[IETF Annouce]
[Security]
[Bugtraq]
[Linux]
[Linux OMAP]
[Linux MIPS]
[ECOS]
[Tools]
[DDR & Rambus]
[Asterisk Internet PBX]
[Linux API]
[Monitors]