英特尔XL710上的RSS(接收侧缩放)每个端口

时间:2018-08-02 18:11:20

标签: network-programming intel dpdk

我为使用DPDK的Intel XL710卡而苦苦挣扎,以使其仅在每个端口上仅使用SRC IPV4或DST IPV4计算RSS哈希。 该卡具有4个10GE端口,无论我做什么,RSS配置都是全局的。我试图在PCTYPE中设置SRC / DST IPV4字段,并且应用的配置 last 仅起作用。

所以我要实现的行为。

假设我有上行数据包到达端口0:

SRC:10.10.10.1 DST:10.10.10.2

并回复下行数据包到达端口1:

SRC:10.10.10.2 DST:10.10.10.1

我希望卡上的端口0(在我们的示例中为上游)基于 SRC 地址 10.10.10.1 计算RSS哈希对于端口1(下游)使用 DST 地址计算哈希,在我们的示例中,该地址也将为 10.10.10.1 。因此,我们的想法是在RX队列之间分配数据包,使之只有SRC / DST地址分别影响这种分配。

我并没有专门针对RSS。只要技术允许,它就会做什么。

我使用的配置:

void setFilter(uint16_t portId, uint32_t value){

//Value = RTE_ETH_FLOW_NONFRAG_IPV4_TCP in that case

struct rte_eth_hash_filter_info info;
uint32_t ftype, idx, offset;
int ret;

if (rte_eth_dev_filter_supported(portId,
            RTE_ETH_FILTER_HASH) < 0) {
    printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
                        portId);
    return;
}

memset(&info, 0, sizeof(info));
info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
info.info.global_conf.hash_func =
  RTE_ETH_HASH_FUNCTION_DEFAULT;

ftype = value;
idx = ftype / UINT64_BIT;
offset = ftype % UINT64_BIT;
info.info.global_conf.valid_bit_mask[idx] |= (1ULL << offset);
info.info.global_conf.sym_hash_enable_mask[idx] |=
  (1ULL << offset);
ret = rte_eth_dev_filter_ctrl(portId, RTE_ETH_FILTER_HASH,
                RTE_ETH_FILTER_SET, &info);
if (ret < 0)
    printf("Cannot set global hash configurations by port %d\n",
                        portId);
else
    printf("Global hash configurations have been set "
           "succcessfully by port %d\n", portId);
}

void setPctypeRss(uint16_t portId, uint16_t fieldIdx) {

/* Note that AVF_FILTER_PCTYPE_NONF_IPV4_TCP is define for
 * Virtual Function. Defines are the same for Physical Functions
 */
int ret = -ENOTSUP;

enum rte_pmd_i40e_inset_type inset_type = INSET_HASH;
struct rte_pmd_i40e_inset inset;

ret = rte_pmd_i40e_inset_get(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
                             &inset, inset_type);

if (ret) {
    printf("Failed to get input set.\n");
    return;
}

memset(&inset, 0, sizeof(inset));

ret = rte_pmd_i40e_inset_set(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
                 &inset, inset_type);

if (ret) {
    printf("Failed to CLEAR input set.\n");
    return;
}
else
{
    printf("Successfull cleared input set\n");
}

ret = rte_pmd_i40e_inset_get(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
                 &inset, inset_type);
if (ret) {
    printf("Failed to get input set.\n");
    return;
}

ret = rte_pmd_i40e_inset_field_set(&inset.inset, fieldIdx);

if (ret) {
    printf("Failed to configure input set field.\n");
    return;
}

ret = rte_pmd_i40e_inset_set(portId, AVF_FILTER_PCTYPE_NONF_IPV4_TCP,
                 &inset, inset_type);
if (ret) {
    printf("Failed to set input set.\n");
    return;
}

if (ret == -ENOTSUP)
    printf("Function not supported\n");
}

1 个答案:

答案 0 :(得分:0)

IMO值得尝试一个更简单的解决方案。我们可以简单地使用rte_eth_dev_configure()

https://doc.dpdk.org/api/rte__ethdev_8h.html#a1a7d3a20b102fee222541fda50fd87bd

然后按照此处所述将eth_conf.rss_conf.rss_hf设置为ETH_RSS_IP

https://doc.dpdk.org/api/structrte__eth__rss__conf.html#ad70f17882a835e5d4e38c64a9f872fdc

DPDK中很少有使用此功能的示例。而且大多数都工作正常;)