[PATCH] mm: memcg-v1: fix memory.memsw.failcnt accounting

Guopeng Zhang posted 1 patch 1 month, 2 weeks ago
mm/memcontrol.c | 1 +
1 file changed, 1 insertion(+)
[PATCH] mm: memcg-v1: fix memory.memsw.failcnt accounting
Posted by Guopeng Zhang 1 month, 2 weeks ago
From: Guopeng Zhang <zhangguopeng@kylinos.cn>

Commit 0e2759afcaf9 ("page_counter: track failcnt only for legacy
cgroups") made failcnt accounting conditional on track_failcnt. It
enabled the flag for memcg->memory, but not for memcg->memsw.

Consequently, memory.memsw.failcnt remains zero when the memory+swap
limit is hit. Enable failcnt accounting for the v1 memsw counter.

Reproducer:

    CG=/sys/fs/cgroup/memory/memsw-test
    LIMIT=33554432
    mkdir "$CG"
    echo "$LIMIT" > "$CG/memory.limit_in_bytes"
    echo "$LIMIT" > "$CG/memory.memsw.limit_in_bytes"

Start a child process in the cgroup and make it allocate and touch 96 MiB
of memory, causing a memcg OOM.

    cat "$CG/memory.memsw.failcnt"

Without the patch, memory.memsw.failcnt is 0. With the patch,
memory.memsw.failcnt is greater than 0.

Fixes: 0e2759afcaf9 ("page_counter: track failcnt only for legacy cgroups")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
---
 mm/memcontrol.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6939a4fbb991..4ffe5b3733d9 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4235,6 +4235,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
 #ifdef CONFIG_MEMCG_V1
 		WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
 		memcg->memory.track_failcnt = !memcg_on_dfl;
+		memcg->memsw.track_failcnt = !memcg_on_dfl;
 		WRITE_ONCE(memcg->oom_kill_disable, READ_ONCE(parent->oom_kill_disable));
 		page_counter_init(&memcg->kmem, &parent->kmem, false);
 		page_counter_init(&memcg->tcpmem, &parent->tcpmem, false);
-- 
2.43.0
Re: [PATCH] mm: memcg-v1: fix memory.memsw.failcnt accounting
Posted by Johannes Weiner 1 month, 2 weeks ago
On Mon, Aug 10, 2026 at 03:42:47PM +0800, Guopeng Zhang wrote:
> From: Guopeng Zhang <zhangguopeng@kylinos.cn>
> 
> Commit 0e2759afcaf9 ("page_counter: track failcnt only for legacy
> cgroups") made failcnt accounting conditional on track_failcnt. It
> enabled the flag for memcg->memory, but not for memcg->memsw.
> 
> Consequently, memory.memsw.failcnt remains zero when the memory+swap
> limit is hit. Enable failcnt accounting for the v1 memsw counter.
> 
> Reproducer:
> 
>     CG=/sys/fs/cgroup/memory/memsw-test
>     LIMIT=33554432
>     mkdir "$CG"
>     echo "$LIMIT" > "$CG/memory.limit_in_bytes"
>     echo "$LIMIT" > "$CG/memory.memsw.limit_in_bytes"
> 
> Start a child process in the cgroup and make it allocate and touch 96 MiB
> of memory, causing a memcg OOM.
> 
>     cat "$CG/memory.memsw.failcnt"
> 
> Without the patch, memory.memsw.failcnt is 0. With the patch,
> memory.memsw.failcnt is greater than 0.
> 
> Fixes: 0e2759afcaf9 ("page_counter: track failcnt only for legacy cgroups")
> Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>

Acked-by: Johannes Weiner <hannes@cmpxchg.org>

Sashiko raises a valid point. kmem.tcp.limit_in_bytes is deprecated
and will warn if set, but the functionality is still there for the
time being. No need to leave it broken until it's removed.

Could you add

		memcg->tcpmem.track_failcnt = !memcg_on_dfl;

as well?

> ---
>  mm/memcontrol.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 6939a4fbb991..4ffe5b3733d9 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -4235,6 +4235,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
>  #ifdef CONFIG_MEMCG_V1
>  		WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
>  		memcg->memory.track_failcnt = !memcg_on_dfl;
> +		memcg->memsw.track_failcnt = !memcg_on_dfl;
>  		WRITE_ONCE(memcg->oom_kill_disable, READ_ONCE(parent->oom_kill_disable));
>  		page_counter_init(&memcg->kmem, &parent->kmem, false);
>  		page_counter_init(&memcg->tcpmem, &parent->tcpmem, false);
Re: [PATCH] mm: memcg-v1: fix memory.memsw.failcnt accounting
Posted by Guopeng Zhang 1 month, 2 weeks ago

在 2026/8/11 03:09, Johannes Weiner 写道:
> On Mon, Aug 10, 2026 at 03:42:47PM +0800, Guopeng Zhang wrote:
>> From: Guopeng Zhang <zhangguopeng@kylinos.cn>
>>
>> Commit 0e2759afcaf9 ("page_counter: track failcnt only for legacy
>> cgroups") made failcnt accounting conditional on track_failcnt. It
>> enabled the flag for memcg->memory, but not for memcg->memsw.
>>
>> Consequently, memory.memsw.failcnt remains zero when the memory+swap
>> limit is hit. Enable failcnt accounting for the v1 memsw counter.
>>
>> Reproducer:
>>
>>     CG=/sys/fs/cgroup/memory/memsw-test
>>     LIMIT=33554432
>>     mkdir "$CG"
>>     echo "$LIMIT" > "$CG/memory.limit_in_bytes"
>>     echo "$LIMIT" > "$CG/memory.memsw.limit_in_bytes"
>>
>> Start a child process in the cgroup and make it allocate and touch 96 MiB
>> of memory, causing a memcg OOM.
>>
>>     cat "$CG/memory.memsw.failcnt"
>>
>> Without the patch, memory.memsw.failcnt is 0. With the patch,
>> memory.memsw.failcnt is greater than 0.
>>
>> Fixes: 0e2759afcaf9 ("page_counter: track failcnt only for legacy cgroups")
>> Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
> 
> Acked-by: Johannes Weiner <hannes@cmpxchg.org>
> 
> Sashiko raises a valid point. kmem.tcp.limit_in_bytes is deprecated
> and will warn if set, but the functionality is still there for the
> time being. No need to leave it broken until it's removed.
> 
> Could you add
> 
> 		memcg->tcpmem.track_failcnt = !memcg_on_dfl;
> 
> as well?

Thanks for the review and Ack.

Agreed. I'll add

    memcg->tcpmem.track_failcnt = !memcg_on_dfl;

and update the changelog accordingly in v2.

Thanks,
Guopeng

> 
>> ---
>>  mm/memcontrol.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
>> index 6939a4fbb991..4ffe5b3733d9 100644
>> --- a/mm/memcontrol.c
>> +++ b/mm/memcontrol.c
>> @@ -4235,6 +4235,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
>>  #ifdef CONFIG_MEMCG_V1
>>  		WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
>>  		memcg->memory.track_failcnt = !memcg_on_dfl;
>> +		memcg->memsw.track_failcnt = !memcg_on_dfl;
>>  		WRITE_ONCE(memcg->oom_kill_disable, READ_ONCE(parent->oom_kill_disable));
>>  		page_counter_init(&memcg->kmem, &parent->kmem, false);
>>  		page_counter_init(&memcg->tcpmem, &parent->tcpmem, false);

Re: [PATCH] mm: memcg-v1: fix memory.memsw.failcnt accounting
Posted by Andrew Morton 1 month, 2 weeks ago
On Mon, 10 Aug 2026 15:42:47 +0800 Guopeng Zhang <guopeng.zhang@linux.dev> wrote:

> Commit 0e2759afcaf9 ("page_counter: track failcnt only for legacy
> cgroups") made failcnt accounting conditional on track_failcnt. It
> enabled the flag for memcg->memory, but not for memcg->memsw.
> 
> Consequently, memory.memsw.failcnt remains zero when the memory+swap
> limit is hit. Enable failcnt accounting for the v1 memsw counter.
> 
> Reproducer:
> 
>     CG=/sys/fs/cgroup/memory/memsw-test
>     LIMIT=33554432
>     mkdir "$CG"
>     echo "$LIMIT" > "$CG/memory.limit_in_bytes"
>     echo "$LIMIT" > "$CG/memory.memsw.limit_in_bytes"
> 
> Start a child process in the cgroup and make it allocate and touch 96 MiB
> of memory, causing a memcg OOM.
> 
>     cat "$CG/memory.memsw.failcnt"
> 
> Without the patch, memory.memsw.failcnt is 0. With the patch,
> memory.memsw.failcnt is greater than 0.

Thanks.  Nice changelog.

> Fixes: 0e2759afcaf9 ("page_counter: track failcnt only for legacy cgroups")

I'll add cc:stable to this.

AI review thinks that memcg->tcpmem.track_failcnt should receive the
same treatment:

	https://sashiko.dev/#/patchset/20260810074247.52747-1-guopeng.zhang@linux.dev
Re: [PATCH] mm: memcg-v1: fix memory.memsw.failcnt accounting
Posted by Guopeng Zhang 1 month, 2 weeks ago

在 2026/8/11 02:47, Andrew Morton 写道:
> On Mon, 10 Aug 2026 15:42:47 +0800 Guopeng Zhang <guopeng.zhang@linux.dev> wrote:
> 
>> Commit 0e2759afcaf9 ("page_counter: track failcnt only for legacy
>> cgroups") made failcnt accounting conditional on track_failcnt. It
>> enabled the flag for memcg->memory, but not for memcg->memsw.
>>
>> Consequently, memory.memsw.failcnt remains zero when the memory+swap
>> limit is hit. Enable failcnt accounting for the v1 memsw counter.
>>
>> Reproducer:
>>
>>     CG=/sys/fs/cgroup/memory/memsw-test
>>     LIMIT=33554432
>>     mkdir "$CG"
>>     echo "$LIMIT" > "$CG/memory.limit_in_bytes"
>>     echo "$LIMIT" > "$CG/memory.memsw.limit_in_bytes"
>>
>> Start a child process in the cgroup and make it allocate and touch 96 MiB
>> of memory, causing a memcg OOM.
>>
>>     cat "$CG/memory.memsw.failcnt"
>>
>> Without the patch, memory.memsw.failcnt is 0. With the patch,
>> memory.memsw.failcnt is greater than 0.
> 
> Thanks.  Nice changelog.
> 
>> Fixes: 0e2759afcaf9 ("page_counter: track failcnt only for legacy cgroups")
> 
> I'll add cc:stable to this.
> 
> AI review thinks that memcg->tcpmem.track_failcnt should receive the
> same treatment:
> 
> 	https://sashiko.dev/#/patchset/20260810074247.52747-1-guopeng.zhang@linux.dev

Yeah, tcpmem has the same issue.

I'll add

    memcg->tcpmem.track_failcnt = !memcg_on_dfl;

and update the changelog accordingly in v2.

Thanks,
Guopeng

Re: [PATCH] mm: memcg-v1: fix memory.memsw.failcnt accounting
Posted by Michal Hocko 1 month, 2 weeks ago
On Mon 10-08-26 15:42:47, Guopeng Zhang wrote:
> From: Guopeng Zhang <zhangguopeng@kylinos.cn>
> 
> Commit 0e2759afcaf9 ("page_counter: track failcnt only for legacy
> cgroups") made failcnt accounting conditional on track_failcnt. It
> enabled the flag for memcg->memory, but not for memcg->memsw.
> 
> Consequently, memory.memsw.failcnt remains zero when the memory+swap
> limit is hit. Enable failcnt accounting for the v1 memsw counter.
> 
> Reproducer:
> 
>     CG=/sys/fs/cgroup/memory/memsw-test
>     LIMIT=33554432
>     mkdir "$CG"
>     echo "$LIMIT" > "$CG/memory.limit_in_bytes"
>     echo "$LIMIT" > "$CG/memory.memsw.limit_in_bytes"
> 
> Start a child process in the cgroup and make it allocate and touch 96 MiB
> of memory, causing a memcg OOM.
> 
>     cat "$CG/memory.memsw.failcnt"
> 
> Without the patch, memory.memsw.failcnt is 0. With the patch,
> memory.memsw.failcnt is greater than 0.
> 
> Fixes: 0e2759afcaf9 ("page_counter: track failcnt only for legacy cgroups")
> Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>

Acked-by: Michal Hocko <mhocko@suse.com>
Thanks!

> ---
>  mm/memcontrol.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 6939a4fbb991..4ffe5b3733d9 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -4235,6 +4235,7 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
>  #ifdef CONFIG_MEMCG_V1
>  		WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
>  		memcg->memory.track_failcnt = !memcg_on_dfl;
> +		memcg->memsw.track_failcnt = !memcg_on_dfl;
>  		WRITE_ONCE(memcg->oom_kill_disable, READ_ONCE(parent->oom_kill_disable));
>  		page_counter_init(&memcg->kmem, &parent->kmem, false);
>  		page_counter_init(&memcg->tcpmem, &parent->tcpmem, false);
> -- 
> 2.43.0

-- 
Michal Hocko
SUSE Labs