我试图使用以下逻辑将IPv4数据包碎片化:
~after pkts ingress~
struct rte_port_ring_writer *p = port_out->h_port;
pool_direct = rte_mempool_lookup("MEMPOOL0");
pool_indirect = rte_mempool_lookup("MEMPOOL1");
printf("before frag mempool size d %d in %d\n",rte_mempool_avail_count(pool_direct),rte_mempool_avail_count(pool_indirect));
struct rte_mbuf *frag_pkts[MAX_FRAG_SIZE];
int out_pkts = rte_ipv4_fragment_packet (m, frag_pkts, n_frags, ip_mtu,pool_direct, pool_indirect);
printf("after frag mempool size d %d in %d\n",rte_mempool_avail_count(pool_direct),rte_mempool_avail_count(pool_indirect));
if(out_pkts > 0)
port_out->ops.f_tx_bulk(port_out->h_port,frag_pkts,RTE_LEN2MASK(out_pkts, uint64_t));
else
printf("frag failed\n");
rte_pktmbuf_free>(m); //free parent pkt现在的问题是间接模池耗尽了。因此,在数据包很少爆发后,由于-ENOMEM,碎片会失败。我完全不明白为什么PMD不释放,并将内存池obj返回到MEMPOOL1。这不太可能是因为NIC端口被限制在MEMPOOL0上,而MEMPOOL1中的pkts却被排除在外。
请查找下面的日志,用于打印直接(d)和间接(在)备忘录池中可用的插槽:
前模池大小d 2060457在2095988
后,模池大小d 2060344在2095952
前模池大小d 2060361在2095945
后,模池大小d 2060215在2095913
。
。
。
在编写内存池大小d 2045013之前,在0
后,内存池大小d 2045013在0。
在编写内存池大小d 2045013之前,在0
后,内存池大小d 2045013在0。
在编写内存池大小d 2045013之前,在0
我可以看到,直接备忘录池减少和增加的数据包进入和下降/出口,如预期。我还可以确认我收到了与MEMPOOL1大小相等的碎片数据包的初始突发。对于理解问题的原因的任何投入都是非常感谢的。
P.S:我们在same 17.11中也有同样的问题。我们不得不折射rte_ipv4_fragment_packet(),而不是使用间接的框架链接,而只是生成它们。
编辑:
DPDK版本- 20.11
Env - linux - centos 7
PMD - i40e -在mode4中使用键
Pkt尺寸- 128
MTU - 70
内存池是用rte_pktmbuf_pool_create()创建的,因此没有SC/SP标志(默认为MC/MP)。也总是n_frags < MAX_FRAG_SIZE。
感谢和问候,
维沙尔莫汉
发布于 2021-07-20 02:55:16
DPDK rte_ipv4_fragment_packet用于testpmd和DPDK示例ip_fragementation。这些也包含在DPDK测试套件中,每个版本都会运行它。
基于Ip_fragementation的内部测试和正确使用的API,例如、、等,问题无法再现。因此,除了一些特殊的角情况(尚未找到),API泄漏的内存池缓冲区是非常不可能的。
根据代码片段分析,以下可能是内存池耗尽的原因
fragmentation
基于电子邮件更新和评论,update rte_ipv4_fragment_packet.确实没有问题。问题来自于应用程序逻辑,新的行为为
DPDK键PMD导致内存池耗尽,使用当前代码片段,dpdk键PMD没有问题,dpdk键PMD没有问题,rte_ipv4_fragment_packet
示例中的dpdk示例有问题,PMD有当前代码段的问题,
因此,问题在于示例代码片段和用法,而不是DPDK。
https://stackoverflow.com/questions/68361046
复制相似问题