From: Maxime Coquelin <maxime.coquelin@redhat.com>
To: tiwei.bie@intel.com, zhihong.wang@intel.com, dev@dpdk.org
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
Subject: [dpdk-dev] [PATCH v3 3/7] vhost: use buffer vectors in dequeue path
Date: Wed, 27 Jun 2018 16:49:55 +0200 [thread overview]
Message-ID: <20180627144959.17277-4-maxime.coquelin@redhat.com> (raw)
In-Reply-To: <20180627144959.17277-1-maxime.coquelin@redhat.com>
To ease packed ring layout integration, this patch makes
the dequeue path to re-use buffer vectors implemented for
enqueue path.
Doing this, copy_desc_to_mbuf() is now ring layout type
agnostic.
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/virtio_net.c | 143 ++++++++++--------------------------------
1 file changed, 33 insertions(+), 110 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index ec4bcc400..4816e8003 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -750,11 +750,9 @@ put_zmbuf(struct zcopy_mbuf *zmbuf)
static __rte_always_inline int
copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
- struct vring_desc *descs, uint16_t max_desc,
- struct rte_mbuf *m, uint16_t desc_idx,
- struct rte_mempool *mbuf_pool)
+ struct buf_vector *buf_vec, uint16_t nr_vec,
+ struct rte_mbuf *m, struct rte_mempool *mbuf_pool)
{
- struct vring_desc *desc;
uint64_t desc_addr, desc_gaddr;
uint32_t desc_avail, desc_offset;
uint32_t mbuf_avail, mbuf_offset;
@@ -764,24 +762,18 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
struct virtio_net_hdr tmp_hdr;
struct virtio_net_hdr *hdr = NULL;
/* A counter to avoid desc dead loop chain */
- uint32_t nr_desc = 1;
+ uint16_t vec_idx = 0;
struct batch_copy_elem *batch_copy = vq->batch_copy_elems;
int error = 0;
- desc = &descs[desc_idx];
- if (unlikely((desc->len < dev->vhost_hlen)) ||
- (desc->flags & VRING_DESC_F_INDIRECT)) {
- error = -1;
- goto out;
- }
-
- desc_chunck_len = desc->len;
- desc_gaddr = desc->addr;
+ desc_chunck_len = buf_vec[vec_idx].buf_len;
+ desc_gaddr = buf_vec[vec_idx].buf_addr;
desc_addr = vhost_iova_to_vva(dev,
vq, desc_gaddr,
&desc_chunck_len,
VHOST_ACCESS_RO);
- if (unlikely(!desc_addr)) {
+ if (unlikely(buf_vec[vec_idx].buf_len < dev->vhost_hlen ||
+ !desc_addr)) {
error = -1;
goto out;
}
@@ -828,16 +820,12 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
* for Tx: the first for storing the header, and others
* for storing the data.
*/
- if (likely((desc->len == dev->vhost_hlen) &&
- (desc->flags & VRING_DESC_F_NEXT) != 0)) {
- desc = &descs[desc->next];
- if (unlikely(desc->flags & VRING_DESC_F_INDIRECT)) {
- error = -1;
+ if (likely(buf_vec[vec_idx].buf_len == dev->vhost_hlen)) {
+ if (unlikely(++vec_idx >= nr_vec))
goto out;
- }
- desc_chunck_len = desc->len;
- desc_gaddr = desc->addr;
+ desc_chunck_len = buf_vec[vec_idx].buf_len;
+ desc_gaddr = buf_vec[vec_idx].buf_addr;
desc_addr = vhost_iova_to_vva(dev,
vq, desc_gaddr,
&desc_chunck_len,
@@ -848,10 +836,9 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
}
desc_offset = 0;
- desc_avail = desc->len;
- nr_desc += 1;
+ desc_avail = buf_vec[vec_idx].buf_len;
} else {
- desc_avail = desc->len - dev->vhost_hlen;
+ desc_avail = buf_vec[vec_idx].buf_len - dev->vhost_hlen;
if (unlikely(desc_chunck_len < dev->vhost_hlen)) {
desc_chunck_len = desc_avail;
@@ -906,7 +893,8 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
if (likely(cpy_len > MAX_BATCH_LEN ||
vq->batch_copy_nb_elems >= vq->size ||
(hdr && cur == m) ||
- desc->len != desc_chunck_len)) {
+ buf_vec[vec_idx].buf_len !=
+ desc_chunck_len)) {
rte_memcpy(rte_pktmbuf_mtod_offset(cur, void *,
mbuf_offset),
(void *)((uintptr_t)(desc_addr +
@@ -933,22 +921,11 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
/* This desc reaches to its end, get the next one */
if (desc_avail == 0) {
- if ((desc->flags & VRING_DESC_F_NEXT) == 0)
+ if (++vec_idx >= nr_vec)
break;
- if (unlikely(desc->next >= max_desc ||
- ++nr_desc > max_desc)) {
- error = -1;
- goto out;
- }
- desc = &descs[desc->next];
- if (unlikely(desc->flags & VRING_DESC_F_INDIRECT)) {
- error = -1;
- goto out;
- }
-
- desc_chunck_len = desc->len;
- desc_gaddr = desc->addr;
+ desc_chunck_len = buf_vec[vec_idx].buf_len;
+ desc_gaddr = buf_vec[vec_idx].buf_addr;
desc_addr = vhost_iova_to_vva(dev,
vq, desc_gaddr,
&desc_chunck_len,
@@ -961,7 +938,7 @@ copy_desc_to_mbuf(struct virtio_net *dev, struct vhost_virtqueue *vq,
rte_prefetch0((void *)(uintptr_t)desc_addr);
desc_offset = 0;
- desc_avail = desc->len;
+ desc_avail = buf_vec[vec_idx].buf_len;
PRINT_PACKET(dev, (uintptr_t)desc_addr,
(uint32_t)desc_chunck_len, 0);
@@ -1085,11 +1062,8 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
struct virtio_net *dev;
struct rte_mbuf *rarp_mbuf = NULL;
struct vhost_virtqueue *vq;
- uint32_t desc_indexes[MAX_PKT_BURST];
- uint32_t used_idx;
uint32_t i = 0;
uint16_t free_entries;
- uint16_t avail_idx;
dev = get_device(vid);
if (!dev)
@@ -1135,7 +1109,6 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
next = TAILQ_NEXT(zmbuf, next);
if (mbuf_is_consumed(zmbuf->mbuf)) {
- used_idx = vq->last_used_idx++ & (vq->size - 1);
update_shadow_used_ring(vq, zmbuf->desc_idx, 0);
nr_updated += 1;
@@ -1182,89 +1155,43 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
}
free_entries = *((volatile uint16_t *)&vq->avail->idx) -
- vq->last_avail_idx;
+ vq->last_avail_idx;
if (free_entries == 0)
goto out;
VHOST_LOG_DEBUG(VHOST_DATA, "(%d) %s\n", dev->vid, __func__);
- /* Prefetch available and used ring */
- avail_idx = vq->last_avail_idx & (vq->size - 1);
- used_idx = vq->last_used_idx & (vq->size - 1);
- rte_prefetch0(&vq->avail->ring[avail_idx]);
- rte_prefetch0(&vq->used->ring[used_idx]);
-
count = RTE_MIN(count, MAX_PKT_BURST);
count = RTE_MIN(count, free_entries);
VHOST_LOG_DEBUG(VHOST_DATA, "(%d) about to dequeue %u buffers\n",
dev->vid, count);
- /* Retrieve all of the head indexes first to avoid caching issues. */
for (i = 0; i < count; i++) {
- avail_idx = (vq->last_avail_idx + i) & (vq->size - 1);
- used_idx = (vq->last_used_idx + i) & (vq->size - 1);
- desc_indexes[i] = vq->avail->ring[avail_idx];
-
- if (likely(dev->dequeue_zero_copy == 0))
- update_shadow_used_ring(vq, desc_indexes[i], 0);
- }
-
- /* Prefetch descriptor index. */
- rte_prefetch0(&vq->desc[desc_indexes[0]]);
- for (i = 0; i < count; i++) {
- struct vring_desc *desc, *idesc = NULL;
- uint16_t sz, idx;
- uint64_t dlen;
+ struct buf_vector buf_vec[BUF_VECTOR_MAX];
+ uint16_t head_idx, dummy_len;
+ uint32_t nr_vec = 0;
int err;
- if (likely(i + 1 < count))
- rte_prefetch0(&vq->desc[desc_indexes[i + 1]]);
-
- if (vq->desc[desc_indexes[i]].flags & VRING_DESC_F_INDIRECT) {
- dlen = vq->desc[desc_indexes[i]].len;
- desc = (struct vring_desc *)(uintptr_t)
- vhost_iova_to_vva(dev, vq,
- vq->desc[desc_indexes[i]].addr,
- &dlen,
- VHOST_ACCESS_RO);
- if (unlikely(!desc))
- break;
-
- if (unlikely(dlen < vq->desc[desc_indexes[i]].len)) {
- /*
- * The indirect desc table is not contiguous
- * in process VA space, we have to copy it.
- */
- idesc = alloc_copy_ind_table(dev, vq,
- &vq->desc[desc_indexes[i]]);
- if (unlikely(!idesc))
- break;
-
- desc = idesc;
- }
+ if (unlikely(fill_vec_buf(dev, vq,
+ vq->last_avail_idx + i,
+ &nr_vec, buf_vec,
+ &head_idx, &dummy_len) < 0))
+ break;
- rte_prefetch0(desc);
- sz = vq->desc[desc_indexes[i]].len / sizeof(*desc);
- idx = 0;
- } else {
- desc = vq->desc;
- sz = vq->size;
- idx = desc_indexes[i];
- }
+ if (likely(dev->dequeue_zero_copy == 0))
+ update_shadow_used_ring(vq, head_idx, 0);
pkts[i] = rte_pktmbuf_alloc(mbuf_pool);
if (unlikely(pkts[i] == NULL)) {
RTE_LOG(ERR, VHOST_DATA,
"Failed to allocate memory for mbuf.\n");
- free_ind_table(idesc);
break;
}
- err = copy_desc_to_mbuf(dev, vq, desc, sz, pkts[i], idx,
- mbuf_pool);
+ err = copy_desc_to_mbuf(dev, vq, buf_vec, nr_vec, pkts[i],
+ mbuf_pool);
if (unlikely(err)) {
rte_pktmbuf_free(pkts[i]);
- free_ind_table(idesc);
break;
}
@@ -1274,11 +1201,10 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
zmbuf = get_zmbuf(vq);
if (!zmbuf) {
rte_pktmbuf_free(pkts[i]);
- free_ind_table(idesc);
break;
}
zmbuf->mbuf = pkts[i];
- zmbuf->desc_idx = desc_indexes[i];
+ zmbuf->desc_idx = head_idx;
/*
* Pin lock the mbuf; we will check later to see
@@ -1291,9 +1217,6 @@ rte_vhost_dequeue_burst(int vid, uint16_t queue_id,
vq->nr_zmbuf += 1;
TAILQ_INSERT_TAIL(&vq->zmbuf_list, zmbuf, next);
}
-
- if (unlikely(!!idesc))
- free_ind_table(idesc);
}
vq->last_avail_idx += i;
--
2.14.4
next prev parent reply other threads:[~2018-06-27 14:50 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-27 14:49 [dpdk-dev] [PATCH v3 0/7] vhost: generalize buffer vectors Maxime Coquelin
2018-06-27 14:49 ` [dpdk-dev] [PATCH v3 1/7] vhost: use shadow used ring in dequeue path Maxime Coquelin
2018-07-03 3:28 ` Tiwei Bie
2018-07-03 5:53 ` Maxime Coquelin
2018-06-27 14:49 ` [dpdk-dev] [PATCH v3 2/7] vhost: make gpa to hpa failure an error Maxime Coquelin
2018-07-03 4:45 ` Tiwei Bie
2018-07-03 5:51 ` Maxime Coquelin
2018-06-27 14:49 ` Maxime Coquelin [this message]
2018-06-27 14:49 ` [dpdk-dev] [PATCH v3 4/7] vhost: translate iovas at vectors fill time Maxime Coquelin
2018-06-27 14:49 ` [dpdk-dev] [PATCH v3 5/7] vhost: improve prefetching in dequeue path Maxime Coquelin
2018-06-27 14:49 ` [dpdk-dev] [PATCH v3 6/7] vhost: prefetch first descriptor " Maxime Coquelin
2018-06-27 14:49 ` [dpdk-dev] [PATCH v3 7/7] vhost: improve prefetching in enqueue path Maxime Coquelin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180627144959.17277-4-maxime.coquelin@redhat.com \
--to=maxime.coquelin@redhat.com \
--cc=dev@dpdk.org \
--cc=tiwei.bie@intel.com \
--cc=zhihong.wang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).