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[40] = { 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 = 0,
        .header_split   = 0, /**< Header Split disabled */
        .hw_ip_checksum = 0, /**< IP checksum offload disabled */
        .hw_vlan_filter = 0, /**< VLAN filtering disabled */
        .jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
        .hw_strip_crc   = 0, /**< 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[40] = { 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 = 0,
            .split_hdr_size = 0,
            .offloads = 0,
        },
        .rx_adv_conf = {
            .rss_conf = {
                .rss_key = rss_intel_key,
                .rss_key_len = 40,
                .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=0 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 = 0, };

    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 != 0) &&
        ((rss_hash_protos & ETH_RSS_PROTO_MASK) == 0)) {
        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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM