-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Ballooning compile time with LVI mitigations #74632
Comments
These are LLVM passes. Is there any reason to believe this is a rustc bug and not an LLVM bug? |
I wouldn't say so, but a rust reproducer is the only one I have and I couldn't find a way to open an issue on the rust-lang/llvm-project fork. Apologies if I missed it. |
cc @jethrogb |
Are these crates being compiled with the MIP optimization plugin? https://github.com/intel/lvi-llvm-optimization-plugin |
Probably not |
Then I think the culprit is probably this issue in CodeGen/RDF that I reported back in April: http://lists.llvm.org/pipermail/llvm-dev/2020-April/141332.html. Looks like it hasn't been fixed yet. I'll open up a bug report and ping Krzysztof. |
Bug report created: https://bugs.llvm.org/show_bug.cgi?id=46808. Hopefully this will address the issue reported by @jberci |
I've reduced the example from the initial post to one file without external dependencies: main.rs
|
@jethrogb Would it be possible to run that example with Linux perf to see which function is responsible for adding all those cycles? |
|
So it looks like ~63% is due to the LVI load hardening pass (specifically, the greedy heuristic for inserting LFENCEs), and another ~24% comes from RDF. I take it that Rust probably does a lot of aggressive inlining and LTO, and the function being mitigated is just absolutely huge? |
Yes to all of the above. Most of the 5000-line file is one function. Is it unreasonable to expect such a case to ever be fast with LVI mitigations? |
I think it should still be possible to have fast compilation for very large functions. I'm curious about the observation that a newer |
I created a patch that should fix the overhead caused by X86LoadValueInjectionLoadHardeningPass::elimMitigatedEdgesAndNodes() A complete solution will also require a patch to address the complexity issues in RDF. |
@jberci would you be able to test your build with Scott's patch? |
Definitely. I built a plain For |
…VI) mitigations Fix for the issue raised in rust-lang/rust#74632. The current heuristic for inserting LFENCEs uses a quadratic-time algorithm. This can apparently cause substantial compilation slowdowns for building Rust projects, where functions > 5000 LoC are apparently common. The updated heuristic in this patch implements a linear-time algorithm. On a set of benchmarks, the slowdown factor for the generated code was comparable (2.55x geo mean for the quadratic-time heuristic, vs. 2.58x for the linear-time heuristic). Both heuristics offer the same security properties, namely, mitigating LVI. This patch also includes some formatting fixes. Differential Revision: https://reviews.llvm.org/D84471
…VI) mitigations Fix for the issue raised in rust-lang/rust#74632. The current heuristic for inserting LFENCEs uses a quadratic-time algorithm. This can apparently cause substantial compilation slowdowns for building Rust projects, where functions > 5000 LoC are apparently common. The updated heuristic in this patch implements a linear-time algorithm. On a set of benchmarks, the slowdown factor for the generated code was comparable (2.55x geo mean for the quadratic-time heuristic, vs. 2.58x for the linear-time heuristic). Both heuristics offer the same security properties, namely, mitigating LVI. This patch also includes some formatting fixes. Differential Revision: https://reviews.llvm.org/D84471
To summarize where we stand now, we have committed a patch to address the slowdown in the LVI LFENCE insertion algorithm. Krzysztof has committed several patches on the RDF side that reduce but may not completely eliminate the overhead for live variables analysis (see https://bugs.llvm.org/show_bug.cgi?id=46808). Maybe it would be good to take stock of where we stand right now with the compile time overhead. If the overhead remains too high, then we may need to do some more involved reworking of some of the RDF algorithms to make them more efficient. |
…VI) mitigations Fix for the issue raised in rust-lang/rust#74632. The current heuristic for inserting LFENCEs uses a quadratic-time algorithm. This can apparently cause substantial compilation slowdowns for building Rust projects, where functions > 5000 LoC are apparently common. The updated heuristic in this patch implements a linear-time algorithm. On a set of benchmarks, the slowdown factor for the generated code was comparable (2.55x geo mean for the quadratic-time heuristic, vs. 2.58x for the linear-time heuristic). Both heuristics offer the same security properties, namely, mitigating LVI. This patch also includes some formatting fixes. Differential Revision: https://reviews.llvm.org/D84471
Update LLVM This (partially?) addresses rust-lang#74632 r? @cuviper
Update LLVM This (partially?) addresses rust-lang#74632 r? @cuviper
Update LLVM This (partially?) addresses rust-lang#74632 r? @cuviper
Update LLVM This (partially?) addresses rust-lang#74632 r? `@cuviper`
…VI) mitigations Fix for the issue raised in rust-lang/rust#74632. The current heuristic for inserting LFENCEs uses a quadratic-time algorithm. This can apparently cause substantial compilation slowdowns for building Rust projects, where functions > 5000 LoC are apparently common. The updated heuristic in this patch implements a linear-time algorithm. On a set of benchmarks, the slowdown factor for the generated code was comparable (2.55x geo mean for the quadratic-time heuristic, vs. 2.58x for the linear-time heuristic). Both heuristics offer the same security properties, namely, mitigating LVI. This patch also includes some formatting fixes. Differential Revision: https://reviews.llvm.org/D84471
Ok we now have a Rust nightly that includes the patches from @scottconstable and Krzysztof. @jberci are you happy with the compile times now? |
…VI) mitigations Fix for the issue raised in rust-lang/rust#74632. The current heuristic for inserting LFENCEs uses a quadratic-time algorithm. This can apparently cause substantial compilation slowdowns for building Rust projects, where functions > 5000 LoC are apparently common. The updated heuristic in this patch implements a linear-time algorithm. On a set of benchmarks, the slowdown factor for the generated code was comparable (2.55x geo mean for the quadratic-time heuristic, vs. 2.58x for the linear-time heuristic). Both heuristics offer the same security properties, namely, mitigating LVI. This patch also includes some formatting fixes. Differential Revision: https://reviews.llvm.org/D84471
…VI) mitigations Fix for the issue raised in rust-lang/rust#74632. The current heuristic for inserting LFENCEs uses a quadratic-time algorithm. This can apparently cause substantial compilation slowdowns for building Rust projects, where functions > 5000 LoC are apparently common. The updated heuristic in this patch implements a linear-time algorithm. On a set of benchmarks, the slowdown factor for the generated code was comparable (2.55x geo mean for the quadratic-time heuristic, vs. 2.58x for the linear-time heuristic). Both heuristics offer the same security properties, namely, mitigating LVI. This patch also includes some formatting fixes. Differential Revision: https://reviews.llvm.org/D84471
…VI) mitigations Fix for the issue raised in rust-lang/rust#74632. The current heuristic for inserting LFENCEs uses a quadratic-time algorithm. This can apparently cause substantial compilation slowdowns for building Rust projects, where functions > 5000 LoC are apparently common. The updated heuristic in this patch implements a linear-time algorithm. On a set of benchmarks, the slowdown factor for the generated code was comparable (2.55x geo mean for the quadratic-time heuristic, vs. 2.58x for the linear-time heuristic). Both heuristics offer the same security properties, namely, mitigating LVI. This patch also includes some formatting fixes. Differential Revision: https://reviews.llvm.org/D84471
As far as I can tell, this has been resolved, so closing the issue. Please let me know if this is not the case. |
…VI) mitigations Fix for the issue raised in rust-lang/rust#74632. The current heuristic for inserting LFENCEs uses a quadratic-time algorithm. This can apparently cause substantial compilation slowdowns for building Rust projects, where functions > 5000 LoC are apparently common. The updated heuristic in this patch implements a linear-time algorithm. On a set of benchmarks, the slowdown factor for the generated code was comparable (2.55x geo mean for the quadratic-time heuristic, vs. 2.58x for the linear-time heuristic). Both heuristics offer the same security properties, namely, mitigating LVI. This patch also includes some formatting fixes. Differential Revision: https://reviews.llvm.org/D84471
There seems to be a significant compile time regression when using the LVI mitigation passes on some crates. The smallest case I could come up with is:
TOML:
This happens with the
x86_64-fortanix-unknown-sgx
target, but also without it with the following codegen options (.cargo/config.toml
):Expected:
Without the
config.toml
on a vanilla rustup-installed nightly, acargo clean && cargo build
takes a second or two.Instead:
With LVI mitigations enabled, compile time explodes to about 35 minutes on my machine.
If I disable linking dead code, it drops to 2 minutes, although that's mostly because the sample above is simple. Using shorter uints (e.g. the ones commented out above) makes it drop further still, but compile time still noticeably depends on the uint length.
Using a newer version of the
uint
crate (e.g. 0.4.1) also seems to solve the issue. The main difference that I could find is that the older version uses inline assembly. Not sure if that's a red herring or not.Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: