mm: Add PGREUSE counter
[linux-2.6-microblaze.git] / mm / slab_common.c
index 37d48a5..fe8b684 100644 (file)
@@ -326,6 +326,14 @@ int slab_unmergeable(struct kmem_cache *s)
        if (s->refcount < 0)
                return 1;
 
+#ifdef CONFIG_MEMCG_KMEM
+       /*
+        * Skip the dying kmem_cache.
+        */
+       if (s->memcg_params.dying)
+               return 1;
+#endif
+
        return 0;
 }
 
@@ -886,12 +894,15 @@ static int shutdown_memcg_caches(struct kmem_cache *s)
        return 0;
 }
 
-static void flush_memcg_workqueue(struct kmem_cache *s)
+static void memcg_set_kmem_cache_dying(struct kmem_cache *s)
 {
        spin_lock_irq(&memcg_kmem_wq_lock);
        s->memcg_params.dying = true;
        spin_unlock_irq(&memcg_kmem_wq_lock);
+}
 
+static void flush_memcg_workqueue(struct kmem_cache *s)
+{
        /*
         * SLAB and SLUB deactivate the kmem_caches through call_rcu. Make
         * sure all registered rcu callbacks have been invoked.
@@ -923,10 +934,6 @@ static inline int shutdown_memcg_caches(struct kmem_cache *s)
 {
        return 0;
 }
-
-static inline void flush_memcg_workqueue(struct kmem_cache *s)
-{
-}
 #endif /* CONFIG_MEMCG_KMEM */
 
 void slab_kmem_cache_release(struct kmem_cache *s)
@@ -944,8 +951,6 @@ void kmem_cache_destroy(struct kmem_cache *s)
        if (unlikely(!s))
                return;
 
-       flush_memcg_workqueue(s);
-
        get_online_cpus();
        get_online_mems();
 
@@ -955,6 +960,22 @@ void kmem_cache_destroy(struct kmem_cache *s)
        if (s->refcount)
                goto out_unlock;
 
+#ifdef CONFIG_MEMCG_KMEM
+       memcg_set_kmem_cache_dying(s);
+
+       mutex_unlock(&slab_mutex);
+
+       put_online_mems();
+       put_online_cpus();
+
+       flush_memcg_workqueue(s);
+
+       get_online_cpus();
+       get_online_mems();
+
+       mutex_lock(&slab_mutex);
+#endif
+
        err = shutdown_memcg_caches(s);
        if (!err)
                err = shutdown_cache(s);