dpdk ixgbe nic multi rx 队列与 rss 不能正常工作
dpdk ixgbe nic multi rx queue with rss not work well
我正在使用 IXGBE Nic,使用带有 rss“ETH_RSS_TCP | ETH_RSS_IP”的 dpdk 19.11 多 rx 队列。
IXGBE 最多支持 64 个队列,我使用了 4 个队列。但是所有包都到达了同一个队列(队列 0),看来 rss 功能不能正常工作。
以下是我的rss部分的伪代码。是不是我配置错误导致rss功能没有生效?
static int rss_setup(const int port_id, const uint16_t nb_queues)
{
int i;
int ret;
struct rte_eth_dev_info dev_info;
struct rte_eth_rss_reta_entry64 *reta_conf = NULL;
rte_eth_dev_info_get(port_id, &dev_info);
if (nb_queues == 0) {
return ERR_VAL;
}
reta_conf = calloc(dev_info.reta_size / RTE_RETA_GROUP_SIZE,
sizeof(struct rte_eth_rss_reta_entry64));
if (!reta_conf) {
return ERR_MEM;
}
for (i = 0; i < dev_info.reta_size; i++) {
struct rte_eth_rss_reta_entry64 *one_reta_conf =
&reta_conf[i / RTE_RETA_GROUP_SIZE];
one_reta_conf->reta[i % RTE_RETA_GROUP_SIZE] = i % nb_queues;
}
for (i = 0; i < dev_info.reta_size / RTE_RETA_GROUP_SIZE; i++) {
struct rte_eth_rss_reta_entry64 *one_reta_conf = &reta_conf[i];
one_reta_conf->mask = 0xFFFFFFFFFFFFFFFFULL;
}
ret = rte_eth_dev_rss_reta_update(port_id, reta_conf, dev_info.reta_size);
if (ret < 0) {
printf("cannot update rss reta at port %d: %s\n",
port_id, rte_strerror(-ret));
}
free(reta_conf);
return ERR_OK;
}
main (){
struct rte_eth_conf conf = {0};
conf.link_speeds = ETH_LINK_SPEED_AUTONEG;
conf.txmode.mq_mode = ETH_MQ_TX_NONE;
conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
struct rte_eth_dev_info dev_info;
rte_eth_dev_info_get(port_id, &dev_info);
int rss_enable = 0;
uint64_t def_rss_hf = ETH_RSS_TCP | ETH_RSS_IP;
struct rte_eth_rss_conf rss_conf = {
NULL,
40,
def_rss_hf,
};
rss_conf.rss_hf &= dev_info->flow_type_rss_offloads;
if (rss_conf.rss_hf) {
rss_enable = 1;
conf->rx_adv_conf.rss_conf = rss_conf;
conf->rxmode.mq_mode = ETH_MQ_RX_RSS;
rss_setup(port_id, 4); // queues cnt is 4
}
}
看起来程序在调用 rss_setup()
之前没有调用 rte_eth_dev_configure()
。这是不正确的,因为 rte_eth_dev_configure()
“必须在以太网 API 中的任何其他函数之前首先被调用”(doc reference)。请re-arrange程序首先调用rte_eth_dev_configure()
并指定rx_adv_conf.rss_conf
和ETH_MQ_RX_RSS
,然后 继续 bring-up.
的其余部分
在rss_setup()
中,程序调用rte_eth_dev_rss_reta_update()
。对于有问题的 PMD,此 API 只能在 启动状态 (code reference) 中调用。所以请 re-arrange 程序多一点调用 rte_eth_dev_start()
before rss_setup()
.
请确保 TCP 源端口号(and/or IP 源地址)在发送端是随机的。如果 IP/TCP 源字段和目标字段没有变化,那么数据包最终会出现在同一个 Rx 队列中也就不足为奇了。
我正在使用 IXGBE Nic,使用带有 rss“ETH_RSS_TCP | ETH_RSS_IP”的 dpdk 19.11 多 rx 队列。 IXGBE 最多支持 64 个队列,我使用了 4 个队列。但是所有包都到达了同一个队列(队列 0),看来 rss 功能不能正常工作。 以下是我的rss部分的伪代码。是不是我配置错误导致rss功能没有生效?
static int rss_setup(const int port_id, const uint16_t nb_queues)
{
int i;
int ret;
struct rte_eth_dev_info dev_info;
struct rte_eth_rss_reta_entry64 *reta_conf = NULL;
rte_eth_dev_info_get(port_id, &dev_info);
if (nb_queues == 0) {
return ERR_VAL;
}
reta_conf = calloc(dev_info.reta_size / RTE_RETA_GROUP_SIZE,
sizeof(struct rte_eth_rss_reta_entry64));
if (!reta_conf) {
return ERR_MEM;
}
for (i = 0; i < dev_info.reta_size; i++) {
struct rte_eth_rss_reta_entry64 *one_reta_conf =
&reta_conf[i / RTE_RETA_GROUP_SIZE];
one_reta_conf->reta[i % RTE_RETA_GROUP_SIZE] = i % nb_queues;
}
for (i = 0; i < dev_info.reta_size / RTE_RETA_GROUP_SIZE; i++) {
struct rte_eth_rss_reta_entry64 *one_reta_conf = &reta_conf[i];
one_reta_conf->mask = 0xFFFFFFFFFFFFFFFFULL;
}
ret = rte_eth_dev_rss_reta_update(port_id, reta_conf, dev_info.reta_size);
if (ret < 0) {
printf("cannot update rss reta at port %d: %s\n",
port_id, rte_strerror(-ret));
}
free(reta_conf);
return ERR_OK;
}
main (){
struct rte_eth_conf conf = {0};
conf.link_speeds = ETH_LINK_SPEED_AUTONEG;
conf.txmode.mq_mode = ETH_MQ_TX_NONE;
conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
struct rte_eth_dev_info dev_info;
rte_eth_dev_info_get(port_id, &dev_info);
int rss_enable = 0;
uint64_t def_rss_hf = ETH_RSS_TCP | ETH_RSS_IP;
struct rte_eth_rss_conf rss_conf = {
NULL,
40,
def_rss_hf,
};
rss_conf.rss_hf &= dev_info->flow_type_rss_offloads;
if (rss_conf.rss_hf) {
rss_enable = 1;
conf->rx_adv_conf.rss_conf = rss_conf;
conf->rxmode.mq_mode = ETH_MQ_RX_RSS;
rss_setup(port_id, 4); // queues cnt is 4
}
}
看起来程序在调用
的其余部分rss_setup()
之前没有调用rte_eth_dev_configure()
。这是不正确的,因为rte_eth_dev_configure()
“必须在以太网 API 中的任何其他函数之前首先被调用”(doc reference)。请re-arrange程序首先调用rte_eth_dev_configure()
并指定rx_adv_conf.rss_conf
和ETH_MQ_RX_RSS
,然后 继续 bring-up.在
rss_setup()
中,程序调用rte_eth_dev_rss_reta_update()
。对于有问题的 PMD,此 API 只能在 启动状态 (code reference) 中调用。所以请 re-arrange 程序多一点调用rte_eth_dev_start()
beforerss_setup()
.请确保 TCP 源端口号(and/or IP 源地址)在发送端是随机的。如果 IP/TCP 源字段和目标字段没有变化,那么数据包最终会出现在同一个 Rx 队列中也就不足为奇了。