linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Mel Gorman <mel@csn.ul.ie>
To: Nick Piggin <npiggin@suse.de>,
	Pekka Enberg <penberg@cs.helsinki.fi>,
	Christoph Lameter <cl@linux-foundation.org>
Cc: heiko.carstens@de.ibm.com, sachinp@in.ibm.com,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	Mel Gorman <mel@csn.ul.ie>, Tejun Heo <tj@kernel.org>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: [PATCH 2/3] slqb: Record what node is local to a kmem_cache_cpu
Date: Mon, 21 Sep 2009 17:10:25 +0100	[thread overview]
Message-ID: <1253549426-917-3-git-send-email-mel@csn.ul.ie> (raw)
In-Reply-To: <1253549426-917-1-git-send-email-mel@csn.ul.ie>

When freeing a page, SLQB checks if the page belongs to the local node.
If it is not, it is considered a remote free. On the allocation side, it
always checks the local lists and if they are empty, the page allocator
is called. On memoryless configurations, this is effectively a memory
leak and the machine quickly kills itself in an OOM storm.

This patch records what node ID is closest to a CPU and considers that to be
the local node. As the management structure for the CPU is always allocated
from the closest node, the node the CPU structure resides on is considered
"local".

Signed-off-by: Mel Gorman <mel@csn.ul.ie>
---
 include/linux/slqb_def.h |    3 +++
 mm/slqb.c                |   23 +++++++++++++++++------
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/include/linux/slqb_def.h b/include/linux/slqb_def.h
index 1243dda..2ccbe7e 100644
--- a/include/linux/slqb_def.h
+++ b/include/linux/slqb_def.h
@@ -101,6 +101,9 @@ struct kmem_cache_cpu {
 	struct kmem_cache_list	list;		/* List for node-local slabs */
 	unsigned int		colour_next;	/* Next colour offset to use */
 
+	/* local_nid will be numa_node_id() except when memoryless */
+	unsigned int		local_nid;
+
 #ifdef CONFIG_SMP
 	/*
 	 * rlist is a list of objects that don't fit on list.freelist (ie.
diff --git a/mm/slqb.c b/mm/slqb.c
index 4ca85e2..1846480 100644
--- a/mm/slqb.c
+++ b/mm/slqb.c
@@ -1375,7 +1375,7 @@ static noinline void *__slab_alloc_page(struct kmem_cache *s,
 	if (unlikely(!page))
 		return page;
 
-	if (!NUMA_BUILD || likely(slqb_page_to_nid(page) == numa_node_id())) {
+	if (!NUMA_BUILD || likely(slqb_page_to_nid(page) == c->local_nid)) {
 		struct kmem_cache_cpu *c;
 		int cpu = smp_processor_id();
 
@@ -1501,15 +1501,16 @@ static __always_inline void *__slab_alloc(struct kmem_cache *s,
 	struct kmem_cache_cpu *c;
 	struct kmem_cache_list *l;
 
+	c = get_cpu_slab(s, smp_processor_id());
+	VM_BUG_ON(!c);
+
 #ifdef CONFIG_NUMA
-	if (unlikely(node != -1) && unlikely(node != numa_node_id())) {
+	if (unlikely(node != -1) && unlikely(node != c->local_nid)) {
 try_remote:
 		return __remote_slab_alloc(s, gfpflags, node);
 	}
 #endif
 
-	c = get_cpu_slab(s, smp_processor_id());
-	VM_BUG_ON(!c);
 	l = &c->list;
 	object = __cache_list_get_object(s, l);
 	if (unlikely(!object)) {
@@ -1518,7 +1519,7 @@ try_remote:
 			object = __slab_alloc_page(s, gfpflags, node);
 #ifdef CONFIG_NUMA
 			if (unlikely(!object)) {
-				node = numa_node_id();
+				node = c->local_nid;
 				goto try_remote;
 			}
 #endif
@@ -1733,7 +1734,7 @@ static __always_inline void __slab_free(struct kmem_cache *s,
 	slqb_stat_inc(l, FREE);
 
 	if (!NUMA_BUILD || !slab_numa(s) ||
-			likely(slqb_page_to_nid(page) == numa_node_id())) {
+			likely(slqb_page_to_nid(page) == c->local_nid)) {
 		/*
 		 * Freeing fastpath. Collects all local-node objects, not
 		 * just those allocated from our per-CPU list. This allows
@@ -1928,6 +1929,16 @@ static void init_kmem_cache_cpu(struct kmem_cache *s,
 	c->rlist.tail		= NULL;
 	c->remote_cache_list	= NULL;
 #endif
+
+	/*
+	 * Determine what the local node to this CPU is. Ordinarily
+	 * this would be cpu_to_node() but for memoryless nodes, that
+	 * is not the best value. Instead, we take the numa node that
+	 * kmem_cache_cpu is allocated from as being the best guess
+	 * as being local because it'll match what the page allocator
+	 * thinks is the most local
+	 */
+	c->local_nid = page_to_nid(virt_to_page((unsigned long)c & PAGE_MASK));
 }
 
 #ifdef CONFIG_NUMA
