mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #3136] [RFC]: RDMA Endpoint and Slice Completion Ownership #804
Labels
No labels
ascend
auto-closed
bug
bug
CI/Build
Common
documentation
enhancement
feature request
good first issue
help wanted
high priority
MetaX
nightly-failure
pull-request
PyTorch Backend
question
RFC
Roadmap
stale
Store
Tests
Transfer Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/Mooncake#804
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @alogfans on GitHub (Jul 27, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/3136
Changes proposed
Summary
This RFC proposes a clearer ownership model for RDMA endpoint lifecycle,
posted work requests, completion handling, and slice retry. The immediate
trigger is the concurrency risk exposed by the dedicated RDMA poller model,
where one worker drains all completion queues while other workers continue
posting sends to the same endpoints.
The short-term mitigation is to keep the historical shared worker model as the
default and make the dedicated poller opt-in. The long-term fix should define
per-post completion ownership so stale completions cannot mutate a slice that
has already been retried on another endpoint.
Background
RDMA transfer work is represented by
Transport::Slice. A slice currentlyserves several roles at once:
wr_idtoken returned by CQ polling.retry_cnt, peer NIC path, destination rkey,source lkey, endpoint pointer, QP depth pointer, and status.
Historically, each worker both posted its assigned send shards and polled a
disjoint shard of CQs. The dedicated poller change separated those roles:
worker 0 polls all CQs, while workers 1..N post send shards. That can improve
polling latency and CQ drain throughput, but it also concentrates completion
error handling and endpoint deletion on one thread while multiple posting
threads continue to use the same endpoint store and endpoint objects.
Problem Statement
The current model lacks a precise ownership boundary between:
Sliceobject for a new attempt.The main risk is not only concurrent polling of the same CQ. It is that a
single
Sliceobject may be reused across retry attempts while an old WRcompletion can still arrive. Because the completion token is the mutable
Slice*itself, the poller cannot tell whether the completion belongs to thecurrent attempt or a stale attempt.
This can lead to incorrect behavior such as:
endpoint being retired or reclaimed.
logical attempt.
spread across completion errors, async events, passive handshakes, and
endpoint-store eviction.
Current Worker Models
Historical Shared Model
Each worker posts and polls a disjoint shard:
This model avoids concurrent polling of the same CQ and keeps post/poll work
more local to each worker, but it does not fully define endpoint or slice
ownership.
Dedicated Poller Model
Worker roles are separated:
This model can improve CQ drain behavior, but it exposes more cross-thread
interleavings between posting, completion error handling, retry, and endpoint
retirement.
Goals
Slice.and reclaim.
Non-goals
Proposed Direction
1. Keep Dedicated Polling Opt-in #3090
Until the ownership model is fixed, the default worker mode should remain the
historical shared model. Dedicated polling should be an explicit opt-in for
deployments that understand the risk and benefit from the performance behavior.
This is a mitigation, not a complete correctness fix.
2. Introduce a Per-post Completion Token
wr_idshould identify a posted attempt, not the reusableSliceobject alone.For example:
The exact allocation strategy is open for discussion. The important property is
that each posted WR owns a stable token until its completion has been processed.
Completion handling should:
and CQ outstanding counters.
current attempt.
completion events.
3. Add Slice Attempt Identity
Each slice should carry a monotonically increasing attempt id. Retry or handoff
increments the attempt before the slice is re-enqueued. A completion token
records the attempt id used at post time.
If a completion arrives for an old attempt, the poller must not mark the slice
successful, mark it failed, retry it again, or delete the current endpoint based
on the stale token.
4. Add Endpoint Generation
Each endpoint instance should have a generation or retire epoch. A post token
records the generation used at post time. Endpoint retirement should invalidate
future posts on that generation, but allow completions for already-posted WRs
to drain and release their counters.
Endpoint generation also makes it explicit when a raw endpoint pointer observed
from an old completion no longer refers to the active endpoint for that peer.
5. Unify Endpoint Retirement
All endpoint deletion paths should converge on one retire API:
IBV_EVENT_QP_FATAL.The retire API should remove the endpoint from the active map, mark it
non-postable, and defer physical QP destruction until all posted attempts have
completed or a bounded timeout policy is applied.
Alternatives Considered
Worker-level Post/Poll Mutex
A striped mutex around
submitPostSend()and completion handling can reduce asmall race window, but it does not cover async events, passive handshakes,
endpoint-store eviction,
disconnectAllEndpoints(), or reclaim. It is thereforenot sufficient as a correctness boundary.
Shared Worker Mode Only
Keeping shared worker mode permanently avoids the dedicated-poller exposure, but
it leaves endpoint and slice ownership ambiguous. It is useful as a mitigation,
not as the long-term model.
Endpoint Locks Only
Endpoint locks protect endpoint-local state, but they do not identify whether a
completion belongs to the current slice attempt. Slice attempt identity is still
needed.
Compatibility and Migration
The short-term mitigation is backward-compatible:
MC_RDMA_DEDICATED_POLLER.The long-term token model can be introduced internally without changing the
public Transfer Engine API. It may change memory allocation behavior on the RDMA
hot path, so the implementation should include benchmarks for high-throughput
small-slice workloads.
Testing Plan
The correctness tests should include fake or controllable RDMA paths that can
force specific interleavings:
bad_wrchain.The tests should verify:
Open Questions
PostedSlicebe allocated per WR, per batch, or from an endpoint-localpool?
wr_idpoint to a token object, or encode an index into a pool?silent on the hot path?
implemented and tested?
Before submitting a new issue...
@github-actions[bot] commented on GitHub (Jul 27, 2026):
Thanks for opening this issue, @alogfans!
6733552A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide
@github-actions[bot] commented on GitHub (Oct 26, 2026):
This issue has had no activity for 90 days and will be closed in 7 days if there is no further activity. Please comment or react if it should stay open.