slub: Fix up missing kmalloc_cache -> kmem_cache_node case for memoryhotplug
[linux-2.6.git] / mm / slub.c
index 417ed84..b244a5a 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/kmemtrace.h>
 #include <linux/kmemcheck.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
  *                     the fast path and disables lockless freelists.
  */
 
+#define SLAB_DEBUG_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
+               SLAB_TRACE | SLAB_DEBUG_FREE)
+
+static inline int kmem_cache_debug(struct kmem_cache *s)
+{
 #ifdef CONFIG_SLUB_DEBUG
-#define SLABDEBUG 1
+       return unlikely(s->flags & SLAB_DEBUG_FLAGS);
 #else
-#define SLABDEBUG 0
+       return 0;
 #endif
+}
 
 /*
  * Issues still to be resolved:
  * Set of flags that will prevent slab merging
  */
 #define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
-               SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE)
+               SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \
+               SLAB_FAILSLAB)
 
 #define SLUB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \
                SLAB_CACHE_DMA | SLAB_NOTRACK)
 
-#ifndef ARCH_KMALLOC_MINALIGN
-#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
-#endif
-
-#ifndef ARCH_SLAB_MINALIGN
-#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
-#endif
-
 #define OO_SHIFT       16
 #define OO_MASK                ((1 << OO_SHIFT) - 1)
 #define MAX_OBJS_PER_PAGE      65535 /* since page.objects is u16 */
 
 /* Internal SLUB flags */
-#define __OBJECT_POISON                0x80000000 /* Poison object */
-#define __SYSFS_ADD_DEFERRED   0x40000000 /* Not yet visible via sysfs */
+#define __OBJECT_POISON                0x80000000UL /* Poison object */
 
 static int kmem_size = sizeof(struct kmem_cache);
 
@@ -180,7 +177,7 @@ static struct notifier_block slab_notifier;
 
 static enum {
        DOWN,           /* No slab functionality available */
-       PARTIAL,        /* kmem_cache_open() works but kmalloc does not */
+       PARTIAL,        /* Kmem_cache_node works */
        UP,             /* Everything works but does not show up in sysfs */
        SYSFS           /* Sysfs up */
 } slab_state = DOWN;
@@ -217,10 +214,10 @@ static inline void sysfs_slab_remove(struct kmem_cache *s)
 
 #endif
 
-static inline void stat(struct kmem_cache_cpu *c, enum stat_item si)
+static inline void stat(struct kmem_cache *s, enum stat_item si)
 {
 #ifdef CONFIG_SLUB_STATS
-       c->stat[si]++;
+       __this_cpu_inc(s->cpu_slab->stat[si]);
 #endif
 }
 
@@ -242,15 +239,6 @@ static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node)
 #endif
 }
 
-static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu)
-{
-#ifdef CONFIG_SMP
-       return s->cpu_slab[cpu];
-#else
-       return &s->cpu_slab;
-#endif
-}
-
 /* Verify that a pointer has an address that is valid within a slab page */
 static inline int check_valid_pointer(struct kmem_cache *s,
                                struct page *page, const void *object)
@@ -269,13 +257,6 @@ static inline int check_valid_pointer(struct kmem_cache *s,
        return 1;
 }
 
