On Tue, May 28, 2019 at 08:08:28PM +0300, Vladimir Davydov wrote: > Hello Roman, > > On Tue, May 21, 2019 at 01:07:33PM -0700, Roman Gushchin wrote: > > This commit makes several important changes in the lifecycle > > of a non-root kmem_cache, which also affect the lifecycle > > of a memory cgroup. > > > > Currently each charged slab page has a page->mem_cgroup pointer > > to the memory cgroup and holds a reference to it. > > Kmem_caches are held by the memcg and are released with it. > > It means that none of kmem_caches are released unless at least one > > reference to the memcg exists, which is not optimal. > > > > So the current scheme can be illustrated as: > > page->mem_cgroup->kmem_cache. > > > > To implement the slab memory reparenting we need to invert the scheme > > into: page->kmem_cache->mem_cgroup. > > > > Let's make every page to hold a reference to the kmem_cache (we > > already have a stable pointer), and make kmem_caches to hold a single > > reference to the memory cgroup. > > Is there any reason why we can't reference both mem cgroup and kmem > cache per each charged kmem page? I mean, > > page->mem_cgroup references mem_cgroup > page->kmem_cache references kmem_cache > mem_cgroup references kmem_cache while it's online > > TBO it seems to me that not taking a reference to mem cgroup per charged > kmem page makes the code look less straightforward, e.g. as you > mentioned in the commit log, we have to use mod_lruvec_state() for memcg > pages and mod_lruvec_page_state() for root pages. I think I completely missed the point here. In the following patch you move kmem caches from a child to the parent cgroup on offline (aka reparent them). That's why you can't maintain page->mem_cgroup. Sorry for misunderstanding.