Merge tag 'usercopy-v5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees...
[linux-2.6-block.git] / mm / slab_common.c
index 807490fe217a97d51b4575d19db8b0e04a40e000..6491c3a418053870ae600830f82fa7f72e16a58d 100644 (file)
@@ -981,6 +981,43 @@ int kmem_cache_shrink(struct kmem_cache *cachep)
 }
 EXPORT_SYMBOL(kmem_cache_shrink);
 
+/**
+ * kmem_cache_shrink_all - shrink a cache and all memcg caches for root cache
+ * @s: The cache pointer
+ */
+void kmem_cache_shrink_all(struct kmem_cache *s)
+{
+       struct kmem_cache *c;
+
+       if (!IS_ENABLED(CONFIG_MEMCG_KMEM) || !is_root_cache(s)) {
+               kmem_cache_shrink(s);
+               return;
+       }
+
+       get_online_cpus();
+       get_online_mems();
+       kasan_cache_shrink(s);
+       __kmem_cache_shrink(s);
+
+       /*
+        * We have to take the slab_mutex to protect from the memcg list
+        * modification.
+        */
+       mutex_lock(&slab_mutex);
+       for_each_memcg_cache(c, s) {
+               /*
+                * Don't need to shrink deactivated memcg caches.
+                */
+               if (s->flags & SLAB_DEACTIVATED)
+                       continue;
+               kasan_cache_shrink(c);
+               __kmem_cache_shrink(c);
+       }
+       mutex_unlock(&slab_mutex);
+       put_online_mems();
+       put_online_cpus();
+}
+
 bool slab_is_available(void)
 {
        return slab_state >= UP;