-/*
- * Slow version of get and set free pointer.
- *
- * This version requires touching the cache lines of kmem_cache which
- * we avoid to do in the fast alloc free paths. There we obtain the offset
- * from the page struct.
- */
 static inline void *get_freepointer(struct kmem_cache *s, void *object)
 {
        return *(void **)(object + s->offset);
@@ -810,6 +791,39 @@ static void trace(struct kmem_cache *s, struct page *page, void *object,
 }
 
 /*
+ * Hooks for other subsystems that check memory allocations. In a typical
+ * production configuration these hooks all should produce no code at all.
+ */
+static inline int slab_pre_alloc_hook(struct kmem_cache *s, gfp_t flags)
+{
+       flags &= gfp_allowed_mask;
+       lockdep_trace_alloc(flags);
+       might_sleep_if(flags & __GFP_WAIT);
+
+       return should_failslab(s->objsize, flags, s->flags);
+}
+
+static inline void slab_post_alloc_hook(struct kmem_cache *s, gfp_t flags, void *object)
+{
+       flags &= gfp_allowed_mask;
+       kmemcheck_slab_alloc(s, flags, object, s->objsize);
+       kmemleak_alloc_recursive(object, s->objsize, 1, s->flags, flags);
+}
+
+static inline void slab_free_hook(struct kmem_cache *s, void *x)
+{
+       kmemleak_free_recursive(x, s->flags);
+}
+
+static inline void slab_free_hook_irq(struct kmem_cache *s, void *object)
+{
+       kmemcheck_slab_free(s, object, s->objsize);
+       debug_check_no_locks_freed(object, s->objsize);
+       if (!(s->flags & SLAB_DEBUG_OBJECTS))
+               debug_check_no_obj_freed(object, s->objsize);
+}
+
+/*
  * Tracking of fully allocated slabs for debugging purposes.
  */
 static void add_full(struct kmem_cache_node *n, struct page *page)
@@ -880,7 +894,7 @@ static void setup_object_debug(struct kmem_cache *s, struct page *page,
        init_tracking(s, object);
 }
 
-static int alloc_debug_processing(struct kmem_cache *s, struct page *page,
+static noinline int alloc_debug_processing(struct kmem_cache *s, struct page *page,
                                        void *object, unsigned long addr)
 {
        if (!check_slab(s, page))
@@ -920,8 +934,8 @@ bad:
        return 0;
 }
 
-static int free_debug_processing(struct kmem_cache *s, struct page *page,
-                                       void *object, unsigned long addr)
+static noinline int free_debug_processing(struct kmem_cache *s,
+                struct page *page, void *object, unsigned long addr)
 {
        if (!check_slab(s, page))
                goto fail;
@@ -1020,6 +1034,9 @@ static int __init setup_slub_debug(char *str)
                case 't':
                        slub_debug |= SLAB_TRACE;
                        break;
+               case 'a':
+                       slub_debug |= SLAB_FAILSLAB;
+                       break;
                default:
                        printk(KERN_ERR "slub_debug option '%c' "
                                "unknown. skipped\n", *str);
@@ -1071,6 +1088,8 @@ static inline unsigned long kmem_cache_flags(unsigned long objsize,
 }
 #define slub_debug 0
 
+#define disable_higher_order_debug 0
+
 static inline unsigned long slabs_node(struct kmem_cache *s, int node)
                                                        { return 0; }
 static inline unsigned long node_nr_slabs(struct kmem_cache_node *n)
@@ -1079,6 +1098,18 @@ static inline void inc_slabs_node(struct kmem_cache *s, int node,
                                                        int objects) {}
 static inline void dec_slabs_node(struct kmem_cache *s, int node,
                                                        int objects) {}
+
+static inline int slab_pre_alloc_hook(struct kmem_cache *s, gfp_t flags)
+                                                       { return 0; }
+
+static inline void slab_post_alloc_hook(struct kmem_cache *s, gfp_t flags,
+               void *object) {}
+
+static inline void slab_free_hook(struct kmem_cache *s, void *x) {}
+
+static inline void slab_free_hook_irq(struct kmem_cache *s,
+               void *object) {}
+
 #endif
 
 /*
@@ -1091,10 +1122,10 @@ static inline struct page *alloc_slab_page(gfp_t flags, int node,
 
        flags |= __GFP_NOTRACK;
 
-       if (node == -1)
+       if (node == NUMA_NO_NODE)
                return alloc_pages(flags, order);
        else
-               return alloc_pages_node(node, flags, order);
+               return alloc_pages_exact_node(node, flags, order);
 }
 
 static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
@@ -1122,7 +1153,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
                if (!page)
                        return NULL;
 
-               stat(get_cpu_slab(s, raw_smp_processor_id()), ORDER_FALLBACK);
+               stat(s, ORDER_FALLBACK);
        }
 
        if (kmemcheck_enabled
@@ -1175,9 +1206,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
        inc_slabs_node(s, page_to_nid(page), page->objects);
        page->slab = s;
        page->flags |= 1 << PG_slab;
-       if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON |
-                       SLAB_STORE_USER | SLAB_TRACE))
-               __SetPageSlubDebug(page);
 
        start = page_address(page);
 
@@ -1204,14 +1232,13 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
        int order = compound_order(page);
        int pages = 1 << order;
 
-       if (unlikely(SLABDEBUG && PageSlubDebug(page))) {
+       if (kmem_cache_debug(s)) {
                void *p;
 
                slab_pad_check(s, page);
                for_each_object(p, s, page_address(page),
                                                page->objects)
                        check_object(s, page, p, 0);
-               __ClearPageSlubDebug(page);
        }
 
        kmemcheck_free_shadow(page, compound_order(page));
@@ -1378,6 +1405,7 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags)
                        get_cycles() % 1024 > s->remote_node_defrag_ratio)
                return NULL;
 
+       get_mems_allowed();
        zonelist = node_zonelist(slab_node(current->mempolicy), flags);
        for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) {
                struct kmem_cache_node *n;
@@ -1387,10 +1415,13 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags)
                if (n && cpuset_zone_allowed_hardwall(zone, flags) &&
                                n->nr_partial > s->min_partial) {
                        page = get_partial_node(n);
-                       if (page)
+                       if (page) {
+                               put_mems_allowed();
                                return page;
+                       }
                }
        }
+       put_mems_allowed();
 #endif
        return NULL;
 }
@@ -1401,10 +1432,10 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags)
 static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node)
 {
        struct page *page;
-       int searchnode = (node == -1) ? numa_node_id() : node;
+       int searchnode = (node == NUMA_NO_NODE) ? numa_node_id() : node;
 
        page = get_partial_node(get_node(s, searchnode));
-       if (page || (flags & __GFP_THISNODE))
+       if (page || node != -1)
                return page;
 
        return get_any_partial(s, flags);
@@ -1420,23 +1451,21 @@ static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node)
 static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
 {
        struct kmem_cache_node *n = get_node(s, page_to_nid(page));
-       struct kmem_cache_cpu *c = get_cpu_slab(s, smp_processor_id());
 
        __ClearPageSlubFrozen(page);
        if (page->inuse) {
 
                if (page->freelist) {
                        add_partial(n, page, tail);
-                       stat(c, tail ? DEACTIVATE_TO_TAIL : DEACTIVATE_TO_HEAD);
+                       stat(s, tail ? DEACTIVATE_TO_TAIL : DEACTIVATE_TO_HEAD);
                } else {
-                       stat(c, DEACTIVATE_FULL);
-                       if (SLABDEBUG && PageSlubDebug(page) &&
-                                               (s->flags & SLAB_STORE_USER))
+                       stat(s, DEACTIVATE_FULL);
+                       if (kmem_cache_debug(s) && (s->flags & SLAB_STORE_USER))
                                add_full(n, page);
                }
                slab_unlock(page);
        } else {
-               stat(c, DEACTIVATE_EMPTY);
+               stat(s, DEACTIVATE_EMPTY);
                if (n->nr_partial < s->min_partial) {
                        /*
                         * Adding an empty slab to the partial slabs in order
@@ -1452,7 +1481,7 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
                        slab_unlock(page);
                } else {
                        slab_unlock(page);
-                       stat(get_cpu_slab(s, raw_smp_processor_id()), FREE_SLAB);
+                       stat(s, FREE_SLAB);
                        discard_slab(s, page);
                }
        }
@@ -1467,7 +1496,7 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
        int tail = 1;
 
        if (page->freelist)
-               stat(c, DEACTIVATE_REMOTE_FREES);
+               stat(s, DEACTIVATE_REMOTE_FREES);
        /*
         * Merge cpu freelist into slab freelist. Typically we get here
         * because both freelists are empty. So this is unlikely
@@ -1480,10 +1509,10 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 
                /* Retrieve object from cpu_freelist */
                object = c->freelist;
-               c->freelist = c->freelist[c->offset];
+               c->freelist = get_freepointer(s, c->freelist);
 
                /* And put onto the regular freelist */
-               object[c->offset] = page->freelist;
+               set_freepointer(s, object, page->freelist);
                page->freelist = object;
                page->inuse--;
        }
@@ -1493,7 +1522,7 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 
 static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 {
-       stat(c, CPUSLAB_FLUSH);
+       stat(s, CPUSLAB_FLUSH);
        slab_lock(c->page);
        deactivate_slab(s, c);
 }
@@ -1505,7 +1534,7 @@ static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
  */
 static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
 {
-       struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+       struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
 
        if (likely(c && c->page))
                flush_slab(s, c);
@@ -1530,7 +1559,7 @@ static void flush_all(struct kmem_cache *s)
 static inline int node_match(struct kmem_cache_cpu *c, int node)
 {
 #ifdef CONFIG_NUMA
-       if (node != -1 && c->node != node)
+       if (node != NUMA_NO_NODE && c->node != node)
                return 0;
 #endif
        return 1;
@@ -1633,22 +1662,22 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
        if (unlikely(!node_match(c, node)))
                goto another_slab;
 
-       stat(c, ALLOC_REFILL);
+       stat(s, ALLOC_REFILL);
 
 load_freelist:
        object = c->page->freelist;
        if (unlikely(!object))
                goto another_slab;
-       if (unlikely(SLABDEBUG && PageSlubDebug(c->page)))
+       if (kmem_cache_debug(s))
                goto debug;
 
-       c->freelist = object[c->offset];
+       c->freelist = get_freepointer(s, object);
        c->page->inuse = c->page->objects;
        c->page->freelist = NULL;
        c->node = page_to_nid(c->page);
 unlock_out:
        slab_unlock(c->page);
-       stat(c, ALLOC_SLOWPATH);
+       stat(s, ALLOC_SLOWPATH);
        return object;
 
 another_slab:
@@ -1658,10 +1687,11 @@ new_slab:
        new = get_partial(s, gfpflags, node);
        if (new) {
                c->page = new;
-               stat(c, ALLOC_FROM_PARTIAL);
+               stat(s, ALLOC_FROM_PARTIAL);
                goto load_freelist;
        }
 
+       gfpflags &= gfp_allowed_mask;
        if (gfpflags & __GFP_WAIT)
                local_irq_enable();
 
@@ -1671,8 +1701,8 @@ new_slab:
                local_irq_disable();
 
        if (new) {
-               c = get_cpu_slab(s, smp_processor_id());
-               stat(c, ALLOC_SLAB);
+               c = __this_cpu_ptr(s->cpu_slab);
+               stat(s, ALLOC_SLAB);
                if (c->page)
                        flush_slab(s, c);
                slab_lock(new);
@@ -1688,7 +1718,7 @@ debug:
                goto another_slab;
 
        c->page->inuse++;
-       c->page->freelist = object[c->offset];
+       c->page->freelist = get_freepointer(s, object);
        c->node = -1;
        goto unlock_out;
 }
@@ -1709,42 +1739,34 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
        void **object;
        struct kmem_cache_cpu *c;
        unsigned long flags;
-       unsigned int objsize;
-
-       gfpflags &= gfp_allowed_mask;
-
-       lockdep_trace_alloc(gfpflags);
-       might_sleep_if(gfpflags & __GFP_WAIT);
 
-       if (should_failslab(s->objsize, gfpflags))
+       if (slab_pre_alloc_hook(s, gfpflags))
                return NULL;
 
        local_irq_save(flags);
-       c = get_cpu_slab(s, smp_processor_id());
-       objsize = c->objsize;
-       if (unlikely(!c->freelist || !node_match(c, node)))
+       c = __this_cpu_ptr(s->cpu_slab);
+       object = c->freelist;
+       if (unlikely(!object || !node_match(c, node)))
 
                object = __slab_alloc(s, gfpflags, node, addr, c);
 
        else {
-               object = c->freelist;
-               c->freelist = object[c->offset];
-               stat(c, ALLOC_FASTPATH);
+               c->freelist = get_freepointer(s, object);
+               stat(s, ALLOC_FASTPATH);
        }
        local_irq_restore(flags);
 
-       if (unlikely((gfpflags & __GFP_ZERO) && object))
-               memset(object, 0, objsize);
+       if (unlikely(gfpflags & __GFP_ZERO) && object)
+               memset(object, 0, s->objsize);
 
-       kmemcheck_slab_alloc(s, gfpflags, object, c->objsize);
-       kmemleak_alloc_recursive(object, objsize, 1, s->flags, gfpflags);
+       slab_post_alloc_hook(s, gfpflags, object);
 
        return object;
 }
 
 void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
 {
-       void *ret = slab_alloc(s, gfpflags, -1, _RET_IP_);
+       void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
 
        trace_kmem_cache_alloc(_RET_IP_, ret, s->objsize, s->size, gfpflags);
 
@@ -1752,10 +1774,10 @@ void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
-#ifdef CONFIG_KMEMTRACE
+#ifdef CONFIG_TRACING
 void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
 {
-       return slab_alloc(s, gfpflags, -1, _RET_IP_);
+       return slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
 }
 EXPORT_SYMBOL(kmem_cache_alloc_notrace);
 #endif
@@ -1773,7 +1795,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 #endif
 
-#ifdef CONFIG_KMEMTRACE
+#ifdef CONFIG_TRACING
 void *kmem_cache_alloc_node_notrace(struct kmem_cache *s,
                                    gfp_t gfpflags,
                                    int node)
@@ -1792,26 +1814,25 @@ EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
  * handling required then we can return immediately.
  */
 static void __slab_free(struct kmem_cache *s, struct page *page,
-                       void *x, unsigned long addr, unsigned int offset)
+                       void *x, unsigned long addr)
 {
        void *prior;
        void **object = (void *)x;
-       struct kmem_cache_cpu *c;
 
-       c = get_cpu_slab(s, raw_smp_processor_id());
-       stat(c, FREE_SLOWPATH);
+       stat(s, FREE_SLOWPATH);
        slab_lock(page);
 
-       if (unlikely(SLABDEBUG && PageSlubDebug(page)))
+       if (kmem_cache_debug(s))
                goto debug;
 
 checks_ok:
-       prior = object[offset] = page->freelist;
+       prior = page->freelist;
+       set_freepointer(s, object, prior);
        page->freelist = object;
        page->inuse--;
 
        if (unlikely(PageSlubFrozen(page))) {
-               stat(c, FREE_FROZEN);
+               stat(s, FREE_FROZEN);
                goto out_unlock;
        }
 
@@ -1824,7 +1845,7 @@ checks_ok:
         */
        if (unlikely(!prior)) {
                add_partial(get_node(s, page_to_nid(page)), page, 1);
-               stat(c, FREE_ADD_PARTIAL);
+               stat(s, FREE_ADD_PARTIAL);
        }
 
 out_unlock:
@@ -1837,10 +1858,10 @@ slab_empty:
                 * Slab still on the partial list.
                 */
                remove_partial(s, page);
-               stat(c, FREE_REMOVE_PARTIAL);
+               stat(s, FREE_REMOVE_PARTIAL);
        }
        slab_unlock(page);
-       stat(c, FREE_SLAB);
+       stat(s, FREE_SLAB);
        discard_slab(s, page);
        return;
 
@@ -1868,19 +1889,19 @@ static __always_inline void slab_free(struct kmem_cache *s,
        struct kmem_cache_cpu *c;
        unsigned long flags;
 
-       kmemleak_free_recursive(x, s->flags);
+       slab_free_hook(s, x);
+
        local_irq_save(flags);
-       c = get_cpu_slab(s, smp_processor_id());
-       kmemcheck_slab_free(s, object, c->objsize);
-       debug_check_no_locks_freed(object, c->objsize);
-       if (!(s->flags & SLAB_DEBUG_OBJECTS))
-               debug_check_no_obj_freed(object, c->objsize);
+       c = __this_cpu_ptr(s->cpu_slab);
+
+       slab_free_hook_irq(s, x);
+
        if (likely(page == c->page && c->node >= 0)) {
-               object[c->offset] = c->freelist;
+               set_freepointer(s, object, c->freelist);
                c->freelist = object;
-               stat(c, FREE_FASTPATH);
+               stat(s, FREE_FASTPATH);
        } else
-               __slab_free(s, page, x, addr, c->offset);
+               __slab_free(s, page, x, addr);
 
        local_irq_restore(flags);
 }
@@ -2067,19 +2088,6 @@ static unsigned long calculate_alignment(unsigned long flags,
        return ALIGN(align, sizeof(void *));
 }
 
-static void init_kmem_cache_cpu(struct kmem_cache *s,
-                       struct kmem_cache_cpu *c)
-{
-       c->page = NULL;
-       c->freelist = NULL;
-       c->node = 0;
-       c->offset = s->offset / sizeof(void *);
-       c->objsize = s->objsize;
-#ifdef CONFIG_SLUB_STATS
-       memset(c->stat, 0, NR_SLUB_STAT_ITEMS * sizeof(unsigned));
-#endif
-}
-
 static void
 init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s)
 {
@@ -2093,132 +2101,19 @@ init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s)
 #endif
 }
 
-#ifdef CONFIG_SMP
-/*
- * Per cpu array for per cpu structures.
- *
- * The per cpu array places all kmem_cache_cpu structures from one processor
- * close together meaning that it becomes possible that multiple per cpu
- * structures are contained in one cacheline. This may be particularly
- * beneficial for the kmalloc caches.
- *
- * A desktop system typically has around 60-80 slabs. With 100 here we are
- * likely able to get per cpu structures for all caches from the array defined
- * here. We must be able to cover all kmalloc caches during bootstrap.
- *
- * If the per cpu array is exhausted then fall back to kmalloc
- * of individual cachelines. No sharing is possible then.
- */
-#define NR_KMEM_CACHE_CPU 100
-
-static DEFINE_PER_CPU(struct kmem_cache_cpu,
-                               kmem_cache_cpu)[NR_KMEM_CACHE_CPU];
-
-static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free);
-static DECLARE_BITMAP(kmem_cach_cpu_free_init_once, CONFIG_NR_CPUS);
-
-static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
-                                                       int cpu, gfp_t flags)
+static inline int alloc_kmem_cache_cpus(struct kmem_cache *s)
 {
-       struct kmem_cache_cpu *c = per_cpu(kmem_cache_cpu_free, cpu);
+       BUILD_BUG_ON(PERCPU_DYNAMIC_EARLY_SIZE <
+                       SLUB_PAGE_SHIFT * sizeof(struct kmem_cache_cpu));
 
-       if (c)
-               per_cpu(kmem_cache_cpu_free, cpu) =
-                               (void *)c->freelist;
-       else {
-               /* Table overflow: So allocate ourselves */
-               c = kmalloc_node(
-                       ALIGN(sizeof(struct kmem_cache_cpu), cache_line_size()),
-                       flags, cpu_to_node(cpu));
-               if (!c)
-                       return NULL;
-       }
+       s->cpu_slab = alloc_percpu(struct kmem_cache_cpu);
 
-       init_kmem_cache_cpu(s, c);
-       return c;
+       return s->cpu_slab != NULL;
 }
 
