Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

memcg: no refilling stock from obj_cgroup_release

obj_cgroup_release is called when all the references to the objcg have
been released i.e. no more memory objects are pointing to it. Most
probably objcg->memcg will be pointing to some ancestor memcg. In
obj_cgroup_release(), the kernel calls obj_cgroup_uncharge_pages() which
refills the local stock.

There is no need to refill the local stock with some ancestor memcg and
flush the local stock. Let's decouple obj_cgroup_release() from the local
stock by uncharging instead of refilling. One additional benefit of this
change is that it removes the requirement to only call obj_cgroup_put()
outside of local_lock.

Link: https://lkml.kernel.org/r/20250404013913.1663035-6-shakeel.butt@linux.dev
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Shakeel Butt and committed by
Andrew Morton
b6d04711 cbc09144

+11 -4
+11 -4
mm/memcontrol.c
··· 129 129 return cgroup_memory_nokmem; 130 130 } 131 131 132 - static void obj_cgroup_uncharge_pages(struct obj_cgroup *objcg, 133 - unsigned int nr_pages); 132 + static void memcg_uncharge(struct mem_cgroup *memcg, unsigned int nr_pages); 134 133 135 134 static void obj_cgroup_release(struct percpu_ref *ref) 136 135 { ··· 162 163 WARN_ON_ONCE(nr_bytes & (PAGE_SIZE - 1)); 163 164 nr_pages = nr_bytes >> PAGE_SHIFT; 164 165 165 - if (nr_pages) 166 - obj_cgroup_uncharge_pages(objcg, nr_pages); 166 + if (nr_pages) { 167 + struct mem_cgroup *memcg; 168 + 169 + memcg = get_mem_cgroup_from_objcg(objcg); 170 + mod_memcg_state(memcg, MEMCG_KMEM, -nr_pages); 171 + memcg1_account_kmem(memcg, -nr_pages); 172 + if (!mem_cgroup_is_root(memcg)) 173 + memcg_uncharge(memcg, nr_pages); 174 + mem_cgroup_put(memcg); 175 + } 167 176 168 177 spin_lock_irqsave(&objcg_lock, flags); 169 178 list_del(&objcg->list);