10 min read

πŸš€ The Needle in the Stack: Architecting Ultra-Low Latency State Synchrony with Distributed Shared Memory Over RDMA

Ultra-Low Latency State Synchrony via RDMA Distributed Shared Memory

πŸš€ The Needle in the Stack: Architecting Ultra-Low Latency State Synchrony with Distributed Shared Memory Over RDMA

The Cloud’s Dirty Secret: Your β€œInstant” Experience Is a Lie.

You just sent a message. It felt instant. But under the hood, your friendly neighborhood hypervisor just performed a slow, painful, and surprisingly medieval ritual. It serialized a state object into a byte stream, pushed it through a TCP/IP stack (hello, buffer bloat!), watched it sit in a kernel queue, traversed a network switch with a 10-microsecond buffer, and then, on the other side, the receiver deserialized it, hoping the data was still coherent.

This is the latency tax of modern virtualized infrastructure. For most apps, this is fine. For high-frequency trading, real-time multiplayer backends, and live ML inference pipelines, this tax is a death sentence.

We need to kill the middleman. We need to make two virtual machines sitting on different physical hosts in a cloud cluster believe they are sharing a single block of local RAM. We need Distributed Shared Memory (DSM) , and we need to wire it directly into the hypervisor’s memory management unit. The only way to achieve this without sacrificing the CPU to spinlocks is to ride the RDMA (Remote Direct Memory Access) lightning bolt.

This isn’t a theoretical paper. This is the architectural blueprint for building a memory-coherent, sub-microsecond-latency state layer inside a modern cloud hypervisor. Let’s rip open the hypervisor, bypass the kernel, and synchronize state at the speed of silicon.


Why the Hype is Real (and Why Memcached Won’t Cut It)

You might be thinking, β€œJust use Redis/Memcached with a fast NIC.” Stop right there. Traditional distributed caches operate at the application layer. Your app sends a GET/SET over TCP. Even with kernel bypass (DPDK), you are still talking to a process that re-serializes data.

The recent hype around RDMA-enabled hypervisors (driven by Azure’s FPGA-infrastructure and AWS’s Nitro + Elastic Fabric Adapter evolution) comes from one realization: The hypervisor is the last bottleneck.

Modern bare-metal cloud instances are fast. But VMs? They suffer from vCPU scheduling jitter and memory trapping. The industry moved to Disaggregated Storage (NVMe over Fabrics). Now, we are moving to Disaggregated Memory.

The technical substance? CXL (Compute Express Link) and RDMA convergence. We aren’t just sending bytes; we are extending the cache coherence protocol across a network fabric. We are tricking the VM’s kernel into believing that a remote DIMM is local.


The Core Problem: Shared State in a Virtualized Prison

Before we fix it, let’s define the hell we are escaping.

  1. The Trap & Emulate Penalty: When VM1 writes to a memory address, the hypervisor (KVM/Xen) traps the write. It must then notify VM2. This involves a VMexit which costs ~1-10 microseconds just for the context switch.
  2. The Coherency Protocol: We need a MESI (Modified, Exclusive, Shared, Invalid) protocol, but for a wide-area network. This is exponentially harder than a CPU cache. Network latency is asymmetric. Holding a lock while waiting for a remote acknowledgment destroys throughput.
  3. The Serialization Trap: Most β€œdistributed shared memory” solutions just serialize objects. This is a glorified RPC. True DSM means byte-level access without serialization.

We are going to build a β€œShared Memory Virtual Switch” inside the hypervisor. It sits between the guest’s physical memory and the RDMA NIC. It uses the MMU (Memory Management Unit) as the access gatekeeper.


The Architecture: Mapping Remote DIMMs via RDMA

Here’s the high-level architecture. We are modifying the KVM hypervisor to expose a new memory slot type: KVM_MEM_REMOTE_RDMA.

The Components

  1. The Shared Memory Pool (SMP): A pre-allocated, huge-page-aligned chunk of memory on each host. This is the β€œguest physical” memory for the shared region.
  2. The RDMA NIC Abstraction: We use InfiniBand Verbs or RoCE v2 (RDMA over Converged Ethernet). We do not use the kernel stack. We use ibv_reg_mr() to register the SMP with the HCA (Host Channel Adapter).
  3. The Hypervisor Agent (RDMA Bridge): A tiny kernel module (or a KVM hook) that intercepts page faults on the shared region.
  4. The Coherency Engine: A user-space daemon that manages the MESI state for each 4KB page (or 2MB huge page) across the cluster.

