fix(clr): let the fat-binary readable bound span a split mapping - #9896
Open
magaonka-amd wants to merge 3 commits into
Open
fix(clr): let the fat-binary readable bound span a split mapping#9896magaonka-amd wants to merge 3 commits into
magaonka-amd wants to merge 3 commits into
Conversation
FindFileNameFromAddress measured the readable bytes to the end of the single /proc/self/maps entry holding the image. One allocation can be described by several entries: the kernel splits a mapping when part of it gets an attribute the rest does not have, and the pieces do not merge back. A NUMA policy set by mbind() is one such attribute and it shows up in neither the maps line nor smaps VmFlags, so the pieces look identical. The bound then comes back short and hipModuleLoadData rejects a valid, fully readable code object. Walk forward over entries that are adjacent, readable, and backed by the same object. Matching the backing object keeps the bound inside the allocation, and the walk stops after 32 entries so the cost does not grow with the number of mappings. os.hpp now describes the value as a no-fault ceiling rather than a bound on the object. JIRA ID: ROCM-29159
Puts an hiprtc-compiled code object across an mprotect-induced split, checks every byte is readable, and requires hipModuleLoadData to succeed. Fails before the os_posix change and passes after it. JIRA ID: ROCM-29159
✅ All Policy Checks Passed
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
…/clr-image-bound-split-mapping
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
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.
Motivation
hipModuleLoadDatarejects valid code objects withhipErrorInvalidImage. Thereadable-size bound is measured to the end of one
/proc/self/mapsentry, but oneallocation can be split across several, so the bound comes back short.
How it shows up in JAX
Random kernels fail to load part-way through a run, with no pattern to which ones.
A 16-process JAX test suite hits it within about 30 minutes. The same run also
fails inside MIOpen and in jaxlib's own FFI kernels, because all three load code
objects the same way.
How to reproduce
Build a code object for your GPU:
repro.cpp:On
developtoday:The image is 9696 bytes and every one of them was just read. The bound says 2048.
This needs
mbindto be permitted. Docker's default seccomp blocks it, whichlibhsakmtalready works around atfmm.c:2037.Why the split happens
The kernel splits a mapping when part of it gets an attribute the rest does not
have, and the pieces do not merge back afterwards. A NUMA memory policy is one such
attribute, and it shows up in neither the
/proc/self/mapsline norsmapsVmFlags, so the pieces look identical:This is not something the application has to do.
libhsakmtdoes it itself, inbind_mem_to_numa()(rocr-runtime/libhsakmt/src/fmm.c:2032).An
straceof a twenty-line JAX program shows 1290mbind(..., MPOL_PREFERRED, ...)calls, plus52039
mprotectand 124madvise(MADV_DONTFORK | MADV_HUGEPAGE), all of whichsplit mappings too.
What the fix does
FindFileNameFromAddresswalks forward from the entry holding the image while thenext one is directly adjacent, readable, and backed by the same object (same
device, inode, path), and reports the end of that run.
Requiring the same backing object keeps the bound inside the allocation instead of
letting it walk into whatever is mapped next. The walk stops after 32 entries so
its cost does not grow with the number of mappings in the process.
Issue Tracking
JIRA ID: ROCM-29159
Test Plan
New test,
OOB_hipModuleLoadData_Positive_ImageSpansSplitMappingincatch/unit/oob/oob_module.cc. It compiles a code object with hiprtc so the archis right, puts it across a split anonymous mapping, checks every byte is readable,
and requires the load to succeed. It fails on
developtoday.Test Result
oob_module, 6 existing cases, 200 assertionsUnit_hipModuleLoad_Negative_MalformedFatBinaryBoundsModuleTest, full run, 5,850,405 assertionsOOB_hipModuleLoadData_Positive_ImageSpansSplitMapping(new)Latency, 2000
hipModuleLoadDataiterations:End to end: the JAX UT passes with no flakes with this fix.
Not tested: Windows. I'm not sure about windows usecase, I'm open to suggestions.
Submission Checklist