From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
Yuanhan Liu <yuanhan.liu@linux.intel.com>,
Victor Kaplansky <victork@redhat.com>
Subject: [Qemu-devel] [PULL 13/13] tests/vhost-user-bridge: add scattering of incoming packets
Date: Fri, 19 Feb 2016 10:00:53 +0200 [thread overview]
Message-ID: <1455868726-26350-14-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1455868726-26350-1-git-send-email-mst@redhat.com>
From: Victor Kaplansky <victork@redhat.com>
This patch adds to the vubr test the scattering of incoming
packets to the chain of RX buffer. Also, this patch corrects the
size of the header preceding the packet in RX buffers.
Note that this patch doesn't add the support for mergeable
buffers.
Signed-off-by: Victor Kaplansky <victork@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
tests/vhost-user-bridge.c | 92 +++++++++++++++++++++++++++++++----------------
1 file changed, 61 insertions(+), 31 deletions(-)
diff --git a/tests/vhost-user-bridge.c b/tests/vhost-user-bridge.c
index 9fb09f1..f5030b2 100644
--- a/tests/vhost-user-bridge.c
+++ b/tests/vhost-user-bridge.c
@@ -47,6 +47,7 @@
#include <arpa/inet.h>
#include <ctype.h>
#include <netdb.h>
+#include <qemu/osdep.h>
#include <linux/vhost.h>
@@ -186,6 +187,8 @@ typedef struct VubrVirtq {
#define VHOST_MEMORY_MAX_NREGIONS 8
#define VHOST_USER_F_PROTOCOL_FEATURES 30
+/* v1.0 compliant. */
+#define VIRTIO_F_VERSION_1 32
#define VHOST_LOG_PAGE 4096
@@ -294,6 +297,7 @@ typedef struct VubrDev {
struct sockaddr_in backend_udp_dest;
int ready;
uint64_t features;
+ int hdrlen;
} VubrDev;
static const char *vubr_request_str[] = {
@@ -484,7 +488,8 @@ vubr_backend_udp_recvbuf(VubrDev *dev, uint8_t *buf, size_t buflen)
static void
vubr_consume_raw_packet(VubrDev *dev, uint8_t *buf, uint32_t len)
{
- int hdrlen = sizeof(struct virtio_net_hdr_v1);
+ int hdrlen = dev->hdrlen;
+ DPRINT(" hdrlen = %d\n", dev->hdrlen);
if (VHOST_USER_BRIDGE_DEBUG) {
print_buffer(buf, len);
@@ -546,6 +551,7 @@ vubr_post_buffer(VubrDev *dev, VubrVirtq *vq, uint8_t *buf, int32_t len)
struct vring_avail *avail = vq->avail;
struct vring_used *used = vq->used;
uint64_t log_guest_addr = vq->log_guest_addr;
+ int32_t remaining_len = len;
unsigned int size = vq->size;
@@ -560,36 +566,49 @@ vubr_post_buffer(VubrDev *dev, VubrVirtq *vq, uint8_t *buf, int32_t len)
uint16_t d_index = avail->ring[a_index];
int i = d_index;
+ uint32_t written_len = 0;
- DPRINT("Post packet to guest on vq:\n");
- DPRINT(" size = %d\n", vq->size);
- DPRINT(" last_avail_index = %d\n", vq->last_avail_index);
- DPRINT(" last_used_index = %d\n", vq->last_used_index);
- DPRINT(" a_index = %d\n", a_index);
- DPRINT(" u_index = %d\n", u_index);
- DPRINT(" d_index = %d\n", d_index);
- DPRINT(" desc[%d].addr = 0x%016"PRIx64"\n", i, desc[i].addr);
- DPRINT(" desc[%d].len = %d\n", i, desc[i].len);
- DPRINT(" desc[%d].flags = %d\n", i, desc[i].flags);
- DPRINT(" avail->idx = %d\n", avail_index);
- DPRINT(" used->idx = %d\n", used->idx);
-
- if (!(desc[i].flags & VRING_DESC_F_WRITE)) {
- /* FIXME: we should find writable descriptor. */
- fprintf(stderr, "Error: descriptor is not writable. Exiting.\n");
- exit(1);
- }
+ do {
+ DPRINT("Post packet to guest on vq:\n");
+ DPRINT(" size = %d\n", vq->size);
+ DPRINT(" last_avail_index = %d\n", vq->last_avail_index);
+ DPRINT(" last_used_index = %d\n", vq->last_used_index);
+ DPRINT(" a_index = %d\n", a_index);
+ DPRINT(" u_index = %d\n", u_index);
+ DPRINT(" d_index = %d\n", d_index);
+ DPRINT(" desc[%d].addr = 0x%016"PRIx64"\n", i, desc[i].addr);
+ DPRINT(" desc[%d].len = %d\n", i, desc[i].len);
+ DPRINT(" desc[%d].flags = %d\n", i, desc[i].flags);
+ DPRINT(" avail->idx = %d\n", avail_index);
+ DPRINT(" used->idx = %d\n", used->idx);
+
+ if (!(desc[i].flags & VRING_DESC_F_WRITE)) {
+ /* FIXME: we should find writable descriptor. */
+ fprintf(stderr, "Error: descriptor is not writable. Exiting.\n");
+ exit(1);
+ }
- void *chunk_start = (void *)gpa_to_va(dev, desc[i].addr);
- uint32_t chunk_len = desc[i].len;
+ void *chunk_start = (void *)gpa_to_va(dev, desc[i].addr);
+ uint32_t chunk_len = desc[i].len;
+ uint32_t chunk_write_len = MIN(remaining_len, chunk_len);
- if (len <= chunk_len) {
- memcpy(chunk_start, buf, len);
- vubr_log_write(dev, desc[i].addr, len);
- } else {
- fprintf(stderr,
- "Received too long packet from the backend. Dropping...\n");
- return;
+ memcpy(chunk_start, buf + written_len, chunk_write_len);
+ vubr_log_write(dev, desc[i].addr, chunk_write_len);
+ remaining_len -= chunk_write_len;
+ written_len += chunk_write_len;
+
+ if ((remaining_len == 0) || !(desc[i].flags & VRING_DESC_F_NEXT)) {
+ break;
+ }
+
+ i = desc[i].next;
+ } while (1);
+
+ if (remaining_len > 0) {
+ fprintf(stderr,
+ "Too long packet for RX, remaining_len = %d, Dropping...\n",
+ remaining_len);
+ return;
}
/* Add descriptor to the used ring. */
@@ -697,7 +716,7 @@ vubr_backend_recv_cb(int sock, void *ctx)
VubrVirtq *rx_vq = &dev->vq[0];
uint8_t buf[4096];
struct virtio_net_hdr_v1 *hdr = (struct virtio_net_hdr_v1 *)buf;
- int hdrlen = sizeof(struct virtio_net_hdr_v1);
+ int hdrlen = dev->hdrlen;
int buflen = sizeof(buf);
int len;
@@ -706,6 +725,7 @@ vubr_backend_recv_cb(int sock, void *ctx)
}
DPRINT("\n\n *** IN UDP RECEIVE CALLBACK ***\n\n");
+ DPRINT(" hdrlen = %d\n", hdrlen);
uint16_t avail_index = atomic_mb_read(&rx_vq->avail->idx);
@@ -717,10 +737,12 @@ vubr_backend_recv_cb(int sock, void *ctx)
return;
}
+ memset(buf, 0, hdrlen);
+ /* TODO: support mergeable buffers. */
+ if (hdrlen == 12)
+ hdr->num_buffers = 1;
len = vubr_backend_udp_recvbuf(dev, buf + hdrlen, buflen - hdrlen);
- *hdr = (struct virtio_net_hdr_v1) { };
- hdr->num_buffers = 1;
vubr_post_buffer(dev, rx_vq, buf, len + hdrlen);
}
@@ -768,7 +790,15 @@ static int
vubr_set_features_exec(VubrDev *dev, VhostUserMsg *vmsg)
{
DPRINT("u64: 0x%016"PRIx64"\n", vmsg->payload.u64);
+
dev->features = vmsg->payload.u64;
+ if ((dev->features & (1ULL << VIRTIO_F_VERSION_1)) ||
+ (dev->features & (1ULL << VIRTIO_NET_F_MRG_RXBUF))) {
+ dev->hdrlen = 12;
+ } else {
+ dev->hdrlen = 10;
+ }
+
return 0;
}
--
MST
next prev parent reply other threads:[~2016-02-19 8:01 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-19 8:00 [Qemu-devel] [PULL 00/13] vhost, virtio, pci, pxe Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 01/13] virtio-net: use the backend cross-endian capabilities Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 02/13] vhost-net: revert support of cross-endian vnet headers Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 03/13] virtio: move cross-endian helper to vhost Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 04/13] vhost: move virtio 1.0 check to cross-endian helper Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 05/13] vhost: simplify vhost_needs_vring_endian() Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 06/13] virtio: optimize virtio_access_is_big_endian() for little-endian targets Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 07/13] msix: fix msix_vector_masked Michael S. Tsirkin
2016-02-19 12:18 ` Stefano Stabellini
2016-02-19 12:20 ` Peter Maydell
2016-02-19 12:29 ` Stefano Stabellini
2016-02-19 8:00 ` [Qemu-devel] [PULL 08/13] tests: add pxe e1000 and virtio-pci tests Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 09/13] dec: convert to realize() Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 10/13] change type of pci_bridge_initfn() to void Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 11/13] rules: filter out irrelevant files Michael S. Tsirkin
2016-02-19 8:00 ` [Qemu-devel] [PULL 12/13] vhost-user interrupt management fixes Michael S. Tsirkin
2016-02-19 8:00 ` Michael S. Tsirkin [this message]
2016-02-19 12:09 ` [Qemu-devel] [PULL 00/13] vhost, virtio, pci, pxe Peter Maydell
2016-02-19 12:41 ` Samuel Thibault
2016-02-19 14:17 ` Peter Maydell
2016-03-23 0:05 ` Samuel Thibault
2016-03-23 12:43 ` Peter Maydell
2016-03-23 12:45 ` Samuel Thibault
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=1455868726-26350-14-git-send-email-mst@redhat.com \
--to=mst@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=victork@redhat.com \
--cc=yuanhan.liu@linux.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).