首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DPDK函数rte_pktmbuf_alloc和rte_pktmbuf_free线程安全吗?

DPDK函数rte_pktmbuf_alloc和rte_pktmbuf_free线程安全吗?
EN

Stack Overflow用户
提问于 2021-06-21 13:03:51
回答 1查看 1.5K关注 0票数 2

我们有一个用例,它有一个RX线程和两个TX线程运行在同一个端口上。RX线程在处理接收到的数据包后使用rte_pktmbuf_free释放mbuf。TX线程使用rte_pktmbuf_alloc调用分配mbuf,并在端口上传输。

当对RX描述符init和TX线程中的mbuf分配使用相同的池时,我们发现有时会出现意外的mbuf泄漏和分配失败。如果对RX和每个TX线程使用单独的池,则不会看到这些问题。

我们没有在mempool_create调用中使用任何标志。DPDK文档似乎表明内存池操作是线程安全的?

我们正在使用DPDK版本: 19.11

我们应该为每个RX和两个TX线程创建唯一的内存池吗?

EDIT1:根据Vipin请求添加的代码段

DPDK初级工艺

代码语言:javascript
复制
mbuf_pool = rte_pktmbuf_pool_create("fast_pkt", 8192,
                256, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());

/* Configure the Ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);

/* Allocate and set up 1 RX queue per Ethernet port. */
retval = rte_eth_rx_queue_setup(port, q, 128,
                                rte_eth_dev_socket_id(port), NULL, mbuf_pool);

/* Allocate and set up 2 TX queue  */
for (q = 0; q < tx_rings; q++) {
    retval = rte_eth_tx_queue_setup(port, q, 512,
                                rte_eth_dev_socket_id(port), NULL);
}

/* Start the Ethernet port. */
retval = rte_eth_dev_start(port);

二次过程

主螺纹

代码语言:javascript
复制
mbuf_pool = rte_mempool_lookup("fast_pkt");

/* Create rx thread attach it to vCPU #4 */
rte_eal_remote_launch( main_rx, NULL, 4 );


/* create two tx threads and assign affinity to different vCPUs*/
pthread_create(&thread_id, NULL, tx_1, NULL );
CPU_ZERO(&cpuset);
CPU_SET(5, &cpuset);
pthread_setaffinity_np(thread_id, sizeof(cpuset), &cpuset);

pthread_create(&thread_id, NULL, tx_2, NULL );
CPU_ZERO(&cpuset);
CPU_SET(6, &cpuset);
pthread_setaffinity_np(thread_id, sizeof(cpuset), &cpuset);

接收线程(main_rx)

代码语言:javascript
复制
for (;; )
{
    nb_rx = rte_eth_rx_burst(port , 0, pkts_burst, 32);

    for ( i = 0; i < nb_rx ; i++ )
    {
        process_packet( pkts_burst[ i] );
        rte_pktmbuf_free(pkts_burst[ i]);
    }
}

传输线程(tx_1,tx_2)

代码语言:javascript
复制
   tx_q = <thread_sepcific queue ID>
   for ( ;; )
   {
         /* Receive Internal message for TX*/
         get_packet ( work_buffer [Burst]);
 
         for ( iterate through each index in work_buffer )
         {  
             tx_mbuf[i] = rte_pktmbuf_alloc(mbuf_pool);
             
             /* combination of following calls to construct packet */
             rte_pktmbuf_mtod( .. );
             /* follow above call with copy from work buffer */

            rte_pktmbuf_prepend( .. );
            rte_pktmbuf_append( .. );
         }

         rte_eth_tx_burst(start_port_id, tx_q, tx_mbuf, num_burst) 

         /* loop through packets not processed by rte_eth_tx_burst */
         for(.. )
         {
             rte_pktmbuf_free (... );
         }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-25 03:01:43

编辑-1下面共享的答案是一个共同的问题,并提供了澄清。

  1. 问题-1 is mempool operations are thread-safe? -(回答)是关于Lcore DPDK线程的。
  2. 问题2 Are we supposed to create unique mempool for each of the RX and the two TX threads? -(答案)不,我们可以安全地在不同端口和端口队列对之间使用相同的内存池。
  3. 问题-3 there is mbuf leak and depletion of mbuf_pool (sample code flow shared in question) -(答案)在修正代码后,它已经运行了over12小时,没有泄漏。
  4. 问题-4 we wanted to understand if the rte_pktmbuf_alloc and rte_pktmbuf_free are intended to be thread-safe or not -(回答)是
  5. 问题-5 Our RX thread uses "rte_eal_remote_launch" whereas our TX threads are created directly using pthread_create from the application. Do you think that makes a difference to thread safety? Should our TX threads also be launched using "rte_eal_remote_launch"? -(回答)是
  6. 问题-6 we should not have multiple threads (I.e., pthreads) allocated to same lcore and accessing same memory pool. -(回答)是的,这是正确的理解

原因:与thread create and set affinity相比,DPDK线程内部完成的事情更多。请参考DPDK EAL文档的清晰性。基于为rte_eal_init选择的选项

  1. coremask (十六进制)是1:1 CPU逻辑核到DPDK核心线程。
  2. lcore (十进制)是1:1 CPU逻辑核到DPDK核心线程。
  3. Lcores掩码(十进制)为1:N,其中1 CPU逻辑核可拆分为N DPDK线程。
  4. 每个DPDK线程内部存储线程局部变量index,即rte_lcore_id
  5. 因此,当您使用rte_pktmbuf_alloc时,它使用id来获取缓存内存池对象。在多个线程上使用相同的id违反了无锁模型,如果多个请求同时出现,可能会造成危险。

因此,用DPDK示例skeleton在主-次要模式下用正确的API调用重写代码片段不会产生内存泄漏。显示下面共享的运行的统计数据

代码语言:javascript
复制
  ######################## NIC statistics for port 0  ########################
  RX-packets: 15048531    RX-errors:  0           RX-bytes:  1123238216
  RX-nombuf:  0
  TX-packets: 15048504    TX-errors:  0           TX-bytes:  902910240


  ############################################################################

  ######################## NIC statistics for port 0  ########################
  RX-packets: 23424430063  RX-errors:  0           RX-bytes:  1405686130136
  RX-nombuf:  0
  TX-packets: 23424430036  TX-errors:  0           TX-bytes:  1405465802032


  ############################################################################

RX-nombuf 很容易显示PMD是否由于mbuf不存在而无法获取数据包。

模池信息

代码语言:javascript
复制
========== show - MEMPOOL ==========
mempool <MBUF_POOL>@0x11ff9fad00
  flags=10
  socket_id=1
  pool=0x11ff9eab00
  iova=0xeff9fad00
  nb_mem_chunks=1
  size=8191
  populated_size=8191
  header_size=64
  elt_size=2304
  trailer_size=0
  total_obj_size=2368
  private_data_size=64
  ops_index=7
  ops_name: <ring_mp_mc>
  avg bytes/object=2368.289098
  internal cache infos:
    cache_size=250
    cache_count[32]=171
    cache_count[34]=90
    total_cache_count=261
  common_pool_count=2874

注:以上数据通过实用程序获取。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68068452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档