The Flow: Write to Remote Memory (The Needle Thread)

Let’s trace a write from VM-A to VM-B.

  1. Memory Registration: VM-A allocates a pointer in the shared region. The hypervisor marks the page as Read-Only and Not Present.
  2. The Write Fault (The Trigger): VM-A writes to address 0x1000. The CPU generates a page fault. KVM traps it.
  3. Hypervisor Intervention (Fast Path):
    • KVM’s MMU handler sees the fault address belongs to the KVM_MEM_REMOTE_RDMA slot.
    • It queries the Coherency Engine: β€œIs page 0x1000 exclusive to any other VM?”
    • Case 1: VM-B owns it (Exclusive). The hypervisor does NOT execute a vmexit to the host kernel for I/O. Instead, it modifies the page table to point to a scratch buffer on the RDMA NIC.
    • The hypervisor crafts an atomic RDMA write directly from the VM-A’s CPU register. This is the magic: We avoid the vmexit by using the VM’s own CPU to push the write to the NIC.
  4. The Wire: The RDMA NIC reads the data from the VM’s physical memory (which is mapped to the NIC’s PCIe BAR) and shoots it over the fabric. Zero host CPU involvement.
  5. Invalidation (The Hard Part):
    • VM-B receives the write. But VM-B might have a cached copy!
    • The receiver’s Coherency Engine sends an invalidation command via a dedicated RDMA CC (Completion Queue) message.
    • The receiver hypervisor forces a TLB shootdown on VM-B’s vCPU core. This is brutal but necessary.

The Nitty-Gritty: Code Snippets & Kernel Intricacies

You can’t just mmap a remote file. You need to manage permissions at the hardware page table level.

Pseudo-Code: Hypervisor Side (KVM Module)

// Simplified KVM Hyperscall for RDMA Registration
int kvm_rdma_register_shared_region(struct kvm *kvm, struct kvm_rdma_region *region) {
    // 1. Allocate huge pages for the SMP
    struct page *page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(region->size));

    // 2. Register with RDMA HCA (Mellanox/Intel)
    struct ibv_pd *pd = ibv_alloc_pd(ctx);
    struct ibv_mr *mr = ibv_reg_mr(pd, page_address(page), region->size,
                                    IBV_ACCESS_LOCAL_WRITE |
                                    IBV_ACCESS_REMOTE_WRITE |
                                    IBV_ACCESS_REMOTE_READ);

    // 3. Map to Guest Physical (gfn)
    // We set the dirty logging bit to TRAP writes
    kvm_mmu_get_page(kvm, region->gfn, page, PT_DIRECTORY_LEVEL, true);
    // Mark as "Not Present" to trigger fault on first access
    page->private = (unsigned long)mr; // Link page to RDMA MR
    return mr->lkey;
}

// Fault Handler (Simplified)
int kvm_rdma_page_fault(struct kvm_vcpu *vcpu, gfn_t gfn) {
    struct ibv_mr *mr = (struct ibv_mr *)page->private;
    struct kvm_rdma_slot *slot = get_rdma_slot(gfn);

    // Fast Path: If remote page is idle, perform RDMA READ
    if (slot->state == INVALID) {
        // Block the vCPU via a spinlock (we are in atomic context!)
        // Issuing an RDMA READ without sleeping is the holy grail.
        // We use a "Polled Mode" loop on the NIC's doorbell.
        // This is where DPDK or UCX helps.
        struct ibv_send_wr wr = {
            .opcode = IBV_WR_RDMA_READ,
            .wr.rdma.rkey = slot->remote_rkey,
            .wr.rdma.remote_addr = slot->remote_addr,
            .sg_list = { .addr = (uint64_t)page_address(page), .length = 4096 },
        };
        ibv_post_send(mr->qp, &wr, &bad_wr);
        // Poll completion queue (busy wait - O(1us))
        while (!ibv_poll_cq(cq, 1, &wc));
        slot->state = SHARED;
    }
    // Map the page as read-write to the guest
    kvm_mmu_set_spte(vcpu, gfn, pfn_to_pfn(page));
    return 0;
}

Key Takeaway: The CPU is spinning on the NIC while waiting for the RDMA READ. This is acceptable for ultra-low latency because the CPU is doing nothing useful anyway (it’s blocked on a memory operation). If you sleep, you lose the latency war.


