Native RDMA cleanup failures#
This gate tests the existing resource owners when native teardown fails while completion debt remains. It uses the public parent/slice transfer protocol and test-only verbs observation; it is separate from the installed healthy host consumer.
Owners and receipts#
RdmaQp owns the physical connection and its SQ/RQ. A CQ lane owns completion
queues and the associated event channel; RdmaContext owns the device/PD.
Grant records retain memory authority, DMA loans and completion waiters.
Failure |
Native mechanism |
Required retained boundary |
|---|---|---|
|
Thread-local seccomp rejects write/ioctl on the selected test-owned uverbs command FD; the real verbs call returns EIO |
QP, its CQs/PD, outstanding grants, MR/backing and SQ/RQ charges |
|
Create a real extra CQ attached to the channel before calling the real destructor; libibverbs returns EBUSY |
Channel/context and grants whose cancellation receipt is incomplete; already destroyed QPs stay released |
|
A real dependent RESET QP prevents CQ destruction |
CQs/PD and unresolved grant, MR/backing and completion debt; the payload QP stays released |
|
A real Type-2 MW prevents idle PD destruction |
PD/device; already drained business allocations, MRs and request charges are released |
|
Existing CPU ABI failure control |
Device owner retained; close/drop never retry an ambiguous failure |
The QP syscall filter is confined to one child thread and one descriptor. It does not take a physical port down or simulate spontaneous device failure. The channel blocker belongs to the test and survives until its process exits. Neither fault alters the shared NIC’s configuration.
The selected rdma-core implementation calls a void provider free_context
and returns zero from ibv_close_device. Blocking a close syscall therefore
does not produce a native nonzero verbs return. Device-close error handling
is explicitly an ABI defense, not a claimed native fault result. Physical
device loss and provider-specific teardown behavior remain separate gates.
Execute the profile#
Use runner: "orbitte-multirail" with the identity-pinned two-node profile,
two physical rails, port 1/GID selection and one resource lock per RNIC.
Select large-qp-cleanup-error or large-channel-busy, an explicit
fault_role (source or requester), fault_rail, READ/WRITE and lane count.
Both rails must be enabled (mask: 3); channel failures require
rdma_events: true.
{
"source": "a", "requester": "b",
"source_kind": "cpu", "requester_kind": "cpu", "transport": "rdma",
"mode": "large-qp-cleanup-error", "operation": "read",
"rdma_events": false, "num_lanes": 1,
"mask": 3, "fault_rail": 0, "fault_role": "source"
}
Run a frozen release libtest using tests/hardware/run.py --profile ... --binary ... --output ..., with output outside the checkout. The fixture
admits eight 5 MiB parents (five slices each), withholds an exact successful
CQE and then triggers teardown. It checks native failure/handle identity,
outstanding work, denied writes through the DMA loan, repeated close failure
and recovery rejection. After removing observer references and dropping the
engine, a weak backing reference and a native QP query or channel/CQ identity
and open descriptor must still prove ownership. A reference count alone is insufficient.
The supervisor reaps the exact retained process before releasing RNIC locks. Fresh processes reuse the RPC addresses, reject the previous source epoch before opening QPs, transfer two complete byte/guard rounds and drain. The controller independently rejects missing native receipts, retries, early backing release, false drain, wrong fault roles and incomplete child reaping.
The installed cleanup fixture now exercises the requester QP boundary through the ordinary packaged crate. Its selected two-host cases pass on both compiler artifacts. The installed MR/MW fixture passes its six selected two-host cases, checking registration/grant ownership through same-process engine replacement. The installed dependency gate now passes six selected CQ/channel/PD cases, including actual backing retention for unresolved debt and release after idle PD failure. Each result remains scoped to its installed or libtest artifact.
Native TENT correspondence#
The frozen reference is Mooncake TENT
e2d6e8e0f2df113d84f9e39379f98c4b67b199ab.
Its RdmaEndPoint::deconstructUnlocked retains QPs when destruction fails;
RdmaContext::disable preserves CQ/PD/device resources when endpoint cleanup
fails. This is the same endpoint/context ownership boundary used here.
There is a deliberate difference in failure policy. TENT’s endpoint monitor
can retry destruction; its context cleanup logs some later destructor errors
and clears those pointers. OrbitTE reports Unquiesced and quarantines the
remaining native owners without automatically retrying an ambiguous failure.
It also preserves unresolved grant loans and quota until a native receipt
proves cancellation. This gate validates that Rust contract; it does not claim
identical error policy or native wire compatibility.
TENT’s LocalBufferManager::removeBuffer removes context-keyed registration
entries after calling RdmaContext::unregisterMemReg; that method reports an
MR deregistration error after removing its tracking entry. OrbitTE retains the
failed MR and backing instead. Its per-request Type-2 MW authority and retained
key/grant charges are deliberate Rust ownership contracts, not features copied
from TENT’s buffer registry.
See qualification for executed profiles and P4’s remaining gates for limits.