memcg: ensure list is empty at rmdir
[linux-2.6.git] / mm / slab.c
index bf0c3af..7451bda 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
 #include       <linux/rtmutex.h>
 #include       <linux/reciprocal_div.h>
 #include       <linux/debugobjects.h>
+#include       <linux/kmemcheck.h>
 
 #include       <asm/cacheflush.h>
 #include       <asm/tlbflush.h>
                         SLAB_STORE_USER | \
                         SLAB_RECLAIM_ACCOUNT | SLAB_PANIC | \
                         SLAB_DESTROY_BY_RCU | SLAB_MEM_SPREAD | \
-                        SLAB_DEBUG_OBJECTS | SLAB_NOLEAKTRACE)
+                        SLAB_DEBUG_OBJECTS | SLAB_NOLEAKTRACE | SLAB_NOTRACK)
 #else
 # define CREATE_MASK   (SLAB_HWCACHE_ALIGN | \
                         SLAB_CACHE_DMA | \
                         SLAB_RECLAIM_ACCOUNT | SLAB_PANIC | \
                         SLAB_DESTROY_BY_RCU | SLAB_MEM_SPREAD | \
-                        SLAB_DEBUG_OBJECTS | SLAB_NOLEAKTRACE)
+                        SLAB_DEBUG_OBJECTS | SLAB_NOLEAKTRACE | SLAB_NOTRACK)
 #endif
 
 /*
@@ -489,7 +490,7 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp)
 
 #endif
 
-#ifdef CONFIG_KMEMTRACE
+#ifdef CONFIG_TRACING
 size_t slab_buffer_size(struct kmem_cache *cachep)
 {
        return cachep->buffer_size;
@@ -603,6 +604,26 @@ static struct kmem_cache cache_cache = {
 
 #define BAD_ALIEN_MAGIC 0x01020304ul
 
+/*
+ * chicken and egg problem: delay the per-cpu array allocation
+ * until the general caches are up.
+ */
+static enum {
+       NONE,
+       PARTIAL_AC,
+       PARTIAL_L3,
+       EARLY,
+       FULL
+} g_cpucache_up;
+
+/*
+ * used by boot code to determine if it can use slab based allocator
+ */
+int slab_is_available(void)
+{
+       return g_cpucache_up >= EARLY;
+}
+
 #ifdef CONFIG_LOCKDEP
 
 /*
@@ -619,40 +640,52 @@ static struct kmem_cache cache_cache = {
 static struct lock_class_key on_slab_l3_key;
 static struct lock_class_key on_slab_alc_key;
 
-static inline void init_lock_keys(void)
-
+static void init_node_lock_keys(int q)
 {
-       int q;
        struct cache_sizes *s = malloc_sizes;
 
-       while (s->cs_size != ULONG_MAX) {
-               for_each_node(q) {
-                       struct array_cache **alc;
-                       int r;
-                       struct kmem_list3 *l3 = s->cs_cachep->nodelists[q];
-                       if (!l3 || OFF_SLAB(s->cs_cachep))
-                               continue;
-                       lockdep_set_class(&l3->list_lock, &on_slab_l3_key);
-                       alc = l3->alien;
-                       /*
-                        * FIXME: This check for BAD_ALIEN_MAGIC
-                        * should go away when common slab code is taught to
-                        * work even without alien caches.
-                        * Currently, non NUMA code returns BAD_ALIEN_MAGIC
-                        * for alloc_alien_cache,
-                        */
-                       if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC)
-                               continue;
-                       for_each_node(r) {
-                               if (alc[r])
-                                       lockdep_set_class(&alc[r]->lock,
-                                            &on_slab_alc_key);
-                       }
+       if (g_cpucache_up != FULL)
+               return;
+
+       for (s = malloc_sizes; s->cs_size != ULONG_MAX; s++) {
+               struct array_cache **alc;
+               struct kmem_list3 *l3;
+               int r;
+
+               l3 = s->cs_cachep->nodelists[q];
+               if (!l3 || OFF_SLAB(s->cs_cachep))
+                       continue;
+               lockdep_set_class(&l3->list_lock, &on_slab_l3_key);
+               alc = l3->alien;
+               /*
+                * FIXME: This check for BAD_ALIEN_MAGIC
+                * should go away when common slab code is taught to
+                * work even without alien caches.
+                * Currently, non NUMA code returns BAD_ALIEN_MAGIC
+                * for alloc_alien_cache,
+                */
+               if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC)
+                       continue;
+               for_each_node(r) {
+                       if (alc[r])
+                               lockdep_set_class(&alc[r]->lock,
+                                       &on_slab_alc_key);
                }
