本文将mark下virtio-net中RSS(Receive Side Scaling)的具体实现。

Spec描述

VIRTIO_NET_F_RSS

5.1.6.4.3 Hash calculation for incoming packets

5.1.6.4.3.1 Supported/enabled hash types

RSS需要通过ctrl q去下发配置参数,所以VIRTIO_NET_F_RSS Requires VIRTIO_NET_F_CTRL_VQ,需要ctrl q。
5.1.6.5.7 Receive-side scaling (RSS)

struct virtio_net_rss_config

研究明白struct virtio_net_rss_config即可理解virtio-net RSS的实现细节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct rss_rq_id { 
le16 vq_index_1_16: 15; /* Bits 1 to 16 of the virtqueue index */
le16 reserved: 1; /* Set to zero */
};

struct virtio_net_rss_config {
le32 hash_types;
le16 indirection_table_mask;
struct rss_rq_id unclassified_queue;
struct rss_rq_id indirection_table[indirection_table_length];
le16 max_tx_vq;
u8 hash_key_length;
u8 hash_key_data[hash_key_length];
};

hash_types

通过hash_types,比如可以选择(Source IP address,Destination IP address,Source TCP port,Destination TCP port)这个四元组作为RSS Input Fields,也可以选择(Source IP address,Destination IP address)这个二元组作为RSS Input Fields。

indirection_table_mask


indirection_table_mask就是上图中的LSB。例如indirection_table_mask为0x111,那么RSS Redirection Table的size就是8。

hash_key_length和hash_key_data

hash_key_length和hash_key_data就代表上图中的Hash Key。

struct rss_rq_id

1
2
3
4
struct rss_rq_id { 
le16 vq_index_1_16: 15; /* Bits 1 to 16 of the virtqueue index */
le16 reserved: 1; /* Set to zero */
};

rss_rq_id is a receive virtqueue id.vq_index_1_16 consists of bits 1 to 16 of a virtqueue index. For example, a vq_index_1_16 value of 3 corresponds to virtqueue index 6, which maps to receiveq4.

vq_id vq
0 rxq1
1 txq1
2 rxq2
3 txq2
4 rxq3
5 txq3
6 rxq4
7 txq4

如果vq_index_1_16为3,那么rss_rq_id就是6(0x110),对应于rxq4。

unclassified_queue

Field unclassified_queue specifies the receive virtqueue id in which to place unclassified packets.

indirection_table

Field indirection_table is an array of receive virtqueues ids.

总结

The device MUST determine the destination queue for a network packet as follows:

  1. Calculate the hash of the packet.
  2. If the device did not calculate the hash for the specific packet, the device directs the packet to the receiveq specified by unclassified_queue of virtio_net_rss_config structure.
  3. Apply indirection_table_maskto the calculated hash and use the result as the index in the indirection table to get the destination receive virtqueue id.
  4. If the destination receive queue is being reset, the device MUST drop the packet.

参考资料:

  1. VIRTIO 1.3 spec