]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - mm/slab_common.c
UBUNTU: Start new release
[mirror_ubuntu-zesty-kernel.git] / mm / slab_common.c
index 71f0b28a1bec8bc58a479f7c53343b647bcf5f24..ae323841adb1ac76052eb6536aa2a3acc36b88e3 100644 (file)
@@ -404,6 +404,12 @@ kmem_cache_create(const char *name, size_t size, size_t align,
                goto out_unlock;
        }
 
+       /* Refuse requests with allocator specific flags */
+       if (flags & ~SLAB_FLAGS_PERMITTED) {
+               err = -EINVAL;
+               goto out_unlock;
+       }
+
        /*
         * Some allocators will constraint the set of valid flags to a subset
         * of all flags. We expect them to define CACHE_CREATE_MASK in this
@@ -533,8 +539,8 @@ void memcg_create_kmem_cache(struct mem_cgroup *memcg,
 
        s = create_cache(cache_name, root_cache->object_size,
                         root_cache->size, root_cache->align,
-                        root_cache->flags, root_cache->ctor,
-                        memcg, root_cache);
+                        root_cache->flags & CACHE_CREATE_MASK,
+                        root_cache->ctor, memcg, root_cache);
        /*
         * If we could not create a memcg cache, do not complain, because
         * that's not critical at all as we can always proceed with the root
@@ -573,6 +579,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 +613,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 +784,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;