-               s++;
        }
 }
+
+static inline void init_lock_keys(void)
+{
+       int node;
+
+       for_each_node(node)
+               init_node_lock_keys(node);
+}
 #else
+static void init_node_lock_keys(int q)
+{
+}
+
 static inline void init_lock_keys(void)
 {
 }
@@ -664,26 +697,7 @@ static inline void init_lock_keys(void)
 static DEFINE_MUTEX(cache_chain_mutex);
 static struct list_head cache_chain;
 
-/*
- * chicken and egg problem: delay the per-cpu array allocation
- * until the general caches are up.
- */
-static enum {
-       NONE,
-       PARTIAL_AC,
-       PARTIAL_L3,
-       FULL
-} g_cpucache_up;
-
-/*
- * used by boot code to determine if it can use slab based allocator
- */
-int slab_is_available(void)
-{
-       return g_cpucache_up == FULL;
-}
-
-static DEFINE_PER_CPU(struct delayed_work, reap_work);
+static DEFINE_PER_CPU(struct delayed_work, slab_reap_work);
 
 static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep)
 {
@@ -810,7 +824,6 @@ static void __slab_error(const char *function, struct kmem_cache *cachep,
   */
 
 static int use_alien_caches __read_mostly = 1;
-static int numa_platform __read_mostly = 1;
 static int __init noaliencache_setup(char *s)
 {
        use_alien_caches = 0;
@@ -825,7 +838,7 @@ __setup("noaliencache", noaliencache_setup);
  * objects freed on different nodes from which they were allocated) and the
  * flushing of remote pcps by calling drain_node_pages.
  */
-static DEFINE_PER_CPU(unsigned long, reap_node);
+static DEFINE_PER_CPU(unsigned long, slab_reap_node);
 
 static void init_reap_node(int cpu)
 {
@@ -835,17 +848,17 @@ static void init_reap_node(int cpu)
        if (node == MAX_NUMNODES)
                node = first_node(node_online_map);
 
-       per_cpu(reap_node, cpu) = node;
+       per_cpu(slab_reap_node, cpu) = node;
 }
 
 static void next_reap_node(void)
 {
-       int node = __get_cpu_var(reap_node);
+       int node = __get_cpu_var(slab_reap_node);
 
        node = next_node(node, node_online_map);
        if (unlikely(node >= MAX_NUMNODES))
                node = first_node(node_online_map);
-       __get_cpu_var(reap_node) = node;
+       __get_cpu_var(slab_reap_node) = node;
 }
 
 #else
@@ -862,7 +875,7 @@ static void next_reap_node(void)
  */
 static void __cpuinit start_cpu_timer(int cpu)
 {
-       struct delayed_work *reap_work = &per_cpu(reap_work, cpu);
+       struct delayed_work *reap_work = &per_cpu(slab_reap_work, cpu);
 
        /*
         * When this gets called from do_initcalls via cpucache_init(),
@@ -1026,7 +1039,7 @@ static void __drain_alien_cache(struct kmem_cache *cachep,
  */
 static void reap_alien(struct kmem_cache *cachep, struct kmem_list3 *l3)
 {
-       int node = __get_cpu_var(reap_node);
+       int node = __get_cpu_var(slab_reap_node);
 
        if (l3->alien) {
                struct array_cache *ac = l3->alien[node];
@@ -1119,7 +1132,7 @@ static void __cpuinit cpuup_canceled(long cpu)
                if (nc)
                        free_block(cachep, nc->entry, nc->avail, node);
 
-               if (!cpus_empty(*mask)) {
+               if (!cpumask_empty(mask)) {
                        spin_unlock_irq(&l3->list_lock);
                        goto free_array_cache;
                }
@@ -1253,6 +1266,8 @@ static int __cpuinit cpuup_prepare(long cpu)
                kfree(shared);
                free_alien_cache(alien);
        }
+       init_node_lock_keys(node);
+
        return 0;
 bad:
        cpuup_canceled(cpu);
@@ -1285,9 +1300,9 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb,
                 * anything expensive but will only modify reap_work
                 * and reschedule the timer.
                */
-               cancel_rearming_delayed_work(&per_cpu(reap_work, cpu));
+               cancel_rearming_delayed_work(&per_cpu(slab_reap_work, cpu));
                /* Now the cache_reaper is guaranteed to be not running. */
-               per_cpu(reap_work, cpu).work.func = NULL;
+               per_cpu(slab_reap_work, cpu).work.func = NULL;
                break;
        case CPU_DOWN_FAILED:
        case CPU_DOWN_FAILED_FROZEN:
@@ -1369,10 +1384,8 @@ void __init kmem_cache_init(void)
        int order;
        int node;
 
-       if (num_possible_nodes() == 1) {
+       if (num_possible_nodes() == 1)
                use_alien_caches = 0;
-               numa_platform = 0;
-       }
 
        for (i = 0; i < NUM_INIT_LISTS; i++) {
                kmem_list3_init(&initkmem_list3[i]);
@@ -1385,7 +1398,7 @@ void __init kmem_cache_init(void)
         * Fragmentation resistance on low memory - only use bigger
         * page orders on machines with more than 32MB of memory.
         */
-       if (num_physpages > (32 << 20) >> PAGE_SHIFT)
+       if (totalram_pages > (32 << 20) >> PAGE_SHIFT)
                slab_break_gfp_order = BREAK_GFP_ORDER_HI;
 
        /* Bootstrap is tricky, because several objects are allocated
@@ -1544,23 +1557,26 @@ void __init kmem_cache_init(void)
                }
        }
 
-       /* 6) resize the head arrays to their final sizes */
-       {
-               struct kmem_cache *cachep;
-               mutex_lock(&cache_chain_mutex);
-               list_for_each_entry(cachep, &cache_chain, next)
-                       if (enable_cpucache(cachep, GFP_NOWAIT))
-                               BUG();
-               mutex_unlock(&cache_chain_mutex);
-       }
+       g_cpucache_up = EARLY;
+}
 
-       /* Annotate slab for lockdep -- annotate the malloc caches */
-       init_lock_keys();
+void __init kmem_cache_init_late(void)
+{
+       struct kmem_cache *cachep;
 
+       /* 6) resize the head arrays to their final sizes */
+       mutex_lock(&cache_chain_mutex);
+       list_for_each_entry(cachep, &cache_chain, next)
+               if (enable_cpucache(cachep, GFP_NOWAIT))
+                       BUG();
+       mutex_unlock(&cache_chain_mutex);
 
        /* Done! */
        g_cpucache_up = FULL;
 
+       /* Annotate slab for lockdep -- annotate the malloc caches */
+       init_lock_keys();
+
        /*
         * Register a cpu startup notifier callback that initializes
         * cpu_cache_get for all new cpus
@@ -1611,7 +1627,7 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
        if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
                flags |= __GFP_RECLAIMABLE;
 
-       page = alloc_pages_node(nodeid, flags, cachep->gfporder);
+       page = alloc_pages_exact_node(nodeid, flags | __GFP_NOTRACK, cachep->gfporder);
        if (!page)
                return NULL;
 
@@ -1624,6 +1640,16 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
                        NR_SLAB_UNRECLAIMABLE, nr_pages);
        for (i = 0; i < nr_pages; i++)
                __SetPageSlab(page + i);
+
+       if (kmemcheck_enabled && !(cachep->flags & SLAB_NOTRACK)) {
+               kmemcheck_alloc_shadow(page, cachep->gfporder, flags, nodeid);
+
+               if (cachep->ctor)
+                       kmemcheck_mark_uninitialized_pages(page, nr_pages);
+               else
+                       kmemcheck_mark_unallocated_pages(page, nr_pages);
+       }
+
        return page_address(page);
 }
 
@@ -1636,6 +1662,8 @@ static void kmem_freepages(struct kmem_cache *cachep, void *addr)
        struct page *page = virt_to_page(addr);
        const unsigned long nr_freed = i;
 
+       kmemcheck_free_shadow(page, cachep->gfporder);
+
        if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
                sub_zone_page_state(page_zone(page),
                                NR_SLAB_RECLAIMABLE, nr_freed);
@@ -2021,7 +2049,7 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep, gfp_t gfp)
                        for_each_online_node(node) {
                                cachep->nodelists[node] =
                                    kmalloc_node(sizeof(struct kmem_list3),
-                                               GFP_KERNEL, node);
+                                               gfp, node);
                                BUG_ON(!cachep->nodelists[node]);
                                kmem_list3_init(cachep->nodelists[node]);
                        }
@@ -2247,9 +2275,11 @@ kmem_cache_create (const char *name, size_t size, size_t align,
        /*
         * Determine if the slab management is 'on' or 'off' slab.
         * (bootstrapping cannot cope with offslab caches so don't do
-        * it too early on.)
+        * it too early on. Always use on-slab management when
+        * SLAB_NOLEAKTRACE to avoid recursive calls into kmemleak)
         */
-       if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init)
+       if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init &&
+           !(flags & SLAB_NOLEAKTRACE))
                /*
                 * Size is large, assume best to place the slab management obj
                 * off-slab (should allow better packing of objs).
@@ -2283,6 +2313,15 @@ kmem_cache_create (const char *name, size_t size, size_t align,
                /* really off slab. No need for manual alignment */
                slab_size =
                    cachep->num * sizeof(kmem_bufctl_t) + sizeof(struct slab);
+
+#ifdef CONFIG_PAGE_POISONING
+               /* If we're going to use the generic kernel_map_pages()
+                * poisoning, then it's going to smash the contents of
+                * the redzone and userword anyhow, so switch them off.
+                */
+               if (size % PAGE_SIZE == 0 && flags & SLAB_POISON)
+                       flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
+#endif
        }
 
        cachep->colour_off = cache_line_size();
@@ -2524,7 +2563,7 @@ void kmem_cache_destroy(struct kmem_cache *cachep)
        }
 
        if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
-               synchronize_rcu();
+               rcu_barrier();
 
        __kmem_cache_destroy(cachep);
        mutex_unlock(&cache_chain_mutex);
@@ -2559,8 +2598,8 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp,
                 * kmemleak does not treat the ->s_mem pointer as a reference
                 * to the object. Otherwise we will not report the leak.
                 */
-               kmemleak_scan_area(slabp, offsetof(struct slab, list),
-                                  sizeof(struct list_head), local_flags);
+               kmemleak_scan_area(&slabp->list, sizeof(struct list_head),
+                                  local_flags);
                if (!slabp)
                        return NULL;
        } else {
@@ -3080,13 +3119,19 @@ static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
        } else {
                STATS_INC_ALLOCMISS(cachep);
                objp = cache_alloc_refill(cachep, flags);
+               /*
+                * the 'ac' may be updated by cache_alloc_refill(),
+                * and kmemleak_erase() requires its correct value.
+                */
+               ac = cpu_cache_get(cachep);
        }
        /*
         * To avoid a false negative, if an object that is in one of the
         * per-CPU caches is leaked, we need to make sure kmemleak doesn't
         * treat the array pointers as a reference to the object.
         */
-       kmemleak_erase(&ac->entry[ac->avail]);
+       if (objp)
+               kmemleak_erase(&ac->entry[ac->avail]);
        return objp;
 }
 
