【问题标题】:DPDK is it possible to remove a rte_mbuff from a rte_mbuff array?DPDK 是否可以从 rte_mbuff 数组中删除 rte_mbuff?
【发布时间】:2021-12-22 09:18:47
【问题描述】:

我想删除 r 中的 arp pakcet 并正常发送另一个数据包。 这是我的代码

for (;;) {
    /*
     * Receive packets on a port and forward them on the paired
     * port. The mapping is 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2, etc.
     */
    RTE_ETH_FOREACH_DEV(port) {
        /* Get burst of RX packets, from first port of pair. */
        struct rte_mbuf *bufs[BURST_SIZE];
        uint16_t nb_rx = rte_eth_rx_burst(port, 0,
                bufs, BURST_SIZE);
        if (unlikely(nb_rx == 0))
            continue;
        /* Send burst of TX packets, to second port of pair. */
    int delete_packet_num = 0;
    for(int i=0;i<nb_rx;i++){
        struct rte_mbuf *p = bufs[i];
        unsigned char *payload =(unsigned char*)p->buf_addr;
        payload = payload+p->data_off;
        struct ethhdr* eth_hdr = (struct ethhdr *)payload;
        if(eth_hdr->h_proto == 1544)
        {
            printf("there is a arp packet!\n");
            //remove a target mbuf or not?
            rte_pktmbuf_free(bufs[i]);
            delete_packet_num++;        
        }
    
    }
    nb_rx -=delete_packet_num;
    const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0,bufs, nb_rx);    
    if (unlikely(nb_tx < nb_rx)) {
        uint16_t buf;
        for (buf = nb_tx; buf < nb_rx; buf++)
            rte_pktmbuf_free(bufs[buf]);
    }
}

它可以拒绝我的 vmware 机器中的 arp 数据包。但是当代码运行大约半小时分钟时,vm 机器变得非常慢。我猜是:

rte_pktmbuf_free(bufs[i])

代码不会释放内存。 谁能帮帮我?

【问题讨论】:

  • 请更新以下详细信息 1) DPDK 版本 2) 是 PCIe 直通还是虚拟网卡? 3) 客户操作系统版本 4) KVM-QEMU 或 XEN 或虚拟机 5) VCPU 是否固定? 6) 是从主机上的 Huge pages 交付的客户内存 7) 数量主机和客户操作系统内存 8) 交换磁盘在客户和主机上都被禁用。代码中还有一个错误,即删除的 ARP 数据包没有被有效的下一个 mbuf 替换(请修复代码)。

标签: dpdk


【解决方案1】:

如 cmets 中所述,释放 ARP 数据包后内存使用不正确。因此,要使用的正确代码是

for (;;) {
    /*
     * Receive packets on a port and forward them on the paired
     * port. The mapping is 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2, etc.
     */
    RTE_ETH_FOREACH_DEV(port) {
        /* Get burst of RX packets, from first port of pair. */
        struct rte_mbuf *bufs[BURST_SIZE];
        uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
        
        if (unlikely(nb_rx == 0))
            continue;

        /* Send burst of TX packets, to second port of pair. */
        int delete_packet_num = 0;
        int i = 0, j = 0;
        
        for(;i<nb_rx;i++){
            struct rte_mbuf *p = bufs[i];
            
            unsigned char *payload =(unsigned char*)p->buf_addr;
            payload = payload+p->data_off;
            struct ethhdr* eth_hdr = (struct ethhdr *)payload;
            
            if(eth_hdr->h_proto == 1544)
            {
                printf("there is a arp packet!\n");
                //remove a target mbuf or not?
                rte_pktmbuf_free(bufs[i]);
                delete_packet_num++;        
            }
            else
            {
                /*
                 for all valid packets update the list 
                 example:
                    - let nb_rx be 16 packets
                    - in which packet at index 5 is ARP packets
                    - with help of check for ARP we are reassigning bufs[5] = bufs[6], because j is running 1 step once it encounters ARP at index 5
                 */
                bufs[j++] = bufs[i];
            }
        }
    
    nb_rx -=delete_packet_num;
    const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0,bufs, nb_rx);    
    if (unlikely(nb_tx < nb_rx)) {
        uint16_t buf;
        for (buf = nb_tx; buf < nb_rx; buf++)
            rte_pktmbuf_free(bufs[buf]);
    }
}

【讨论】:

  • 非常感谢,我有不同的方法来解决我的问题。我阅读了 rte_pktmbuf_free API,我注意到 rte_pktmbuf_free 可以处理 NULL 点,所以我不再更改 nb_rx 值并正常使用 rte_pktmbuf_free。最后我释放了所有的 nb_tx 数据包 bufs。代码似乎运行正常!
  • 释放所有成功的nb_tx 肯定是错误的,因为它是由 PMD 释放的。这不是正确的方法。
猜你喜欢
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 2010-10-11
  • 2017-11-19
  • 2017-08-19
  • 1970-01-01
相关资源
最近更新 更多