Skip to content

feat(racer): persistent zero-copy RDMA links - #956

Merged
Jordan Olshevski (jveski) merged 188 commits into
mainfrom
racer-rdma-persistent
Oct 22, 2026
Merged

Jordan Olshevski (jveski) merged 188 commits into
mainfrom
racer-rdma-persistent

Conversation

@jveski

@jveski Jordan Olshevski (jveski) commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Replace per-page RDMA sessions with persistent authenticated links and direct ODP-backed sends, using HTTP when a link cannot serve a request. Remove the staged RDMA path, obsolete verbs APIs, and unused protocol code, and require the current native adapter ABI. Reuse aligned ciphertext for memory caching and vectored disk writes, add pressure-aware buffer reclamation, update the XAES implementation without changing its wire format, and fix load-generator drain contention. Keep public documentation changes limited to removing incorrect statements and align the design documents with the implemented protocol and ownership rules.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Buffer-return callbacks can deadlock, and activation unintentionally limits the node to one RDMA rail.

2 open issues
What changed in this PR

Replaces Racer’s per-page RDMA connections with persistent bidirectional links, retaining HTTP fallback.

Changes:

  • Adds signed link setup and streamlined per-page transfers.
  • Introduces node-wide registered buffers and crypto-thread send staging.
  • Updates lifecycle handling, simulation tests, and documentation.
File Description
docs/​content/​reference/​racer.md Documents persistent links and memory budgets.
cmd/​racer-dataplane/​verbs/​tests/​startup.rs Removes legacy startup tests.
cmd/​racer-dataplane/​verbs/​tests/​links.rs Tests persistent-link operations and failures.
cmd/​racer-dataplane/​verbs/​tests/​device_discovery.rs Removes legacy discovery tests.
cmd/​racer-dataplane/​verbs/​src/​pool.rs Adds registered-buffer ownership states.
cmd/​racer-dataplane/​verbs/​src/​discovery_fault_tests.rs Migrates discovery tests to node ownership.
cmd/​racer-dataplane/​verbs/​src/​control.rs Adds in-band control encoding and validation.
cmd/​racer-dataplane/​verbs/​src/​channel.rs Adds worker queues and operation results.
cmd/​racer-dataplane/​verbs/​native/​verbs.c Extends native verbs operations and completion data.
cmd/​racer-dataplane/​tests/​production_dataplane.rs Updates transfer construction.
cmd/​racer-dataplane/​src/​worker.rs Updates native lifecycle test wiring.
cmd/​racer-dataplane/​src/​store.rs Copies registered ciphertext before queue retention.
cmd/​racer-dataplane/​src/​security.rs Adds crypto-thread send staging.
cmd/​racer-dataplane/​src/​read/​tests/​remote.rs Updates transfer construction.
cmd/​racer-dataplane/​src/​read/​tests/​peer_copies.rs Tests registered-page decryption and persistence.
cmd/​racer-dataplane/​src/​read/​tests/​hot_reads.rs Updates transfer construction.
cmd/​racer-dataplane/​src/​read/​candidates.rs Updates transfer test wiring.
cmd/​racer-dataplane/​src/​rdma/​retry.rs Removes obsolete fence retry handling.
cmd/​racer-dataplane/​src/​rdma/​links/​tests/​zero_copy.rs Tests registered-page retention boundaries.
cmd/​racer-dataplane/​src/​rdma/​links/​tests.rs Tests setup, transfers, staging, and drainage.
cmd/​racer-dataplane/​src/​rdma/​link_setup.rs Adds setup codec and simultaneous-setup arbitration.
cmd/​racer-dataplane/​src/​peer/​tests/​protocol_socket.rs Updates socket test wiring.
cmd/​racer-dataplane/​src/​peer/​tests/​opaque.rs Updates relay test wiring.
cmd/​racer-dataplane/​src/​peer/​tests.rs Updates peer transfer construction.
cmd/​racer-dataplane/​src/​peer/​server.rs Dispatches authenticated link setup requests.
cmd/​racer-dataplane/​src/​peer.rs Exposes current membership for setup validation.
cmd/​racer-dataplane/​src/​memory.rs Supports registered ciphertext and copy-out retention.
cmd/​racer-dataplane/​src/​app/​tests/​dst.rs Adapts fault simulation to persistent links.
cmd/​racer-dataplane/​src/​app/​tests.rs Updates application composition assertions.
cmd/​racer-dataplane/​src/​app/​native.rs Introduces node-wide native ownership and activation.
cmd/​racer-dataplane/​src/​app.rs Integrates links and node-wide registered budgets.
cmd/​racer-dataplane/​peer-wire/​tests/​control_deadline.rs Updates deadline tests for revised phases.
cmd/​racer-dataplane/​peer-wire/​src/​tests.rs Tests signed link setup and revised controls.
cmd/​racer-dataplane/​peer-wire/​src/​link.rs Adds signed setup request and response heads.
cmd/​racer-dataplane/​peer-wire/​src/​lib.rs Exports the link protocol module.
cmd/​racer-dataplane/​peer-wire/​src/​control.rs Simplifies per-page control phases.

