mm: memcg/slab: use a single set of kmem_caches for all allocations
Instead of having two sets of kmem_caches: one for system-wide and non-accounted allocations and the second one shared by all accounted allocations, we can use just one. The idea is simple: space for obj_cgroup metadata can be allocated on demand and filled only for accounted allocations. It allows to remove a bunch of code which is required to handle kmem_cache clones for accounted allocations. There is no more need to create them, accumulate statistics, propagate attributes, etc. It's a quite significant simplification. Also, because the total number of slab_caches is reduced almost twice (not all kmem_caches have a memcg clone), some additional memory savings are expected. On my devvm it additionally saves about 3.5% of slab memory. [guro@fb.com: fix build on MIPS] Link: http://lkml.kernel.org/r/20200717214810.3733082-1-guro@fb.com Suggested-by: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Roman Gushchin <guro@fb.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Reviewed-by: Vlastimil Babka <vbabka@suse.cz> Reviewed-by: Shakeel Butt <shakeelb@google.com> Cc: Christoph Lameter <cl@linux.com> Cc: Michal Hocko <mhocko@kernel.org> Cc: Tejun Heo <tj@kernel.org> Cc: Naresh Kamboju <naresh.kamboju@linaro.org> Link: http://lkml.kernel.org/r/20200623174037.3951353-18-guro@fb.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
15999eef7f
commit
10befea91b
@@ -2800,6 +2800,26 @@ static void commit_charge(struct page *page, struct mem_cgroup *memcg)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMCG_KMEM
|
||||
int memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s,
|
||||
gfp_t gfp)
|
||||
{
|
||||
unsigned int objects = objs_per_slab_page(s, page);
|
||||
void *vec;
|
||||
|
||||
vec = kcalloc_node(objects, sizeof(struct obj_cgroup *), gfp,
|
||||
page_to_nid(page));
|
||||
if (!vec)
|
||||
return -ENOMEM;
|
||||
|
||||
if (cmpxchg(&page->obj_cgroups, NULL,
|
||||
(struct obj_cgroup **) ((unsigned long)vec | 0x1UL)))
|
||||
kfree(vec);
|
||||
else
|
||||
kmemleak_not_leak(vec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a pointer to the memory cgroup to which the kernel object is charged.
|
||||
*
|
||||
@@ -2826,7 +2846,10 @@ struct mem_cgroup *mem_cgroup_from_obj(void *p)
|
||||
|
||||
off = obj_to_index(page->slab_cache, page, p);
|
||||
objcg = page_obj_cgroups(page)[off];
|
||||
return obj_cgroup_memcg(objcg);
|
||||
if (objcg)
|
||||
return obj_cgroup_memcg(objcg);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* All other pages use page->mem_cgroup */
|
||||
|
Reference in New Issue
Block a user