We don't keep a pointer to the owner kmem cache in the memcg_cache_params struct, because we can always get the cache by reading the slot corresponding to the owner memcg in the root cache's memcg_caches array (see memcg_params_to_cache). However, this means that offline css's, which can be zombieing around for quite a long time, will occupy slots in memcg_caches arrays, making them grow larger and larger, which doesn't sound good. Therefore I'm going to make memcg release the slots on offline, which will render memcg_params_to_cache invalid. So I'm removing it and adding a back pointer to memcg_cache_params instead. Signed-off-by: Vladimir Davydov <vdavydov@xxxxxxxxxxxxx> --- include/linux/slab.h | 2 ++ mm/memcontrol.c | 20 ++++---------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/include/linux/slab.h b/include/linux/slab.h index 14888328e96b..e6e6ddb769c7 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -523,6 +523,7 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) * * Child caches will hold extra metadata needed for its operation. Fields are: * + * @cachep: cache which this struct is for * @memcg: pointer to the memcg this cache belongs to * @list: list_head for the list of all caches in this memcg * @root_cache: pointer to the global, root cache, this cache was derived from @@ -536,6 +537,7 @@ struct memcg_cache_params { struct kmem_cache *memcg_caches[0]; }; struct { + struct kmem_cache *cachep; struct mem_cgroup *memcg; struct list_head list; struct kmem_cache *root_cache; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index cc1064a504cc..aa3111ac3b7e 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2790,19 +2790,6 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg) return memcg ? memcg->kmemcg_id : -1; } -/* - * This is a bit cumbersome, but it is rarely used and avoids a backpointer - * in the memcg_cache_params struct. - */ -static struct kmem_cache *memcg_params_to_cache(struct memcg_cache_params *p) -{ - struct kmem_cache *cachep; - - VM_BUG_ON(p->is_root_cache); - cachep = p->root_cache; - return cache_from_memcg_idx(cachep, memcg_cache_id(p->memcg)); -} - #ifdef CONFIG_SLABINFO static int mem_cgroup_slabinfo_read(struct seq_file *m, void *v) { @@ -2816,7 +2803,7 @@ static int mem_cgroup_slabinfo_read(struct seq_file *m, void *v) mutex_lock(&memcg_slab_mutex); list_for_each_entry(params, &memcg->memcg_slab_caches, list) - cache_show(memcg_params_to_cache(params), m); + cache_show(params->cachep, m); mutex_unlock(&memcg_slab_mutex); return 0; @@ -2979,6 +2966,7 @@ int memcg_alloc_cache_params(struct mem_cgroup *memcg, struct kmem_cache *s, return -ENOMEM; if (memcg) { + s->memcg_params->cachep = s; s->memcg_params->memcg = memcg; s->memcg_params->root_cache = root_cache; css_get(&memcg->css); @@ -3124,7 +3112,6 @@ int __memcg_cleanup_cache_params(struct kmem_cache *s) static void memcg_unregister_all_caches(struct mem_cgroup *memcg) { - struct kmem_cache *cachep; struct memcg_cache_params *params, *tmp; if (!memcg_kmem_is_active(memcg)) @@ -3132,7 +3119,8 @@ static void memcg_unregister_all_caches(struct mem_cgroup *memcg) mutex_lock(&memcg_slab_mutex); list_for_each_entry_safe(params, tmp, &memcg->memcg_slab_caches, list) { - cachep = memcg_params_to_cache(params); + struct kmem_cache *cachep = params->cachep; + kmem_cache_shrink(cachep); if (atomic_read(&cachep->memcg_params->nr_pages) == 0) memcg_unregister_cache(cachep); -- 1.7.10.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>