Review effort: Balanced

Comment thread cmd/racer-dataplane/src/app/native.rs Outdated
Comment thread cmd/racer-dataplane/verbs/src/pool.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Budget-limited activation repeatedly closes healthy links, and exhausted buffer pools accumulate duplicate waiter registrations.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Prevent duplicate waker registrations on exhausted pools

cmd/​racer-dataplane/​verbs/​src/​pool.rs:193

Every poll against an exhausted pool appends another waker, including repeated polls from the same task. Until a buffer returns, the vector grows with poll attempts, and returning a buffer invokes every duplicate. Links::stage also registers a noop waker before immediately falling back (src/rdma/links.rs:626-635), so production fallback attempts accumulate entries without actually waiting. Deduplicate registrations with will_wake, provide a non-registering staging attempt for that caller, and update the reentrancy test to verify safe waking without requiring duplicate notifications.

2 resolved since last review

Review effort: Balanced

Comment thread cmd/racer-dataplane/src/app.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved correctness issues and hardware-sensitive memory lifetimes require corrective work and final human review.

No open issues 🎉

3 previously missed issues

In code that hasn't changed since last review

Medium severity Drive crypto work cooperatively during native owner drain

cmd/​racer-dataplane/​src/​app/​native.rs:98

[P1] Keep crypto progressing while draining the native owner. This composition uses WithNative::drain and fence, which await native drainage before driving the inner service (verbs/src/lib.rs:301-318). The new owner cannot drain until every pool buffer is returned (verbs/src/node.rs:1053-1054). A queued Stage or registered-page decrypt job on this same crypto engine can still own such a buffer, but only the engine's polling/drain processes that job (security.rs:690-711). If teardown reaches this state, native drainage and the queued crypto work wait on each other; the I/O completion fence cannot finish either. Drive native teardown and crypto work cooperatively in both drain and fence, and test shutdown with queued buffer-owning jobs.

Medium severity Honor peer grant limits when issuing outgoing grants

cmd/​racer-dataplane/​src/​rdma/​link_setup.rs:89

[P2] Honor the peer's advertised grant limit. Links::connect and Links::accept discard this decoded field when constructing the verbs setup (rdma/links.rs:449-452,524-527). Local grant admission uses the local limit, while incoming grants exceeding the peer's local limit break the link (verbs/src/link.rs:548-550,961-964). For example, a receiver configured for four grants can break a sender configured for two by issuing a third outstanding grant. Propagate the peer limit and constrain outgoing grants, or negotiate the minimum; test unequal configurations.

Medium severity Use completion admission for registered-page copy-out

cmd/​racer-dataplane/​src/​store.rs:650

[P2] Use completion admission for this copy-out. retainable reserves ordinary ciphertext admission, which fails after admission stops even when this fill already holds an accepted dirty charge and quota remains. This defeats the drain behavior tested in store/tests.rs:3006-3023; read/fill.rs:1950-1961 ignores the enqueue error, so the page is not persisted. Reserve the registered-page copy with reserve_completion, as disk staging does, and add a drain test using registered ciphertext.

1 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Setup cancellation and release handling can strand state, suppress retries, or disrupt shared links.

2 open issues
1 previously missed issue

In code that hasn't changed since last review

Medium severity Cancelled ambiguous writes leak tags and exhaust the waiting table

cmd/​racer-dataplane/​src/​rdma/​links.rs:614

Cancellation can arrive after the owner completes the write but before this worker polls its result. NativeRetry::wait checks the scope first (src/rdma/retry.rs:80-83), so send_native receives an error and releases an already-consumed tag (src/peer/transport.rs:330-332). That creates a Waiting::Release with no future grant and no expiry (verbs/src/link.rs:701-724,1056-1060). Repeated cancellations can fill the waiting table on an active link and reject later writes with Overloaded. Break the matching link epoch when cancellation or a deadline makes the submitted write's outcome ambiguous.