-static void free_kmem_cache_cpu(struct kmem_cache_cpu *c, int cpu)
-{
-       if (c < per_cpu(kmem_cache_cpu, cpu) ||
-                       c >= per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) {
-               kfree(c);
-               return;
-       }
-       c->freelist = (void *)per_cpu(kmem_cache_cpu_free, cpu);
-       per_cpu(kmem_cache_cpu_free, cpu) = c;
-}
-
-static void free_kmem_cache_cpus(struct kmem_cache *s)
-{
-       int cpu;
-
-       for_each_online_cpu(cpu) {
-               struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
-
-               if (c) {
-                       s->cpu_slab[cpu] = NULL;
-                       free_kmem_cache_cpu(c, cpu);
-               }
-       }
-}
-
-static int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
-{
-       int cpu;
-
-       for_each_online_cpu(cpu) {
-               struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
-
-               if (c)
-                       continue;
-
-               c = alloc_kmem_cache_cpu(s, cpu, flags);
-               if (!c) {
-                       free_kmem_cache_cpus(s);
-                       return 0;
-               }
-               s->cpu_slab[cpu] = c;
-       }
-       return 1;
-}
-
-/*
- * Initialize the per cpu array.
- */
-static void init_alloc_cpu_cpu(int cpu)
-{
-       int i;
-
-       if (cpumask_test_cpu(cpu, to_cpumask(kmem_cach_cpu_free_init_once)))
-               return;
-
-       for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--)
-               free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu);
-
-       cpumask_set_cpu(cpu, to_cpumask(kmem_cach_cpu_free_init_once));
-}
-
-static void __init init_alloc_cpu(void)
-{
-       int cpu;
-
-       for_each_online_cpu(cpu)
-               init_alloc_cpu_cpu(cpu);
-  }
-
-#else
-static inline void free_kmem_cache_cpus(struct kmem_cache *s) {}
-static inline void init_alloc_cpu(void) {}
-
-static inline int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
-{
-       init_kmem_cache_cpu(s, &s->cpu_slab);
-       return 1;
-}
-#endif
-
 #ifdef CONFIG_NUMA
