Re: [PATCH v2 2/2] selftests/cgroup: test_zswap: fix implicit unsigned promotion bug in test_no_kmem_bypass

Michal Koutný <[email protected]>
Newsgroups org.kvack.linux-mm,org.kernel.vger.cgroups,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest
Message-ID <[email protected]>
On Mon, Aug 24, 2026 at 03:33:58AM +0000, Wilson Felipe Pereira <[email protected]> wrote:
> In test_no_kmem_bypass(), delta (stored_pages * page_size - zswapped) is
> checked against stored_pages * page_size / 4 to verify that the pages
> pushed to zswap belong to the test memory cgroup.
> 
> Due to slight stat update timing differences, delta can evaluate to a small
> negative number (e.g. -5MB out of 1GB). Because delta is declared as a
> signed int and stored_pages is an unsigned size_t, C's usual arithmetic
> conversions implicitly promote a negative delta to a large unsigned 64-bit
> integer, causing `delta < stored_pages * page_size / 4` to falsely evaluate
> to 0 and fail the test.
> 
> Fix this by declaring zswapped and delta as signed longs and comparing
> against a signed threshold, ensuring negative deltas correctly evaluate
> to true.
> 
> Fixes: a549f9f31561a ("selftests: cgroup: add test_zswap with no kmem bypass test")
> Signed-off-by: Wilson Felipe Pereira <[email protected]>
> ---
>  tools/testing/selftests/cgroup/test_zswap.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
> index a7ff525c1267..15cc1dfdd1f4 100644
> --- a/tools/testing/selftests/cgroup/test_zswap.c
> +++ b/tools/testing/selftests/cgroup/test_zswap.c
> @@ -621,9 +621,11 @@ static int test_no_kmem_bypass(const char *root)
>  			break;
>  		/* If memory was pushed to zswap, verify it belongs to memcg */
>  		if (stored_pages > stored_pages_threshold) {
> -			int zswapped = cg_read_key_long(test_group, "memory.stat", "zswapped ");
> -			int delta = stored_pages * page_size - zswapped;
> -			int result_ok = delta < stored_pages * page_size / 4;
> +			long zswapped = cg_read_key_long(
> +				test_group, "memory.stat", "zswapped ");
> +			long delta = stored_pages * page_size - zswapped;
> +			long max_delta = (long)(stored_pages * page_size / 4);
> +			int result_ok = delta < max_delta;

I'd rewrite it like below for higher type confidence (mainly, an explict
cast of stored_pages so that subtraction is signed; possibly, implicit
cast of expression assinged to max_delta):

			long delta = (long)stored_pages * page_size - zswapped;
			long max_delta = stored_pages * page_size / 4;


>  
>  			ret = result_ok ? KSFT_PASS : KSFT_FAIL;
			ret = (delta < max_delta) ? KSFT_PASS : KSFT_FAIL;

Thanks,
Michal
signature.asc (application/pgp-signature, 265 B)
-----BEGIN PGP SIGNATURE-----

iJEEABYKADkWIQRCE24Fn/AcRjnLivR+PQLnlNv4CAUCaow68xsUgAAAAAAEAA5t
YW51MiwyLjUrMS4xMiwyLDIACgkQfj0C55Tb+Ah3wQEAkD4CY79HnHFL3zUOh2xO
fMcsSq7vsvnmYX7s4mYh8CsBAMi2iZwoDAROyEEUXSL3lUZmgimfzFx6ViqPPxyO
Z8UD
=UNwY
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.