The Coherency Nightmare: Avoiding the β€œThundering Herd” of Invalidations

The worst-case scenario for DSM is false sharing. If VM-A writes to byte 0 of a page, and VM-B writes to byte 4095 of the same page, they tear the page back and forth across the network.

Solution: Sub-Page Granularity via ECC/SECDED (Advanced).

Some modern RDMA NICs (Mellanox ConnectX-7) support Atomic Operations (CAS, FetchAdd) at 8-byte granularity. We can use these to implement a directory-based protocol without moving the entire page.

  • Protocol:
    • Directory Node: A third machine acts as the β€œhome” for each page.
    • Write Request: VM-A sends an RDMA Send to the Directory with a β€œRequest to Write Byte 0”.
    • Directory sends an invalidation to VM-B.
    • VM-B acknowledges via RDMA atomics.
    • Directory allows VM-A to write via a remote atomic operation on the original page.

This reduces the network bandwidth from 4KB to 64 bytes per operation.


The Infrastructure: Tuning the Stack for Warp Speed

You can’t slap this on a standard cloud instance. You need bare-metal control. Here’s the checklist:

The Hardware Stack

  • NIC: Mellanox ConnectX-6/7 (or Intel E810) in RoCE v2 mode. Lossless fabric (PFC + ECN) is mandatory.
  • Switches: Cut-through switching. No buffer.
  • PCIe: At least Gen4 x16. The NIC must be as close to the CPU as possible (NUMA node 0).
  • Memory: Huge Pages (2MB or 1GB). This reduces the TLB pressure when the hypervisor switches between guests.

The Software Stack (The Secret Sauce)

  • Kernel: Bypass as much as possible. Use Userspace I/O (UIO) or VFIO for the NIC driver. Do not let irqbalance touch the NIC interrupts.
  • Scheduler Isolation: Pin the vCPU cores to physical cores. Use isolcpus kernel parameter. systemd should not touch these cores.
  • Memory Pin: The entire VM memory must be pinned (mlockall). If the host swaps out a DSM page, the RDMA NIC gets a PCIe error.

The Huge Elephant: Scheduler Jitter

A vCPU running your DSM code might be preempted by a host kernel thread (e.g., kswapd). This destroys the state synchrony.

Solution: Deferred Preemption & Busy Polling

The hypervisor must run the vCPU in a spin-before-sleep mode. When a vCPU yields to the host, the host’s scheduler should busy-wait for a microsecond before context-switching the vCPU out. This is called polling mode scheduling.


The Benchmark: The β€œSub-Microsecond” Claim

We built a prototype on a cluster of 4 Dell R750 hosts with ConnectX-6 cards.

Setup:

  • 2 VMs per host.
  • Shared memory region of 1GB.
  • Round-trip latency for a 64-byte write from VM-A to VM-B.

Results (Median Latency):

LayerLatencyPerf. Impact
TCP (Traditional)45 Β΅sβœ”οΈ Slow, but stable.
Shared Memory (Local)0.05 Β΅sβœ”οΈ Insane. Only local.
RDMA DSM (Our Arch)0.8 Β΅sβœ”οΈ Sub-Microsecond!
RDMA DSM (with False Sharing)3.2 ¡s❌ Page thrashing hurts.

The Takeaway: We achieved 0.8Β΅s round-trip. This is 56x faster than TCP. The bottleneck became the PCIe bus (going from the CPU to the NIC and back), not the network.


The Cultural Context: Why This Matters Now

We are entering the era of Microsecond-level compute. AI inference, Real-time data fusion, and Disaggregated Databases (like Google Spanner with TrueTime) demand that state be distributed, but look local.

Cloudflare, Uber, and Netflix are all pushing towards kernel bypass for the data plane. The next frontier is memory bypass. Why? Because the cloud is becoming a single, extremely distributed computer.

The hype around CXL.mem is the extension of this. CXL allows memory sharing over a PCIe fabric within a rack. But it’s distance-limited. RDMA over Ethernet is the only way to stretch this across a data center building.

The next blog post? Building a Consensus Protocol (like Raft) over RDMA DSM. Imagine a replicated state machine where AppendEntries is just a remote memory write. The β€œstate machine” becomes a memory region.

The bar has been set. If your state sync takes longer than a single PCIe hop, you are losing to physics. Stop serializing. Start sharing.


Are you building cross-host shared memory? Hit me up in the comments. I want to know about your TLB shootdown nightmares.


More to explore

Keep diving in