Add vhost packed ring zero copy batch and single dequeue functions like
normal dequeue path.

Signed-off-by: Marvin Liu <yong....@intel.com>

diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 5cdca9a7f..01d1603e3 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -1886,6 +1886,122 @@ virtio_dev_tx_single_packed(struct virtio_net *dev,
        return 0;
 }
 
+static __rte_unused int
+virtio_dev_tx_batch_packed_zmbuf(struct virtio_net *dev,
+                                struct vhost_virtqueue *vq,
+                                struct rte_mempool *mbuf_pool,
+                                struct rte_mbuf **pkts)
+{
+       struct zcopy_mbuf *zmbufs[PACKED_BATCH_SIZE];
+       uintptr_t desc_addrs[PACKED_BATCH_SIZE];
+       uint16_t ids[PACKED_BATCH_SIZE];
+       uint16_t i;
+
+       uint16_t avail_idx = vq->last_avail_idx;
+
+       if (vhost_reserve_avail_batch_packed(dev, vq, mbuf_pool, pkts,
+                                            avail_idx, desc_addrs, ids))
+               return -1;
+
+       for_each_try_unroll(i, 0, PACKED_BATCH_SIZE)
+               zmbufs[i] = get_zmbuf(vq);
+
+       for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) {
+               if (!zmbufs[i])
+                       goto free_pkt;
+       }
+
+       for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) {
+               zmbufs[i]->mbuf = pkts[i];
+               zmbufs[i]->desc_idx = avail_idx + i;
+               zmbufs[i]->desc_count = 1;
+       }
+
+       for_each_try_unroll(i, 0, PACKED_BATCH_SIZE)
+               rte_mbuf_refcnt_update(pkts[i], 1);
+
+       for_each_try_unroll(i, 0, PACKED_BATCH_SIZE)
+               TAILQ_INSERT_TAIL(&vq->zmbuf_list, zmbufs[i], next);
+
+       vq->nr_zmbuf += PACKED_BATCH_SIZE;
+       vq_inc_last_avail_packed(vq, PACKED_BATCH_SIZE);
+
+       return 0;
+
+free_pkt:
+       for_each_try_unroll(i, 0, PACKED_BATCH_SIZE)
+               rte_pktmbuf_free(pkts[i]);
+
+       return -1;
+}
+
+static __rte_unused int
+virtio_dev_tx_single_packed_zmbuf(struct virtio_net *dev,
+                                 struct vhost_virtqueue *vq,
+                                 struct rte_mempool *mbuf_pool,
+                                 struct rte_mbuf **pkts)
+{
+       uint16_t buf_id, desc_count;
+       struct zcopy_mbuf *zmbuf;
+
+       if (vhost_dequeue_single_packed(dev, vq, mbuf_pool, pkts, &buf_id,
+                                       &desc_count))
+               return -1;
+
+       zmbuf = get_zmbuf(vq);
+       if (!zmbuf) {
+               rte_pktmbuf_free(*pkts);
+               return -1;
+       }
+       zmbuf->mbuf = *pkts;
+       zmbuf->desc_idx = vq->last_avail_idx;
+       zmbuf->desc_count = desc_count;
+
+       rte_mbuf_refcnt_update(*pkts, 1);
+
+       vq->nr_zmbuf += 1;
+       TAILQ_INSERT_TAIL(&vq->zmbuf_list, zmbuf, next);
+
+       vq_inc_last_avail_packed(vq, desc_count);
+       return 0;
+}
+
+static __rte_always_inline void
+free_zmbuf(struct vhost_virtqueue *vq)
+{
+       struct zcopy_mbuf *next = NULL;
+       struct zcopy_mbuf *zmbuf;
+
+       for (zmbuf = TAILQ_FIRST(&vq->zmbuf_list);
+            zmbuf != NULL; zmbuf = next) {
+               next = TAILQ_NEXT(zmbuf, next);
+
+               uint16_t last_used_idx = vq->last_used_idx;
+
+               if (mbuf_is_consumed(zmbuf->mbuf)) {
+                       uint16_t flags = 0;
+                       bool wrap;
+
+                       wrap = vq->used_wrap_counter;
+                       flags = PACKED_DESC_DEQUEUE_USED_FLAG(wrap);
+
+                       vq->desc_packed[last_used_idx].id = zmbuf->desc_idx;
+                       vq->desc_packed[last_used_idx].len = 0;
+
+                       rte_smp_wmb();
+                       vq->desc_packed[last_used_idx].flags = flags;
+
+                       vq_inc_last_used_packed(vq, zmbuf->desc_count);
+
+                       TAILQ_REMOVE(&vq->zmbuf_list, zmbuf, next);
+                       restore_mbuf(zmbuf->mbuf);
+                       rte_pktmbuf_free(zmbuf->mbuf);
+                       put_zmbuf(zmbuf);
+                       vq->nr_zmbuf -= 1;
+               }
+       }
+}
+
 static __rte_noinline uint16_t
 virtio_dev_tx_packed(struct virtio_net *dev, struct vhost_virtqueue *vq,
        struct rte_mempool *mbuf_pool, struct rte_mbuf **pkts, uint16_t count)
-- 
2.17.1

Reply via email to