feat(io): fuse RDMA notification into write-with-immediate - #1
Open
itej89 wants to merge 1 commit into
Open
Conversation
Replace the separate IBV_WR_SEND notification after each RDMA write with IBV_WR_RDMA_WRITE_WITH_IMM on the last data WR per endpoint. This eliminates one ibv_post_send call, one SQ slot reservation, and one CQE per QP per transfer while preserving notification semantics. Benchmark on MI350X + AINIC shows 50-170% bandwidth recovery at mid-range message sizes (4KB-64KB) with notifications enabled, matching or exceeding the notifications-OFF baseline. - Pack notification metadata (seq, qpIndex, totalNum) into 32-bit immediate value with seq-to-TransferUniqueId lookup in NotifManager - Handle IBV_WC_RECV_RDMA_WITH_IMM in ProcessOneCqe alongside existing IBV_WC_RECV path - Fall back to legacy IBV_WR_SEND notification for READ operations - Add --enable-notification flag to IO benchmark CLI Co-Authored-By: Claude <noreply@anthropic.com>
itej89
pushed a commit
that referenced
this pull request
Aug 27, 2026
- Check wc.status first in DrainCq — on error, opcode may be garbage - Null-check atomic target address from SEND_WITH_IMM payload - Replace fprintf with MORI_LOG_ERROR in proxy_thread.cpp - Replace fprintf with MORI_APP_INFO in init.cpp proxy log line Addresses PR ROCm#558 review comments #1, #3, and #7. Co-Authored-By: Claude <noreply@anthropic.com>
itej89
pushed a commit
that referenced
this pull request
Aug 27, 2026
- Check wc.status first in DrainCq — on error, opcode may be garbage - Null-check atomic target address from SEND_WITH_IMM payload - Replace fprintf with MORI_LOG_ERROR in proxy_thread.cpp - Replace fprintf with MORI_APP_INFO in init.cpp proxy log line Addresses PR ROCm#558 review comments #1, #3, and #7. Co-Authored-By: Claude <noreply@anthropic.com>
itej89
pushed a commit
that referenced
this pull request
Aug 27, 2026
- Check wc.status first in DrainCq — on error, opcode may be garbage - Null-check atomic target address from SEND_WITH_IMM payload - Replace fprintf with MORI_LOG_ERROR in proxy_thread.cpp - Replace fprintf with MORI_APP_INFO in init.cpp proxy log line Addresses PR ROCm#558 review comments #1, #3, and #7. Co-Authored-By: Claude <noreply@anthropic.com>
2 tasks
itej89
pushed a commit
that referenced
this pull request
Aug 27, 2026
- Check wc.status first in DrainCq — on error, opcode may be garbage - Null-check atomic target address from SEND_WITH_IMM payload - Replace fprintf with MORI_LOG_ERROR in proxy_thread.cpp - Replace fprintf with MORI_APP_INFO in init.cpp proxy log line Addresses PR ROCm#558 review comments #1, #3, and #7. Co-Authored-By: Claude <noreply@anthropic.com>
itej89
pushed a commit
that referenced
this pull request
Aug 27, 2026
- Check wc.status first in DrainCq — on error, opcode may be garbage - Null-check atomic target address from SEND_WITH_IMM payload - Replace fprintf with MORI_LOG_ERROR in proxy_thread.cpp - Replace fprintf with MORI_APP_INFO in init.cpp proxy log line Addresses PR ROCm#558 review comments #1, #3, and #7. Co-Authored-By: Claude <noreply@anthropic.com>
itej89
pushed a commit
that referenced
this pull request
Aug 27, 2026
- Check wc.status first in DrainCq — on error, opcode may be garbage - Null-check atomic target address from SEND_WITH_IMM payload - Replace fprintf with MORI_LOG_ERROR in proxy_thread.cpp - Replace fprintf with MORI_APP_INFO in init.cpp proxy log line Addresses PR ROCm#558 review comments #1, #3, and #7. Co-Authored-By: Claude <noreply@anthropic.com>
itej89
added a commit
that referenced
this pull request
Aug 27, 2026
* fix: null-check atomic target address in proxy DrainCq Guard against dereferencing a null pointer from the SEND_WITH_IMM payload. The address comes from the wire — skip the atomic if zero. Addresses PR ROCm#558 review comments #1 and #7 (wc.status check was already implemented in the current code). Co-Authored-By: Claude <noreply@anthropic.com> * fix: check wc.status before opcode, use MORI logger in proxy - Check wc.status first in DrainCq — on error, opcode may be garbage - Null-check atomic target address from SEND_WITH_IMM payload - Replace fprintf with MORI_LOG_ERROR in proxy_thread.cpp - Replace fprintf with MORI_APP_INFO in init.cpp proxy log line Addresses PR ROCm#558 review comments #1, #3, and #7. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Tej Kiran <kiran.tej@amd.com> Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
IBV_WR_SENDnotification after each RDMA write intoIBV_WR_RDMA_WRITE_WITH_IMMon the last data WR per endpointibv_post_sendcall, one SQ slot reservation, and one CQE per QP per transfer while preserving notification semanticsIBV_WR_SENDnotification for READ operations (imm only works with writes)--enable-notificationflag to IO benchmark CLIMotivation
MORI-IO sends a separate
IBV_WR_SENDnotification after each RDMA write transfer. With notifications enabled (the default in production KV cache transfer), this adds significant overhead at mid-range message sizes — the sizes used by vLLM's MoRIIOConnector for KV cache blocks (~128 KB).The RDMA hardware supports
IBV_WR_RDMA_WRITE_WITH_IMMwhich carries a 32-bit immediate value in the same packet as the data write. The receiver gets anIBV_WC_RECV_RDMA_WITH_IMMcompletion — data + notification in one wire transaction instead of two.Implementation
common.hpp):PackWriteImmediate(seq, qpIndex, totalNum)— 16-bit wrapping sequence number + 8-bit QP index + 8-bit total countbackend_impl.cpp):AllocImmSeq(TransferUniqueId)stores the full 64-bit ID, returns a 16-bit seq for the immediate value;ResolveImmSeq(seq)recovers it on the receiver sidecommon.cpp): Whencontrol.useWriteImmis set and the operation is a write, the last WR's opcode is changed toIBV_WR_RDMA_WRITE_WITH_IMMwith the packed immediateIBV_WC_RECV_RDMA_WITH_IMM(backend_impl.cpp): New CQE handler alongside existingIBV_WC_RECV, unpacks immediate, resolves seq to transfer ID, decrements notifPool counter, replenishes recv WRRdmaNotifyTransfer()for writes when imm is used — the notification is already delivered with the dataBenchmark Results (MI350X + AINIC, 400 GbE RoCE)
RDMA write bandwidth with 128 consecutive transfers,
--enable-notification:Write-with-immediate recovers and exceeds the notifications-OFF baseline at all message sizes. The biggest wins are at mid-range sizes (4-64 KB) where the separate notification SEND was the dominant overhead.
At the KV cache transfer size used by vLLM (~128 KB per block), the improvement is ~18-27% — modest but measurable since the notification round-trip is a smaller fraction of total transfer time at larger sizes.
What Gets Eliminated (per write transfer with N QPs)
ibv_post_sendcalls for notificationRdmaNotifyTransfer()function callWhat Stays the Same
IBV_WR_SENDnotification pathFiles Changed
src/io/rdma/common.hpp—PackWriteImmediate/UnpackWriteImmediatehelpers,useWriteImm+perEpImmDatafields inRdmaTransferControlsrc/io/rdma/common.cpp— Set last WR opcode toIBV_WR_RDMA_WRITE_WITH_IMMwhencontrol.useWriteImmsrc/io/rdma/backend_impl.hpp— AddNotifManager*toRdmaBackendSession, seq-to-ID mapping inNotifManagersrc/io/rdma/backend_impl.cpp—AllocImmSeq/ResolveImmSeq,IBV_WC_RECV_RDMA_WITH_IMMCQE handler, wire imm through session ReadWrite/BatchReadWritetests/python/io/benchmark.py— Add--enable-notificationCLI flagTest plan
--enable-notification --op-type write— verified on MI350X + AINIC cluster--enable-notification— verified no regression🤖 Generated with Claude Code