+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
@@ -2228,15 +2123,15 @@ static inline int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
  * when allocating for the kmalloc_node_cache. This is used for bootstrapping
  * memory on a fresh node that has no slab structures yet.
  */
-static void early_kmem_cache_node_alloc(gfp_t gfpflags, int node)
+static void early_kmem_cache_node_alloc(int node)
 {
        struct page *page;
        struct kmem_cache_node *n;
        unsigned long flags;
 
-       BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node));
+       BUG_ON(kmem_cache_node->size < sizeof(struct kmem_cache_node));
 
-       page = new_slab(kmalloc_caches, gfpflags, node);
+       page = new_slab(kmem_cache_node, GFP_NOWAIT, node);
 
        BUG_ON(!page);
        if (page_to_nid(page) != node) {
@@ -2248,15 +2143,15 @@ static void early_kmem_cache_node_alloc(gfp_t gfpflags, int node)
 
        n = page->freelist;
        BUG_ON(!n);
-       page->freelist = get_freepointer(kmalloc_caches, n);
+       page->freelist = get_freepointer(kmem_cache_node, n);
        page->inuse++;
-       kmalloc_caches->node[node] = n;
+       kmem_cache_node->node[node] = n;
 #ifdef CONFIG_SLUB_DEBUG
-       init_object(kmalloc_caches, n, 1);
-       init_tracking(kmalloc_caches, n);
+       init_object(kmem_cache_node, n, 1);
+       init_tracking(kmem_cache_node, n);
 #endif
-       init_kmem_cache_node(n, kmalloc_caches);
-       inc_slabs_node(kmalloc_caches, node, page->objects);
+       init_kmem_cache_node(n, kmem_cache_node);
+       inc_slabs_node(kmem_cache_node, node, page->objects);
 
        /*
         * lockdep requires consistent irq usage for each lock
@@ -2274,41 +2169,33 @@ static void free_kmem_cache_nodes(struct kmem_cache *s)
 
        for_each_node_state(node, N_NORMAL_MEMORY) {
                struct kmem_cache_node *n = s->node[node];
-               if (n && n != &s->local_node)
-                       kmem_cache_free(kmalloc_caches, n);
+
+               if (n)
+                       kmem_cache_free(kmem_cache_node, n);
+
                s->node[node] = NULL;
        }
 }
 
-static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
+static int init_kmem_cache_nodes(struct kmem_cache *s)
 {
        int node;
-       int local_node;
-
-       if (slab_state >= UP)
-               local_node = page_to_nid(virt_to_page(s));
-       else
-               local_node = 0;
 
        for_each_node_state(node, N_NORMAL_MEMORY) {
                struct kmem_cache_node *n;
 
-               if (local_node == node)
-                       n = &s->local_node;
-               else {
-                       if (slab_state == DOWN) {
-                               early_kmem_cache_node_alloc(gfpflags, node);
-                               continue;
-                       }
-                       n = kmem_cache_alloc_node(kmalloc_caches,
-                                                       gfpflags, node);
-
-                       if (!n) {
-                               free_kmem_cache_nodes(s);
-                               return 0;
-                       }
+               if (slab_state == DOWN) {
+                       early_kmem_cache_node_alloc(node);
+                       continue;
+               }
+               n = kmem_cache_alloc_node(kmem_cache_node,
+                                               GFP_KERNEL, node);
 
+               if (!n) {
+                       free_kmem_cache_nodes(s);
+                       return 0;
                }
+
                s->node[node] = n;
                init_kmem_cache_node(n, s);
        }
@@ -2319,7 +2206,7 @@ static void free_kmem_cache_nodes(struct kmem_cache *s)
 {
 }
 
-static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
+static int init_kmem_cache_nodes(struct kmem_cache *s)
 {
        init_kmem_cache_node(&s->local_node, s);
        return 1;
@@ -2459,7 +2346,7 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
 
 }
 
-static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
+static int kmem_cache_open(struct kmem_cache *s,
                const char *name, size_t size,
                size_t align, unsigned long flags,
                void (*ctor)(void *))
@@ -2495,11 +2382,12 @@ static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
 #ifdef CONFIG_NUMA
        s->remote_node_defrag_ratio = 1000;
 #endif
-       if (!init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA))
+       if (!init_kmem_cache_nodes(s))
                goto error;
 
-       if (alloc_kmem_cache_cpus(s, gfpflags & ~SLUB_DMA))
+       if (alloc_kmem_cache_cpus(s))
                return 1;
+
        free_kmem_cache_nodes(s);
 error:
        if (flags & SLAB_PANIC)
@@ -2517,6 +2405,9 @@ int kmem_ptr_validate(struct kmem_cache *s, const void *object)
 {
        struct page *page;
 
+       if (!kern_ptr_validate(object, s->size))
+               return 0;
+
        page = get_object_page(object);
 
        if (!page || s != page->slab)
@@ -2557,9 +2448,11 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page,
 #ifdef CONFIG_SLUB_DEBUG
        void *addr = page_address(page);
        void *p;
-       DECLARE_BITMAP(map, page->objects);
+       long *map = kzalloc(BITS_TO_LONGS(page->objects) * sizeof(long),
+                           GFP_ATOMIC);
 
-       bitmap_zero(map, page->objects);
+       if (!map)
+               return;
        slab_err(s, page, "%s", text);
        slab_lock(page);
        for_each_free_object(p, s, page->freelist)
@@ -2574,6 +2467,7 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page,
                }
        }
        slab_unlock(page);
+       kfree(map);
 #endif
 }
 
@@ -2607,9 +2501,8 @@ static inline int kmem_cache_close(struct kmem_cache *s)
        int node;
 
        flush_all(s);
-
+       free_percpu(s->cpu_slab);
        /* Attempt to free all objects */
-       free_kmem_cache_cpus(s);
        for_each_node_state(node, N_NORMAL_MEMORY) {
                struct kmem_cache_node *n = get_node(s, node);
 
@@ -2631,7 +2524,6 @@ void kmem_cache_destroy(struct kmem_cache *s)
        s->refcount--;
        if (!s->refcount) {
                list_del(&s->list);
-               up_write(&slub_lock);
                if (kmem_cache_close(s)) {
                        printk(KERN_ERR "SLUB %s: %s called for cache that "
                                "still has objects.\n", s->name, __func__);
@@ -2640,8 +2532,8 @@ void kmem_cache_destroy(struct kmem_cache *s)
                if (s->flags & SLAB_DESTROY_BY_RCU)
                        rcu_barrier();
                sysfs_slab_remove(s);
-       } else
-               up_write(&slub_lock);
+       }
+       up_write(&slub_lock);
 }
 EXPORT_SYMBOL(kmem_cache_destroy);
 
@@ -2649,9 +2541,15 @@ EXPORT_SYMBOL(kmem_cache_destroy);
  *             Kmalloc subsystem
  *******************************************************************/
 
-struct kmem_cache kmalloc_caches[SLUB_PAGE_SHIFT] __cacheline_aligned;
+struct kmem_cache *kmalloc_caches[SLUB_PAGE_SHIFT];
 EXPORT_SYMBOL(kmalloc_caches);
 
+static struct kmem_cache *kmem_cache;
+
+#ifdef CONFIG_ZONE_DMA
+static struct kmem_cache *kmalloc_dma_caches[SLUB_PAGE_SHIFT];
+#endif
+
 static int __init setup_slub_min_order(char *str)
 {
        get_option(&str, &slub_min_order);
@@ -2688,108 +2586,29 @@ static int __init setup_slub_nomerge(char *str)
 
 __setup("slub_nomerge", setup_slub_nomerge);
 
-static struct kmem_cache *create_kmalloc_cache(struct kmem_cache *s,
-               const char *name, int size, gfp_t gfp_flags)
+static struct kmem_cache *__init create_kmalloc_cache(const char *name,
+                                               int size, unsigned int flags)
 {
-       unsigned int flags = 0;
+       struct kmem_cache *s;
 
-       if (gfp_flags & SLUB_DMA)
-               flags = SLAB_CACHE_DMA;
+       s = kmem_cache_alloc(kmem_cache, GFP_NOWAIT);
 
        /*
         * This function is called with IRQs disabled during early-boot on
         * single CPU so there's no need to take slub_lock here.
         */
-       if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN,
+       if (!kmem_cache_open(s, name, size, ARCH_KMALLOC_MINALIGN,
                                                                flags, NULL))
                goto panic;
 
        list_add(&s->list, &slab_caches);
-
-       if (sysfs_slab_add(s))
-               goto panic;
        return s;
 
 panic:
        panic("Creation of kmalloc slab %s size=%d failed.\n", name, size);
+       return NULL;
 }
 
-#ifdef CONFIG_ZONE_DMA
-static struct kmem_cache *kmalloc_caches_dma[SLUB_PAGE_SHIFT];
-
-static void sysfs_add_func(struct work_struct *w)
-{
-       struct kmem_cache *s;
-
-       down_write(&slub_lock);
-       list_for_each_entry(s, &slab_caches, list) {
-               if (s->flags & __SYSFS_ADD_DEFERRED) {
-                       s->flags &= ~__SYSFS_ADD_DEFERRED;
-                       sysfs_slab_add(s);
-               }
-       }
-       up_write(&slub_lock);
-}
-
-static DECLARE_WORK(sysfs_add_work, sysfs_add_func);
-
-static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags)
-{
-       struct kmem_cache *s;
-       char *text;
-       size_t realsize;
-       unsigned long slabflags;
-
-       s = kmalloc_caches_dma[index];
-       if (s)
-               return s;
-
-       /* Dynamically create dma cache */
-       if (flags & __GFP_WAIT)
-               down_write(&slub_lock);
-       else {
-               if (!down_write_trylock(&slub_lock))
-                       goto out;
-       }
-
-       if (kmalloc_caches_dma[index])
-               goto unlock_out;
-
-       realsize = kmalloc_caches[index].objsize;
-       text = kasprintf(flags & ~SLUB_DMA, "kmalloc_dma-%d",
-                        (unsigned int)realsize);
-       s = kmalloc(kmem_size, flags & ~SLUB_DMA);
-
-       /*
-        * Must defer sysfs creation to a workqueue because we don't know
-        * what context we are called from. Before sysfs comes up, we don't
-        * need to do anything because our sysfs initcall will start by
-        * adding all existing slabs to sysfs.
-        */
-       slabflags = SLAB_CACHE_DMA|SLAB_NOTRACK;
-       if (slab_state >= SYSFS)
-               slabflags |= __SYSFS_ADD_DEFERRED;
-
-       if (!s || !text || !kmem_cache_open(s, flags, text,
-                       realsize, ARCH_KMALLOC_MINALIGN, slabflags, NULL)) {
-               kfree(s);
-               kfree(text);
-               goto unlock_out;
-       }
-
-       list_add(&s->list, &slab_caches);
-       kmalloc_caches_dma[index] = s;
-
-       if (slab_state >= SYSFS)
-               schedule_work(&sysfs_add_work);
-
-unlock_out:
-       up_write(&slub_lock);
-out:
-       return kmalloc_caches_dma[index];
-}
-#endif
-
 /*
  * Conversion table for small slabs sizes / 8 to the index in the
  * kmalloc array. This is necessary for slabs < 192 since we have non power
@@ -2842,10 +2661,10 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
 
 #ifdef CONFIG_ZONE_DMA
        if (unlikely((flags & SLUB_DMA)))
-               return dma_kmalloc_cache(index, flags);
+               return kmalloc_dma_caches[index];
 
 #endif
-       return &kmalloc_caches[index];
+       return kmalloc_caches[index];
 }
 
 void *__kmalloc(size_t size, gfp_t flags)
@@ -2861,7 +2680,7 @@ void *__kmalloc(size_t size, gfp_t flags)
        if (unlikely(ZERO_OR_NULL_PTR(s)))
                return s;
 
-       ret = slab_alloc(s, flags, -1, _RET_IP_);
+       ret = slab_alloc(s, flags, NUMA_NO_NODE, _RET_IP_);
 
        trace_kmalloc(_RET_IP_, ret, size, s->size, flags);
 
@@ -3084,13 +2903,13 @@ static void slab_mem_offline_callback(void *arg)
                        /*
                         * if n->nr_slabs > 0, slabs still exist on the node
                         * that is going down. We were unable to free them,
-                        * and offline_pages() function shoudn't call this
+                        * and offline_pages() function shouldn't call this
                         * callback. So, we must fail.
                         */
                        BUG_ON(slabs_node(s, offline_node));
 
                        s->node[offline_node] = NULL;
-                       kmem_cache_free(kmalloc_caches, n);
+                       kmem_cache_free(kmem_cache_node, n);
                }
        }
        up_read(&slub_lock);