@@ -3165,7 +3210,7 @@ retry:
                if (local_flags & __GFP_WAIT)
                        local_irq_enable();
                kmem_flagcheck(cache, flags);
-               obj = kmem_getpages(cache, local_flags, -1);
+               obj = kmem_getpages(cache, local_flags, numa_node_id());
                if (local_flags & __GFP_WAIT)
                        local_irq_disable();
                if (obj) {
@@ -3273,6 +3318,8 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
        unsigned long save_flags;
        void *ptr;
 
+       flags &= gfp_allowed_mask;
+
        lockdep_trace_alloc(flags);
 
        if (slab_should_failslab(cachep, flags))
@@ -3281,7 +3328,7 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
        cache_alloc_debugcheck_before(cachep, flags);
        local_irq_save(save_flags);
 
-       if (unlikely(nodeid == -1))
+       if (nodeid == -1)
                nodeid = numa_node_id();
 
        if (unlikely(!cachep->nodelists[nodeid])) {
@@ -3309,6 +3356,9 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
        kmemleak_alloc_recursive(ptr, obj_size(cachep), 1, cachep->flags,
                                 flags);
 
+       if (likely(ptr))
+               kmemcheck_slab_alloc(cachep, flags, ptr, obj_size(cachep));
+
        if (unlikely((flags & __GFP_ZERO) && ptr))
                memset(ptr, 0, obj_size(cachep));
 
@@ -3353,6 +3403,8 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
        unsigned long save_flags;
        void *objp;
 
+       flags &= gfp_allowed_mask;
+
        lockdep_trace_alloc(flags);
 
        if (slab_should_failslab(cachep, flags))
@@ -3367,6 +3419,9 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
                                 flags);
        prefetchw(objp);
 
+       if (likely(objp))
+               kmemcheck_slab_alloc(cachep, flags, objp, obj_size(cachep));
+
        if (unlikely((flags & __GFP_ZERO) && objp))
                memset(objp, 0, obj_size(cachep));
 
@@ -3483,6 +3538,8 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp)
        kmemleak_free_recursive(objp, cachep->flags);
        objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
 
