我们有一个用例,它有一个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初级工艺
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);二次过程
主螺纹
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)
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)
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 (... );
}
}发布于 2021-06-25 03:01:43
编辑-1下面共享的答案是一个共同的问题,并提供了澄清。
is mempool operations are thread-safe? -(回答)是关于Lcore DPDK线程的。Are we supposed to create unique mempool for each of the RX and the two TX threads? -(答案)不,我们可以安全地在不同端口和端口队列对之间使用相同的内存池。there is mbuf leak and depletion of mbuf_pool (sample code flow shared in question) -(答案)在修正代码后,它已经运行了over12小时,没有泄漏。we wanted to understand if the rte_pktmbuf_alloc and rte_pktmbuf_free are intended to be thread-safe or not -(回答)是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"? -(回答)是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选择的选项
N DPDK线程。index,即rte_lcore_id。rte_pktmbuf_alloc时,它使用id来获取缓存内存池对象。在多个线程上使用相同的id违反了无锁模型,如果多个请求同时出现,可能会造成危险。因此,用DPDK示例skeleton在主-次要模式下用正确的API调用重写代码片段不会产生内存泄漏。显示下面共享的运行的统计数据
######################## 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不存在而无法获取数据包。
模池信息
========== 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注:以上数据通过实用程序获取。
https://stackoverflow.com/questions/68068452
复制相似问题