[https://nvbugs/6215218][fix] Add escape hatch for KV transfer timeout-triggered UAF in disagg - #14565
[https://nvbugs/6215218][fix] Add escape hatch for KV transfer timeout-triggered UAF in disagg#14565hyukn wants to merge 1 commit into
Conversation
…t-triggered UAF in disagg
Under sustained high-concurrency disaggregated workloads (e.g. Kimi-K2.5-NVFP4
at concurrency=16384 on GB200 dep16), the KV-cache transfer timeout
(default 60 s) triggers a request-termination code path that contains a
use-after-free on Python LlmRequest objects. The crash surfaces as either:
- SIGSEGV in `_PyObject_GenericGetAttrWithDict` / `_PyEval_EvalFrameDefault`
- `CUBLAS_STATUS_EXECUTION_FAILED` from `cublasLtMatmul` (latched async
CUDA error from the same race)
The crash is request-count-correlated (consistently at ~90% of total
requests), regardless of cache_transceiver buffer size, and is always
preceded by `Terminating ... request ... due to KV cache transfer
timeout` in the CTX worker log.
Empirically verified workaround: setting `kv_transfer_timeout_ms=None`
on both CTX and GEN `cache_transceiver_config` eliminates the crash.
The same dep16 c=16384 benchmark that reliably failed at request
~14,700 now completes cleanly to 99.5 %.
This patch:
1. Adds `TRTLLM_DISABLE_KV_TRANSFER_TIMEOUT=1` env-var escape hatch in
`_check_kv_transfer_timeout`. When set, the function returns early
without inspecting any requests. Lets users disable the buggy
path without changing the schema default.
2. Updates the `kv_transfer_timeout_ms` docstring in
`CacheTransceiverConfig` to document the NVBug, the None workaround,
and the env-var override.
This is an interim fix. The proper repair is to fix the UAF in the
cancellation/cleanup chain that runs when a request is flagged
`py_kv_transfer_timed_out=True`. Suspect code areas (introduced between
v1.3.0rc12.post1 and main commit ~c7d609bd, ~3 weeks before this PR):
- `_flush_pending_transfer_responses` / `_pending_transfer_responses`
(PR NVIDIA#13115, TRTLLM-12015 -- KV reuse in transceiver v2)
- `commit_blocks_for_reuse` on `KvCacheTransceiver`
- `cancelled_reqs` tuple handling in `_check_disagg_gen_cache_transfer_status`
(PR NVIDIA#12734, TRTLLM-11635 -- cancellation in transceiver v2)
Signed-off-by: Yukun He <23156053+hyukn@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR introduces a workaround for a known use-after-free issue in KV cache transfer timeout detection under high concurrency in disaggregated deployments. It adds an environment-variable escape hatch and updates the configuration documentation to guide users toward the mitigation. ChangesKV Cache Transfer Timeout Workaround
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Closing as redundant: the proposed env var ( This patch was a workaround, not a fix. The proper repair is to address the use-after-free in the cancellation/cleanup chain that runs when a request is flagged
Full repro + evidence on the NVBug: https://nvbugspro.nvidia.com/bug/6215218 |
Background
NVBug 6215218 reports that disaggregated serving of Kimi-K2.5-NVFP4
(ISL=OSL=1024, concurrency=16384) on GB200 (NVL72, aarch64, dep16)
crashes the CTX worker shortly after benchmark start. The CTX worker
dies with SIGSEGV (exit 139); the disagg server then fails all
subsequent requests with
aiohttp.ClientConnectorErrorand the SLURMjob eventually times out. The same configuration runs cleanly on
nvcr.io/nvidia/tensorrt-llm/release:1.3.0rc12.post1— so this is aregression introduced between rc12.post1 and main.
Empirical findings (lyris GB200 dep16, c=16384)
kv_transfer_timeout_msc7d609bd(image57a1b8)1.3.0rc12.post19ec3c8(May 23, 2 days after BAD)Terminating ... due to KV cache transfer timeoutTwo key observations:
[RANK X] Terminating ... request ... due to KV cache transfer timeoutin the CTX worker log. The SEGV stack is consistently_PyObject_GenericGetAttrWithDict → PyObject_GetAttr → _PyEval_EvalFrameDefault— classic Python attribute access on a freed object. Under different timing, the same race surfaces asCUBLAS_STATUS_EXECUTION_FAILEDfromcublasLtMatmul(latched async CUDA error on the stream from the same freed-pointer access).Summary
This patch adds an environment-variable escape hatch (
TRTLLM_DISABLE_KV_TRANSFER_TIMEOUT=1) to_check_kv_transfer_timeoutand documents the workaround inCacheTransceiverConfig.kv_transfer_timeout_ms. Users who hit the crash can disable the timeout via either:cache_transceiver_config.kv_transfer_timeout_ms: null(already supported)TRTLLM_DISABLE_KV_TRANSFER_TIMEOUT=1(added by this PR)Why this is an interim fix
This is not a fix for the underlying use-after-free. It is an escape hatch so users hitting NVBug 6215218 can run their workloads while the proper repair lands. The real fix requires auditing the cancellation / cleanup chain that runs when a request is flagged
py_kv_transfer_timed_out=True. Suspect code areas (introduced betweenv1.3.0rc12.post1andc7d609bd):_flush_pending_transfer_responses/_pending_transfer_responses— added in PR [TRTLLM-12015][feat] Introduce KV reuse in transceiver v2 #13115 (TRTLLM-12015, KV reuse in transceiver v2). This is a TP gather collective that requires lockstep across DP ranks; a response queued for a soon-to-be-terminated request can outlive the request itself.commit_blocks_for_reuse(req)onKvCacheTransceiver— same PR. Per-request callback during transfer completion; verify pybind/nanobind INCREF discipline.cancelled_reqstuple-result handling in_check_disagg_gen_cache_transfer_status— added in PR [TRTLLM-11635][feat] Introduce cancellation in transceiver v2 #12734 (TRTLLM-11635, cancellation in transceiver v2). Dereferencesreq.py_request_id/is_child/parent_request_idon objects coming back from C++; verify the list holds strong references.A
git bisectbetweenv1.3.0rc12.post1andc7d609bdwith the dep16 c=16384 repro as the pass/fail check would conclusively identify the introducing PR (~14 bisect steps).Impact assessment
kv_transfer_timeout_msis left at its default. Sets are purely opt-in.os.environ.getper_check_kv_transfer_timeoutcall (which is itself called from the executor event loop, not the hot path).Test plan
1907412): bench progressed to 99.5% with zero CTX errors before SLURM wall-clock.Related
Summary by CodeRabbit
Release Notes
Bug Fixes
TRTLLM_DISABLE_KV_TRANSFER_TIMEOUT=1or configure the timeout toNoneto resolve the issue.Documentation