On Mon, Jan 27, 2020 at 09:34:42AM -0800, Roman Gushchin wrote: > 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@xxxxxx> > --- > include/linux/memcontrol.h | 3 +- > mm/memcontrol.c | 14 +++++++-- > mm/slab.c | 18 +++++++----- > mm/slab.h | 60 ++++++++++++++++++++++++++++++++++---- > mm/slub.c | 14 +++++---- > 5 files changed, 88 insertions(+), 21 deletions(-) > > diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h > index 30bbea3f85e2..54bfb26b5016 100644 > --- a/include/linux/memcontrol.h > +++ b/include/linux/memcontrol.h > @@ -1431,7 +1431,8 @@ static inline void memcg_set_shrinker_bit(struct mem_cgroup *memcg, > } > #endif > > -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); > void memcg_kmem_put_cache(struct kmem_cache *cachep); > > #ifdef CONFIG_MEMCG_KMEM > diff --git a/mm/memcontrol.c b/mm/memcontrol.c > index 94337ab1ebe9..0e9fe272e688 100644 > --- a/mm/memcontrol.c > +++ b/mm/memcontrol.c > @@ -2896,7 +2896,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; > @@ -2952,8 +2953,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; > + } As per the reply to the previous patch: I don't understand why the objcg requires a pulse check here. As long as the memcg is alive and can be charged with memory, how can the objcg disappear?