DPDK-22.11.2 [六] RSS receive side scaling 网卡分流机制

这个的作用就是为了提高性能。
当分析网络数据时,可以为网口提供多个接收队列,每个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表示分片包如何处理

posted @ 2024-02-05 14:57  秋来叶黄  阅读(425)  评论(0编辑  收藏  举报