Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753659AbXJAJgG (ORCPT ); Mon, 1 Oct 2007 05:36:06 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1750963AbXJAJfz (ORCPT ); Mon, 1 Oct 2007 05:35:55 -0400 Received: from fgwmail6.fujitsu.co.jp ([192.51.44.36]:60975 "EHLO fgwmail6.fujitsu.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750886AbXJAJfy (ORCPT ); Mon, 1 Oct 2007 05:35:54 -0400 Date: Mon, 01 Oct 2007 18:34:39 +0900 From: Yasunori Goto To: Andrew Morton Subject: [Patch / 002](memory hotplug) Callback function to create kmem_cache_node. Cc: Christoph Lameter , Linux Kernel ML , linux-mm In-Reply-To: <20071001182329.7A97.Y-GOTO@jp.fujitsu.com> References: <20071001182329.7A97.Y-GOTO@jp.fujitsu.com> X-Mailer-Plugin: BkASPil for Becky!2 Ver.2.068 Message-Id: <20071001183316.7A9B.Y-GOTO@jp.fujitsu.com> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Mailer: Becky! ver. 2.27 [ja] Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3168 Lines: 130 This is to make kmem_cache_nodes of all SLUBs for new node when memory-hotadd is called. This fixes panic due to access NULL pointer at discard_slab() after memory hot-add. If pages on the new node available, slub can use it before making new kmem_cache_nodes. So, this callback should be called BEFORE pages on the node are available. Signed-off-by: Yasunori Goto --- mm/slub.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) Index: current/mm/slub.c =================================================================== --- current.orig/mm/slub.c 2007-09-28 11:23:50.000000000 +0900 +++ current/mm/slub.c 2007-09-28 11:23:59.000000000 +0900 @@ -20,6 +20,7 @@ #include #include #include +#include /* * Lock order: @@ -2097,6 +2098,82 @@ static int init_kmem_cache_nodes(struct } return 1; } + +#ifdef CONFIG_MEMORY_HOTPLUG +static void __slab_callback_offline(int nid) +{ + struct kmem_cache_node *n; + struct kmem_cache *s; + + list_for_each_entry(s, &slab_caches, list) { + if (s->node[nid]) { + n = get_node(s, nid); + s->node[nid] = NULL; + kmem_cache_free(kmalloc_caches, n); + } + } +} + +static int slab_callback_going_online(void *arg) +{ + struct kmem_cache_node *n; + struct kmem_cache *s; + struct memory_notify *marg = arg; + int nid; + + nid = page_to_nid(pfn_to_page(marg->start_pfn)); + + /* If the node already has memory, then nothing is necessary. */ + if (node_state(nid, N_HIGH_MEMORY)) + return 0; + + /* + * New memory will be onlined on the node which has no memory so far. + * New kmem_cache_node is necssary for it. + */ + down_read(&slub_lock); + list_for_each_entry(s, &slab_caches, list) { + /* + * XXX: The new node's memory can't be allocated yet, + * kmem_cache_node will be allocated other node. + */ + n = kmem_cache_alloc(kmalloc_caches, GFP_KERNEL); + if (!n) + goto error; + init_kmem_cache_node(n); + s->node[nid] = n; + } + up_read(&slub_lock); + + return 0; + +error: + __slab_callback_offline(nid); + up_read(&slub_lock); + + return -ENOMEM; +} + +static int slab_callback(struct notifier_block *self, unsigned long action, + void *arg) +{ + int ret = 0; + + switch (action) { + case MEM_GOING_ONLINE: + ret = slab_callback_going_online(arg); + break; + case MEM_ONLINE: + case MEM_GOING_OFFLINE: + case MEM_MAPPING_INVALID: + break; + } + + ret = notifier_from_errno(ret); + return ret; +} + +#endif /* CONFIG_MEMORY_HOTPLUG */ #else static void free_kmem_cache_nodes(struct kmem_cache *s) { @@ -2730,6 +2807,8 @@ void __init kmem_cache_init(void) sizeof(struct kmem_cache_node), GFP_KERNEL); kmalloc_caches[0].refcount = -1; caches++; + + hotplug_memory_notifier(slab_callback, 1); #endif /* Able to allocate the per node structures */ -- Yasunori Goto - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/