Slub: UP bandaid
authorChristoph Lameter <cl@linux.com>
Thu, 26 Aug 2010 14:41:19 +0000 (09:41 -0500)
committerPekka Enberg <penberg@kernel.org>
Sat, 2 Oct 2010 07:24:29 +0000 (10:24 +0300)
Since the percpu allocator does not provide early allocation in UP mode (only
in SMP configurations) use __get_free_page() to improvise a compound page
allocation that can be later freed via kfree().

Compound pages will be released when the cpu caches are resized.

Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
mm/slub.c

index 4c5a76f505ea2f217b449379842caadc8b1790db..05674aac929498e1ffba2c40a8c5b5fa7b41bb06 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2103,8 +2103,24 @@ init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s)
 
 static inline int alloc_kmem_cache_cpus(struct kmem_cache *s)
 {
+#ifdef CONFIG_SMP
+       /*
+        * Will use reserve that does not require slab operation during
+        * early boot.
+        */
        BUILD_BUG_ON(PERCPU_DYNAMIC_EARLY_SIZE <
                        SLUB_PAGE_SHIFT * sizeof(struct kmem_cache_cpu));
+#else
+       /*
+        * Special hack for UP mode. allocpercpu() falls back to kmalloc
+        * operations. So we cannot use that before the slab allocator is up
+        * Simply get the smallest possible compound page. The page will be
+        * released via kfree() when the cpu caches are resized later.
+        */
+       if (slab_state < UP)
+               s->cpu_slab = (__percpu void *)kmalloc_large(PAGE_SIZE << 1, GFP_NOWAIT);
+       else
+#endif
 
        s->cpu_slab = alloc_percpu(struct kmem_cache_cpu);