我有一个奇怪的掉落问题,要理解我的问题,最好的方法是看一下这个简单的代码段:
while( 1 ) { if( config->running == false ) { break; } num_of_pkt = rte_eth_rx_burst( config->port_id, config->queue_idx, buffers, MAX_BURST_DEQ_SIZE); if( unlikely( num_of_pkt == MAX_BURST_DEQ_SIZE ) ) { rx_ring_full = true; //probably not the best name } if( likely( num_of_pkt > 0 ) ) { pk_captured += num_of_pkt; num_of_enq_pkt = rte_ring_sp_enqueue_bulk(config->incoming_pkts_ring, (void*)buffers, num_of_pkt, &rx_ring_free_space); //if num_of_enq_pkt == 0 free the mbufs.. } }
此循环正在从设备中检索数据包,并将其推入队列以供另一个lcore进一步处理。
当我用Mellanox卡以2.5M p / s发送20M(20878300)数据包进行测试时,循环似乎丢失了一些数据包,而pk_captured始终类似于19M或类似数据。
rx_ring_full永远不会为真,这意味着num_of_pkt始终<MAX_BURST_DEQ_SIZE,因此根据文档,我不会在硬件级别上丢弃。同样,num_of_enq_pkt永远不会为0,这意味着所有数据包都已入队。
现在,如果从该片段中删除了rte_ring_sp_enqueue_bulk调用(并确保释放所有mbuf),则pk_captured始终等于我发送至NIC的数据包数量。
因此,似乎(但我无法解决这个问题)rte_ring_sp_enqueue_bulk有点太慢,在一次调用rte_eth_rx_burst和另一个由于NIC上的完整环而导致的其他数据包之间被丢弃的情况下,但是为什么num_of_pkt(来自rte_eth_rx_burst)总是小于好像总是有足够的空间容纳MAX_BURST_DEQ_SIZE(小得多)?
请注意,MAX_BURST_DEQ_SIZE为512。
编辑1:
也许这些信息可能会有所帮助:丢弃似乎也可以通过rte_eth_stats_get看到,或更准确地说,没有丢弃被报告(被忽略且错误数为0),但是ipackets的值等于我的计数器pk_captured(丢失的数据包刚刚消失了吗? ?)
编辑2:
根据ethtools,rx_crc_errors_phy为零,并且所有数据包都在PHY级别接收(rx_packets_phy用正确数量的已传输数据包更新)。
来自rte_eth_stats的rx_nombuf的值似乎包含废纸((这是来自我们测试应用程序的打印内容):
OUT(4):端口1统计信息:ipkt:19439285,opkt:0,ierr:0,oerr:0,imiss:0,rxnobuf:2061021195718
对于2000万个数据包的传输,您可以看到rxnobuf是垃圾,或者它具有我不理解的含义。日志由以下人员生成:
log("Port %"PRIu8" stats: ipkt:%"PRIu64",opkt:%"PRIu64",ierr:%"PRIu64",oerr:%"PRIu64",imiss:%"PRIu64", rxnobuf:%"PRIu64, config->port_id, stats.ipackets, stats.opackets, stats.ierrors, stats.oerrors, stats.imissed, stats.rx_nombuf);
统计信息来自rte_eth_stats_get。
数据包不是即时生成的,而是从现有的PCAP重放的。
编辑3
在回答了Adriy的问题(谢谢!)之后,我包括了Mellanox卡的xstats输出,同时使用较小的数据包集再现了相同的问题,我可以看到rx_mbuf_allocation_errors得到了更新,但似乎包含垃圾:
OUT(4): rx_good_packets = 8094164 OUT(4): tx_good_packets = 0 OUT(4): rx_good_bytes = 4211543077 OUT(4): tx_good_bytes = 0 OUT(4): rx_missed_errors = 0 OUT(4): rx_errors = 0 OUT(4): tx_errors = 0 OUT(4): rx_mbuf_allocation_errors = 146536495542
这些计数器似乎也很有趣:
OUT(4): tx_errors_phy = 0 OUT(4): rx_out_of_buffer = 257156 OUT(4): tx_packets_phy = 9373 OUT(4): rx_packets_phy = 8351320
其中rx_packets_phy是我一直发送的确切数据包数量,然后将rx_out_of_buffer与rx_good_packets求和就得出了确切的数量。因此,似乎mbuf耗尽了,一些数据包被丢弃了。
我对原始代码进行了调整,现在使用链接从RX环中复制了mbuf ,它们立即释放了内存,其他lcore对该副本进行了进一步的处理。但这并不能解决问题,事实证明,要解决该问题,我必须禁用数据包处理并释放数据包副本(在另一个lcore上),这没有任何意义。
好吧,将做更多的调查,但是至少rx_mbuf_allocation_errors似乎需要在这里修复。