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
    }
}
  1. 看起来程序在调用 rss_setup() 之前没有调用 rte_eth_dev_configure()。这是不正确的,因为 rte_eth_dev_configure()“必须在以太网 API 中的任何其他函数之前首先被调用”(doc reference)。请re-arrange程序首先调用rte_eth_dev_configure()并指定rx_adv_conf.rss_confETH_MQ_RX_RSS然后 继续 bring-up.

    的其余部分
  2. rss_setup()中,程序调用rte_eth_dev_rss_reta_update()。对于有问题的 PMD,此 API 只能在 启动状态 (code reference) 中调用。所以请 re-arrange 程序多一点调用 rte_eth_dev_start() before rss_setup().

  3. 请确保 TCP 源端口号(and/or IP 源地址)在发送端是随机的。如果 IP/TCP 源字段和目标字段没有变化,那么数据包最终会出现在同一个 Rx 队列中也就不足为奇了。