+       kmemcheck_slab_free(cachep, objp, obj_size(cachep));
+
        /*
         * Skip calling cache_free_alien() when the platform is not numa.
         * This will avoid cache misses that happen while accessing slabp (which
@@ -3490,7 +3547,7 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp)
         * variable to skip the call, which is mostly likely to be present in
         * the cache.
         */
-       if (numa_platform && cache_free_alien(cachep, objp))
+       if (nr_online_nodes > 1 && cache_free_alien(cachep, objp))
                return;
 
        if (likely(ac->avail < ac->limit)) {
@@ -3523,7 +3580,7 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
-#ifdef CONFIG_KMEMTRACE
+#ifdef CONFIG_TRACING
 void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
 {
        return __cache_alloc(cachep, flags, __builtin_return_address(0));
@@ -3586,7 +3643,7 @@ void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 }
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 
-#ifdef CONFIG_KMEMTRACE
+#ifdef CONFIG_TRACING
 void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
                                    gfp_t flags,
                                    int nodeid)
@@ -3614,7 +3671,7 @@ __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
        return ret;
 }
 
-#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING)
 void *__kmalloc_node(size_t size, gfp_t flags, int node)
 {
        return __do_kmalloc_node(size, flags, node,
@@ -3634,7 +3691,7 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node)
        return __do_kmalloc_node(size, flags, node, NULL);
 }
 EXPORT_SYMBOL(__kmalloc_node);
-#endif /* CONFIG_DEBUG_SLAB */
+#endif /* CONFIG_DEBUG_SLAB || CONFIG_TRACING */
 #endif /* CONFIG_NUMA */
 
 /**
@@ -3666,7 +3723,7 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
 }
 
 
-#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING)
 void *__kmalloc(size_t size, gfp_t flags)
 {
        return __do_kmalloc(size, flags, __builtin_return_address(0));