Atomics
| Opcode | Extended headers | Notes |
|---|---|---|
COMPARE_SWAP | BTH + ATMETH | conditional swap against a 64-bit remote word |
FETCH_ADD | BTH + ATMETH | add to a 64-bit remote word, return the prior value |
ATOMIC_ACKNOWLEDGE | BTH + AETH + ATMACK | atomic-specific ack, returns the pre-operation value |
ATOMIC_ACKNOWLEDGE is the atomic family’s own response. The plain ACKNOWLEDGE (BTH + AETH), the ACK or NAK for any SEND or RDMA WRITE message, belongs to no family: it is the reliability layer’s response to SEND and WRITE alike.
Atomics have no FIRST/MIDDLE/LAST variants at all — both operations act on a single fixed 64-bit value, so there is no such thing as a multi-packet atomic message to frame.
Atomics are the one family that costs more at the responder than a plain DMA write does. COMPARE_SWAP and FETCH_ADD both require an in-hardware read-modify-write at the responder’s memory: read the current 64-bit value, then either conditionally replace it (compare against ATMETH’s comparand, swap only on match) or add to it, atomically with respect to any other operation touching that same word — and then hand the pre-operation value back to the requester in ATOMIC_ACKNOWLEDGE’s ATMACK field, so the requester knows what was actually there before its atomic executed. A WRITE places data; an Atomic reads, computes, and conditionally replaces, all as one indivisible responder-side action — a memory-side compute operation, not just a placement, and meaningfully more hardware than the rest of this catalog needs.
Compare and Swap
A compare-and-swap that succeeds, with the original value coming back:
All 6 steps
- The application asks for a compare and swap on a remote 64-bit word: if it holds 5, make it 9. The WQE and the Send Queue Descriptor
- The request is one packet with an ATMETH: target address, rkey, swap value and compare value. The target must be 8-byte aligned. A local buffer, under an lkey, waits for the reply. Atomics
- PSN check, then the rkey, which this time must carry remote atomic permission. Permission and Bounds Violations
- It reads 5, finds it equal to the compare value, and writes 9, as one indivisible read-modify-write. A WRITE only places bytes; this computes on them. Atomics
- It sends back the value it found, 5, not the one it wrote. ATOMIC_ACKNOWLEDGE carries it in the ATMACK, and the requester writes it to the reply buffer. Atomics
- Only if the Work Request was signaled: The completion posts. Software sees 5 come back, equal to its compare value, and knows the swap happened. Had the word held 7, it would get 7 back and nothing would have changed. CQE Generation
The same operation across both hosts. The atomic unit on RNIC B is the one block no other family lights, and the read, the compare and the write happen there as a single step.
All 9 steps
- On Host A (Requester). The application writes a COMPARE_SWAP WQE: a remote 64-bit word and its rkey, compare value 5, swap value 9, and a local buffer for the reply. It rings the doorbell. The Send Queue Ring
- RNIC A reads the WQE out of host memory and looks up the QP’s context. WQE Prefetch
- Both operands are in the WQE itself, so no payload is read from Host A’s memory. The Key Cache checks the lkey on the reply buffer, and TX Packet Build sends one packet: a BTH and an ATMETH. The Gather Path
- On Host B (Responder). RX Parse checks the PSN, and the Key Cache checks the rkey. This time the region must allow remote atomics, and the address must be 8-byte aligned. Permission and Bounds Violations
- The atomic unit reads the target word through the DMA engine. It holds 5. Target Selection
- 9 is written, and nothing else touches the word between the read and the write: the two are one indivisible step. How hardware makes them indivisible is the adapter’s choice. Linux’s soft-RoCE driver holds a lock across both; PCIe also defines atomic operations a device can ask the host to perform. Target Selection
- RNIC B’s TX path builds ATOMIC_ACKNOWLEDGE. Its ATMACK carries the value the word held before, 5, not the 9 just written. Atomics
- The reply returns (Requester). RNIC A matches the acknowledgement, retires the Replay Buffer entry, and writes the 8-byte original value into the reply buffer. The Scatter Path
- Only if the Work Request was signaled: The completion posts. The application sees 5, equal to its compare value, and knows the swap happened. Had the word held 7, it would read 7 back, and RNIC B would have skipped the write. CQE Generation
Fetch and Add
Fetch and Add always writes: it adds its operand to the word and returns what was there before. That makes a resent request dangerous in a way a resent WRITE never is. A WRITE placed twice leaves the same bytes; an add run twice counts twice. So the responder keeps the original value of each recent atomic, and answers a duplicate from what it kept instead of running it again.
All 11 steps
- The application asks to add 1 to a remote 64-bit counter and get back what it held before. The WQE and the Send Queue Descriptor
- The request is one packet: a BTH and an ATMETH carrying the address, the rkey and the add value. It gets a Replay Buffer entry and the retry timer arms, like any request. The Replay Buffer
- PSN check, then the rkey, which must allow remote atomics on an 8-byte-aligned address. Permission and Bounds Violations
- The responder reads 41 and writes 42 as one indivisible read-modify-write. Fetch and Add always writes; there is no compare to fail. Atomics
- It keeps 41 alongside PSN 3100. Nothing needs it yet. QP Context
- The ATOMIC_ACKNOWLEDGE carrying 41 is lost in the fabric. Go-Back-N Retransmission
- No acknowledgement arrives, the ACK timeout expires, and the requester rebuilds PSN 3100 from the Replay Buffer. Retry and Timeout State
- Not add again. PSN 3100 is below the expected 3101, so it is a duplicate. The responder finds the 41 it kept for that PSN and sends it back without touching the counter. If the saved value were already gone, Linux’s soft-RoCE driver would drop the request rather than run it. PSN Check and Out-of-Order Arrival
- This acknowledgement gets through, with the original value in its ATMACK. Atomics
- The requester writes 41 to the reply buffer and retires the entry. The counter holds 42: one add, though the request crossed the wire twice. The Scatter Path
- Only if the Work Request was signaled: The send completion posts with 41 in the reply buffer. CQE Generation
All 12 steps
- On Host A (Requester). The application writes a FETCH_ADD WQE: a remote 64-bit counter and its rkey, an add value of 1, and a local buffer for the reply. It rings the doorbell. The Send Queue Ring
- RNIC A reads the WQE out of host memory and looks up the QP’s context. WQE Prefetch
- After the lkey check on the reply buffer, TX Packet Build sends a BTH and an ATMETH carrying the add value; the compare field goes unused. A Replay Buffer entry is recorded and the retry timer arms. The Replay Buffer
- On Host B (Responder). RX Parse checks the PSN, and the Key Cache checks the rkey for remote atomic permission on an 8-byte-aligned address. Permission and Bounds Violations
- The atomic unit reads the counter. It holds 41. Target Selection
- It writes 42, as part of the same indivisible step. Unlike Compare and Swap, Fetch and Add always writes. Target Selection
- RNIC B keeps the original value, 41, with the request’s PSN, then sends ATOMIC_ACKNOWLEDGE. The acknowledgement is lost in the fabric and never reaches RNIC A. Go-Back-N Retransmission
- The resend (Requester). RNIC A’s retry timer expires. It rebuilds FETCH_ADD PSN 3100 from the Replay Buffer and sends it again, unchanged. Retry and Timeout State
- The duplicate (Responder). No. RNIC B expects 3101, so 3100 is a duplicate. It is not executed again: RNIC B finds the 41 it kept for that PSN, and Host B’s memory is not touched. PSN Check and Out-of-Order Arrival
- The acknowledgement goes again, with the same original value, 41. Atomics
- The reply returns (Requester). RNIC A writes 41 into the reply buffer and retires the Replay Buffer entry. The counter on Host B holds 42: the add ran once, though the request crossed the wire twice. The Scatter Path
- Only if the Work Request was signaled: The completion posts to Host A’s Completion Queue. CQE Generation
References
- InfiniBand Trade Association, InfiniBand™ Architecture Specification, Volume 1 (General Specifications).
- Linux kernel soft-RoCE driver,
drivers/infiniband/sw/rxe/–rxe_mr.c(rxe_mr_do_atomic_op) rejects an unaligned target and performs the read, compare or add, and write under one lock;rxe_resp.c(atomic_reply,duplicate_request) saves the original value with the request’s PSN and replays it for a duplicate instead of executing again.