Re: [PATCH] selftests/cgroup: convert cg_read_key_*() helpers to s64
From: Wilson Felipe Pereira
Date: Fri Oct 23 2026 - 20:24:25 EST
Tejun Heo <tj@xxxxxxxxxx> writes:
> Hello, Wilson.
>
> The following is a Claude-generated review.
>
> On Thu, Oct 22, 2026 at 04:28:57AM +0000, Wilson Felipe Pereira wrote:
>> On 32-bit platforms, cg_read_key_long() relies on atol(), which returns a
>> 32-bit signed long. When values in memory.stat or event counters exceed
>> 2.14GB (such as on 32-bit systems with large memory), the parsed value
>> overflows and wraps into negative numbers, leading to subtle bugs and
>> false test failures.
>
> On 32-bit, glibc's atol() saturates at LONG_MAX instead of wrapping:
> atol("3000000000") returns 2147483647. Event counters are counts, not
> bytes. No test reads a value near 2^31 from its cgroups, so the false
> failures are hypothetical. Can the description be updated to match?
>
> cg_read_long() and cg_read_long_fd() still use atol() and return long.
> They read memory.current, memory.peak and the swap counters, which the
> same reasoning covers.
>
>> - Migrate helper functions (get_cg_wb_count(), get_zswpout(),
>> get_zswap_incomp(), wait_for_writeback(), and cg_check_freezetime())
>> and their callers to s64.
>
> In test_freezer.c, only test_cgfreezer_time_empty() is converted.
> test_cgfreezer_time_simple(), _populate(), _migrate(), _parent(),
> _child() and _nested() still store cg_check_freezetime() results in
> long and print them with %ld. In test_cpu.c, overprovision_validate()
> still computes "long delta" from two s64 usage values. A 32-bit build
> with -Wshorten-64-to-32 flags all of these.
>
>> rebased on top of mm-stable to complete the s64 conversion across the
>> cgroup selftests (including updating test_no_kmem_bypass() to s64).
>
> This doesn't apply to mainline. The test_zswap.c hunks depend on the
> test_zswap fixes in mm-stable, which aren't in mainline yet. The
> tcp_client() hunk in test_memcontrol.c conflicts with eb69e955de7b
> ("selftests: cgroup: make test_memcg_sock check flushed sock stats"),
> which went in through the cgroup tree for v7.4. Can it be rebased on
> v7.4-rc1 once that's out?
>
>> +typedef signed long long s64;
>
> This is the main problem. The KVM selftests build libcgroup too:
> kvm/Makefile.kvm includes ../cgroup/lib/libcgroup.mk and links
> cgroup_util.o into every KVM test, and access_tracking_perf_test.c
> includes cgroup_util.h. That build uses -I tools/include, and
> tools/include/linux/types.h has "typedef int64_t s64;", which is long
> on 64-bit.
>
> cgroup_util.c then fails with "typedef redefinition with different
> types ('long long' vs 'int64_t' (aka 'long'))", so none of the KVM
> selftests build on 64-bit. Maybe use int64_t with PRId64 from
> <inttypes.h> instead of the local typedef and %lld?
>
>> -
>> ret = KSFT_PASS;
>
> The blank line removal is unrelated to the conversion, same for the one
> in test_cpu.c.
>
>> + ksft_print_msg("debug: zswpout=%lld zswapped=%lld zswap_b=%lld\n",
>> + zswpout, zswapped, zswap_b);
>
> The continuation line was aligned with the opening parenthesis before
> and now isn't.
>
> Thanks.
Thanks for the review and I'm sorry for the build failures! I believe I
messed up with I rebased it on mm-stable and didn't check all places
that had changed.
I've updated the patch locally to:
* Use `typedef int64_t s64` and to use `PRId64` from <inttypes.h>,
similar to how KVM selftests are using, while fixing the build
failures.
* Convert cg_read_long(), cg_read_long_fd(), and cg_write_numeric() to
s64 along with the remaining callers in test_freezer.c, test_cpu.c,
test_hugetlb_memcg.c, test_kmem.c, test_memcontrol.c, and
test_zswap.c.
* Update the commit description to reflect atol() clamping at LONG_MAX
and clean up the whitespace changes.
I'll wait until 7.4-rc1 is out and send the v2 that applies cleanly on
mm-stable and cgroup tree.
Thanks!