* Re: [PATCH] memcg: flush nr_charged_bytes when the obj stock trylock fails
2026-11-12 1:32 [PATCH] memcg: flush nr_charged_bytes when the obj stock trylock fails Shakeel Butt
@ 2026-11-12 2:26 ` Muchun Song
2026-11-12 10:55 ` Vlastimil Babka (SUSE)
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Muchun Song @ 2026-11-12 2:26 UTC (permalink / raw)
To: Shakeel Butt
Cc: Andrew Morton, Johannes Weiner, David Hildenbrand, Michal Hocko,
Roman Gushchin, Vlastimil Babka, Meta kernel team, cgroups,
linux-mm, linux-kernel, Chris Mason, stable
> On Nov 12, 2026, at 09:32, Shakeel Butt <shakeel.butt@linux.dev> wrote:
>
> When interrupt code, such as an RCU callback in softirq, runs on top of
> a task that holds the obj stock lock, its trylock fails and the bytes go
> to objcg->nr_charged_bytes. Nothing empties that counter while every CPU
> using the objcg keeps it in its stock, so it can grow without limit.
>
> Users see memory.current and the "kernel" field of memory.stat keep
> growing while the cgroup's real usage does not. With memory.high or
> memory.max set, the cgroup is reclaimed, throttled or even OOM-killed
> for memory it does not use. The counter is 32-bit, so after 4 GiB it
> wraps, and those 4 GiB stay charged to the cgroup and its ancestors
> until reboot, even after the cgroup is removed.
>
> Fix it by uncharging the whole pages in nr_charged_bytes whenever the
> trylock fails.
>
> Fixes: 200577f69f29 ("memcg: objcg stock trylock without irq disabling")
> Reported-by: Chris Mason <mason@kernel.org>
> Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
> Cc: stable@vger.kernel.org
Acked-by: Muchun Song (ByteDance) <muchun.song@linux.dev>
Thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] memcg: flush nr_charged_bytes when the obj stock trylock fails
2026-11-12 1:32 [PATCH] memcg: flush nr_charged_bytes when the obj stock trylock fails Shakeel Butt
2026-11-12 2:26 ` Muchun Song
@ 2026-11-12 10:55 ` Vlastimil Babka (SUSE)
2026-11-12 14:30 ` Harry Yoo
2026-11-12 15:21 ` Johannes Weiner
3 siblings, 0 replies; 5+ messages in thread
From: Vlastimil Babka (SUSE) @ 2026-11-12 10:55 UTC (permalink / raw)
To: Shakeel Butt, Andrew Morton
Cc: Johannes Weiner, David Hildenbrand, Michal Hocko, Roman Gushchin,
Muchun Song, Meta kernel team, cgroups, linux-mm, linux-kernel,
Chris Mason, stable
On 11/12/26 02:32, Shakeel Butt wrote:
> When interrupt code, such as an RCU callback in softirq, runs on top of
> a task that holds the obj stock lock, its trylock fails and the bytes go
> to objcg->nr_charged_bytes. Nothing empties that counter while every CPU
> using the objcg keeps it in its stock, so it can grow without limit.
>
> Users see memory.current and the "kernel" field of memory.stat keep
> growing while the cgroup's real usage does not. With memory.high or
> memory.max set, the cgroup is reclaimed, throttled or even OOM-killed
> for memory it does not use. The counter is 32-bit, so after 4 GiB it
> wraps, and those 4 GiB stay charged to the cgroup and its ancestors
> until reboot, even after the cgroup is removed.
>
> Fix it by uncharging the whole pages in nr_charged_bytes whenever the
> trylock fails.
>
> Fixes: 200577f69f29 ("memcg: objcg stock trylock without irq disabling")
> Reported-by: Chris Mason <mason@kernel.org>
> Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
> Cc: stable@vger.kernel.org
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
> ---
> mm/memcontrol.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index f5f567f7d4a9..091401cecf39 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -3553,6 +3553,8 @@ static void __refill_obj_stock(struct obj_cgroup *objcg,
> int i, slot = -1, empty_slot = -1;
>
> if (!stock) {
> + nr_bytes += atomic_read(&objcg->nr_charged_bytes)
> + ? atomic_xchg(&objcg->nr_charged_bytes, 0) : 0;
> nr_pages = nr_bytes >> PAGE_SHIFT;
> nr_bytes = nr_bytes & (PAGE_SIZE - 1);
> atomic_add(nr_bytes, &objcg->nr_charged_bytes);
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] memcg: flush nr_charged_bytes when the obj stock trylock fails
2026-11-12 1:32 [PATCH] memcg: flush nr_charged_bytes when the obj stock trylock fails Shakeel Butt
2026-11-12 2:26 ` Muchun Song
2026-11-12 10:55 ` Vlastimil Babka (SUSE)
@ 2026-11-12 14:30 ` Harry Yoo
2026-11-12 15:21 ` Johannes Weiner
3 siblings, 0 replies; 5+ messages in thread
From: Harry Yoo @ 2026-11-12 14:30 UTC (permalink / raw)
To: Shakeel Butt
Cc: Andrew Morton, Johannes Weiner, David Hildenbrand, Michal Hocko,
Roman Gushchin, Muchun Song, Vlastimil Babka, Meta kernel team,
cgroups, linux-mm, linux-kernel, Chris Mason, stable
On Wed, Nov 11, 2026 at 05:32:20PM -0800, Shakeel Butt wrote:
> When interrupt code, such as an RCU callback in softirq, runs on top of
> a task that holds the obj stock lock, its trylock fails and the bytes go
> to objcg->nr_charged_bytes. Nothing empties that counter while every CPU
> using the objcg keeps it in its stock, so it can grow without limit.
>
> Users see memory.current and the "kernel" field of memory.stat keep
> growing while the cgroup's real usage does not. With memory.high or
> memory.max set, the cgroup is reclaimed, throttled or even OOM-killed
> for memory it does not use. The counter is 32-bit, so after 4 GiB it
> wraps, and those 4 GiB stay charged to the cgroup and its ancestors
> until reboot, even after the cgroup is removed.
>
> Fix it by uncharging the whole pages in nr_charged_bytes whenever the
> trylock fails.
>
> Fixes: 200577f69f29 ("memcg: objcg stock trylock without irq disabling")
> Reported-by: Chris Mason <mason@kernel.org>
> Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
> Cc: stable@vger.kernel.org
> ---
Looks good to me,
Reviewed-by: Harry Yoo (Meta) <harry@kernel.org>
> mm/memcontrol.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index f5f567f7d4a9..091401cecf39 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -3553,6 +3553,8 @@ static void __refill_obj_stock(struct obj_cgroup *objcg,
> int i, slot = -1, empty_slot = -1;
>
> if (!stock) {
> + nr_bytes += atomic_read(&objcg->nr_charged_bytes)
> + ? atomic_xchg(&objcg->nr_charged_bytes, 0) : 0;
> nr_pages = nr_bytes >> PAGE_SHIFT;
> nr_bytes = nr_bytes & (PAGE_SIZE - 1);
> atomic_add(nr_bytes, &objcg->nr_charged_bytes);
> --
> 2.53.0-Meta
--
Cheers,
Harry / Hyeonggon
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] memcg: flush nr_charged_bytes when the obj stock trylock fails
2026-11-12 1:32 [PATCH] memcg: flush nr_charged_bytes when the obj stock trylock fails Shakeel Butt
` (2 preceding siblings ...)
2026-11-12 14:30 ` Harry Yoo
@ 2026-11-12 15:21 ` Johannes Weiner
3 siblings, 0 replies; 5+ messages in thread
From: Johannes Weiner @ 2026-11-12 15:21 UTC (permalink / raw)
To: Shakeel Butt
Cc: Andrew Morton, David Hildenbrand, Michal Hocko, Roman Gushchin,
Muchun Song, Vlastimil Babka, Meta kernel team, cgroups,
linux-mm, linux-kernel, Chris Mason, stable
On Wed, Nov 11, 2026 at 05:32:20PM -0800, Shakeel Butt wrote:
> When interrupt code, such as an RCU callback in softirq, runs on top of
> a task that holds the obj stock lock, its trylock fails and the bytes go
> to objcg->nr_charged_bytes. Nothing empties that counter while every CPU
> using the objcg keeps it in its stock, so it can grow without limit.
>
> Users see memory.current and the "kernel" field of memory.stat keep
> growing while the cgroup's real usage does not. With memory.high or
> memory.max set, the cgroup is reclaimed, throttled or even OOM-killed
> for memory it does not use. The counter is 32-bit, so after 4 GiB it
> wraps, and those 4 GiB stay charged to the cgroup and its ancestors
> until reboot, even after the cgroup is removed.
>
> Fix it by uncharging the whole pages in nr_charged_bytes whenever the
> trylock fails.
>
> Fixes: 200577f69f29 ("memcg: objcg stock trylock without irq disabling")
> Reported-by: Chris Mason <mason@kernel.org>
> Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
> Cc: stable@vger.kernel.org
Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
^ permalink raw reply [flat|nested] 5+ messages in thread