From: Maxime Coquelin <maxime.coquelin@redhat.com>
To: stable@dpdk.org
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
Subject: [dpdk-stable] [PATCH v16.11 LTS 5/6] vhost: handle virtually non-contiguous buffers in Rx
Date: Mon, 23 Apr 2018 17:59:17 +0200 [thread overview]
Message-ID: <20180423155918.21350-6-maxime.coquelin@redhat.com> (raw)
In-Reply-To: <20180423155918.21350-1-maxime.coquelin@redhat.com>
This patch enables the handling of buffers non-contiguous in
process virtual address space in the enqueue path when mergeable
buffers aren't used.
When virtio-net header doesn't fit in a single chunck, it is
computed in a local variable and copied to the buffer chuncks
afterwards.
For packet content, the copy length is limited to the chunck
size, next chuncks VAs being fetched afterward.
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/virtio_net.c | 79 +++++++++++++++++++++++++++++++++++--------
1 file changed, 65 insertions(+), 14 deletions(-)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index f66c67b43..99dfdefb3 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -253,36 +253,75 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vring_desc *descs,
struct rte_mbuf *m, uint16_t desc_idx, uint32_t size)
{
uint32_t desc_avail, desc_offset;
- uint64_t desc_len;
uint32_t mbuf_avail, mbuf_offset;
uint32_t cpy_len;
+ uint64_t desc_chunck_len;
struct vring_desc *desc;
- uint64_t desc_addr;
+ uint64_t desc_addr, desc_gaddr;
struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0, 0, 0, 0, 0, 0}, 0};
/* A counter to avoid desc dead loop chain */
uint16_t nr_desc = 1;
desc = &descs[desc_idx];
- desc_len = desc->len;
- desc_addr = gpa_to_vva(dev, desc->addr, &desc_len);
+ desc_chunck_len = desc->len;
+ desc_gaddr = desc->addr;
+ desc_addr = gpa_to_vva(dev, desc_gaddr, &desc_chunck_len);
/*
* Checking of 'desc_addr' placed outside of 'unlikely' macro to avoid
* performance issue with some versions of gcc (4.8.4 and 5.3.0) which
* otherwise stores offset on the stack instead of in a register.
*/
- if (unlikely(desc_len != desc->len ||
- desc->len < dev->vhost_hlen) || !desc_addr)
+ if (unlikely(desc->len < dev->vhost_hlen) || !desc_addr)
return -1;
rte_prefetch0((void *)(uintptr_t)desc_addr);
virtio_enqueue_offload(m, &virtio_hdr.hdr);
- copy_virtio_net_hdr(dev, desc_addr, virtio_hdr);
- vhost_log_write(dev, desc->addr, dev->vhost_hlen);
- PRINT_PACKET(dev, (uintptr_t)desc_addr, dev->vhost_hlen, 0);
+ if (likely(desc_chunck_len >= dev->vhost_hlen)) {
+ copy_virtio_net_hdr(dev, desc_addr, virtio_hdr);
+
+ virtio_enqueue_offload(m,
+ (struct virtio_net_hdr *)(uintptr_t)desc_addr);
+ PRINT_PACKET(dev, (uintptr_t)desc_addr, dev->vhost_hlen, 0);
+ } else {
+ uint64_t remain = dev->vhost_hlen;
+ uint64_t len;
+ uint64_t src = (uint64_t)(uintptr_t)&virtio_hdr, dst;
+ uint64_t guest_addr = desc_gaddr;
+
+ while (remain) {
+ len = remain;
+ dst = gpa_to_vva(dev, guest_addr, &len);
+ if (unlikely(!dst || !len))
+ return -1;
+
+ rte_memcpy((void *)(uintptr_t)dst,
+ (void *)(uintptr_t)src, len);
+
+ PRINT_PACKET(dev, (uintptr_t)dst, len, 0);
+ remain -= len;
+ guest_addr += len;
+ dst += len;
+ }
+ }
+
+ vhost_log_write(dev, desc_gaddr, dev->vhost_hlen);
- desc_offset = dev->vhost_hlen;
desc_avail = desc->len - dev->vhost_hlen;
+ if (unlikely(desc_chunck_len < dev->vhost_hlen)) {
+ desc_chunck_len = desc_avail;
+ desc_gaddr += dev->vhost_hlen;
+ desc_addr = gpa_to_vva(dev,
+ desc_gaddr,
+ &desc_chunck_len);
+ if (unlikely(!desc_addr))
+ return -1;
+
+ desc_offset = 0;
+ } else {
+ desc_offset = dev->vhost_hlen;
+ desc_chunck_len -= dev->vhost_hlen;
+ }
mbuf_avail = rte_pktmbuf_data_len(m);
mbuf_offset = 0;
@@ -305,20 +344,31 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vring_desc *descs,
return -1;
desc = &descs[desc->next];
- desc_len = desc->len;
- desc_addr = gpa_to_vva(dev, desc->addr, &desc_len);
- if (unlikely(!desc_addr || desc_len != desc->len))
+ desc_chunck_len = desc->len;
+ desc_gaddr = desc->addr;
+ desc_addr = gpa_to_vva(dev,
+ desc_gaddr, &desc_chunck_len);
+ if (unlikely(!desc_addr))
return -1;
desc_offset = 0;
desc_avail = desc->len;
+ } else if (unlikely(desc_chunck_len == 0)) {
+ desc_chunck_len = desc_avail;
+ desc_gaddr += desc_offset;
+ desc_addr = gpa_to_vva(dev,
+ desc_gaddr, &desc_chunck_len);
+ if (unlikely(!desc_addr))
+ return -1;
+
+ desc_offset = 0;
}
cpy_len = RTE_MIN(desc_avail, mbuf_avail);
rte_memcpy((void *)((uintptr_t)(desc_addr + desc_offset)),
rte_pktmbuf_mtod_offset(m, void *, mbuf_offset),
cpy_len);
- vhost_log_write(dev, desc->addr + desc_offset, cpy_len);
+ vhost_log_write(dev, desc_gaddr + desc_offset, cpy_len);
PRINT_PACKET(dev, (uintptr_t)(desc_addr + desc_offset),
cpy_len, 0);
@@ -326,6 +376,7 @@ copy_mbuf_to_desc(struct virtio_net *dev, struct vring_desc *descs,
mbuf_offset += cpy_len;
desc_avail -= cpy_len;
desc_offset += cpy_len;
+ desc_chunck_len -= cpy_len;
}
return 0;
--
2.14.3
next prev parent reply other threads:[~2018-04-23 15:59 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-23 15:59 [dpdk-stable] [PATCH v16.11 LTS 0/6] Vhost: CVE-2018-1059 fixes Maxime Coquelin
2018-04-23 15:59 ` [dpdk-stable] [PATCH v16.11 LTS 1/6] vhost: check all range is mapped when translating GPAs Maxime Coquelin
2018-04-23 15:59 ` [dpdk-stable] [PATCH v16.11 LTS 2/6] vhost: ensure all range is mapped when translating QVAs Maxime Coquelin
2018-04-23 15:59 ` [dpdk-stable] [PATCH v16.11 LTS 3/6] vhost: add support for non-contiguous indirect descs tables Maxime Coquelin
2018-04-23 15:59 ` [dpdk-stable] [PATCH v16.11 LTS 4/6] vhost: handle virtually non-contiguous buffers in Tx Maxime Coquelin
2018-04-23 15:59 ` Maxime Coquelin [this message]
2018-04-23 15:59 ` [dpdk-stable] [PATCH v16.11 LTS 6/6] vhost: handle virtually non-contiguous buffers in Rx-mrg 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=20180423155918.21350-6-maxime.coquelin@redhat.com \
--to=maxime.coquelin@redhat.com \
--cc=stable@dpdk.org \
/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).