@@ -3123,7 +2942,7 @@ static int slab_mem_going_online_callback(void *arg)
                 *      since memory is not yet available from the node that
                 *      is brought up.
                 */
-               n = kmem_cache_alloc(kmalloc_caches, GFP_KERNEL);
+               n = kmem_cache_alloc(kmem_cache_node, GFP_KERNEL);
                if (!n) {
                        ret = -ENOMEM;
                        goto out;
@@ -3169,48 +2988,113 @@ static int slab_memory_callback(struct notifier_block *self,
  *                     Basic setup of slabs
  *******************************************************************/
 
+/*
+ * Used for early kmem_cache structures that were allocated using
+ * the page allocator
+ */
+
+static void __init kmem_cache_bootstrap_fixup(struct kmem_cache *s)
+{
+       int node;
+
+       list_add(&s->list, &slab_caches);
+       s->refcount = -1;
+
+       for_each_node_state(node, N_NORMAL_MEMORY) {
+               struct kmem_cache_node *n = get_node(s, node);
+               struct page *p;
+
+               if (n) {
+                       list_for_each_entry(p, &n->partial, lru)
+                               p->slab = s;
+
+#ifdef CONFIG_SLAB_DEBUG
+                       list_for_each_entry(p, &n->full, lru)
+                               p->slab = s;
+#endif
+               }
+       }
+}
+
 void __init kmem_cache_init(void)
 {
        int i;
        int caches = 0;
-
-       init_alloc_cpu();
+       struct kmem_cache *temp_kmem_cache;
+       int order;
 
 #ifdef CONFIG_NUMA
+       struct kmem_cache *temp_kmem_cache_node;
+       unsigned long kmalloc_size;
+
+       kmem_size = offsetof(struct kmem_cache, node) +
+                               nr_node_ids * sizeof(struct kmem_cache_node *);
+
+       /* Allocate two kmem_caches from the page allocator */
+       kmalloc_size = ALIGN(kmem_size, cache_line_size());
+       order = get_order(2 * kmalloc_size);
+       kmem_cache = (void *)__get_free_pages(GFP_NOWAIT, order);
+
        /*
         * Must first have the slab cache available for the allocations of the
         * struct kmem_cache_node's. There is special bootstrap code in
         * kmem_cache_open for slab_state == DOWN.
         */
-       create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
-               sizeof(struct kmem_cache_node), GFP_NOWAIT);
-       kmalloc_caches[0].refcount = -1;
-       caches++;
+       kmem_cache_node = (void *)kmem_cache + kmalloc_size;
+
+       kmem_cache_open(kmem_cache_node, "kmem_cache_node",
+               sizeof(struct kmem_cache_node),
+               0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
 
        hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
+#else
+       /* Allocate a single kmem_cache from the page allocator */
+       kmem_size = sizeof(struct kmem_cache);
+       order = get_order(kmem_size);
+       kmem_cache = (void *)__get_free_pages(GFP_NOWAIT, order);
 #endif
 
        /* Able to allocate the per node structures */
        slab_state = PARTIAL;
 
-       /* Caches that are not of the two-to-the-power-of size */
-       if (KMALLOC_MIN_SIZE <= 32) {
-               create_kmalloc_cache(&kmalloc_caches[1],
-                               "kmalloc-96", 96, GFP_NOWAIT);
-               caches++;
-       }
-       if (KMALLOC_MIN_SIZE <= 64) {
-               create_kmalloc_cache(&kmalloc_caches[2],
-                               "kmalloc-192", 192, GFP_NOWAIT);
-               caches++;
-       }
+       temp_kmem_cache = kmem_cache;
+       kmem_cache_open(kmem_cache, "kmem_cache", kmem_size,
+               0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
+       kmem_cache = kmem_cache_alloc(kmem_cache, GFP_NOWAIT);
+       memcpy(kmem_cache, temp_kmem_cache, kmem_size);
 
-       for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) {
-               create_kmalloc_cache(&kmalloc_caches[i],
-                       "kmalloc", 1 << i, GFP_NOWAIT);
-               caches++;
-       }
+#ifdef CONFIG_NUMA
+       /*
+        * Allocate kmem_cache_node properly from the kmem_cache slab.
+        * kmem_cache_node is separately allocated so no need to
+        * update any list pointers.
+        */
+       temp_kmem_cache_node = kmem_cache_node;
+
+       kmem_cache_node = kmem_cache_alloc(kmem_cache, GFP_NOWAIT);
+       memcpy(kmem_cache_node, temp_kmem_cache_node, kmem_size);
+
+       kmem_cache_bootstrap_fixup(kmem_cache_node);
+
+       caches++;
+#else
+       /*
+        * kmem_cache has kmem_cache_node embedded and we moved it!
+        * Update the list heads
+        */
+       INIT_LIST_HEAD(&kmem_cache->local_node.partial);
+       list_splice(&temp_kmem_cache->local_node.partial, &kmem_cache->local_node.partial);
+#ifdef CONFIG_SLUB_DEBUG
+       INIT_LIST_HEAD(&kmem_cache->local_node.full);
+       list_splice(&temp_kmem_cache->local_node.full, &kmem_cache->local_node.full);
+#endif
+#endif
+       kmem_cache_bootstrap_fixup(kmem_cache);
+       caches++;
+       /* Free temporary boot structure */
+       free_pages((unsigned long)temp_kmem_cache, order);
 
+       /* Now we can use the kmem_cache to allocate kmalloc slabs */
 
        /*
         * Patch up the size_index table if we have strange large alignment
@@ -3250,21 +3134,50 @@ void __init kmem_cache_init(void)
                        size_index[size_index_elem(i)] = 8;
        }
 
+       /* Caches that are not of the two-to-the-power-of size */
+       if (KMALLOC_MIN_SIZE <= 32) {
+               kmalloc_caches[1] = create_kmalloc_cache("kmalloc-96", 96, 0);
+               caches++;
+       }
+
+       if (KMALLOC_MIN_SIZE <= 64) {
+               kmalloc_caches[2] = create_kmalloc_cache("kmalloc-192", 192, 0);
+               caches++;
+       }
+
+       for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) {
+               kmalloc_caches[i] = create_kmalloc_cache("kmalloc", 1 << i, 0);
+               caches++;
+       }
+
        slab_state = UP;
 
        /* Provide the correct kmalloc names now that the caches are up */
-       for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++)
-               kmalloc_caches[i]. name =
-                       kasprintf(GFP_NOWAIT, "kmalloc-%d", 1 << i);
+       for (i = KMALLOC_SHIFT_LOW; i < SLUB_PAGE_SHIFT; i++) {
+               char *s = kasprintf(GFP_NOWAIT, "kmalloc-%d", 1 << i);
+
+               BUG_ON(!s);
+               kmalloc_caches[i]->name = s;
+       }
 
 #ifdef CONFIG_SMP
        register_cpu_notifier(&slab_notifier);
-       kmem_size = offsetof(struct kmem_cache, cpu_slab) +
-                               nr_cpu_ids * sizeof(struct kmem_cache_cpu *);
-#else
-       kmem_size = sizeof(struct kmem_cache);
 #endif
 
+#ifdef CONFIG_ZONE_DMA
+       for (i = 0; i < SLUB_PAGE_SHIFT; i++) {
+               struct kmem_cache *s = kmalloc_caches[i];
+
+               if (s && s->size) {
+                       char *name = kasprintf(GFP_NOWAIT,
+                                "dma-kmalloc-%d", s->objsize);
+
+                       BUG_ON(!name);
+                       kmalloc_dma_caches[i] = create_kmalloc_cache(name,
+                               s->objsize, SLAB_CACHE_DMA);
+               }
+       }
+#endif
        printk(KERN_INFO
                "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
                " CPUs=%d, Nodes=%d\n",
@@ -3343,50 +3256,39 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
 {
        struct kmem_cache *s;
 
+       if (WARN_ON(!name))
+               return NULL;
+
        down_write(&slub_lock);
        s = find_mergeable(size, align, flags, name, ctor);
        if (s) {
-               int cpu;
-
                s->refcount++;
                /*
                 * Adjust the object sizes so that we clear
                 * the complete object on kzalloc.
                 */
                s->objsize = max(s->objsize, (int)size);
-
-               /*
-                * And then we need to update the object size in the
-                * per cpu structures
-                */
-               for_each_online_cpu(cpu)
-                       get_cpu_slab(s, cpu)->objsize = s->objsize;
-
                s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
-               up_write(&slub_lock);
 
                if (sysfs_slab_alias(s, name)) {
-                       down_write(&slub_lock);
                        s->refcount--;
-                       up_write(&slub_lock);
                        goto err;
                }
+               up_write(&slub_lock);
                return s;
        }
 
        s = kmalloc(kmem_size, GFP_KERNEL);
        if (s) {
-               if (kmem_cache_open(s, GFP_KERNEL, name,
+               if (kmem_cache_open(s, name,
                                size, align, flags, ctor)) {
                        list_add(&s->list, &slab_caches);
-                       up_write(&slub_lock);
                        if (sysfs_slab_add(s)) {
-                               down_write(&slub_lock);
                                list_del(&s->list);
-                               up_write(&slub_lock);
                                kfree(s);
                                goto err;
                        }
+                       up_write(&slub_lock);
                        return s;
                }
                kfree(s);
@@ -3415,29 +3317,15 @@ static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
        unsigned long flags;
 
        switch (action) {
-       case CPU_UP_PREPARE:
-       case CPU_UP_PREPARE_FROZEN:
-               init_alloc_cpu_cpu(cpu);
-               down_read(&slub_lock);
-               list_for_each_entry(s, &slab_caches, list)
-                       s->cpu_slab[cpu] = alloc_kmem_cache_cpu(s, cpu,
-                                                       GFP_KERNEL);
-               up_read(&slub_lock);
-               break;
-
        case CPU_UP_CANCELED:
        case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
                down_read(&slub_lock);
                list_for_each_entry(s, &slab_caches, list) {
-                       struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
-
                        local_irq_save(flags);
                        __flush_cpu_slab(s, cpu);
                        local_irq_restore(flags);
-                       free_kmem_cache_cpu(c, cpu);
-                       s->cpu_slab[cpu] = NULL;
                }
                up_read(&slub_lock);
                break;
@@ -3466,7 +3354,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
        if (unlikely(ZERO_OR_NULL_PTR(s)))
                return s;
 
-       ret = slab_alloc(s, gfpflags, -1, caller);
+       ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, caller);
 
        /* Honor the call site pointer we recieved. */
        trace_kmalloc(caller, ret, size, s->size, gfpflags);
@@ -3480,8 +3368,15 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
        struct kmem_cache *s;
        void *ret;
 
-       if (unlikely(size > SLUB_MAX_SIZE))
-               return kmalloc_large_node(size, gfpflags, node);
+       if (unlikely(size > SLUB_MAX_SIZE)) {
+               ret = kmalloc_large_node(size, gfpflags, node);
+
+               trace_kmalloc_node(caller, ret,
+                                  size, PAGE_SIZE << get_order(size),
+                                  gfpflags, node);
+
+               return ret;
+       }
 
        s = get_slab(size, gfpflags);
 
@@ -3542,16 +3437,6 @@ static void validate_slab_slab(struct kmem_cache *s, struct page *page,
        } else
                printk(KERN_INFO "SLUB %s: Skipped busy slab 0x%p\n",
                        s->name, page);
-
-       if (s->flags & DEBUG_DEFAULT_FLAGS) {
-               if (!PageSlubDebug(page))
-                       printk(KERN_ERR "SLUB %s: SlubDebug not set "
-                               "on slab 0x%p\n", s->name, page);
-       } else {
-               if (PageSlubDebug(page))
-                       printk(KERN_ERR "SLUB %s: SlubDebug set on "
-                               "slab 0x%p\n", s->name, page);
-       }
 }
 
 static int validate_slab_node(struct kmem_cache *s,
@@ -3793,10 +3678,10 @@ static int add_location(struct loc_track *t, struct kmem_cache *s,
 }
 
 static void process_slab(struct loc_track *t, struct kmem_cache *s,
-               struct page *page, enum track_item alloc)
+               struct page *page, enum track_item alloc,
+               long *map)
 {
        void *addr = page_address(page);
-       DECLARE_BITMAP(map, page->objects);
        void *p;
 
        bitmap_zero(map, page->objects);
@@ -3815,11 +3700,14 @@ static int list_locations(struct kmem_cache *s, char *buf,
        unsigned long i;
        struct loc_track t = { 0, 0, NULL };
        int node;
+       unsigned long *map = kmalloc(BITS_TO_LONGS(oo_objects(s->max)) *
+                                    sizeof(unsigned long), GFP_KERNEL);
 
-       if (!alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location),
-                       GFP_TEMPORARY))
+       if (!map || !alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location),
+                                    GFP_TEMPORARY)) {
+               kfree(map);
                return sprintf(buf, "Out of memory\n");
-
+       }
        /* Push back cpu slabs */
        flush_all(s);
 
@@ -3833,9 +3721,9 @@ static int list_locations(struct kmem_cache *s, char *buf,
 
                spin_lock_irqsave(&n->list_lock, flags);
                list_for_each_entry(page, &n->partial, lru)
-                       process_slab(&t, s, page, alloc);
+                       process_slab(&t, s, page, alloc, map);
                list_for_each_entry(page, &n->full, lru)
-                       process_slab(&t, s, page, alloc);
+                       process_slab(&t, s, page, alloc, map);
                spin_unlock_irqrestore(&n->list_lock, flags);
        }
 
@@ -3886,6 +3774,7 @@ static int list_locations(struct kmem_cache *s, char *buf,
        }
 
        free_loc_track(&t);
+       kfree(map);
        if (!t.count)
                len += sprintf(buf, "No data\n");
        return len;
@@ -3923,7 +3812,7 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
                int cpu;
 
                for_each_possible_cpu(cpu) {
-                       struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
+                       struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
 
                        if (!c || c->node < 0)
                                continue;
@@ -4166,6 +4055,23 @@ static ssize_t trace_store(struct kmem_cache *s, const char *buf,
 }
 SLAB_ATTR(trace);
 
+#ifdef CONFIG_FAILSLAB
+static ssize_t failslab_show(struct kmem_cache *s, char *buf)
+{
+       return sprintf(buf, "%d\n", !!(s->flags & SLAB_FAILSLAB));
+}
+
+static ssize_t failslab_store(struct kmem_cache *s, const char *buf,
+                                                       size_t length)
+{
+       s->flags &= ~SLAB_FAILSLAB;
+       if (buf[0] == '1')
+               s->flags |= SLAB_FAILSLAB;
+       return length;
+}
+SLAB_ATTR(failslab);
+#endif
+
 static ssize_t reclaim_account_show(struct kmem_cache *s, char *buf)
 {
        return sprintf(buf, "%d\n", !!(s->flags & SLAB_RECLAIM_ACCOUNT));
@@ -4348,7 +4254,7 @@ static int show_stat(struct kmem_cache *s, char *buf, enum stat_item si)
                return -ENOMEM;
 
        for_each_online_cpu(cpu) {
-               unsigned x = get_cpu_slab(s, cpu)->stat[si];
+               unsigned x = per_cpu_ptr(s->cpu_slab, cpu)->stat[si];
 
                data[cpu] = x;
                sum += x;
@@ -4366,12 +4272,28 @@ static int show_stat(struct kmem_cache *s, char *buf, enum stat_item si)
        return len + sprintf(buf + len, "\n");
 }
 
+static void clear_stat(struct kmem_cache *s, enum stat_item si)
+{
+       int cpu;
+
+       for_each_online_cpu(cpu)
+               per_cpu_ptr(s->cpu_slab, cpu)->stat[si] = 0;
+}
+
 #define STAT_ATTR(si, text)                                    \
 static ssize_t text##_show(struct kmem_cache *s, char *buf)    \
 {                                                              \
        return show_stat(s, buf, si);                           \
 }                                                              \
-SLAB_ATTR_RO(text);                                            \
+static ssize_t text##_store(struct kmem_cache *s,              \
+                               const char *buf, size_t length) \
+{                                                              \
+       if (buf[0] != '0')                                      \
+               return -EINVAL;                                 \
+       clear_stat(s, si);                                      \
+       return length;                                          \
+}                                                              \
+SLAB_ATTR(text);                                               \
 
 STAT_ATTR(ALLOC_FASTPATH, alloc_fastpath);
 STAT_ATTR(ALLOC_SLOWPATH, alloc_slowpath);
@@ -4446,6 +4368,10 @@ static struct attribute *slab_attrs[] = {
        &deactivate_remote_frees_attr.attr,
        &order_fallback_attr.attr,
 #endif
+#ifdef CONFIG_FAILSLAB
+       &failslab_attr.attr,
+#endif
+
        NULL
 };
 
@@ -4498,7 +4424,7 @@ static void kmem_cache_release(struct kobject *kobj)
        kfree(s);
 }
 
-static struct sysfs_ops slab_sysfs_ops = {
+static const struct sysfs_ops slab_sysfs_ops = {
        .show = slab_attr_show,
        .store = slab_attr_store,
 };
@@ -4517,7 +4443,7 @@ static int uevent_filter(struct kset *kset, struct kobject *kobj)
        return 0;
 }
 
-static struct kset_uevent_ops slab_uevent_ops = {
+static const struct kset_uevent_ops slab_uevent_ops = {
        .filter = uevent_filter,
 };
 
@@ -4610,6 +4536,13 @@ static int sysfs_slab_add(struct kmem_cache *s)
 
 static void sysfs_slab_remove(struct kmem_cache *s)
 {
+       if (slab_state < SYSFS)
+               /*
+                * Sysfs has not been setup yet so no need to remove the
+                * cache from sysfs.
+                */
+               return;
+
        kobject_uevent(&s->kobj, KOBJ_REMOVE);
        kobject_del(&s->kobj);
        kobject_put(&s->kobj);
@@ -4655,8 +4588,11 @@ static int __init slab_sysfs_init(void)
        struct kmem_cache *s;
        int err;
 
+       down_write(&slub_lock);
+
        slab_kset = kset_create_and_add("slab", &slab_uevent_ops, kernel_kobj);
        if (!slab_kset) {
+               up_write(&slub_lock);
                printk(KERN_ERR "Cannot register slab subsystem.\n");
                return -ENOSYS;
        }
@@ -4681,6 +4617,7 @@ static int __init slab_sysfs_init(void)
                kfree(al);
        }
 
+       up_write(&slub_lock);
        resiliency_test();
        return 0;
 }