slub: Fix up missing kmalloc_cache -> kmem_cache_node case for memoryhotplug
[linux-2.6.git] / mm / slub.c
index 94fee96..b244a5a 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -791,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)
@@ -1065,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
 
 /*
@@ -1646,6 +1691,7 @@ new_slab:
                goto load_freelist;
        }
 
+       gfpflags &= gfp_allowed_mask;
        if (gfpflags & __GFP_WAIT)
                local_irq_enable();
 
@@ -1694,12 +1740,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
        struct kmem_cache_cpu *c;
        unsigned long flags;
 
-       gfpflags &= gfp_allowed_mask;
-
-       lockdep_trace_alloc(gfpflags);
-       might_sleep_if(gfpflags & __GFP_WAIT);
-
-       if (should_failslab(s->objsize, gfpflags, s->flags))
+       if (slab_pre_alloc_hook(s, gfpflags))
                return NULL;
 
        local_irq_save(flags);
@@ -1718,8 +1759,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
        if (unlikely(gfpflags & __GFP_ZERO) && object)
                memset(object, 0, s->objsize);
 
-       kmemcheck_slab_alloc(s, gfpflags, object, s->objsize);
-       kmemleak_alloc_recursive(object, s->objsize, 1, s->flags, gfpflags);
+       slab_post_alloc_hook(s, gfpflags, object);
 
        return object;
 }
@@ -1849,13 +1889,13 @@ 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 = __this_cpu_ptr(s->cpu_slab);
-       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);
+
+       slab_free_hook_irq(s, x);
+
        if (likely(page == c->page && c->node >= 0)) {
                set_freepointer(s, object, c->freelist);
                c->freelist = object;
@@ -2869,7 +2909,7 @@ static void slab_mem_offline_callback(void *arg)
                        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);
@@ -2902,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;