Skip to content
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

libstore: Add load-limit setting to dynamically control parallelism #6855

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/manual/src/release-notes/rl-next.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Release X.Y (202?-??-??)

* Add new `load-limit` setting to control the `-lN` flag of GNU Make.
3 changes: 3 additions & 0 deletions src/libstore/build/local-derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,9 @@ void LocalDerivationGoal::initEnv()
/* The maximum number of cores to utilize for parallel building. */
env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();

/* If the load average is greater than N, disable parallel building. */
env["NIX_LOAD_LIMIT"] = (format("%d") % settings.loadLimit).str();

initTmpDir();

/* Compatibility hack with Nix <= 0.7: if this is a fixed-output
Expand Down
24 changes: 24 additions & 0 deletions src/libstore/globals.hh
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,30 @@ public:
)",
{"build-cores"}, false};

Setting<unsigned int> loadLimit{
this,
getDefaultCores(),
"load-limit",
R"(
Sets the value of the `NIX_LOAD_LIMIT` environment variable in the
invocation of builders. Builders can use this value at their discretion
to dynamically control the amount of parallelism with respect to the
machine's load average. For instance, in Nixpkgs, if this value is >0,
the builder passes the `-lN` flag to GNU Make. In this case, if the
load average of the machine exceeds `N`, the amount of parallelism will
be dynamically reduced to 1.
Comment on lines +153 to +156
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
machine's load average. For instance, in Nixpkgs, if this value is >0,
the builder passes the `-lN` flag to GNU Make. In this case, if the
load average of the machine exceeds `N`, the amount of parallelism will
be dynamically reduced to 1.
machine's load average.
For instance, a builder could use the value to set the `-l` flag to GNU Make.
In this case, if the load average of the machine exceeds `NIX_LOAD_LIMIT`, the amount of parallelism will be dynamically reduced to 1.

No need to point to a specific implementation, as we'd have to keep track of if that statement is still correct.


By default, it is set to the number of cores available to Nix.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Along the lines of #7091 we may want to instead fall back to the cores setting and only then system cores, i.e. settings.buildCores.


On busy machines where Nix co-exists with other workloads, parallelism
may not work as intended. For example, consider a 64 core machine whose
load average is 24 and where Nix is limited to 8 cores. By default,
`-j8 -l8` will be passed to GNU Make. Since the load average exceeds 8,
Comment on lines +162 to +163
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
load average is 24 and where Nix is limited to 8 cores. By default,
`-j8 -l8` will be passed to GNU Make. Since the load average exceeds 8,
load average is 24 and where Nix is limited to 8 cores. By default,
`-j8 -l8` would be passed to GNU Make. Since the load average exceeds 8,

Since we're still in the example where the builder is a Make invocation.

no parallelism will take place despite the fact that 8 cores are
available. In this case, `load-limit` should be set to `0` to prevent
the `-lN` flag from being passed to GNU Make.
Comment on lines +165 to +166
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
available. In this case, `load-limit` should be set to `0` to prevent
the `-lN` flag from being passed to GNU Make.
available. In this case, `load-limit` should be set to `-1`, which GNU Make would interpret as "no limit".

Setting it to zero won't necessarily prevent it to be passed to Make, that would depend on how a builder is implemented. Right now -l is not set at all in Nixpkgs builders.
Make's source code says that the -1 (default) means no limit.

)"};

/* Read-only mode. Don't copy stuff to the store, don't change
the database. */
bool readOnlyMode = false;
Expand Down
1 change: 1 addition & 0 deletions src/nix-build/nix-build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ static void main_nix_build(int argc, char * * argv)
env["NIX_BUILD_TOP"] = env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = *tmp;
env["NIX_STORE"] = store->storeDir;
env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores);
env["NIX_LOAD_LIMIT"] = std::to_string(settings.loadLimit);

auto passAsFile = tokenizeString<StringSet>(getOr(drv.env, "passAsFile", ""));

Expand Down