On Fri, Jul 17, 2026 at 03:18:14PM -0400, Waiman Long <[email protected]> wrote: > With commit 98149f542530 ("selftests/cgroup: Add test for cpuset affinity > on controller disable"), sashiko [1] had report 3 different issues with > the new test_cpuset_affinity_on_controller_disable() test. > > 1) `cpu_set_equal` iterates over mask bytes instead of bits, ignoring > CPUs >= 8.
Inline comment
> 2) Thread synchronization logic allows the main thread to read
> uninitialized stack memory, causing test flakiness.
Hm, I cannot see it (alhtough I don't see it through), what was the
stack memory?
(test_phase is static, then re-initalized)
> 3) Test fails instead of skipping gracefully on uniprocessor systems
> or when CPU 1 is unavailable.
Interesting catch.
>
> Fix the reported issues by:
> 1) Iterates over the bit size of the mask.
> 2) Test the new ready flag for each thread to end the wait
> on the condoitional variable and eliminate the now unneeded
> AFFINITY_THREAD_A_READY and AFFINITY_THREADS_READY test phases.
But the symmetric synchronization with counter is easier to reason
about.
> 3) Return KSFT_SKIP on "cpuset.cpus" setting failure.
It'd be better to have same style with test_cpuset_prs.sh, i.e. a guard
at the beginning requesting a minimal number of CPUs. Next time...
> @@ -251,7 +251,7 @@ static int cpu_set_equal(cpu_set_t *dst, unsigned long
> mask)
> CPU_ZERO(&expected);
> assert(sizeof(mask) < CPU_SETSIZE);
>
> - for (int cpu = 0; cpu < sizeof(mask); ++cpu)
> + for (int cpu = 0; cpu < sizeof(mask) * 8; ++cpu)
> if ((1UL << cpu) & mask)
> CPU_SET(cpu, &expected);
Oh, that was my braino in how masks are stored.
Thanks for correcting me!
It should also extend the assert accordingly:
assert(sizeof(mask) * 8 < CPU_SETSIZE);
Michal
signature.asc
Description: PGP signature

