summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorPekka Enberg <penberg@cs.helsinki.fi>2009-10-04 15:07:12 +0300
committerPekka Enberg <penberg@cs.helsinki.fi>2009-10-04 15:07:12 +0300
commitabeafb875f1d79482cf35cdcbd80b0fa7fcb3ef3 (patch)
tree4b2611d177d7ae6b86c9470f45074f38dbc50b9c /mm
parent11b7576bc42afa6096d966c3bc8737a5fe3c848a (diff)
parentd4d16d927262619c419006ecff6536834e8cd56c (diff)
Merge branch 'slqb/core' into for-next
Diffstat (limited to 'mm')
-rw-r--r--mm/slqb.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/mm/slqb.c b/mm/slqb.c
index 4d72be2391d0..e745d9ac0956 100644
--- a/mm/slqb.c
+++ b/mm/slqb.c
@@ -1513,16 +1513,32 @@ try_remote:
l = &c->list;
object = __cache_list_get_object(s, l);
if (unlikely(!object)) {
- object = cache_list_get_page(s, l);
- if (unlikely(!object)) {
- object = __slab_alloc_page(s, gfpflags, node);
#ifdef CONFIG_NUMA
+ int thisnode = numa_node_id();
+
+ /*
+ * If the local node is memoryless, try remote alloc before
+ * trying the page allocator. Otherwise, what happens is
+ * objects are always freed to remote lists but the allocation
+ * side always allocates a new page with only one object
+ * used in each page
+ */
+ if (unlikely(!node_state(thisnode, N_HIGH_MEMORY)))
+ object = __remote_slab_alloc(s, gfpflags, thisnode);
+#endif
+
+ if (!object) {
+ object = cache_list_get_page(s, l);
if (unlikely(!object)) {
- node = numa_node_id();
- goto try_remote;
- }
+ object = __slab_alloc_page(s, gfpflags, node);
+#ifdef CONFIG_NUMA
+ if (unlikely(!object)) {
+ node = numa_node_id();
+ goto try_remote;
+ }
#endif
- return object;
+ return object;
+ }
}
}
if (likely(object))