-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Bundle assemblies at 4K for linux arm64 #41809
Conversation
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @swaroop-sridhar, @agocke |
|
||
if (IsLinux && Arch == Architecture.Arm64) | ||
{ | ||
// On ARM64, we use adrp; add instructions to encode pointers in the instruction stream. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment needs a little more explanation; that:
- R2R assemblies from bundle are loaded on Linux via direct mmap() + offset fixups
- R2R code sections will be individually mapped, adjusted for offset within the bundle + offset within the assembly and explicitly fixed up at load time.
- Only on ARM64 the fixup logic is special and uses
ardp
... - Only Linux ARM64 R2R assemblies need to be aligned, but here we align all assemblies for simplicity
- Removing the alignment requirement is tracked by [Please file an issue in 6.0].
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the information to the design doc too, in this section. Add a Linux-ARM64 limitation, in addition to Windows limitations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I filed #41832, updated the comment, and am updating the docs at dotnet/designs#156.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much, looks good.
To fix ARM64 Linux behavior. See dotnet/runtime#41809.
@@ -29,13 +29,29 @@ public class Bundler | |||
readonly TargetInfo Target; | |||
readonly BundleOptions Options; | |||
|
|||
// Assemblies are 16 bytes aligned, so that their sections can be memory-mapped cache aligned. | |||
public const int AssemblyAlignment = 16; | |||
// Temporary overload to avoid breaking the SDK build. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we want to break the SDK build? That is, don't we want the insertion that brings this into the SDK to be accompanied with our change on the SDK side?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would block dependency flow from runtime -> SDK until that change went in, which might be nice to avoid in case there are other fixes going through. If temporarily blocking it is ok, I'll remove this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will only block ingestion of 6.0 bits right? That seems fine to me. We just have to make sure to have the change ready on the SDK side and move somewhat quickly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this as discussed. The plan is to make the SDK change quickly so that the dependency flow is not blocked for long.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also need the change migrated to 5.0 branches in both repos, isn't it? Can we briefly take breaking changes there too?
In SDK, it is typical to only checkin to the 5.0 branch release, and let the change flow into master branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The SDK's invocation of the bundler needs to pass in the architecture argument, but it can only do so when this change flows into the SDK through HostModel version update. Given the position of Architecture
argument, this looks like it'll break the SDK integration job; Isn't it?. So, we have the following options:
- Make the update as part of SDK integration commit
- Make the update in two steps -- once SDK gets a chance to update.
In this case, the change is small, and its OK to follow the former approach. But, we've followed the latter approach so far for HostModel/SDK interdependencies (originally per Nick's recommendation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why he suggested (2), but I rather prefer (1), as it removes the possibility of accidentally dropping the corresponding change somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nick suggested (2) because the SDK parts of the change are typically non-trivial, and they could be independently reviewed in a normal PR, rather than in the automated integration job, and because they can be independently reverted if there's a problem without affecting the other parts of integration.
But in this case, the change on the SDK side is very small, so I'm fine with (1).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. For larger changes (2) could definitely be appropriate, especially if we're concerned that CI wouldn't fully validate the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be clear - I do plan to get the change reviewed in a normal PR, not in the automated job. I'll include a manual dependency update in my PR, but the automated flow will be blocked until my PR is merged.
public readonly Version FrameworkVersion; | ||
public readonly uint BundleVersion; | ||
public readonly BundleOptions DefaultOptions; | ||
public readonly int AssemblyAlignment; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to store the AssemblyAlignment in a field? It looks like it could be a calculated property based on the Arch. Moreover, do we need to store it on TargetInfo
at all? It's not really a property of the target info. It was previously stored in Bundler.cs, which seems like the only place it's needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made it a field for consistency with DefaultOptions
and BundleVersion
, but don't have a strong preference. To me it seems like it belongs with TargetInfo
because it depends on the alignment requirements of the target platform - for example if the bundler accepted an option to change the alignment, we would still only allow multiples of this value (similar to DefaultOptions
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
belongs with TargetInfo because it depends on the alignment requirements of the target platform
I would disagree -- TargetInfo
is a collection of data about the target, while alignment is a piece of data about the bundler, which is dependent on TargetInfo
. My general strategy would be for TargetInfo to carry only the essentials of the target, because that makes it more reusable and lighter weight for dependent components.
However I think this is all pretty academic because all of this code is pretty small, so it doesn't particularly matter to me either way 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Point taken - I'll leave it this way for consistency, but we could consider removing bundler-related decisions from it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from overload LGTM
src/installer/tests/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs
Outdated
Show resolved
Hide resolved
src/installer/tests/Microsoft.NET.HostModel.Tests/Helpers/BundleHelper.cs
Outdated
Show resolved
Hide resolved
/backport to release/5.0-rc2 |
Started backporting to release/5.0-rc2: https://github.com/dotnet/runtime/actions/runs/240210475 |
To fix ARM64 Linux behavior. See dotnet/runtime#41809.
* Pass architecture to bundler To fix ARM64 Linux behavior. See dotnet/runtime#41809. * Fix how we get architecture from RIDs * Update dependencies from runtime * Revert incorrect targetOS change We fall back to linux so that RIDs like ubuntu* are supported.
* Pass architecture to bundler To fix ARM64 Linux behavior. See dotnet/runtime#41809. * Fix how we get architecture from RIDs * Update dependencies from runtime * Revert incorrect targetOS change We fall back to linux so that RIDs like ubuntu* are supported.
* Pass architecture to bundler To fix ARM64 Linux behavior. See dotnet/runtime#41809. * Fix how we get architecture from RIDs * Update dependencies from runtime * Revert incorrect targetOS change We fall back to linux so that RIDs like ubuntu* are supported.
On ARM64 Linux, single-file apps were segfaulting because of an incorrect address computed in R2R code. See #41832 for details about the issue.
This is a temporary fix that uses 4K offsets within the bundle. This will preserve the page alignment when we mmap assemblies, working around the lack of fixups for
adrp
;add
instruction sequences.I've confirmed that the fix, together with these SDK changes, produces a functional single-file app on Linux ARM64: sbomer/sdk@19998e6. I will make the SDK changes in the rc2 branch after this fix is ported and flows to the SDK.