Skip to content

Conversation

@mitchellallison
Copy link
Contributor

Fix coreCount on Linux when using cgroup v2 with CFS throttling disabled

Motivation:

When using swift-nio on Linux with cgroup v2 enabled, but with CFS throttling disabled, it falls back to attempting to read the cpuset file at the cgroup v1 path. This does not exist, which in turns falls back to returning _SC_NPROCESSORS_ONLN, which will return the total number of cores available (ignoring cgroup assignments).

This has unexpected effects, including the default behaviour of starting the MultiThreadedEventLoopGroup.singleton with significantly more event loops than cores available to the workload.

Modifications:

  • Adds SystemCalls.statfs, and associated constants, to determine the cgroup version.
  • Adds Linux.cgroupVersion() API to expose cgroup version.
  • Adds Linux.cgroupV2MountPoint variable to determine the cgroup v2 mount point.
  • Adds Linux.cpuSetPathV1 & Linux.cpuSetPathV2 (and Linux.cpuSetPath convenience) variables to determine the correct cpu set path.
  • Alters System.coreCount to use the appropriate logic from above to ensure that cpuset.cpus is parsed from the correct location.

Result:

Linux.coreCount should correctly parse and return the core count on Linux cgroup v2 enabled systems (when CFS throttling is disabled), while maintaining correctness for other configurations.

@Lukasa Lukasa added the 🔨 semver/patch No public API change. label Dec 12, 2025
@Lukasa
Copy link
Contributor

Lukasa commented Dec 18, 2025

These compiler crashes on the static SDK are, unfortunately, relevant. They are hit when compiling "@one-time initialization function for (sysStatfs in _1CE543A537E680768F082F96BA7810FB)", which we've added here. This is probably because of the confusion around the type and function with the same name. I'd recommend adding a little thunk function in CNIOLinux which does the dispatch in order to try to work around it.

@FranzBusch
Copy link
Member

This is great. @mitchellallison are you interested in also applying this change to https://github.com/swiftlang/swift-platform-executors? Which also has a core count calculating method.

@mitchellallison
Copy link
Contributor Author

mitchellallison commented Dec 19, 2025

These compiler crashes on the static SDK are, unfortunately, relevant. They are hit when compiling "@one-time initialization function for (sysStatfs in _1CE543A537E680768F082F96BA7810FB)", which we've added here. This is probably because of the confusion around the type and function with the same name. I'd recommend adding a little thunk function in CNIOLinux which does the dispatch in order to try to work around it.

@Lukasa thanks for the pointer! 20e9453 seems to resolve it. Also filed swiftlang/swift#86149.

@mitchellallison
Copy link
Contributor Author

This is great. @mitchellallison are you interested in also applying this change to https://github.com/swiftlang/swift-platform-executors? Which also has a core count calculating method.

@FranzBusch I wasn't aware of this effort, but sure! Looks like this code was mostly lifted from the implementation here, so should be fairly straightforward to port across.

@Lukasa
Copy link
Contributor

Lukasa commented Jan 2, 2026

I'm afraid we now have some failing CXX interop tests cases.

@mitchellallison
Copy link
Contributor Author

I'm afraid we now have some failing CXX interop tests cases.

Indeed, looks like I was missing an extern. Validated this across the CXX interop test cases, as well as with the regular tests.

@Lukasa Lukasa merged commit e3d5c56 into apple:main Jan 5, 2026
54 checks passed
@mitchellallison mitchellallison deleted the fix-cgroups-v2-core-count branch January 5, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants