[Bugfix][KV Transfer] Reject NixlConnector + expandable_segments:True - #41237
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds a validation check to prevent the use of 'expandable_segments:True' in 'PYTORCH_CUDA_ALLOC_CONF' when using 'NixlConnector', as it causes memory remapping that invalidates RDMA registrations. The reviewer suggested a more robust way to parse the configuration string to avoid potential false positives with simple substring matching.
| conf = os.environ.get("PYTORCH_CUDA_ALLOC_CONF", "") | ||
| if "expandable_segments:True" in conf: |
There was a problem hiding this comment.
Using os.environ.get to check for a substring in a comma-separated configuration string is fragile. If PYTORCH_CUDA_ALLOC_CONF contains expandable_segments:True,other_config:1, the check if "expandable_segments:True" in conf works, but if it contains expandable_segments:True1 or similar, it might produce false positives. It is safer to parse the configuration string properly.
conf_dict = dict(item.split(':') for item in os.environ.get('PYTORCH_CUDA_ALLOC_CONF', '').split(',') if ':' in item)
if conf_dict.get('expandable_segments') == 'True':There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 863fe56a3b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| conf = os.environ.get("PYTORCH_CUDA_ALLOC_CONF", "") | ||
| if "expandable_segments:True" in conf: |
There was a problem hiding this comment.
Validate expandable_segments from PYTORCH_ALLOC_CONF too
This guard only reads PYTORCH_CUDA_ALLOC_CONF, so it is bypassed when users set PYTORCH_ALLOC_CONF (the primary allocator env var; PYTORCH_CUDA_ALLOC_CONF is just an alias). In that case NixlConnector still starts with expandable_segments:True, and the exact RDMA corruption/hang this change is meant to prevent can still occur. Please check both env var names (and add a test for the PYTORCH_ALLOC_CONF path) so the fail-fast behavior is reliable.
Useful? React with 👍 / 👎.
NickLucche
left a comment
There was a problem hiding this comment.
I believe this might be true for more than just nixl.
Let me do a quick check for other cases, but thanks a lot for the great work bringing this up for PD @esmeetu !
|
@NickLucche , I forgot this #40812. So we must enable sleep mode to make expandable segments work. |
NixlConnector pins KV cache memory once via ibv_reg_mr at startup. When PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True, PyTorch's CUDA VMM allocator can later remap KV cache virtual addresses to different physical pages, leaving the registered IB rkey pointing at stale physical pages. This produces RDMA failures at runtime: IBV_WC_REM_ACCESS_ERR (synd 0x13), "remote agent invalidated in between prepXferDlist and this call", and NIXL_ERR_REMOTE_DISCONNECT. The two settings are fundamentally incompatible in general: ibv_reg_mr expects stable physical mappings for the lifetime of the MR, while expandable_segments explicitly trades that guarantee for memory-pool flexibility. Sleep mode is exempt: CuMemAllocator.use_memory_pool toggles expandable_segments off around its pool (see vllm-project#40812), so the KV cache allocated within that context lands on stable physical pages even when the env var is set globally. Validate this combination at config-load time so it fails fast with an actionable message instead of silently producing RDMA errors that surface only at the first inter-node KV transfer. Signed-off-by: inf-yasong <yasong.wang@inferact.ai>
863fe56 to
269932e
Compare
|
I just add new gate logic to check both |
There was a problem hiding this comment.
@dtcccc I suppose mooncake would have a similar issue given this invalidates kv addresses, and similarly moriioo (guessing, not really familiar with moriioo).
@esmeetu I would raise this check to "if any connector is present", given we can't guarantee that for OOT connectors.
Generally speaking, given my current (perhaps superficial) understanding of this allocator, I am actually afraid using it might be sweeping under the rug a deeper issue that may arise when using a static allocator.
I believe ideally as inference engine we should be able to predict our allocations and the added dynamic factor here might actually work against us.
We could also consider disabling it altogether for kv cache allocations.
Yes, MooncakeConnector would be affected the same way. |
|
@esmeetu can we change the connector check to "any connector" rather than nixl-specific? |
Per @NickLucche's review feedback: NixlConnector is not the only connector that pins KV cache memory and gets corrupted when PyTorch's CUDA VMM allocator remaps physical pages. MooncakeConnector has the same vulnerability (confirmed by @dtcccc), and we can't enumerate every in-tree and out-of-tree connector that does similar pinning. Apply the rejection whenever any KV connector is configured (rather than NixlConnector-specifically). Sleep-mode exemption and the expandable_segments:True trigger are unchanged. Tests are reorganized: parametrize the rejection test over multiple connector names (including a hypothetical OOT one), keep the sleep-mode and benign-alloc-conf cases, and replace the 'non-NIXL connector is allowed' case with a 'no connector is allowed' case (since the new behavior rejects non-NIXL connectors too). Signed-off-by: inf-yasong <yasong.wang@inferact.ai> Signed-off-by: esmeetu <jasonailu87@gmail.com>
|
@NickLucche SGTM. Updated. |
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by setting vmm_safe_transfers = True. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#41612 Co-authored-by: opencode
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by setting vmm_safe_transfers = True. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#41612 Co-authored-by: opencode
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by setting vmm_safe_transfers = True. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Co-authored-by: opencode
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Co-authored-by: opencode Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Co-authored-by: opencode Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Co-authored-by: opencode Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into by inheriting. The config validation now checks this protocol before rejecting, allowing DMA-only connectors to work with expandable_segments without requiring sleep mode. Closes vllm-project#42404 Signed-off-by: Tiberiu Rezus <tiberiu@rezus.net>
…vllm-project#41237) Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into to signal they only use DMA (not RDMA), exempting them from the rejecting, allowing DMA-only connectors to work with expandable_segments. Also includes fork-only CI workflow (.github/workflows/build-and-push.yml) for building and testing the image on the self-hosted runner.
Cherry-pick 62 bugfix/security PRs from upstream vllm-project/vllm main (2026-05-03 to 2026-06-17), covering scheduler, engine core, model runner, worker, attention, KV cache, compilation, and structured output fixes. Security (4): vllm-project#43286 vllm-project#44744 vllm-project#45118 vllm-project#45252 Bugfix (56): vllm-project#35536 vllm-project#36616 vllm-project#38895 vllm-project#39155 vllm-project#39324 vllm-project#39562 vllm-project#39805 vllm-project#40398 vllm-project#40726 vllm-project#40727 vllm-project#40737 vllm-project#40749 vllm-project#40961 vllm-project#41119 vllm-project#41133 vllm-project#41233 vllm-project#41237 vllm-project#41411 vllm-project#41496 vllm-project#41549 vllm-project#41674 vllm-project#41873 vllm-project#41895 vllm-project#42040 vllm-project#42112 vllm-project#42289 vllm-project#42479 vllm-project#42585 vllm-project#42692 vllm-project#42706 vllm-project#42709 vllm-project#42739 vllm-project#42967 vllm-project#43001 vllm-project#43079 vllm-project#43125 vllm-project#43160 vllm-project#43616 vllm-project#43669 vllm-project#43719 vllm-project#43768 vllm-project#43808 vllm-project#43961 vllm-project#43982 vllm-project#43988 vllm-project#43998 vllm-project#44057 vllm-project#44560 vllm-project#44574 vllm-project#44568 vllm-project#44603 vllm-project#44744 vllm-project#45195 vllm-project#45345 vllm-project#45383 vllm-project#45487 vllm-project#45564 vllm-project#45673 Runner fix (2): vllm-project#44568 vllm-project#44603 Skipped: vllm-project#43781 (ROCm-specific, not applicable to Ascend NPU) Conflict resolutions: - Manual merge: vllm-project#43286 vllm-project#45118 vllm-project#42112 vllm-project#43160 vllm-project#43719 vllm-project#44560 - Upstream-preferred (-X theirs): vllm-project#43808 vllm-project#43988 vllm-project#42967 vllm-project#35536 vllm-project#45195 - Test files (--theirs): vllm-project#44744 vllm-project#41895 vllm-project#42040 vllm-project#41233 vllm-project#45345 vllm-project#43982 Co-authored-by: GitHub Copilot Signed-off-by: MingqiWang-coder <mingqiwang@hust.edu.cn>
Cherry-pick 62 bugfix/security PRs from upstream vllm-project/vllm main (2026-05-03 to 2026-06-17), covering scheduler, engine core, model runner, worker, attention, KV cache, compilation, and structured output fixes. Security (4): vllm-project#43286 vllm-project#44744 vllm-project#45118 vllm-project#45252 Bugfix (56): vllm-project#35536 vllm-project#36616 vllm-project#38895 vllm-project#39155 vllm-project#39324 vllm-project#39562 vllm-project#39805 vllm-project#40398 vllm-project#40726 vllm-project#40727 vllm-project#40737 vllm-project#40749 vllm-project#40961 vllm-project#41119 vllm-project#41133 vllm-project#41233 vllm-project#41237 vllm-project#41411 vllm-project#41496 vllm-project#41549 vllm-project#41674 vllm-project#41873 vllm-project#41895 vllm-project#42040 vllm-project#42112 vllm-project#42289 vllm-project#42479 vllm-project#42585 vllm-project#42692 vllm-project#42706 vllm-project#42709 vllm-project#42739 vllm-project#42967 vllm-project#43001 vllm-project#43079 vllm-project#43125 vllm-project#43160 vllm-project#43616 vllm-project#43669 vllm-project#43719 vllm-project#43768 vllm-project#43808 vllm-project#43961 vllm-project#43982 vllm-project#43988 vllm-project#43998 vllm-project#44057 vllm-project#44560 vllm-project#44574 vllm-project#44568 vllm-project#44603 vllm-project#44744 vllm-project#45195 vllm-project#45345 vllm-project#45383 vllm-project#45487 vllm-project#45564 vllm-project#45673 Runner fix (2): vllm-project#44568 vllm-project#44603 Skipped: vllm-project#43781 (ROCm-specific, not applicable to Ascend NPU) Conflict resolutions: - Manual merge: vllm-project#43286 vllm-project#45118 vllm-project#42112 vllm-project#43160 vllm-project#43719 vllm-project#44560 - Upstream-preferred (-X theirs): vllm-project#43808 vllm-project#43988 vllm-project#42967 vllm-project#35536 vllm-project#45195 - Test files (--theirs): vllm-project#44744 vllm-project#41895 vllm-project#42040 vllm-project#41233 vllm-project#45345 vllm-project#43982 Co-authored-by: GitHub Copilot Signed-off-by: MingqiWang-coder <mingqiwang@hust.edu.cn>
…nts:True PR vllm-project#41237 conservatively rejects ALL KV connectors when PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True is set, because RDMA-registered memory (e.g. via ibv_reg_mr) becomes stale after CUDA VMM remaps virtual addresses to different physical pages. However, DMA-only connectors like SimpleCPUOffloadConnector are unaffected: they transfer KV data via cuMemcpy/cudaMemcpy on virtual addresses, which the CUDA driver transparently updates after remapping. Introduce a SupportsVmmSafeTransfers mixin that connectors opt into to signal they only use DMA (not RDMA), exempting them from the rejecting, allowing DMA-only connectors to work with expandable_segments. Also includes fork-only CI workflow (.github/workflows/build-and-push.yml) for building and testing the image on the self-hosted runner.
Purpose
NixlConnectorpins the KV cache viaibv_reg_mronce at startup. WhenPYTORCH_CUDA_ALLOC_CONF=expandable_segments:True, PyTorch's CUDA VMM allocator can later remap KV cache virtual addresses to different physical pages — leaving the registered IBrkeypointing at stale physical pages.The two settings are fundamentally incompatible:
ibv_reg_mrexpects stable physical mappings for the lifetime of the MR, whileexpandable_segmentsexplicitly trades that guarantee for memory-pool flexibility.In practice this combination silently corrupts inter-node KV transfers and only surfaces at the first request, with errors like:
IBV_WC_REM_ACCESS_ERR (synd 0x13 vend 0x88 hw_synd 0/0)on the decode sidemakeXferReq: remote agent '<uuid>' was invalidated in between prepXferDlist and this callNIXL_ERR_REMOTE_DISCONNECT/NIXL_ERR_NOT_FOUND/NIXL_ERR_CANCELEDThe prefill side shows zero errors because the allocator misbehavior happens at the CUDA VMM layer below NIXL's awareness. Diagnosing this from the symptom is hours of work; preventing the misconfiguration up front is one
if.This change validates the combination at config-load time in
KVTransferConfig.__post_init__and fails fast with an actionable error.This affects only
NixlConnector— other connectors do not pin GPU memory throughibv_reg_mr, so the same env var is harmless for them and is left untouched.Test Plan
Adds three cases covering:
NixlConnector+expandable_segments:True→ raises with a clear messageNixlConnector+expandable_segments:False(or other allocator config) → allowedexpandable_segments:True→ unaffectedTest Result
Before this change, a real GB200 NVL72 1P/1D run with
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:Trueon the prefill side accepts the config, allocates and registers KV memory, then produces 66 NIXL transfer failures at the first request and the benchmark hangs at 12/320 progress. Removingexpandable_segments:True(the only change) fixes it: 0 NIXL errors, benchmark progresses normally to 132/320 within ~2 minutes.After this change, the same misconfiguration is rejected at startup with: