]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
memcg: fix slab accounting in refill_obj_stock() trylock path
authorHao Li <hao.li@linux.dev>
Thu, 26 Feb 2026 11:51:37 +0000 (19:51 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 4 Mar 2026 17:44:23 +0000 (09:44 -0800)
In the trylock path of refill_obj_stock(), mod_objcg_mlstate() should use
the real alloc/free bytes (i.e., nr_acct) for accounting, rather than
nr_bytes.

The user-visible impact is that the NR_SLAB_RECLAIMABLE_B and
NR_SLAB_UNRECLAIMABLE_B stats can end up being incorrect.

For example, if a user allocates a 6144-byte object, then before this
fix efill_obj_stock() calls mod_objcg_mlstate(..., nr_bytes=2048), even
though it should account for 6144 bytes (i.e., nr_acct).

When the user later frees the same object with kfree(),
refill_obj_stock() calls mod_objcg_mlstate(..., nr_bytes=6144).  This
ends up adding 6144 to the stats, but it should be applying -6144
(i.e., nr_acct) since the object is being freed.

Link: https://lkml.kernel.org/r/20260226115145.62903-1-hao.li@linux.dev
Fixes: 200577f69f29 ("memcg: objcg stock trylock without irq disabling")
Signed-off-by: Hao Li <hao.li@linux.dev>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Vlastimil Babka <vbabka@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/memcontrol.c

index a52da3a5e4fd91a333ec041711d5a9e177446b2a..772bac21d15584ce495cba6ad2eebfa7f693677f 100644 (file)
@@ -3086,7 +3086,7 @@ static void refill_obj_stock(struct obj_cgroup *objcg, unsigned int nr_bytes,
 
        if (!local_trylock(&obj_stock.lock)) {
                if (pgdat)
-                       mod_objcg_mlstate(objcg, pgdat, idx, nr_bytes);
+                       mod_objcg_mlstate(objcg, pgdat, idx, nr_acct);
                nr_pages = nr_bytes >> PAGE_SHIFT;
                nr_bytes = nr_bytes & (PAGE_SIZE - 1);
                atomic_add(nr_bytes, &objcg->nr_charged_bytes);