dpdk-18.11网卡多队列RSS设置
背景
最近在做将基于dpdk-16.11.1开发的程序,转移到基于dpdk-18.11版本下开发。遇到了网卡RSS配置的问题,在这里纪录一下。
问题
dpdk-16.11.1
在dpdk-16.11.1上的程序如下:
static uint8_t rss_intel_key[] = { 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
};
static const struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.split_hdr_size = ,
.header_split = , /**< Header Split disabled */
.hw_ip_checksum = , /**< IP checksum offload disabled */
.hw_vlan_filter = , /**< VLAN filtering disabled */
.jumbo_frame = , /**< Jumbo Frame Support disabled */
.hw_strip_crc = , /**< CRC stripped by hardware */
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = rss_intel_key,
.rss_hf = ETH_RSS_PROTO_MASK,
},
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
},
};
rte_eth_dev_configure函数声明
int rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_queue,
uint16_t nb_tx_queue, const struct rte_eth_conf *eth_conf);
无论是千兆网卡还是万兆网卡,在调用 rte_eth_dev_configure(port_id, nb_rx_queue, nb_tx_queue, &port_conf) 函数时都可以正常启动。
dpdk-18.11
dpdk-18.11中对 struct rte_eth_conf 结构体进行了修改,使用offloads代替了之前的几个变量标志位,不过这都影响不大。
static uint8_t rss_intel_key[] = { 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
};
static const struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = ,
.split_hdr_size = ,
.offloads = ,
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = rss_intel_key,
.rss_key_len = ,
.rss_hf = ETH_RSS_PROTO_MASK,
},
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
},
};
在调用 rte_eth_dev_configure(port_id, nb_rx_queue, nb_tx_queue, &port_conf) 函数是和16.11.1上是一致的。
在编译完成后,进行运行时发现,报错无法运行。报错如下:
Ethdev port_id= invalid rss_hf: 0x3ffffc, valid value: 0x38d34
port_id 0是一个igb驱动的网卡,型号为I350。
报错的意思是在调用 rte_eth_dev_configure 函数时,传入的最后一个函数参数(也就是网卡配置)中的 rx_adv_conf.rss_conf.rss_hf 参数值有问题,这个值是无效的。有效值是 0x38d34。
找到dpdk源码中打印错误信息的位置,前后代码如下:
int
rte_eth_dev_rss_hash_update(uint16_t port_id,
struct rte_eth_rss_conf *rss_conf)
{
struct rte_eth_dev *dev;
struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = , }; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
rte_eth_dev_info_get(port_id, &dev_info);
if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
dev_info.flow_type_rss_offloads) {
RTE_ETHDEV_LOG(ERR,
"Ethdev port_id=%u invalid rss_hf: 0x%"PRIx64", valid value: 0x%"PRIx64"\n",
port_id, rss_conf->rss_hf,
dev_info.flow_type_rss_offloads);
return -EINVAL;
}
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
return eth_err(port_id, (*dev->dev_ops->rss_hash_update)(dev,
rss_conf));
}
dev_info.flow_type_rss_offloads 就是网卡支持的flow类型, rss_conf->rss_hf 就是我们调用 rte_eth_dev_configure 函数的最后一个参考中的 rx_adv_conf.rss_conf.rss_hf 的值,
这里的if判断意思是配置的flow类型必须是网卡支持的flow类型,如果配置了网卡不支持的类型,就会报错。
经过计算器算出 0x38d34的二进制是111000110100110100,再配合在 rte_ethdev.h 中 ETH_RSS_开头的宏定义,得出111000110100110100就是下面所有宏定义的 或 值:
ETH_RSS_IPV4 | \
ETH_RSS_NONFRAG_IPV4_TCP| \
ETH_RSS_NONFRAG_IPV4_UDP| \
ETH_RSS_IPV6 | \
ETH_RSS_NONFRAG_IPV6_TCP | \
ETH_RSS_NONFRAG_IPV6_UDP | \
ETH_RSS_IPV6_EX | \
ETH_RSS_IPV6_TCP_EX | \
ETH_RSS_IPV6_UDP_EX
而我们配置中的参数 ETH_RSS_PROTO_MASK 显然比上面的类型要多,也就是 ETH_RSS_PROTO_MASK 定义的一些类型,网卡不支持,故而报错。
我们再看16.11.1中的源码
int
rte_eth_dev_rss_hash_update(uint8_t port_id, struct rte_eth_rss_conf *rss_conf)
{
struct rte_eth_dev *dev;
uint16_t rss_hash_protos; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
rss_hash_protos = rss_conf->rss_hf;
if ((rss_hash_protos != ) &&
((rss_hash_protos & ETH_RSS_PROTO_MASK) == )) {
RTE_PMD_DEBUG_TRACE("Invalid rss_hash_protos=0x%x\n",
rss_hash_protos);
return -EINVAL;
}
dev = &rte_eth_devices[port_id];
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rss_hash_update, -ENOTSUP);
return (*dev->dev_ops->rss_hash_update)(dev, rss_conf);
}
显然判断逻辑不同的。这里的判断意思是,只要有配置,并且配置中的flow类型至少有1项是在 ETH_RSS_PROTO_MASK 中的就可以,除非你配置的类型都不在 ETH_RSS_PROTO_MASK 中才会报错,这里就可以看出,即使你配置了网卡不支持的特性,也不会报错。
至此问题已解决。
总结
在dpdk-18.11中,配置网卡rss,必须网卡支持这种特性才行,否则会报错。
下面是整理的 igb , ixgbe , i40e 驱动网卡所支持的flow类型。
igb支持的特性
测试使用I350及I211网卡,有效值为0x38d34,二进制为111000110100110100,对应宏定义为
#define ETH_RSS_E1000_IGB (\
ETH_RSS_IPV4 | \
ETH_RSS_NONFRAG_IPV4_TCP| \
ETH_RSS_NONFRAG_IPV4_UDP| \
ETH_RSS_IPV6 | \
ETH_RSS_NONFRAG_IPV6_TCP | \
ETH_RSS_NONFRAG_IPV6_UDP | \
ETH_RSS_IPV6_EX | \
ETH_RSS_IPV6_TCP_EX | \
ETH_RSS_IPV6_UDP_EX)
ixgbe支持的特性
测试使用82599ES网卡,有效值和igb相同
#define ETH_RSS_IXGBE ETH_RSS_E1000_IGB
i40e支持的特性
测试使用X710网卡,有效值为0x7ef8,二进制为111111011111000,对应宏定义为
#define ETH_RSS_I40E (\
ETH_RSS_FRAG_IPV4 | \
ETH_RSS_NONFRAG_IPV4_TCP | \
ETH_RSS_NONFRAG_IPV4_UDP | \
ETH_RSS_NONFRAG_IPV4_SCTP | \
ETH_RSS_NONFRAG_IPV4_OTHER | \
ETH_RSS_FRAG_IPV6 | \
ETH_RSS_NONFRAG_IPV6_TCP | \
ETH_RSS_NONFRAG_IPV6_UDP | \
ETH_RSS_NONFRAG_IPV6_SCTP | \
ETH_RSS_NONFRAG_IPV6_OTHER | \
ETH_RSS_L2_PAYLOAD)
dpdk-18.11网卡多队列RSS设置的更多相关文章
- 为什么使能RPS/RFS, 或者RSS/网卡多队列后,QPS反而下降?
http://laoar.github.io/blog/2017/05/07/rps/ TL;DR RPS 即receive side steering,利用网卡的多队列特性,将每个核分别跟网卡的一个 ...
- 【转帖】网卡多队列技术与RSS功能介绍
网卡多队列技术与RSS功能介绍 2017年02月08日 15:44:37 Murphy_0806 阅读数 10665 标签: rss网卡dpdk 更多 个人分类: DPDK https://blog. ...
- [CareerCup] 18.11 Maximum Subsquare 最大子方形
18.11 Imagine you have a square matrix, where each cell (pixel) is either black or white. Design an ...
- 日本IT行业劳动力缺口达22万 在日中国留学生迎来就业好时机 2017/07/18 11:25:09
作者:倪亚敏 来源:日本新华侨报 发布时间:2017/07/18 11:25:09 据日本政府提供的数据,日本2018年应届毕业生的“求人倍率”已经达到了1.78倍.换言之,就是100名大学生 ...
- [18/11/11] java标识符及变量
一.标识符规范 1.必须以字母.下划线 .美元符号开头. 即数字不能作为开头,其它位随便 2.不可以是java关键字(即保留字), 如static .class.new 等 . 注:int 年 ...
- CentOS 7网卡网桥、绑定设置
一.网卡桥接设置: 1.网卡配置文件: [root@localhost /]# vim /etc/sysconfig/network-scripts/ifcfg-enp8s0 TYPE=Etherne ...
- 跟我一起学WCF(11)——WCF中队列服务详解
一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端 ...
- highgui.h备查 分类: C/C++ OpenCV 2014-11-08 18:11 292人阅读 评论(0) 收藏
/*M/////////////////////////////////////////////////////////////////////////////////////// // // IMP ...
- centos6 网卡配置,多IP设置
##云服务器 centos6网卡配置 #设置出口IP vim /etc/sysconfig/network-scripts/ifcfg-eth0DEVICE=seth0 #网卡名称 BOOTPROTO ...
随机推荐
- Linux知识要点大全(第一章)
第一章 Linux操作系统简介 主要内容: 1:Linux的发展历史 2:开源软件 3:Linux系统结构与特性 ...
- Spring之旅第六篇-事务管理
一.什么是事务 什么是事务(Transaction)?事务是数据库中的概念,是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 有个非常经典的转账问题:A向B转款1000元,A转出成 ...
- 查看ntp时间是否同步
nptq -p 命令 ntpq用来监视ntpd操作,ntpq -p查询网络中的NTP服务器,同时显示客户端和每个服务器的关系,也可以用watch实时查看. 位置 标志 含义 remote之前 * 响应 ...
- TabLayoutBottomDemo【TabLayout实现底部选项卡】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用TabLayout实现底部选项卡切换功能. 效果图 代码分析 1.演示固定模式的展现 2.演示自定义布局的实现 使用步骤 一.项 ...
- [SpringBoot guides系列翻译]SpringBoot构建RESTful程序入门
原文地址 构建一个RESTful的WebService 这个指南将带你用Spring创建一个RESTful的helloworld程序. 你将完成 在下面地址上创建一个接收http get请求的服务 h ...
- App.config自定义节点读取
<?xml version="1.0" encoding="utf-8"?> <configuration> <!--<ot ...
- Java 合并、拆分PDF文档
处理PDF文档时,我们可以通过合并的方式,来任意组几个不同的PDF文件或者通过拆分将一个文件分解成多个子文件,这样的好处是对文档的存储.管理很方便.下面将通过Java程序代码介绍具体的PDF合并.拆分 ...
- 【spring实战第五版遇到的坑】3.2中配置关系映射时,表名和3.1中不一样
3.2章中按照书中的步骤写好相应类的映射关系,发现启动时,之前在3.1章中建的表全部被删重新建立了,并且Ingredient表的数据没了,由于使用了JPA,默认使用的是hibernate,在启动时会删 ...
- [C#学习笔记1]用csc.exe和记事本写一个C#应用程序
csc.exe是C#的命令行编译器(CSharpCompiler),可以编译C#源程序成可执行程序.它与Visual Studio等IDE(Integrated Development Environ ...
- jQueryMobile 網頁使用 ASP.NET Web API 服務
微軟的 ASP.NET Web API 框架,能以 RESTful 輕量級的架構風格,建立 HTTP 服務,讓多種不同的用戶端,如: 手機.平板.電腦(PC),透過 HTTP 的 GET.POST.P ...