-- 
1.6.3.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  parent reply	other threads:[~2009-09-21 16:10 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-21 16:10 [RFC PATCH 0/3] Fix SLQB on memoryless configurations V2 Mel Gorman
2009-09-21 16:10 ` [PATCH 1/3] powerpc: Allocate per-cpu areas for node IDs for SLQB to use as per-node areas Mel Gorman
2009-09-21 17:17   ` Daniel Walker
2009-09-21 17:24     ` Randy Dunlap
2009-09-21 17:29       ` Daniel Walker
2009-09-21 17:42     ` Mel Gorman
2009-09-22  0:01   ` Tejun Heo
2009-09-22  9:32     ` Mel Gorman
2009-09-21 16:10 ` Mel Gorman [this message]
2009-09-21 16:10 ` [PATCH 3/3] slqb: Allow SLQB to be used on PPC Mel Gorman
2009-09-22  9:30   ` Heiko Carstens
2009-09-22  9:32     ` Mel Gorman
2009-09-21 17:46 ` [RFC PATCH 0/3] Fix SLQB on memoryless configurations V2 Mel Gorman
2009-09-21 17:54   ` Christoph Lameter
2009-09-21 18:05     ` Pekka Enberg
2009-09-21 18:07     ` Mel Gorman
2009-09-21 18:17       ` Christoph Lameter
2009-09-22 10:05         ` Mel Gorman
2009-09-22 10:21           ` Pekka Enberg
2009-09-22 10:24             ` Mel Gorman
2009-09-22  5:03       ` Sachin Sant
2009-09-22 10:07         ` Mel Gorman
2009-09-22 12:55         ` Mel Gorman
2009-09-22 13:05           ` Sachin Sant
2009-09-22 13:20             ` Mel Gorman
     [not found]               ` <363172900909220629j2f5174cbo9fe027354948d37@mail.gmail.com>
2009-09-22 13:38                 ` Mel Gorman
2009-09-22 23:07                 ` Christoph Lameter
2009-09-22  0:00 ` Benjamin Herrenschmidt
2009-09-22  0:19   ` David Rientjes
2009-09-22  6:30     ` Christoph Lameter
2009-09-22  7:59       ` David Rientjes
2009-09-22  8:11         ` Benjamin Herrenschmidt
2009-09-22  8:44           ` David Rientjes
2009-09-22 15:26   ` Mel Gorman
2009-09-22 17:31     ` David Rientjes

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=1253549426-917-3-git-send-email-mel@csn.ul.ie \
    --to=mel@csn.ul.ie \
    --cc=benh@kernel.crashing.org \
    --cc=cl@linux-foundation.org \
    --cc=heiko.carstens@de.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=npiggin@suse.de \
    --cc=penberg@cs.helsinki.fi \
    --cc=sachinp@in.ibm.com \
    --cc=tj@kernel.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).