When vIOMMU is enabled and Virtio device is bound to kernel
driver in guest, rte_vhost_dequeue_burst() will often return
early because of IOTLB misses.

This patch fixes a mbuf leak occurring in this case.

Fixes: 242695f6122a ("vhost: allocate and free packets in bulk in Tx split")
Cc: sta...@dpdk.org

Signed-off-by: Maxime Coquelin <maxime.coque...@redhat.com>
Signed-off-by: David Marchand <david.march...@redhat.com>
---

Changes in v2:
==============
- Fix descriptors leak (David)
- Rebased on top of next-virtio

---
 lib/vhost/virtio_net.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/lib/vhost/virtio_net.c b/lib/vhost/virtio_net.c
index c738b7edc9..9951842b9f 100644
--- a/lib/vhost/virtio_net.c
+++ b/lib/vhost/virtio_net.c
@@ -3104,7 +3104,6 @@ virtio_dev_tx_split(struct virtio_net *dev, struct 
vhost_virtqueue *vq,
 {
        uint16_t i;
        uint16_t avail_entries;
-       uint16_t dropped = 0;
        static bool allocerr_warned;
 
        /*
@@ -3143,11 +3142,8 @@ virtio_dev_tx_split(struct virtio_net *dev, struct 
vhost_virtqueue *vq,
 
                update_shadow_used_ring_split(vq, head_idx, 0);
 
-               if (unlikely(buf_len <= dev->vhost_hlen)) {
-                       dropped += 1;
-                       i++;
+               if (unlikely(buf_len <= dev->vhost_hlen))
                        break;
-               }
 
                buf_len -= dev->vhost_hlen;
 
@@ -3164,8 +3160,6 @@ virtio_dev_tx_split(struct virtio_net *dev, struct 
vhost_virtqueue *vq,
                                        buf_len, mbuf_pool->name);
                                allocerr_warned = true;
                        }
-                       dropped += 1;
-                       i++;
                        break;
                }
 
@@ -3176,27 +3170,21 @@ virtio_dev_tx_split(struct virtio_net *dev, struct 
vhost_virtqueue *vq,
                                VHOST_DATA_LOG(dev->ifname, ERR, "failed to 
copy desc to mbuf.");
                                allocerr_warned = true;
                        }
-                       dropped += 1;
-                       i++;
                        break;
                }
-
        }
 
-       if (dropped)
-               rte_pktmbuf_free_bulk(&pkts[i - 1], count - i + 1);
+       if (unlikely(count != i))
+               rte_pktmbuf_free_bulk(&pkts[i], count - i);
 
-       vq->last_avail_idx += i;
-
-       do_data_copy_dequeue(vq);
-       if (unlikely(i < count))
-               vq->shadow_used_idx = i;
        if (likely(vq->shadow_used_idx)) {
+               vq->last_avail_idx += vq->shadow_used_idx;
+               do_data_copy_dequeue(vq);
                flush_shadow_used_ring_split(dev, vq);
                vhost_vring_call_split(dev, vq);
        }
 
-       return (i - dropped);
+       return i;
 }
 
 __rte_noinline
-- 
2.43.0

Reply via email to