summaryrefslogtreecommitdiff
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorRoman Gushchin <guro@fb.com>2020-08-06 23:20:56 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-08-07 11:33:24 -0700
commit964d4bd370d559d9bd8e4abc139e85d2753956fb (patch)
treeb7bf28d5cd4f81730d9fa53ec60e017feb3089aa /mm/memcontrol.c
parent286e04b8ed7a04279ae277f0f024430246ea5eec (diff)
mm: memcg/slab: save obj_cgroup for non-root slab objects
Store the obj_cgroup pointer in the corresponding place of page->obj_cgroups for each allocated non-root slab object. Make sure that each allocated object holds a reference to obj_cgroup. Objcg pointer is obtained from the memcg->objcg dereferencing in memcg_kmem_get_cache() and passed from pre_alloc_hook to post_alloc_hook. Then in case of successful allocation(s) it's getting stored in the page->obj_cgroups vector. The objcg obtaining part look a bit bulky now, but it will be simplified by next commits in the series. 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: Johannes Weiner <hannes@cmpxchg.org> Cc: Michal Hocko <mhocko@kernel.org> Cc: Tejun Heo <tj@kernel.org> Link: http://lkml.kernel.org/r/20200623174037.3951353-9-guro@fb.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index e6cd4c0d44d1..ab96a120e630 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2973,7 +2973,8 @@ static inline bool memcg_kmem_bypass(void)
* done with it, memcg_kmem_put_cache() must be called to release the
* reference.
*/
-struct kmem_cache *memcg_kmem_get_cache(struct kmem_cache *cachep)
+struct kmem_cache *memcg_kmem_get_cache(struct kmem_cache *cachep,
+ struct obj_cgroup **objcgp)
{
struct mem_cgroup *memcg;
struct kmem_cache *memcg_cachep;
@@ -3029,8 +3030,17 @@ struct kmem_cache *memcg_kmem_get_cache(struct kmem_cache *cachep)
*/
if (unlikely(!memcg_cachep))
memcg_schedule_kmem_cache_create(memcg, cachep);
- else if (percpu_ref_tryget(&memcg_cachep->memcg_params.refcnt))
+ else if (percpu_ref_tryget(&memcg_cachep->memcg_params.refcnt)) {
+ struct obj_cgroup *objcg = rcu_dereference(memcg->objcg);
+
+ if (!objcg || !obj_cgroup_tryget(objcg)) {
+ percpu_ref_put(&memcg_cachep->memcg_params.refcnt);
+ goto out_unlock;
+ }
+
+ *objcgp = objcg;
cachep = memcg_cachep;
+ }
out_unlock:
rcu_read_unlock();
return cachep;