]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/slab.c
Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6-omap-h63xx.git] / mm / slab.c
index 85adf0992011aa457f2c22892364e01a86012b55..add05d808a4a6fe96823cf3a5899d1c9a5a3f95b 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -55,7 +55,7 @@
  *
  * SMP synchronization:
  *  constructors and destructors are called without any locking.
- *  Several members in kmem_cache_t and struct slab never change, they
+ *  Several members in struct kmem_cache and struct slab never change, they
  *     are accessed without any locking.
  *  The per-cpu arrays are never accessed from the wrong cpu, no locking,
  *     and local interrupts are disabled so slab code is preempt-safe.
@@ -244,7 +244,7 @@ struct slab {
  */
 struct slab_rcu {
        struct rcu_head head;
-       kmem_cache_t *cachep;
+       struct kmem_cache *cachep;
        void *addr;
 };
 
@@ -294,6 +294,7 @@ struct kmem_list3 {
        unsigned long next_reap;
        int free_touched;
        unsigned int free_limit;
+       unsigned int colour_next;       /* Per-node cache coloring */
        spinlock_t list_lock;
        struct array_cache *shared;     /* shared per node */
        struct array_cache **alien;     /* on other nodes */
@@ -337,13 +338,14 @@ static __always_inline int index_of(const size_t size)
 #define INDEX_AC index_of(sizeof(struct arraycache_init))
 #define INDEX_L3 index_of(sizeof(struct kmem_list3))
 
-static inline void kmem_list3_init(struct kmem_list3 *parent)
+static void kmem_list3_init(struct kmem_list3 *parent)
 {
        INIT_LIST_HEAD(&parent->slabs_full);
        INIT_LIST_HEAD(&parent->slabs_partial);
        INIT_LIST_HEAD(&parent->slabs_free);
        parent->shared = NULL;
        parent->alien = NULL;
+       parent->colour_next = 0;
        spin_lock_init(&parent->list_lock);
        parent->free_objects = 0;
        parent->free_touched = 0;
@@ -363,7 +365,7 @@ static inline void kmem_list3_init(struct kmem_list3 *parent)
        } while (0)
 
 /*
- * kmem_cache_t
+ * struct kmem_cache
  *
  * manages a cache.
  */
@@ -390,16 +392,15 @@ struct kmem_cache {
 
        size_t colour;          /* cache colouring range */
        unsigned int colour_off;        /* colour offset */
-       unsigned int colour_next;       /* cache colouring */
-       kmem_cache_t *slabp_cache;
+       struct kmem_cache *slabp_cache;
        unsigned int slab_size;
        unsigned int dflags;    /* dynamic flags */
 
        /* constructor func */
-       void (*ctor) (void *, kmem_cache_t *, unsigned long);
+       void (*ctor) (void *, struct kmem_cache *, unsigned long);
 
        /* de-constructor func */
-       void (*dtor) (void *, kmem_cache_t *, unsigned long);
+       void (*dtor) (void *, struct kmem_cache *, unsigned long);
 
 /* 4) cache creation/removal */
        const char *name;
@@ -509,23 +510,23 @@ struct kmem_cache {
  * cachep->buffer_size - 2* BYTES_PER_WORD: redzone word [BYTES_PER_WORD long]
  * cachep->buffer_size - 1* BYTES_PER_WORD: last caller address [BYTES_PER_WORD long]
  */
-static int obj_offset(kmem_cache_t *cachep)
+static int obj_offset(struct kmem_cache *cachep)
 {
        return cachep->obj_offset;
 }
 
-static int obj_size(kmem_cache_t *cachep)
+static int obj_size(struct kmem_cache *cachep)
 {
        return cachep->obj_size;
 }
 
-static unsigned long *dbg_redzone1(kmem_cache_t *cachep, void *objp)
+static unsigned long *dbg_redzone1(struct kmem_cache *cachep, void *objp)
 {
        BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
        return (unsigned long*) (objp+obj_offset(cachep)-BYTES_PER_WORD);
 }
 
-static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp)
+static unsigned long *dbg_redzone2(struct kmem_cache *cachep, void *objp)
 {
        BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
        if (cachep->flags & SLAB_STORE_USER)
@@ -534,7 +535,7 @@ static unsigned long *dbg_redzone2(kmem_cache_t *cachep, void *objp)
        return (unsigned long *)(objp + cachep->buffer_size - BYTES_PER_WORD);
 }
 
-static void **dbg_userword(kmem_cache_t *cachep, void *objp)
+static void **dbg_userword(struct kmem_cache *cachep, void *objp)
 {
        BUG_ON(!(cachep->flags & SLAB_STORE_USER));
        return (void **)(objp + cachep->buffer_size - BYTES_PER_WORD);
@@ -596,6 +597,18 @@ static inline struct slab *page_get_slab(struct page *page)
        return (struct slab *)page->lru.prev;
 }
 
+static inline struct kmem_cache *virt_to_cache(const void *obj)
+{
+       struct page *page = virt_to_page(obj);
+       return page_get_cache(page);
+}
+
+static inline struct slab *virt_to_slab(const void *obj)
+{
+       struct page *page = virt_to_page(obj);
+       return page_get_slab(page);
+}
+
 /* These are the default caches for kmalloc. Custom caches can have other sizes. */
 struct cache_sizes malloc_sizes[] = {
 #define CACHE(x) { .cs_size = (x) },
@@ -624,16 +637,16 @@ static struct arraycache_init initarray_generic =
     { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
 
 /* internal cache of cache description objs */
-static kmem_cache_t cache_cache = {
+static struct kmem_cache cache_cache = {
        .batchcount = 1,
        .limit = BOOT_CPUCACHE_ENTRIES,
        .shared = 1,
-       .buffer_size = sizeof(kmem_cache_t),
+       .buffer_size = sizeof(struct kmem_cache),
        .flags = SLAB_NO_REAP,
        .spinlock = SPIN_LOCK_UNLOCKED,
        .name = "kmem_cache",
 #if DEBUG
-       .obj_size = sizeof(kmem_cache_t),
+       .obj_size = sizeof(struct kmem_cache),
 #endif
 };
 
@@ -662,17 +675,17 @@ static enum {
 
 static DEFINE_PER_CPU(struct work_struct, reap_work);
 
-static void free_block(kmem_cache_t *cachep, void **objpp, int len, int node);
-static void enable_cpucache(kmem_cache_t *cachep);
+static void free_block(struct kmem_cache *cachep, void **objpp, int len, int node);
+static void enable_cpucache(struct kmem_cache *cachep);
 static void cache_reap(void *unused);
-static int __node_shrink(kmem_cache_t *cachep, int node);
+static int __node_shrink(struct kmem_cache *cachep, int node);
 
-static inline struct array_cache *ac_data(kmem_cache_t *cachep)
+static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep)
 {
        return cachep->array[smp_processor_id()];
 }
 
-static inline kmem_cache_t *__find_general_cachep(size_t size, gfp_t gfpflags)
+static inline struct kmem_cache *__find_general_cachep(size_t size, gfp_t gfpflags)
 {
        struct cache_sizes *csizep = malloc_sizes;
 
@@ -696,7 +709,7 @@ static inline kmem_cache_t *__find_general_cachep(size_t size, gfp_t gfpflags)
        return csizep->cs_cachep;
 }
 
-kmem_cache_t *kmem_find_general_cachep(size_t size, gfp_t gfpflags)
+struct kmem_cache *kmem_find_general_cachep(size_t size, gfp_t gfpflags)
 {
        return __find_general_cachep(size, gfpflags);
 }
@@ -769,7 +782,7 @@ static void cache_estimate(unsigned long gfporder, size_t buffer_size,
 
 #define slab_error(cachep, msg) __slab_error(__FUNCTION__, cachep, msg)
 
-static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg)
+static void __slab_error(const char *function, struct kmem_cache *cachep, char *msg)
 {
        printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
               function, cachep->name, msg);
@@ -816,9 +829,9 @@ static struct array_cache *alloc_arraycache(int node, int entries,
 }
 
 #ifdef CONFIG_NUMA
-static void *__cache_alloc_node(kmem_cache_t *, gfp_t, int);
+static void *__cache_alloc_node(struct kmem_cache *, gfp_t, int);
 
-static inline struct array_cache **alloc_alien_cache(int node, int limit)
+static struct array_cache **alloc_alien_cache(int node, int limit)
 {
        struct array_cache **ac_ptr;
        int memsize = sizeof(void *) * MAX_NUMNODES;
@@ -845,7 +858,7 @@ static inline struct array_cache **alloc_alien_cache(int node, int limit)
        return ac_ptr;
 }
 
-static inline void free_alien_cache(struct array_cache **ac_ptr)
+static void free_alien_cache(struct array_cache **ac_ptr)
 {
        int i;
 
@@ -858,8 +871,8 @@ static inline void free_alien_cache(struct array_cache **ac_ptr)
        kfree(ac_ptr);
 }
 
-static inline void __drain_alien_cache(kmem_cache_t *cachep,
-                                      struct array_cache *ac, int node)
+static void __drain_alien_cache(struct kmem_cache *cachep,
+                               struct array_cache *ac, int node)
 {
        struct kmem_list3 *rl3 = cachep->nodelists[node];
 
@@ -871,14 +884,14 @@ static inline void __drain_alien_cache(kmem_cache_t *cachep,
        }
 }
 
-static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3)
+static void drain_alien_cache(struct kmem_cache *cachep, struct array_cache **alien)
 {
        int i = 0;
        struct array_cache *ac;
        unsigned long flags;
 
        for_each_online_node(i) {
-               ac = l3->alien[i];
+               ac = alien[i];
                if (ac) {
                        spin_lock_irqsave(&ac->lock, flags);
                        __drain_alien_cache(cachep, ac, i);
@@ -887,16 +900,25 @@ static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3)
        }
 }
 #else
-#define alloc_alien_cache(node, limit) do { } while (0)
-#define free_alien_cache(ac_ptr) do { } while (0)
-#define drain_alien_cache(cachep, l3) do { } while (0)
+
+#define drain_alien_cache(cachep, alien) do { } while (0)
+
+static inline struct array_cache **alloc_alien_cache(int node, int limit)
+{
+       return (struct array_cache **) 0x01020304ul;
+}
+
+static inline void free_alien_cache(struct array_cache **ac_ptr)
+{
+}
+
 #endif
 
 static int __devinit cpuup_callback(struct notifier_block *nfb,
                                    unsigned long action, void *hcpu)
 {
        long cpu = (long)hcpu;
-       kmem_cache_t *cachep;
+       struct kmem_cache *cachep;
        struct kmem_list3 *l3 = NULL;
        int node = cpu_to_node(cpu);
        int memsize = sizeof(struct kmem_list3);
@@ -923,6 +945,11 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
                                l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
                                    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 
+                               /*
+                                * The l3s don't come and go as CPUs come and
+                                * go.  cache_chain_mutex is sufficient
+                                * protection here.
+                                */
                                cachep->nodelists[node] = l3;
                        }
 
@@ -937,26 +964,46 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
                   & array cache's */
                list_for_each_entry(cachep, &cache_chain, next) {
                        struct array_cache *nc;
+                       struct array_cache *shared;
+                       struct array_cache **alien;
 
                        nc = alloc_arraycache(node, cachep->limit,
-                                             cachep->batchcount);
+                                               cachep->batchcount);
                        if (!nc)
                                goto bad;
+                       shared = alloc_arraycache(node,
+                                       cachep->shared * cachep->batchcount,
+                                       0xbaadf00d);
+                       if (!shared)
+                               goto bad;
+
+                       alien = alloc_alien_cache(node, cachep->limit);
+                       if (!alien)
+                               goto bad;
                        cachep->array[cpu] = nc;
 
                        l3 = cachep->nodelists[node];
                        BUG_ON(!l3);
-                       if (!l3->shared) {
-                               if (!(nc = alloc_arraycache(node,
-                                                           cachep->shared *
-                                                           cachep->batchcount,
-                                                           0xbaadf00d)))
-                                       goto bad;
 
-                               /* we are serialised from CPU_DEAD or
-                                  CPU_UP_CANCELLED by the cpucontrol lock */
-                               l3->shared = nc;
+                       spin_lock_irq(&l3->list_lock);
+                       if (!l3->shared) {
+                               /*
+                                * We are serialised from CPU_DEAD or
+                                * CPU_UP_CANCELLED by the cpucontrol lock
+                                */
+                               l3->shared = shared;
+                               shared = NULL;
+                       }
+#ifdef CONFIG_NUMA
+                       if (!l3->alien) {
+                               l3->alien = alien;
+                               alien = NULL;
                        }
+#endif
+                       spin_unlock_irq(&l3->list_lock);
+
+                       kfree(shared);
+                       free_alien_cache(alien);
                }
                mutex_unlock(&cache_chain_mutex);
                break;
@@ -965,25 +1012,34 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
                break;
 #ifdef CONFIG_HOTPLUG_CPU
        case CPU_DEAD:
+               /*
+                * Even if all the cpus of a node are down, we don't free the
+                * kmem_list3 of any cache. This to avoid a race between
+                * cpu_down, and a kmalloc allocation from another cpu for
+                * memory from the node of the cpu going down.  The list3
+                * structure is usually allocated from kmem_cache_create() and
+                * gets destroyed at kmem_cache_destroy().
+                */
                /* fall thru */
        case CPU_UP_CANCELED:
                mutex_lock(&cache_chain_mutex);
 
                list_for_each_entry(cachep, &cache_chain, next) {
                        struct array_cache *nc;
+                       struct array_cache *shared;
+                       struct array_cache **alien;
                        cpumask_t mask;
 
                        mask = node_to_cpumask(node);
-                       spin_lock_irq(&cachep->spinlock);
                        /* cpu is dead; no one can alloc from it. */
                        nc = cachep->array[cpu];
                        cachep->array[cpu] = NULL;
                        l3 = cachep->nodelists[node];
 
                        if (!l3)
-                               goto unlock_cache;
+                               goto free_array_cache;
 
-                       spin_lock(&l3->list_lock);
+                       spin_lock_irq(&l3->list_lock);
 
                        /* Free limit for this kmem_list3 */
                        l3->free_limit -= cachep->batchcount;
@@ -991,34 +1047,44 @@ static int __devinit cpuup_callback(struct notifier_block *nfb,
                                free_block(cachep, nc->entry, nc->avail, node);
 
                        if (!cpus_empty(mask)) {
-                               spin_unlock(&l3->list_lock);
-                               goto unlock_cache;
+                               spin_unlock_irq(&l3->list_lock);
+                               goto free_array_cache;
                        }
 
-                       if (l3->shared) {
+                       shared = l3->shared;
+                       if (shared) {
                                free_block(cachep, l3->shared->entry,
                                           l3->shared->avail, node);
-                               kfree(l3->shared);
                                l3->shared = NULL;
                        }
-                       if (l3->alien) {
-                               drain_alien_cache(cachep, l3);
-                               free_alien_cache(l3->alien);
-                               l3->alien = NULL;
-                       }
 
-                       /* free slabs belonging to this node */
-                       if (__node_shrink(cachep, node)) {
-                               cachep->nodelists[node] = NULL;
-                               spin_unlock(&l3->list_lock);
-                               kfree(l3);
-                       } else {
-                               spin_unlock(&l3->list_lock);
+                       alien = l3->alien;
+                       l3->alien = NULL;
+
+                       spin_unlock_irq(&l3->list_lock);
+
+                       kfree(shared);
+                       if (alien) {
+                               drain_alien_cache(cachep, alien);
+                               free_alien_cache(alien);
                        }
-                     unlock_cache:
-                       spin_unlock_irq(&cachep->spinlock);
+free_array_cache:
                        kfree(nc);
                }
+               /*
+                * In the previous loop, all the objects were freed to
+                * the respective cache's slabs,  now we can go ahead and
+                * shrink each nodelist to its limit.
+                */
+               list_for_each_entry(cachep, &cache_chain, next) {
+                       l3 = cachep->nodelists[node];
+                       if (!l3)
+                               continue;
+                       spin_lock_irq(&l3->list_lock);
+                       /* free slabs belonging to this node */
+                       __node_shrink(cachep, node);
+                       spin_unlock_irq(&l3->list_lock);
+               }
                mutex_unlock(&cache_chain_mutex);
                break;
 #endif
@@ -1034,7 +1100,7 @@ static struct notifier_block cpucache_notifier = { &cpuup_callback, NULL, 0 };
 /*
  * swap the static kmem_list3 with kmalloced memory
  */
-static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list, int nodeid)
+static void init_list(struct kmem_cache *cachep, struct kmem_list3 *list, int nodeid)
 {
        struct kmem_list3 *ptr;
 
@@ -1074,14 +1140,14 @@ void __init kmem_cache_init(void)
 
        /* Bootstrap is tricky, because several objects are allocated
         * from caches that do not exist yet:
-        * 1) initialize the cache_cache cache: it contains the kmem_cache_t
+        * 1) initialize the cache_cache cache: it contains the struct kmem_cache
         *    structures of all caches, except cache_cache itself: cache_cache
         *    is statically allocated.
         *    Initially an __init data area is used for the head array and the
         *    kmem_list3 structures, it's replaced with a kmalloc allocated
         *    array at the end of the bootstrap.
         * 2) Create the first kmalloc cache.
-        *    The kmem_cache_t for the new cache is allocated normally.
+        *    The struct kmem_cache for the new cache is allocated normally.
         *    An __init data area is used for the head array.
         * 3) Create the remaining kmalloc caches, with minimally sized
         *    head arrays.
@@ -1107,7 +1173,6 @@ void __init kmem_cache_init(void)
                BUG();
 
        cache_cache.colour = left_over / cache_cache.colour_off;
-       cache_cache.colour_next = 0;
        cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) +
                                      sizeof(struct slab), cache_line_size());
 
@@ -1174,8 +1239,8 @@ void __init kmem_cache_init(void)
                ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
 
                local_irq_disable();
-               BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache);
-               memcpy(ptr, ac_data(&cache_cache),
+               BUG_ON(cpu_cache_get(&cache_cache) != &initarray_cache.cache);
+               memcpy(ptr, cpu_cache_get(&cache_cache),
                       sizeof(struct arraycache_init));
                cache_cache.array[smp_processor_id()] = ptr;
                local_irq_enable();
@@ -1183,9 +1248,9 @@ void __init kmem_cache_init(void)
                ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
 
                local_irq_disable();
-               BUG_ON(ac_data(malloc_sizes[INDEX_AC].cs_cachep)
+               BUG_ON(cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep)
                       != &initarray_generic.cache);
-               memcpy(ptr, ac_data(malloc_sizes[INDEX_AC].cs_cachep),
+               memcpy(ptr, cpu_cache_get(malloc_sizes[INDEX_AC].cs_cachep),
                       sizeof(struct arraycache_init));
                malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] =
                    ptr;
@@ -1212,7 +1277,7 @@ void __init kmem_cache_init(void)
 
        /* 6) resize the head arrays to their final sizes */
        {
-               kmem_cache_t *cachep;
+               struct kmem_cache *cachep;
                mutex_lock(&cache_chain_mutex);
                list_for_each_entry(cachep, &cache_chain, next)
                    enable_cpucache(cachep);
@@ -1223,7 +1288,7 @@ void __init kmem_cache_init(void)
        g_cpucache_up = FULL;
 
        /* Register a cpu startup notifier callback
-        * that initializes ac_data for all new cpus
+        * that initializes cpu_cache_get for all new cpus
         */
        register_cpu_notifier(&cpucache_notifier);
 
@@ -1255,7 +1320,7 @@ __initcall(cpucache_init);
  * did not request dmaable memory, we might get it, but that
  * would be relatively rare and ignorable.
  */
-static void *kmem_getpages(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
        struct page *page;
        void *addr;
@@ -1281,7 +1346,7 @@ static void *kmem_getpages(kmem_cache_t *cachep, gfp_t flags, int nodeid)
 /*
  * Interface to system's page release.
  */
-static void kmem_freepages(kmem_cache_t *cachep, void *addr)
+static void kmem_freepages(struct kmem_cache *cachep, void *addr)
 {
        unsigned long i = (1 << cachep->gfporder);
        struct page *page = virt_to_page(addr);
@@ -1303,7 +1368,7 @@ static void kmem_freepages(kmem_cache_t *cachep, void *addr)
 static void kmem_rcu_free(struct rcu_head *head)
 {
        struct slab_rcu *slab_rcu = (struct slab_rcu *)head;
-       kmem_cache_t *cachep = slab_rcu->cachep;
+       struct kmem_cache *cachep = slab_rcu->cachep;
 
        kmem_freepages(cachep, slab_rcu->addr);
        if (OFF_SLAB(cachep))
@@ -1313,7 +1378,7 @@ static void kmem_rcu_free(struct rcu_head *head)
 #if DEBUG
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
-static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr,
+static void store_stackinfo(struct kmem_cache *cachep, unsigned long *addr,
                            unsigned long caller)
 {
        int size = obj_size(cachep);
@@ -1346,7 +1411,7 @@ static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr,
 }
 #endif
 
-static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val)
+static void poison_obj(struct kmem_cache *cachep, void *addr, unsigned char val)
 {
        int size = obj_size(cachep);
        addr = &((char *)addr)[obj_offset(cachep)];
@@ -1368,7 +1433,7 @@ static void dump_line(char *data, int offset, int limit)
 
 #if DEBUG
 
-static void print_objinfo(kmem_cache_t *cachep, void *objp, int lines)
+static void print_objinfo(struct kmem_cache *cachep, void *objp, int lines)
 {
        int i, size;
        char *realobj;
@@ -1397,7 +1462,7 @@ static void print_objinfo(kmem_cache_t *cachep, void *objp, int lines)
        }
 }
 
-static void check_poison_obj(kmem_cache_t *cachep, void *objp)
+static void check_poison_obj(struct kmem_cache *cachep, void *objp)
 {
        char *realobj;
        int size, i;
@@ -1437,7 +1502,7 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp)
                /* Print some data about the neighboring objects, if they
                 * exist:
                 */
-               struct slab *slabp = page_get_slab(virt_to_page(objp));
+               struct slab *slabp = virt_to_slab(objp);
                int objnr;
 
                objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size;
@@ -1464,7 +1529,7 @@ static void check_poison_obj(kmem_cache_t *cachep, void *objp)
  * slab_destroy_objs - call the registered destructor for each object in
  *      a slab that is to be destroyed.
  */
-static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp)
+static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp)
 {
        int i;
        for (i = 0; i < cachep->num; i++) {
@@ -1496,7 +1561,7 @@ static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp)
        }
 }
 #else
-static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp)
+static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp)
 {
        if (cachep->dtor) {
                int i;
@@ -1513,7 +1578,7 @@ static void slab_destroy_objs(kmem_cache_t *cachep, struct slab *slabp)
  * Before calling the slab must have been unlinked from the cache.
  * The cache-lock is not held/needed.
  */
-static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp)
+static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp)
 {
        void *addr = slabp->s_mem - slabp->colouroff;
 
@@ -1534,7 +1599,7 @@ static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp)
 
 /* For setting up all the kmem_list3s for cache whose buffer_size is same
    as size of kmem_list3. */
-static inline void set_up_list3s(kmem_cache_t *cachep, int index)
+static void set_up_list3s(struct kmem_cache *cachep, int index)
 {
        int node;
 
@@ -1547,15 +1612,20 @@ static inline void set_up_list3s(kmem_cache_t *cachep, int index)
 }
 
 /**
- * calculate_slab_order - calculate size (page order) of slabs and the number
- *                        of objects per slab.
+ * calculate_slab_order - calculate size (page order) of slabs
+ * @cachep: pointer to the cache that is being created
+ * @size: size of objects to be created in this cache.
+ * @align: required alignment for the objects.
+ * @flags: slab allocation flags
+ *
+ * Also calculates the number of objects per slab.
  *
  * This could be made much more intelligent.  For now, try to avoid using
  * high order pages for slabs.  When the gfp() functions are more friendly
  * towards high-order requests, this should be changed.
  */
-static inline size_t calculate_slab_order(kmem_cache_t *cachep, size_t size,
-                                         size_t align, gfp_t flags)
+static inline size_t calculate_slab_order(struct kmem_cache *cachep,
+                       size_t size, size_t align, unsigned long flags)
 {
        size_t left_over = 0;
 
@@ -1626,13 +1696,13 @@ static inline size_t calculate_slab_order(kmem_cache_t *cachep, size_t size,
  * cacheline.  This can be beneficial if you're counting cycles as closely
  * as davem.
  */
-kmem_cache_t *
+struct kmem_cache *
 kmem_cache_create (const char *name, size_t size, size_t align,
-       unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
-       void (*dtor)(void*, kmem_cache_t *, unsigned long))
+       unsigned long flags, void (*ctor)(void*, struct kmem_cache *, unsigned long),
+       void (*dtor)(void*, struct kmem_cache *, unsigned long))
 {
        size_t left_over, slab_size, ralign;
-       kmem_cache_t *cachep = NULL;
+       struct kmem_cache *cachep = NULL;
        struct list_head *p;
 
        /*
@@ -1647,10 +1717,16 @@ kmem_cache_create (const char *name, size_t size, size_t align,
                BUG();
        }
 
+       /*
+        * Prevent CPUs from coming and going.
+        * lock_cpu_hotplug() nests outside cache_chain_mutex
+        */
+       lock_cpu_hotplug();
+
        mutex_lock(&cache_chain_mutex);
 
        list_for_each(p, &cache_chain) {
-               kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+               struct kmem_cache *pc = list_entry(p, struct kmem_cache, next);
                mm_segment_t old_fs = get_fs();
                char tmp;
                int res;
@@ -1750,10 +1826,10 @@ kmem_cache_create (const char *name, size_t size, size_t align,
        align = ralign;
 
        /* Get cache's description obj. */
-       cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
+       cachep = kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
        if (!cachep)
                goto oops;
-       memset(cachep, 0, sizeof(kmem_cache_t));
+       memset(cachep, 0, sizeof(struct kmem_cache));
 
 #if DEBUG
        cachep->obj_size = size;
@@ -1848,8 +1924,6 @@ kmem_cache_create (const char *name, size_t size, size_t align,
        cachep->dtor = dtor;
        cachep->name = name;
 
-       /* Don't let CPUs to come and go */
-       lock_cpu_hotplug();
 
        if (g_cpucache_up == FULL) {
                enable_cpucache(cachep);
@@ -1897,23 +1971,23 @@ kmem_cache_create (const char *name, size_t size, size_t align,
                    jiffies + REAPTIMEOUT_LIST3 +
                    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 
-               BUG_ON(!ac_data(cachep));
-               ac_data(cachep)->avail = 0;
-               ac_data(cachep)->limit = BOOT_CPUCACHE_ENTRIES;
-               ac_data(cachep)->batchcount = 1;
-               ac_data(cachep)->touched = 0;
+               BUG_ON(!cpu_cache_get(cachep));
+               cpu_cache_get(cachep)->avail = 0;
+               cpu_cache_get(cachep)->limit = BOOT_CPUCACHE_ENTRIES;
+               cpu_cache_get(cachep)->batchcount = 1;
+               cpu_cache_get(cachep)->touched = 0;
                cachep->batchcount = 1;
                cachep->limit = BOOT_CPUCACHE_ENTRIES;
        }
 
        /* cache setup completed, link it into the list */
        list_add(&cachep->next, &cache_chain);
-       unlock_cpu_hotplug();
       oops:
        if (!cachep && (flags & SLAB_PANIC))
                panic("kmem_cache_create(): failed to create slab `%s'\n",
                      name);
        mutex_unlock(&cache_chain_mutex);
+       unlock_cpu_hotplug();
        return cachep;
 }
 EXPORT_SYMBOL(kmem_cache_create);
@@ -1929,7 +2003,7 @@ static void check_irq_on(void)
        BUG_ON(irqs_disabled());
 }
 
-static void check_spinlock_acquired(kmem_cache_t *cachep)
+static void check_spinlock_acquired(struct kmem_cache *cachep)
 {
 #ifdef CONFIG_SMP
        check_irq_off();
@@ -1937,7 +2011,7 @@ static void check_spinlock_acquired(kmem_cache_t *cachep)
 #endif
 }
 
-static inline void check_spinlock_acquired_node(kmem_cache_t *cachep, int node)
+static void check_spinlock_acquired_node(struct kmem_cache *cachep, int node)
 {
 #ifdef CONFIG_SMP
        check_irq_off();
@@ -1970,45 +2044,43 @@ static void smp_call_function_all_cpus(void (*func)(void *arg), void *arg)
        preempt_enable();
 }
 
-static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac,
+static void drain_array_locked(struct kmem_cache *cachep, struct array_cache *ac,
                                int force, int node);
 
 static void do_drain(void *arg)
 {
-       kmem_cache_t *cachep = (kmem_cache_t *) arg;
+       struct kmem_cache *cachep = (struct kmem_cache *) arg;
        struct array_cache *ac;
        int node = numa_node_id();
 
        check_irq_off();
-       ac = ac_data(cachep);
+       ac = cpu_cache_get(cachep);
        spin_lock(&cachep->nodelists[node]->list_lock);
        free_block(cachep, ac->entry, ac->avail, node);
        spin_unlock(&cachep->nodelists[node]->list_lock);
        ac->avail = 0;
 }
 
-static void drain_cpu_caches(kmem_cache_t *cachep)
+static void drain_cpu_caches(struct kmem_cache *cachep)
 {
        struct kmem_list3 *l3;
        int node;
 
        smp_call_function_all_cpus(do_drain, cachep);
        check_irq_on();
-       spin_lock_irq(&cachep->spinlock);
        for_each_online_node(node) {
                l3 = cachep->nodelists[node];
                if (l3) {
-                       spin_lock(&l3->list_lock);
+                       spin_lock_irq(&l3->list_lock);
                        drain_array_locked(cachep, l3->shared, 1, node);
-                       spin_unlock(&l3->list_lock);
+                       spin_unlock_irq(&l3->list_lock);
                        if (l3->alien)
-                               drain_alien_cache(cachep, l3);
+                               drain_alien_cache(cachep, l3->alien);
                }
        }
-       spin_unlock_irq(&cachep->spinlock);
 }
 
-static int __node_shrink(kmem_cache_t *cachep, int node)
+static int __node_shrink(struct kmem_cache *cachep, int node)
 {
        struct slab *slabp;
        struct kmem_list3 *l3 = cachep->nodelists[node];
@@ -2037,7 +2109,7 @@ static int __node_shrink(kmem_cache_t *cachep, int node)
        return ret;
 }
 
-static int __cache_shrink(kmem_cache_t *cachep)
+static int __cache_shrink(struct kmem_cache *cachep)
 {
        int ret = 0, i = 0;
        struct kmem_list3 *l3;
@@ -2063,7 +2135,7 @@ static int __cache_shrink(kmem_cache_t *cachep)
  * Releases as many slabs as possible for a cache.
  * To help debugging, a zero exit status indicates all slabs were released.
  */
-int kmem_cache_shrink(kmem_cache_t *cachep)
+int kmem_cache_shrink(struct kmem_cache *cachep)
 {
        if (!cachep || in_interrupt())
                BUG();
@@ -2076,7 +2148,7 @@ EXPORT_SYMBOL(kmem_cache_shrink);
  * kmem_cache_destroy - delete a cache
  * @cachep: the cache to destroy
  *
- * Remove a kmem_cache_t object from the slab cache.
+ * Remove a struct kmem_cache object from the slab cache.
  * Returns 0 on success.
  *
  * It is expected this function will be called by a module when it is
@@ -2089,7 +2161,7 @@ EXPORT_SYMBOL(kmem_cache_shrink);
  * The caller must guarantee that noone will allocate memory from the cache
  * during the kmem_cache_destroy().
  */
-int kmem_cache_destroy(kmem_cache_t *cachep)
+int kmem_cache_destroy(struct kmem_cache *cachep)
 {
        int i;
        struct kmem_list3 *l3;
@@ -2140,7 +2212,7 @@ int kmem_cache_destroy(kmem_cache_t *cachep)
 EXPORT_SYMBOL(kmem_cache_destroy);
 
 /* Get the memory for a slab management obj. */
-static struct slab *alloc_slabmgmt(kmem_cache_t *cachep, void *objp,
+static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp,
                                   int colour_off, gfp_t local_flags)
 {
        struct slab *slabp;
@@ -2166,7 +2238,7 @@ static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)
        return (kmem_bufctl_t *) (slabp + 1);
 }
 
-static void cache_init_objs(kmem_cache_t *cachep,
+static void cache_init_objs(struct kmem_cache *cachep,
                            struct slab *slabp, unsigned long ctor_flags)
 {
        int i;
@@ -2215,7 +2287,7 @@ static void cache_init_objs(kmem_cache_t *cachep,
        slabp->free = 0;
 }
 
-static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags)
+static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags)
 {
        if (flags & SLAB_DMA) {
                if (!(cachep->gfpflags & GFP_DMA))
@@ -2226,7 +2298,43 @@ static void kmem_flagcheck(kmem_cache_t *cachep, gfp_t flags)
        }
 }
 
-static void set_slab_attr(kmem_cache_t *cachep, struct slab *slabp, void *objp)
+static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slabp, int nodeid)
+{
+       void *objp = slabp->s_mem + (slabp->free * cachep->buffer_size);
+       kmem_bufctl_t next;
+
+       slabp->inuse++;
+       next = slab_bufctl(slabp)[slabp->free];
+#if DEBUG
+       slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
+       WARN_ON(slabp->nodeid != nodeid);
+#endif
+       slabp->free = next;
+
+       return objp;
+}
+
+static void slab_put_obj(struct kmem_cache *cachep, struct slab *slabp, void *objp,
+                         int nodeid)
+{
+       unsigned int objnr = (unsigned)(objp-slabp->s_mem) / cachep->buffer_size;
+
+#if DEBUG
+       /* Verify that the slab belongs to the intended node */
+       WARN_ON(slabp->nodeid != nodeid);
+
+       if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
+               printk(KERN_ERR "slab: double free detected in cache "
+                      "'%s', objp %p\n", cachep->name, objp);
+               BUG();
+       }
+#endif
+       slab_bufctl(slabp)[objnr] = slabp->free;
+       slabp->free = objnr;
+       slabp->inuse--;
+}
+
+static void set_slab_attr(struct kmem_cache *cachep, struct slab *slabp, void *objp)
 {
        int i;
        struct page *page;
@@ -2245,7 +2353,7 @@ static void set_slab_attr(kmem_cache_t *cachep, struct slab *slabp, void *objp)
  * Grow (by 1) the number of slabs within a cache.  This is called by
  * kmem_cache_alloc() when there are no active objs left in a cache.
  */
-static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
        struct slab *slabp;
        void *objp;
@@ -2271,20 +2379,20 @@ static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
                 */
                ctor_flags |= SLAB_CTOR_ATOMIC;
 
-       /* About to mess with non-constant members - lock. */
+       /* Take the l3 list lock to change the colour_next on this node */
        check_irq_off();
-       spin_lock(&cachep->spinlock);
+       l3 = cachep->nodelists[nodeid];
+       spin_lock(&l3->list_lock);
 
        /* Get colour for the slab, and cal the next value. */
-       offset = cachep->colour_next;
-       cachep->colour_next++;
-       if (cachep->colour_next >= cachep->colour)
-               cachep->colour_next = 0;
-       offset *= cachep->colour_off;
+       offset = l3->colour_next;
+       l3->colour_next++;
+       if (l3->colour_next >= cachep->colour)
+               l3->colour_next = 0;
+       spin_unlock(&l3->list_lock);
 
-       spin_unlock(&cachep->spinlock);
+       offset *= cachep->colour_off;
 
-       check_irq_off();
        if (local_flags & __GFP_WAIT)
                local_irq_enable();
 
@@ -2314,7 +2422,6 @@ static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
        if (local_flags & __GFP_WAIT)
                local_irq_disable();
        check_irq_off();
-       l3 = cachep->nodelists[nodeid];
        spin_lock(&l3->list_lock);
 
        /* Make slab active. */
@@ -2356,7 +2463,7 @@ static void kfree_debugcheck(const void *objp)
        }
 }
 
-static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp,
+static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
                                   void *caller)
 {
        struct page *page;
@@ -2430,7 +2537,7 @@ static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp,
        return objp;
 }
 
-static void check_slabp(kmem_cache_t *cachep, struct slab *slabp)
+static void check_slabp(struct kmem_cache *cachep, struct slab *slabp)
 {
        kmem_bufctl_t i;
        int entries = 0;
@@ -2463,14 +2570,14 @@ static void check_slabp(kmem_cache_t *cachep, struct slab *slabp)
 #define check_slabp(x,y) do { } while(0)
 #endif
 
-static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags)
+static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)
 {
        int batchcount;
        struct kmem_list3 *l3;
        struct array_cache *ac;
 
        check_irq_off();
-       ac = ac_data(cachep);
+       ac = cpu_cache_get(cachep);
       retry:
        batchcount = ac->batchcount;
        if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
@@ -2515,22 +2622,12 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags)
                check_slabp(cachep, slabp);
                check_spinlock_acquired(cachep);
                while (slabp->inuse < cachep->num && batchcount--) {
-                       kmem_bufctl_t next;
                        STATS_INC_ALLOCED(cachep);
                        STATS_INC_ACTIVE(cachep);
                        STATS_SET_HIGH(cachep);
 
-                       /* get obj pointer */
-                       ac->entry[ac->avail++] = slabp->s_mem +
-                           slabp->free * cachep->buffer_size;
-
-                       slabp->inuse++;
-                       next = slab_bufctl(slabp)[slabp->free];
-#if DEBUG
-                       slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
-                       WARN_ON(numa_node_id() != slabp->nodeid);
-#endif
-                       slabp->free = next;
+                       ac->entry[ac->avail++] = slab_get_obj(cachep, slabp,
+                                                           numa_node_id());
                }
                check_slabp(cachep, slabp);
 
@@ -2552,7 +2649,7 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags)
                x = cache_grow(cachep, flags, numa_node_id());
 
                // cache_grow can reenable interrupts, then ac could change.
-               ac = ac_data(cachep);
+               ac = cpu_cache_get(cachep);
                if (!x && ac->avail == 0)       // no objects in sight? abort
                        return NULL;
 
@@ -2564,7 +2661,7 @@ static void *cache_alloc_refill(kmem_cache_t *cachep, gfp_t flags)
 }
 
 static inline void
-cache_alloc_debugcheck_before(kmem_cache_t *cachep, gfp_t flags)
+cache_alloc_debugcheck_before(struct kmem_cache *cachep, gfp_t flags)
 {
        might_sleep_if(flags & __GFP_WAIT);
 #if DEBUG
@@ -2573,7 +2670,7 @@ cache_alloc_debugcheck_before(kmem_cache_t *cachep, gfp_t flags)
 }
 
 #if DEBUG
-static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags,
+static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep, gfp_t flags,
                                        void *objp, void *caller)
 {
        if (!objp)
@@ -2622,7 +2719,7 @@ static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags,
 #define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
 #endif
 
-static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags)
+static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
        void *objp;
        struct array_cache *ac;
@@ -2637,7 +2734,7 @@ static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags)
 #endif
 
        check_irq_off();
-       ac = ac_data(cachep);
+       ac = cpu_cache_get(cachep);
        if (likely(ac->avail)) {
                STATS_INC_ALLOCHIT(cachep);
                ac->touched = 1;
@@ -2649,7 +2746,8 @@ static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags)
        return objp;
 }
 
-static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
+static __always_inline void *
+__cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
 {
        unsigned long save_flags;
        void *objp;
@@ -2660,7 +2758,7 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
        objp = ____cache_alloc(cachep, flags);
        local_irq_restore(save_flags);
        objp = cache_alloc_debugcheck_after(cachep, flags, objp,
-                                           __builtin_return_address(0));
+                                           caller);
        prefetchw(objp);
        return objp;
 }
@@ -2669,19 +2767,19 @@ static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
 /*
  * A interface to enable slab creation on nodeid
  */
-static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+static void *__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
        struct list_head *entry;
        struct slab *slabp;
        struct kmem_list3 *l3;
        void *obj;
-       kmem_bufctl_t next;
        int x;
 
        l3 = cachep->nodelists[nodeid];
        BUG_ON(!l3);
 
       retry:
+       check_irq_off();
        spin_lock(&l3->list_lock);
        entry = l3->slabs_partial.next;
        if (entry == &l3->slabs_partial) {
@@ -2701,14 +2799,7 @@ static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
 
        BUG_ON(slabp->inuse == cachep->num);
 
-       /* get obj pointer */
-       obj = slabp->s_mem + slabp->free * cachep->buffer_size;
-       slabp->inuse++;
-       next = slab_bufctl(slabp)[slabp->free];
-#if DEBUG
-       slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
-#endif
-       slabp->free = next;
+       obj = slab_get_obj(cachep, slabp, nodeid);
        check_slabp(cachep, slabp);
        l3->free_objects--;
        /* move slabp to correct slabp list: */
@@ -2739,7 +2830,7 @@ static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
 /*
  * Caller needs to acquire correct kmem_list's list_lock
  */
-static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects,
+static void free_block(struct kmem_cache *cachep, void **objpp, int nr_objects,
                       int node)
 {
        int i;
@@ -2748,29 +2839,14 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects,
        for (i = 0; i < nr_objects; i++) {
                void *objp = objpp[i];
                struct slab *slabp;
-               unsigned int objnr;
 
-               slabp = page_get_slab(virt_to_page(objp));
+               slabp = virt_to_slab(objp);
                l3 = cachep->nodelists[node];
                list_del(&slabp->list);
-               objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size;
                check_spinlock_acquired_node(cachep, node);
                check_slabp(cachep, slabp);
-
-#if DEBUG
-               /* Verify that the slab belongs to the intended node */
-               WARN_ON(slabp->nodeid != node);
-
-               if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
-                       printk(KERN_ERR "slab: double free detected in cache "
-                              "'%s', objp %p\n", cachep->name, objp);
-                       BUG();
-               }
-#endif
-               slab_bufctl(slabp)[objnr] = slabp->free;
-               slabp->free = objnr;
+               slab_put_obj(cachep, slabp, objp, node);
                STATS_DEC_ACTIVE(cachep);
-               slabp->inuse--;
                l3->free_objects++;
                check_slabp(cachep, slabp);
 
@@ -2792,7 +2868,7 @@ static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects,
        }
 }
 
-static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac)
+static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)
 {
        int batchcount;
        struct kmem_list3 *l3;
@@ -2851,9 +2927,9 @@ static void cache_flusharray(kmem_cache_t *cachep, struct array_cache *ac)
  *
  * Called with disabled ints.
  */
-static inline void __cache_free(kmem_cache_t *cachep, void *objp)
+static inline void __cache_free(struct kmem_cache *cachep, void *objp)
 {
-       struct array_cache *ac = ac_data(cachep);
+       struct array_cache *ac = cpu_cache_get(cachep);
 
        check_irq_off();
        objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
@@ -2864,7 +2940,7 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp)
 #ifdef CONFIG_NUMA
        {
                struct slab *slabp;
-               slabp = page_get_slab(virt_to_page(objp));
+               slabp = virt_to_slab(objp);
                if (unlikely(slabp->nodeid != numa_node_id())) {
                        struct array_cache *alien = NULL;
                        int nodeid = slabp->nodeid;
@@ -2910,9 +2986,9 @@ static inline void __cache_free(kmem_cache_t *cachep, void *objp)
  * Allocate an object from this cache.  The flags are only relevant
  * if the cache has no available objects.
  */
-void *kmem_cache_alloc(kmem_cache_t *cachep, gfp_t flags)
+void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
-       return __cache_alloc(cachep, flags);
+       return __cache_alloc(cachep, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
@@ -2930,7 +3006,7 @@ EXPORT_SYMBOL(kmem_cache_alloc);
  *
  * Currently only used for dentry validation.
  */
-int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)
+int fastcall kmem_ptr_validate(struct kmem_cache *cachep, void *ptr)
 {
        unsigned long addr = (unsigned long)ptr;
        unsigned long min_addr = PAGE_OFFSET;
@@ -2971,7 +3047,7 @@ int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)
  * New and improved: it will now make sure that the object gets
  * put on the correct node list so that there is no false sharing.
  */
-void *kmem_cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
+void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
        unsigned long save_flags;
        void *ptr;
@@ -2995,7 +3071,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
 
 void *kmalloc_node(size_t size, gfp_t flags, int node)
 {
-       kmem_cache_t *cachep;
+       struct kmem_cache *cachep;
 
        cachep = kmem_find_general_cachep(size, flags);
        if (unlikely(cachep == NULL))
@@ -3026,9 +3102,10 @@ EXPORT_SYMBOL(kmalloc_node);
  * platforms.  For example, on i386, it means that the memory must come
  * from the first 16MB.
  */
-void *__kmalloc(size_t size, gfp_t flags)
+static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
+                                         void *caller)
 {
-       kmem_cache_t *cachep;
+       struct kmem_cache *cachep;
 
        /* If you want to save a few bytes .text space: replace
         * __ with kmem_.
@@ -3038,10 +3115,27 @@ void *__kmalloc(size_t size, gfp_t flags)
        cachep = __find_general_cachep(size, flags);
        if (unlikely(cachep == NULL))
                return NULL;
-       return __cache_alloc(cachep, flags);
+       return __cache_alloc(cachep, flags, caller);
+}
+
+#ifndef CONFIG_DEBUG_SLAB
+
+void *__kmalloc(size_t size, gfp_t flags)
+{
+       return __do_kmalloc(size, flags, NULL);
 }
 EXPORT_SYMBOL(__kmalloc);
 
+#else
+
+void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller)
+{
+       return __do_kmalloc(size, flags, caller);
+}
+EXPORT_SYMBOL(__kmalloc_track_caller);
+
+#endif
+
 #ifdef CONFIG_SMP
 /**
  * __alloc_percpu - allocate one copy of the object for every present
@@ -3099,7 +3193,7 @@ EXPORT_SYMBOL(__alloc_percpu);
  * Free an object which was previously allocated from this
  * cache.
  */
-void kmem_cache_free(kmem_cache_t *cachep, void *objp)
+void kmem_cache_free(struct kmem_cache *cachep, void *objp)
 {
        unsigned long flags;
 
@@ -3120,14 +3214,14 @@ EXPORT_SYMBOL(kmem_cache_free);
  */
 void kfree(const void *objp)
 {
-       kmem_cache_t *c;
+       struct kmem_cache *c;
        unsigned long flags;
 
        if (unlikely(!objp))
                return;
        local_irq_save(flags);
        kfree_debugcheck(objp);
-       c = page_get_cache(virt_to_page(objp));
+       c = virt_to_cache(objp);
        mutex_debug_check_no_locks_freed(objp, obj_size(c));
        __cache_free(c, (void *)objp);
        local_irq_restore(flags);
@@ -3157,13 +3251,13 @@ void free_percpu(const void *objp)
 EXPORT_SYMBOL(free_percpu);
 #endif
 
-unsigned int kmem_cache_size(kmem_cache_t *cachep)
+unsigned int kmem_cache_size(struct kmem_cache *cachep)
 {
        return obj_size(cachep);
 }
 EXPORT_SYMBOL(kmem_cache_size);
 
-const char *kmem_cache_name(kmem_cache_t *cachep)
+const char *kmem_cache_name(struct kmem_cache *cachep)
 {
        return cachep->name;
 }
@@ -3172,7 +3266,7 @@ EXPORT_SYMBOL_GPL(kmem_cache_name);
 /*
  * This initializes kmem_list3 for all nodes.
  */
-static int alloc_kmemlist(kmem_cache_t *cachep)
+static int alloc_kmemlist(struct kmem_cache *cachep)
 {
        int node;
        struct kmem_list3 *l3;
@@ -3228,7 +3322,7 @@ static int alloc_kmemlist(kmem_cache_t *cachep)
 }
 
 struct ccupdate_struct {
-       kmem_cache_t *cachep;
+       struct kmem_cache *cachep;
        struct array_cache *new[NR_CPUS];
 };
 
@@ -3238,13 +3332,13 @@ static void do_ccupdate_local(void *info)
        struct array_cache *old;
 
        check_irq_off();
-       old = ac_data(new->cachep);
+       old = cpu_cache_get(new->cachep);
 
        new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()];
        new->new[smp_processor_id()] = old;
 }
 
-static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
+static int do_tune_cpucache(struct kmem_cache *cachep, int limit, int batchcount,
                            int shared)
 {
        struct ccupdate_struct new;
@@ -3265,11 +3359,11 @@ static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
        smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
 
        check_irq_on();
-       spin_lock_irq(&cachep->spinlock);
+       spin_lock(&cachep->spinlock);
        cachep->batchcount = batchcount;
        cachep->limit = limit;
        cachep->shared = shared;
-       spin_unlock_irq(&cachep->spinlock);
+       spin_unlock(&cachep->spinlock);
 
        for_each_online_cpu(i) {
                struct array_cache *ccold = new.new[i];
@@ -3290,7 +3384,7 @@ static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
        return 0;
 }
 
-static void enable_cpucache(kmem_cache_t *cachep)
+static void enable_cpucache(struct kmem_cache *cachep)
 {
        int err;
        int limit, shared;
@@ -3342,7 +3436,7 @@ static void enable_cpucache(kmem_cache_t *cachep)
                       cachep->name, -err);
 }
 
-static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac,
+static void drain_array_locked(struct kmem_cache *cachep, struct array_cache *ac,
                                int force, int node)
 {
        int tofree;
@@ -3387,12 +3481,12 @@ static void cache_reap(void *unused)
        }
 
        list_for_each(walk, &cache_chain) {
-               kmem_cache_t *searchp;
+               struct kmem_cache *searchp;
                struct list_head *p;
                int tofree;
                struct slab *slabp;
 
-               searchp = list_entry(walk, kmem_cache_t, next);
+               searchp = list_entry(walk, struct kmem_cache, next);
 
                if (searchp->flags & SLAB_NO_REAP)
                        goto next;
@@ -3401,10 +3495,10 @@ static void cache_reap(void *unused)
 
                l3 = searchp->nodelists[numa_node_id()];
                if (l3->alien)
-                       drain_alien_cache(searchp, l3);
+                       drain_alien_cache(searchp, l3->alien);
                spin_lock_irq(&l3->list_lock);
 
-               drain_array_locked(searchp, ac_data(searchp), 0,
+               drain_array_locked(searchp, cpu_cache_get(searchp), 0,
                                   numa_node_id());
 
                if (time_after(l3->next_reap, jiffies))
@@ -3495,15 +3589,15 @@ static void *s_start(struct seq_file *m, loff_t *pos)
                if (p == &cache_chain)
                        return NULL;
        }
-       return list_entry(p, kmem_cache_t, next);
+       return list_entry(p, struct kmem_cache, next);
 }
 
 static void *s_next(struct seq_file *m, void *p, loff_t *pos)
 {
-       kmem_cache_t *cachep = p;
+       struct kmem_cache *cachep = p;
        ++*pos;
        return cachep->next.next == &cache_chain ? NULL
-           : list_entry(cachep->next.next, kmem_cache_t, next);
+           : list_entry(cachep->next.next, struct kmem_cache, next);
 }
 
 static void s_stop(struct seq_file *m, void *p)
@@ -3513,7 +3607,7 @@ static void s_stop(struct seq_file *m, void *p)
 
 static int s_show(struct seq_file *m, void *p)
 {
-       kmem_cache_t *cachep = p;
+       struct kmem_cache *cachep = p;
        struct list_head *q;
        struct slab *slabp;
        unsigned long active_objs;
@@ -3525,8 +3619,7 @@ static int s_show(struct seq_file *m, void *p)
        int node;
        struct kmem_list3 *l3;
 
-       check_irq_on();
-       spin_lock_irq(&cachep->spinlock);
+       spin_lock(&cachep->spinlock);
        active_objs = 0;
        num_slabs = 0;
        for_each_online_node(node) {
@@ -3534,7 +3627,8 @@ static int s_show(struct seq_file *m, void *p)
                if (!l3)
                        continue;
 
-               spin_lock(&l3->list_lock);
+               check_irq_on();
+               spin_lock_irq(&l3->list_lock);
 
                list_for_each(q, &l3->slabs_full) {
                        slabp = list_entry(q, struct slab, list);
@@ -3559,9 +3653,10 @@ static int s_show(struct seq_file *m, void *p)
                        num_slabs++;
                }
                free_objects += l3->free_objects;
-               shared_avail += l3->shared->avail;
+               if (l3->shared)
+                       shared_avail += l3->shared->avail;
 
-               spin_unlock(&l3->list_lock);
+               spin_unlock_irq(&l3->list_lock);
        }
        num_slabs += active_slabs;
        num_objs = num_slabs * cachep->num;
@@ -3605,7 +3700,7 @@ static int s_show(struct seq_file *m, void *p)
        }
 #endif
        seq_putc(m, '\n');
-       spin_unlock_irq(&cachep->spinlock);
+       spin_unlock(&cachep->spinlock);
        return 0;
 }
 
@@ -3663,7 +3758,8 @@ ssize_t slabinfo_write(struct file *file, const char __user * buffer,
        mutex_lock(&cache_chain_mutex);
        res = -EINVAL;
        list_for_each(p, &cache_chain) {
-               kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next);
+               struct kmem_cache *cachep = list_entry(p, struct kmem_cache,
+                                                      next);
 
                if (!strcmp(cachep->name, kbuf)) {
                        if (limit < 1 ||
@@ -3701,5 +3797,5 @@ unsigned int ksize(const void *objp)
        if (unlikely(objp == NULL))
                return 0;
 
-       return obj_size(page_get_cache(virt_to_page(objp)));
+       return obj_size(virt_to_cache(objp));
 }