這個的作用就是爲了提高性能。
當分析網絡數據時,可以爲網口提供多個接收隊列,每個cpu處理一個隊列。
如果每條隊列是獨立的,那麼就可以很好的併發。
這裏有兩個問題,一個是數據需要平均的分配到每個隊列;二是同一組數據需要分配到同一個隊列。
rss就是這個作用,可以設定以ip進行區分,或者以端口進行區分。
比如以ip進行區分,那麼dpdk會根據網絡包的ip創建一個哈希值,相同ip的網絡包,哈希值一致,也會進入同一個接收隊列。
可以從獲取到的dpdk的rte_mbuf結構體的hash.rss
查看生成的哈希值。如果哈希值都是0,則表示配置失敗。
如何開啓rss,需要通過api rte_eth_dev_configure
設置,其配置如下
static const struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = RTE_ETH_MQ_RX_RSS,//表示打開rss
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = NULL,//自定義rsskey,如果不設置,則使用默認的
.rss_key_len = 0,//如果設定了自定義key,需要指定自定義rsskey的大小
.rss_hf = RTE_ETH_RSS_IPV4,//rss類型,這裏就是根據ipv4區分
},
},
};
上面有幾點需要注意:
- 之所以需要自定義rsskey,是因爲默認rsskey會把ip往返的數據所做兩種哈希值,也就是a->b的網絡包與b->a的網絡包認爲是不同的。實際上確實是不同的,但是往往我們開發是需要放到一個隊列計算,所以有專門的rsskey,可以屏蔽方向,把a->b和b->a的包都算作相同的。
- rss_hf指定的rss類型並不是所有網卡都通用的,這個需要根據對應的設備來確定,如果設置錯誤,會導致dpdk無法運行,並且報錯
Ethdev port_id=0 invalid rss_hf: 0xa38c, valid value: 0x38d34
我們可以通過dpdk的rte_eth_dev_info_get
獲取網卡的設備信息,在其獲得的rte_eth_dev_info
結構體中,有一個字段flow_type_rss_offloads
給定了網卡支持的rss類型,可以通過位預算與上進行判斷是否支持。這是一個bit mask
dpdk設定的常見的幾種rss規則如下
#define RTE_ETH_RSS_IP ( \
RTE_ETH_RSS_IPV4 | \
RTE_ETH_RSS_FRAG_IPV4 | \
RTE_ETH_RSS_NONFRAG_IPV4_OTHER | \
RTE_ETH_RSS_IPV6 | \
RTE_ETH_RSS_FRAG_IPV6 | \
RTE_ETH_RSS_NONFRAG_IPV6_OTHER | \
RTE_ETH_RSS_IPV6_EX)
#define RTE_ETH_RSS_UDP ( \
RTE_ETH_RSS_NONFRAG_IPV4_UDP | \
RTE_ETH_RSS_NONFRAG_IPV6_UDP | \
RTE_ETH_RSS_IPV6_UDP_EX)
#define RTE_ETH_RSS_TCP ( \
RTE_ETH_RSS_NONFRAG_IPV4_TCP | \
RTE_ETH_RSS_NONFRAG_IPV6_TCP | \
RTE_ETH_RSS_IPV6_TCP_EX)
實際上我們可以設定多重rss規則,當其中一種不符合條件時,會用另一種進行匹配。
上面的意思都比較明確,FRAG表示分片包如何處理