Repository navigation
fix(rocr): honor NUMA memory policy for host allocations - #14056
Conversation
…ions bind_mem_to_numa() unconditionally mbind()s host-pool allocations to the owning CPU agent's NUMA node, overriding an explicitly-set process memory policy (numactl -m / set_mempolicy). Skip the per-agent mbind when the process has set an explicit policy (get_mempolicy() != MPOL_DEFAULT) so the policy governs host placement. HSA_FORCE_MBIND=1 restores the legacy per-agent binding. No change when no policy is set. Relates to ROCM-32080; tracked by ROCM-33395.
✅ All Policy Checks Passed
📖 Need help? See the Policy FAQ for details on every check and how to fix failures. |
|
🚫 Please fix the failed policies before requesting reviews. The following policy checks failed:
The |
There was a problem hiding this comment.
🟡 Changes recommended
The new shortcut bypasses required placement checks and binding for NoSubstitute allocations, including APU device allocations.
1 open issue
What changed in this PR
This PR updates ROCr host-memory placement to honor explicit NUMA memory policies instead of always binding allocations to the owning CPU agent’s node.
Changes:
- Detect explicit memory policies and skip per-agent binding when one is set.
- Add
HSA_FORCE_MBINDto restore legacy binding behavior. - Preserve existing placement behavior when no explicit policy is set.
| File | Description |
|---|---|
projects/rocr-runtime/libhsakmt/src/openclose.c |
Read the HSA_FORCE_MBIND environment setting. |
projects/rocr-runtime/libhsakmt/src/libhsakmt.h |
Declare the shared binding override. |
projects/rocr-runtime/libhsakmt/src/globals.c |
Define and document the binding override. |
projects/rocr-runtime/libhsakmt/src/fmm.c |
Detect explicit NUMA policies and conditionally bypass binding. |
Review effort: Balanced
|
LGTM, nit pick. Please adjust your AI agent to use the "new" PR description format. You can use this PR as an example: |
The early return that defers host placement to an explicit process memory policy ran for every allocation, including strict (NoSubstitute) binds. The udmabuf APU path forces NoSubstitute=1 to pin host memory to the GPU's nearest CPU node for hardware locality; deferring there silently dropped that bind and returned success, violating the no-fallback contract. Gate the deferral on !NoSubstitute so only substitutable host-pool allocations (kernarg / signals / RPC) honor the policy, while strict binds keep their hard per-agent mbind and error handling. Rename the helper to reflect that Linux mempolicy is per-thread (numactl-set policy is inherited by every thread). Relates to ROCM-32080; tracked by ROCM-33395.
shwetagkhatri
left a comment
There was a problem hiding this comment.
Accepted and LGTM. Both points are addressed - the early return is now gated on NoSubstitute, and the helper is renamed to thread_has_explicit_mempolicy. Thanks Chris.

Motivation
bind_mem_to_numa()unconditionally issues anmbind(MPOL_PREFERRED | MPOL_F_STATIC_NODES, <owning CPU agent's NUMA node>)on every host-pool allocation. An explicit-rangembindoutranks the process/task memory policy, sonumactl -m/set_mempolicy()are silently inert for ROCr host buffers: the runtime always wins, and HPC jobs that pin memory by policy cannot place GPU-accessed host memory (kernarg, completion signals, RPC buffers) where they asked. This is the explicit-policy half of ROCM-32080 (the no-policy default half — callers selecting CPU-agent-0 host pools — is fixed upstream in llvm-project PR #233099; ROCr's per-agent binding is correct there).Technical Details
Defer to an explicitly-set process memory policy: when the process has one, skip the per-agent
mbindand let the policy govern host placement. Behavior is unchanged when no policy is set.mbindwhenget_mempolicy()reports a non-default policy (masking off theMPOL_F_STATIC_NODES/MPOL_F_RELATIVE_NODESmode flags before the comparison). Returning0lets the allocation proceed under the process policy and is also correct for theNoSubstitutepath.HSA_FORCE_MBIND=1restores the legacy per-agent binding (escape hatch).HSA_ZFB/PM4_TARGET_XCC):hsakmt_force_mbindglobal inglobals.c, read once at init inopenclose.c:init_vars_from_env()viahsakmt_safe_env_to_int, declaredexterninlibhsakmt.h— no inlinegetenvin the alloc path.Note:
cpuset.memsis kernel-enforced andmbindcannot escape it, so no ROCr change is needed for the cgroup case.Issue Tracking
JIRA ID : ROCM-33395
Relates to ROCM-32080. Complements upstream llvm-project PR #233099 (the no-policy default case).
Test Plan
Validated on b06-2 (2-socket EPYC 9655 + 8× MI350X gfx950, ROCm 10.2), node-1 GPU with the process pinned to node 1, tracing allocations with
strace -f -e trace=mbind. Four cases covering the honor path, the legacy override, and no-regression:numactl -m 1numactl -m 1numactl -m 1+HSA_FORCE_MBIND=1Test Result
mbindHSA_FORCE_MBIND=1All four cases PASS.
Submission Checklist