๐ฏ Receive steering & virtualization
Getting each packet to the right queue, core, and cache line โ across processes, guests, and CPUs.
5.1 Filtering: flow to queue
The problem: demux without a syscall. Once the kernel is out of the receive path, the NIC itself has to answer a hard question for every arriving frame: which of potentially thousands of endpoints does this packet belong to, and which queue โ which user-level VI, which process, which core โ should receive it? A modern host might run many Onload or ef_vi applications, each owning private receive queues, plus the ordinary kernel stack. The NIC must demultiplex incoming traffic onto exactly the right queue at line rate, because there is no longer a kernel demux step in the common case to clean up after a sloppy hardware decision.
Why not a giant CAM. The textbook hardware answer to "match this key against a table of flows" is a content-addressable memory: present the 5-tuple, every entry compares in parallel, you get the index in one cycle. CAMs are wonderful and brutally expensive โ area, power, and heat scale with the number of entries, and a NIC that must hold tens of thousands of active flow filters cannot afford a CAM that large. Worse, a CAM gives you a fixed capacity ceiling; you cannot trade a little latency for a lot more entries. For a device whose whole reason to exist is to be cheap-per-flow and scale to many user-space sockets, a fully associative match on every filter is the wrong shape.
`US7984180B2` / `US8959095B2` โ the bounded-hash filter table. The Solarflare answer is a hardware-friendly hash over the relevant packet header fields โ protocol plus source/destination address and port, the usual 5-tuple material โ used to index a receive-filter table held in ordinary (cheap, dense) memory rather than a CAM. The hash points at a bucket; the hardware then searches a bounded number of entries from there looking for a real match on the full header fields. The crucial word is bounded: the search is capped at a fixed, small number of probes. If a matching filter is found within that limit, the packet is steered to the queue that filter names. If no match appears within the search budget, the lookup does not keep walking the table chasing a possible far-away entry โ it stops and takes the fallback path. That cap is what turns an associative-match problem into a constant-time hardware operation with a predictable worst case.
Why bounded search is the whole point for tail latency. An unbounded probe sequence โ keep hashing and re-probing until you either find the entry or exhaust the table โ has a worst case proportional to table occupancy, and worst cases are exactly what a low-latency NIC cannot have. Tail latency, not average latency, is what kills a trading feed handler or a tightly-coupled RPC fabric. A filter lookup whose duration depends on how full the table is, or on an adversary's ability to provoke collisions, injects jitter into every single received packet. Capping the search makes the per-packet classification cost a flat, known quantity regardless of how many flows are installed, which is precisely the property you want to reason about when you are accounting for nanoseconds.
Why the kernel fallback path matters. A bounded search means the NIC will sometimes fail to resolve a packet to a user-level queue even though, in principle, an entry might have fit further down a longer probe chain โ and it will also see plenty of legitimate traffic for which no user filter exists at all (ARP, ICMP, control packets, connections still owned by the ordinary stack, brand-new flows not yet installed). Rather than drop these or stall, the filter delivers them to a default/kernel queue. This is the safety valve that makes the whole scheme shippable: the fast hardware path handles the overwhelming common case in constant time, and anything it cannot cheaply classify falls through to trusted kernel software, which has the full routing state and all the time it needs to do the slow, correct thing. The hardware is allowed to be fast and occasionally give up, because giving up is well-defined and lands somewhere safe. That is the same split that runs through the rest of the portfolio โ latency-critical work in the cheap fast path, correctness and the awkward residual cases owned by trusted software.
Sources
5.2 Virtual RSS, placement & switching
Steering is only half the job. Filtering answers "which queue?" but a queue is just an address. The deeper claim across this cluster of patents is that getting the packet to the right queue is useless unless the software state that queue touches is also partitioned for locality and ordering. A packet steered to core 3 that then has to grab a lock owned by core 11, or DMA into memory on the wrong NUMA node, or land in a cache line another core is writing, has not been steered well โ it has just moved the contention somewhere harder to see. These four patents are about making the destination, not just the route, correct.
`US8543729B2` โ virtualised RSS: domain first, then channel. Classic RSS hashes the 5-tuple and uses the result to index one global indirection table that maps flows across CPUs, spreading load while keeping each flow pinned to one core for ordering and cache reuse. That breaks down the moment the host is virtualised. Different guests and user domains have different CPU sets, different notification channels, and different trust boundaries; a single global table cannot express "spread guest A's flows across its three vCPUs and guest B's across its two" without leaking one tenant's steering into another's. The patent's answer is two-stage: first map the packet to a software domain or VNIC, then apply a per-domain RSS table to pick the channel/CPU within that domain. Each tenant gets its own scaling policy, its own core affinity, and its own ordering guarantees, while the hardware still does the hash. This preserves both isolation between domains and per-flow locality inside a domain โ the two things one flat table cannot give you at once.
`US8286193B2` โ direct placement into the right buffer. Choosing a queue and core is wasted if the data then takes a detour through hypervisor or kernel buffers before reaching the application. This patent covers placing received data directly into the correct user-level or VI receive buffer, so a packet destined for a guest or a user-space stack lands in that consumer's own memory without an intermediate copy through privileged software. Every avoided copy is bytes you do not push through the memory system twice and a cache footprint you do not pollute โ and for virtualised I/O it removes the hypervisor from the per-packet hot path entirely, which is where the bulk of the latency and CPU cost of naive virtual networking lives.
`US10838763B2` โ the descriptor picks the cache line. This pushes placement down to the finest grain: the receive descriptor the host posts can select which host cache location receives the data. On a multi-socket machine, where a buffer physically lives โ which NUMA node, and whether it is steered into a cache close to the consuming core โ determines whether the consumer's first touch is a fast local hit or a slow cross-socket miss. By letting the descriptor name the destination, the software that knows which core will process this flow can ensure the data arrives where that core can read it cheaply. This is the hardware hook behind the "fast networking is a cache/NUMA-locality problem" theme: steer to a core and place the bytes in that core's neighbourhood, or the steering buys you nothing.
`US8423639B2` โ switching API: steering is not static. All of the above assumes the forwarding state is correct, but in a virtualised datacentre it changes constantly โ VMs migrate, virtual networks are reconfigured, endpoints move between hosts. This patent describes a control-plane interface for updating the routing/forwarding tables in switching entities (NICs, hypervisors, soft switches that route to virtual interfaces or guest domains), including trapping control packets and applying route-table updates at the NIC or driver level. It is the mechanism that keeps the fast steering path coherent while the topology underneath it shifts: when a guest migrates, its filters and forwarding entries must follow it without dropping flows or violating ordering. Steering is a moving target, and this is the trusted-software API that re-aims it.
Why this matters for tail latency and isolation. Read together, the throughline is that locality is something you engineer end to end, not something RSS hands you for free. Per-domain scaling tables keep tenants from interfering with each other's affinity; direct placement and cache-line selection keep the consuming core's first touch local; the switching API keeps all of it correct as VMs move. Skip any one and you reintroduce the costs kernel bypass set out to remove โ cross-core locking, copies, cache bouncing, NUMA misses โ exactly the jitter that shows up in the tail.
Sources