-
Notifications
You must be signed in to change notification settings - Fork 3k
BaseTools: Build: Balance thread concurrency with file descriptor limits #11813
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
AydenMeng
wants to merge
2
commits into
tianocore:master
Choose a base branch
from
AydenMeng:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+17
−1
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Previously, when file descriptors were exhausted in high-concurrency builds (e.g., 512 threads with 1024 FD limit), the build would hang or fail silently without clear indication of the root cause. This change catches relevant OSError instances and terminates the build, ensuring failures due to resource limits are explicit. Signed-off-by: Ayden Meng <[email protected]>
mikebeaton
reviewed
Nov 27, 2025
mikebeaton
reviewed
Nov 28, 2025
3dd9779 to
7fe81bb
Compare
mikebeaton
reviewed
Nov 28, 2025
When the number of build threads multiplied by per-thread file descriptor usage exceeds the system's open file descriptor limit, some threads may fail to acquire necessary resources (e.g., pipes or semaphores), leading to deadlocks or hangs during parallel builds. To prevent this situation, calculate the safety upper limit of concurrency by dividing the system's maximum file descriptor limit by 3 (An empirical value derived from balancing performance overhead against the theoretical number of file descriptors consumed per thread). The actual thread count is then clamped to this safe value. Other usages of ThreadNum()—such as during actual compilation or log queue creation—do not significantly contribute to file descriptor consumption. Therefore, adjusting ThreadNum() globally would be unwarranted, as it could unnecessarily restrict parallelism in stages that are not FD-bound. This ensures stable parallel builds even under constrained resource limits. Signed-off-by: Ayden Meng <[email protected]>
Member
|
I think two final ones from me: can you change the second commit subject line to 'BaseTools: Cap AutoGen thread count to avoid file descriptor exhaustion'; and can you change the newly added |
mikebeaton
approved these changes
Nov 28, 2025
ardbiesheuvel
approved these changes
Nov 28, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Problem
When the system's file descriptor limit is low (e.g., ulimit -n 1024) and the build is configured to use a high number of threads (e.g., 512), the build process can exhaust available file descriptors. This occurs because each multiprocessing worker typically consumes multiple file descriptors (for pipes, queues, semaphores, etc.).
As a result:
This issue can be confirmed via strace, which reveals failures like:
Solution
This PR introduces two complementary fixes:
Commit 31d5b3:
Explicitly catches OSError exceptions caused by file descriptor exhaustion during worker initialization or execution, logs a clear diagnostic message, and terminates the build gracefully—instead of hanging silently.
Commit 456393:
Dynamically computes a safe upper bound for the number of concurrent build threads based on the current file descriptor limit. The calculation assumes ~4 FDs per worker (3 for multiprocessing pipes + 1 for POSIX named semaphores) and caps the thread count accordingly:
Breaking change?
Impacts security?
Includes tests?
How This Was Tested
To reproduce the issue, run the following commands before starting the build (replace [THREAD_COUNT] with the actual number of threads used by your build, e.g., 16):
With the first two settings ([THREAD_COUNT] and [THREAD_COUNT * 2]), the build will likely fail or hang indefinitely due to file descriptor exhaustion (e.g., EMFILE: Too many open files), often without a clear error message.
The third setting ([THREAD_COUNT * 4]) usually provides enough file descriptors for the build to succeed.
After Applying the Patch
Under low FD limits (e.g., ulimit -Sn 16), the build will either:
Integration Instructions
N/A