Receive side scaling (RSS)

Reference

http://galsagie.github.io/2015/02/26/dpdk-tips-1/

What is RSS?

Receive side scaling (RSS) is a network driver technology that enables the efficient distribution of network receive processing across multiple CPUs in multiprocessor systems.

What it does is issue a hash function with a predefined hash key on every packet coming in. The hash function takes the packet IP addresses, the protocol (UDP or TCP) and the ports (5 tuple) as the key and calculate the hash value. (RSS hash function can take only 2,3 or 4 tuples to create the key if configured so).

A number of least significant bits (LSBs) of the hash value are used to index an indirection table. The values in the indirection table are used to assign the received data to a CPU.

This means a multi process application can use the hardware to distribute and split the traffic between the CPU’s. The use of the indirection table in the process is very use full for implementing dynamic load balancing as the indirection table can be reprogrammed by the driver/application.

Symmetric RSS

It is very important in networking applications to have the same CPU handle two sides of the connection, what is called symmetrical flow. Many networking applications needs to save information about the connection, and you dont want this information shared between two CPU’s, this introduce locking which is bad performance wise.

RSS algorithm is usually using the Toeplitz hash function, this function takes two inputs: the static hash key and the tuples which are extracted from the packet.

The problem is that the default hash key that is used in DPDK (and is the recommended key from Microsoft) does not distribute symmetrical flows to the same CPU.

For example if we have the following packet {src ip=1.1.1.1, dst ip=2.2.2.2, src port=123, dst port=88} then the symmetrical packet {src ip=2.2.2.2, dst ip=1.1.1.1, src port=88, dst port=123} might not have the same hash result.

I dont want to get too much into the hash calculation internals, but one can achieve symmetric RSS by changing the hash key (which as i showed earlier can be changed in DPDK configuration) such that the first 32 bits of the key need to be identical to the second 32 bits, and the 16 bits afterwards should be identical to the next 16 bits.

Using that key achieve symmetrical RSS, the problem is that changing this leads to bad distribution of the traffic between the different cores.

But fear not! as there is a solution to this problem. A group of smart people found that there is a specific hash key which gives you both symmetrical flow distribution and a uniform one which is same with the default key)

You can read about it in their published paper.

I can say that i did some tests to check the uniform distribution of this key with random ip traffic and found it to be good (and symmetrical). The hash key (in case you dont want to read the document) is:

static uint8_t hash_key[RSS_HASH_KEY_LENGTH] = { 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, };

You can configure DPDK to use it in the RSS advance configuration structure as shown above.

Leave a comment