在DPDK的多个内核中应用IP分片的正确方法

时间:2018-11-05 04:18:03

标签: dpdk

您好Stackoverflow专家

我无法在多个内核中应用ip分段。

我的最终问题是,是否可以为每个不同的直接池和间接池分配多个ip分片表。

如果有人能指出我在这里做错了什么,或者提供一些替代解决方案,我真的很感激。


目的

我正在尝试在多个内核中应用ip分段,并通过大于MTU的消息来最大化吞吐量性能。

  • 对于每个本地和远程主机(使用1到8个逻辑内核)
  • 1〜4用于传输碎片消息
  • 4〜8用于接收和组合消息
  • 从本地发送4KB消息
  • 远程将消息回显到本地。
  • 计算总吞吐量


问题

如果我尝试将碎片表分配给每个内核,则会出现分段错误,并且无论我缩小碎片表的大小如何,都会发生这种情况。 我尝试分配池和碎片表的方式如下所示。

for each coreid, coreid < allocated cores; coreid++
     fragmentation_table[coreid] = rte_ip_frag_table_create(...);
     direct_pool[coreid] = rte_pktmbuf_pool_create(...);
     indirect_pool[coreid] rte_pktmbuf_pool_create(...);

因此,或者,我为每个lcores分配了多个碎片表,但让直接池和间接池共享在一起。

for each coreid, coreid < allocated cores; coreid++
     fragmentation_table[coreid] = rte_ip_frag_table_create(...);

direct_pool = rte_pktmbuf_pool_create(...);
indirect_pool = rte_pktmbuf_pool_create(...);


情况

现在,当我使用多个内核从本地主机向远程主机发送消息时,远程主机仅在我发送消息时成功添加了消息,并添加了一个延迟,例如(为每个发送消息添加sleep(1);)。能够接收从本地到远程的消息。但是,当我尝试毫无延迟地发送数据时,无法接收任何数据。


结论

我个人认为应该为每个逻辑核心分配直接池和间接池,我认为这是主要问题。由于只能使用一个逻辑内核才能成功使用碎片表,因此我怀疑我没有在多个内核中正确使用碎片表。

我真的很想从DPDK专家那里得知我所面临的这个问题,并且非常感谢您对此提供的任何建议...

static int
setup_queue_tbl(struct lcore_rx_queue *rxq, uint32_t lcore, uint32_t queue)
{
    int socket;
    uint32_t nb_mbuf;
    uint64_t frag_cycles;
    char buf[RTE_MEMPOOL_NAMESIZE];

    socket = rte_lcore_to_socket_id(lcore);
    if (socket == SOCKET_ID_ANY)
        socket = 0;

    frag_cycles = (rte_get_tsc_hz() + MS_PER_S - 1) / MS_PER_S * max_flow_ttl;
    if ((rxq->frag_tbl = rte_ip_frag_table_create(max_flow_num,
                                                  IP_FRAG_TBL_BUCKET_ENTRIES, max_flow_num, frag_cycles,
                                                  socket)) == NULL) {
        printf("rte_ip_frag_table_create failed!!!!\n");
        return -1;
    }

    nb_mbuf = RTE_MAX(max_flow_num, 2UL * MAX_PKT_BURST) * MAX_FRAG_NUM;
    nb_mbuf *= (port_conf.rxmode.max_rx_pkt_len + BUF_SIZE - 1) / BUF_SIZE;
    nb_mbuf *= 1;
    nb_mbuf += nb_rxd + nb_txd;

    if (transfer_pool[lcore] == NULL) {

        snprintf(buf, sizeof(buf), "pool_recieve_%d", socket);
        receive_pool[lcore] = rte_pktmbuf_pool_create(buf, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, socket);

        snprintf(buf, sizeof(buf), "pool_transfer_%d", socket);
        transfer_pool[lcore] = rte_pktmbuf_pool_create(buf, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, PKT_SIZE + 128, socket);

        snprintf(buf, sizeof(buf), "pool_direct_%d", socket);
        direct_pool[lcore] = rte_pktmbuf_pool_create(buf, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, socket);

        snprintf(buf, sizeof(buf), "pool_indirect_%d", socket);
        indirect_pool[lcore] = rte_pktmbuf_pool_create(buf, nb_mbuf, MEMPOOL_CACHE_SIZE, 0, 0, socket);
    }

    snprintf(buf, sizeof(buf), "mbuf_rx_ring_%d", lcore);
    rx_ring[lcore] = rte_ring_create(buf, 512, socket, 0);
    snprintf(buf, sizeof(buf), "mbuf_tx_ring_%d", lcore);
    tx_ring[lcore] = rte_ring_create(buf, 512, socket, 0);

    // for packet assemble
    rxq->ar = (struct assembled_result *)malloc(sizeof(struct assembled_result));
    rxq->ar->length = 0;
    rxq->ar->assembled_pkt = (char *)malloc(sizeof(char)*PKT_SIZE);
    return 0;
}

这是完整的源代码,我要确保它正确的代码在dpdk_init.h

中。

https://github.com/SungHoHong2/DPDK-Experiment/blob/master/dpdk-server-multi/dpdk_init.h

2 个答案:

答案 0 :(得分:1)

1。请提供源代码

这将帮助您获得答案,而不是猜测;)

2。片段表与lcores

DPDK程序员指南明确指出:

  

片段表上的所有更新/查找操作都不是线程安全的。

Source

因此,每个lcore必须具有其自己的片段表或必须使用锁。

3。内存池与lcores

默认情况下,除非我们传递MEMPOOL_F_SP_PUT之类的标志,否则DPDK中的默认内存池是线程安全的。因此,回答您的问题:

  

是否可以为每个不同的直接池和间接池分配多个ip分段表。

默认情况下,很少有lcore可以共享内存池。

4。猜猜!

由于没有源代码,所以我想根本原因是片段的TTL不到1秒,因此sleep(1)包到达太晚而无法重新组装。

5。旁注

重新组装非常耗时又占空间,应不惜一切代价避免。

考虑通过更改协议或使用巨型帧将消息放入一个数据包的一些方法。

答案 1 :(得分:0)

答案是一个非常基本的答案。 问题在于大页面的配置。 对于我未测试的每个群集,巨大的页面大小是不同的。

一个正在分配碎片表的集群是...

AnonHugePages:    208896 kB
HugePages_Total:       8
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:    1048576 kB

当我尝试分配碎片表时,另一个一直返回分段错误的集群是...

AnonHugePages:      6144 kB 
HugePages_Total:    1024    
HugePages_Free:        0    
HugePages_Rsvd:        0    
HugePages_Surp:        0    
Hugepagesize:       2048 kB 

这是每个逻辑核心扩展rx和tx -queue的基本性能,如您所见,可以使用多个rx-tx队列,每个队列与带有逻辑核心和所需池的frag-table相关联。

enter image description here