Review effort: Balanced

Comment thread cmd/racer-dataplane/src/rdma/links.rs Outdated
Comment thread cmd/racer-dataplane/src/rdma/links.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Native memory fencing and cross-worker lifecycle changes require human validation, and the identified reentrant-waker deadlock remains unresolved.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment thread cmd/racer-dataplane/verbs/src/pool.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Unresolved correctness and scheduling issues remain, and native ABI, DMA fencing, and shared-buffer lifecycle changes require human review and hardware validation.

No open issues 🎉

2 previously missed issues

In code that hasn't changed since last review

Medium severity Use reclamation-aware reservation for registered-page persistence

cmd/​racer-dataplane/​src/​store.rs:654

Registered-page copy-out bypasses the caller's reclamation-aware reserve_staging callback. When Ciphertext quota is occupied by reclaimable cached pages, self.reserve_staging retries only after reclaiming idle slab buffers (store.rs:578-593). It can therefore return Overloaded here before the caller can reclaim cached pages, rejecting persistence despite reclaimable capacity. The callbacks in src/read/fill.rs:1810-1825 and 1953-1960 provide that reclamation path. Extend the reservation contract to cover both copy-out and disk staging through that path, while preserving completion admission during drain. Add a registered-page persistence test with quota occupied by reclaimable cached pages.

Medium severity Advance drain cursor past the last visited worker

cmd/​racer-dataplane/​verbs/​src/​channel.rs:234

Advance the cursor past the last visited worker rather than by one. With 128 nonempty queues and a budget of 64, consecutive drains service workers 0..63, then 1..64; worker 127 is not serviced until the 65th poll instead of the second. The node owner passes its polling budget to this drain (verbs/src/node.rs:633), so sustained load gives some workers long gaps between RDMA command-processing turns. Save the starting cursor and update self.next after each visited queue. Add a regression test with more workers than the drain budget.

2 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Native ABI, DMA fencing, and cross-thread ownership changes require human review, with real-hardware validation still outstanding.

No open issues 🎉

Review effort: Balanced

Remove the staged-copy RDMA path: Source becomes a single direct source,
SendBuffer, staging states and waiters, NodeConfig zero_copy and
mr_remote_write, RACER_RDMA_ZERO_COPY, the crypto Stage job, and copied
send telemetry. Activation now fails with Unavailable and releases its
charge when a selected device lacks implicit ODP.
Page buffers only receive now that sends read pages in place, so a
device needs one registered buffer, not a send and a receive buffer.
Remove PoolShared::buffer_len, Buffer::index, and Owner::workers, which
only tests called; tests now read the private fields directly. Gate
Owner::poll_drain, Owner::is_closed, Link::failure, and
NativeQueuePair::failure behind cfg(test) instead of allowing dead code
under a stale 'tests and diagnostics' claim.
No production code reads NativeQueuePair's cached first Failure since
its getters became test-only, so gate the type, field, and recording
under cfg(test). Failed completions still stop the QP and return
Error::Io.
Name the test-only RNR status as plain text and disambiguate the node
function link.
…ive pool

An unsupported device now fails activation before the page MR is
allocated, zeroed, and registered, so each activation retry no longer
builds and destroys an unused receive pool. Extend the ODP activation
test to assert the failed probe is the only registration.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The combined native ABI, DMA ownership, buffer-lifetime, and cryptographic changes require final human review and target-hardware validation.

No open issues 🎉

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The combined native ABI, RDMA memory ownership, I/O lifetime, and cryptographic changes require final human review and target-hardware validation.

No open issues 🎉

Review effort: Balanced

@jveski

Copy link
Copy Markdown
Contributor Author

Copilot resolve the merge conflicts in this pull request

# Conflicts:
#	cmd/racer-dataplane/src/app/tests/dst.rs

Co-authored-by: jveski <7576912+jveski@users.noreply.github.com>

Copilot AI commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Copilot resolve the merge conflicts in this pull request

Merged main and resolved the test conflict in f08f752. The targeted concurrent relay pressure tests pass.

@jveski
Jordan Olshevski (jveski) added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 71912a9 Oct 22, 2026
36 checks passed
@jveski
Jordan Olshevski (jveski) deleted the racer-rdma-persistent branch October 22, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants