]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: cpu_topo: work around a small bug in musl's CPU_ISSET()
authorWilly Tarreau <w@1wt.eu>
Sat, 6 Sep 2025 08:50:31 +0000 (10:50 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 6 Sep 2025 09:05:52 +0000 (11:05 +0200)
As found in GH issue #3103, CPU_ISSET() on musl 1.25 doesn't match the man
page which says it's returning an int. The reason is pretty simple, it's
a macro that operates on the bits directly and returns the result of the
bit field applied to the mask as an unsigned long. Bits above 31 will
simply be dropped if returned as an int, which causes CPUs 32..63 to
appear as absent from cpu_sets.

The fix is trivial, it consists in just comparing the result against zero
(i.e. turning it to a boolean), but before it's merged and deployed we'll
have to face such deployments, so better implement the same workaround
in the code here since we have access to the raw long value.

This workaround should be backported to 3.0.

src/cpuset.c

index 5b23f15031bf1c0ed0600448f7061a1d589daecc..f85c31b9c967dabff6cb18eadd1ade56ab354e9d 100644 (file)
@@ -77,7 +77,10 @@ int ha_cpuset_isset(const struct hap_cpuset *set, int cpu)
                return 0;
 
 #if defined(CPUSET_USE_CPUSET) || defined(CPUSET_USE_FREEBSD_CPUSET)
-       return CPU_ISSET(cpu, &set->cpuset);
+       /* Turn to boolean because musl directly returns the mask as a
+        * a long instead of an int, hence loses bits 32+.
+        */
+       return !!CPU_ISSET(cpu, &set->cpuset);
 
 #elif defined(CPUSET_USE_ULONG)
        return !!(set->cpuset & (0x1 << cpu));