Going beyond RSS (Receive-Side Scaling)

Posted · Add Comment

When RSS was introduced some years ago, operating systems had the chance to scale also when handling network packets as RSS allowed incoming packets to be distributed across processor cores.

Unfortunately RSS uses a one-way hash, that while distributes packets heavenly across queues, it has some drawbacks. The main one is that if you have a connection A <-> B, packets A->B will go on queue X, and those of B->A on queue Y, where X <> Y. This is a major issue for applications, as you cannot assume that each RX queue is “self-contained”, being packets shuffled across RX queues. Applications such as those that analyze traffic, and also IDS/IPS such as Suricata and Snort are affected by this issue.

In order to overcome this limitation, PF_RING is now featuring a new API call:

int pfring_enable_rss_rehash(pfring *ring);

If you call it on your applications sitting on top of multi-queue adapters (with single-queue adapters,of course, it has no effect) incoming packets will be rehashed using a bi-directional hash function. In this case, in the above example X == Y, thus you can insulate apps per RX queue. Note that the above call is effective on all driver types (PF_RING-aware and TNAPI). Its cost is basically zero, as PF_RING always parses incoming packets, thus hashing them is a very little cost.

It’s now time to use multi-queue RX adapters.