]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - mm/slab_common.c
slub: move synchronize_sched out of slab_mutex on shrink
[mirror_ubuntu-hirsute-kernel.git] / mm / slab_common.c
index 329b03843863940f2288ea046d6b950d126c0a49..5d2f24fbafc5535997f282e6751476afdf28f83e 100644 (file)
@@ -573,6 +573,29 @@ void memcg_deactivate_kmem_caches(struct mem_cgroup *memcg)
        get_online_cpus();
        get_online_mems();
 
+#ifdef CONFIG_SLUB
+       /*
+        * In case of SLUB, we need to disable empty slab caching to
+        * avoid pinning the offline memory cgroup by freeable kmem
+        * pages charged to it. SLAB doesn't need this, as it
+        * periodically purges unused slabs.
+        */
+       mutex_lock(&slab_mutex);
+       list_for_each_entry(s, &slab_caches, list) {
+               c = is_root_cache(s) ? cache_from_memcg_idx(s, idx) : NULL;
+               if (c) {
+                       c->cpu_partial = 0;
+                       c->min_partial = 0;
+               }
+       }
+       mutex_unlock(&slab_mutex);
+       /*
+        * kmem_cache->cpu_partial is checked locklessly (see
+        * put_cpu_partial()). Make sure the change is visible.
+        */
+       synchronize_sched();
+#endif
+
        mutex_lock(&slab_mutex);
        list_for_each_entry(s, &slab_caches, list) {
                if (!is_root_cache(s))
@@ -584,7 +607,7 @@ void memcg_deactivate_kmem_caches(struct mem_cgroup *memcg)
                if (!c)
                        continue;
 
-               __kmem_cache_shrink(c, true);
+               __kmem_cache_shrink(c);
                arr->entries[idx] = NULL;
        }
        mutex_unlock(&slab_mutex);
@@ -755,7 +778,7 @@ int kmem_cache_shrink(struct kmem_cache *cachep)
        get_online_cpus();
        get_online_mems();
        kasan_cache_shrink(cachep);
-       ret = __kmem_cache_shrink(cachep, false);
+       ret = __kmem_cache_shrink(cachep);
        put_online_mems();
        put_online_cpus();
        return ret;