socsvn commit: r307241 - soc2016/vincenzo/head/usr.sbin/bhyve
vincenzo at FreeBSD.org
vincenzo at FreeBSD.org
Fri Aug 5 14:17:00 UTC 2016
Author: vincenzo
Date: Fri Aug 5 14:16:58 2016
New Revision: 307241
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307241
Log:
bhyve: netmap_recv: write it from scratch
Modified:
soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c
soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h
soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c
Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c
==============================================================================
--- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:16:10 2016 (r307240)
+++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:16:58 2016 (r307241)
@@ -91,8 +91,7 @@
* times to receive a single packet, depending of how big is
* buffers you provide.
*/
- int (*recv)(struct net_backend *be, struct iovec *iov,
- int iovcnt, int *more);
+ int (*recv)(struct net_backend *be, struct iovec *iov, int iovcnt);
/*
* Ask the backend for the virtio-net features it is able to
@@ -158,8 +157,7 @@
}
static int
-netbe_null_recv(struct net_backend *be, struct iovec *iov,
- int iovcnt, int *more)
+netbe_null_recv(struct net_backend *be, struct iovec *iov, int iovcnt)
{
fprintf(stderr, "netbe_null_recv called ?\n");
return -1; /* never called, i believe */
@@ -278,13 +276,12 @@
}
static int
-tap_recv(struct net_backend *be, struct iovec *iov, int iovcnt, int *more)
+tap_recv(struct net_backend *be, struct iovec *iov, int iovcnt)
{
int ret;
/* Should never be called without a valid tap fd */
assert(be->fd != -1);
- *more = 0;
ret = readv(be->fd, iov, iovcnt);
@@ -739,90 +736,68 @@
}
static int
-netmap_recv(struct net_backend *be, struct iovec *iov,
- int iovcnt, int *more)
+netmap_recv(struct net_backend *be, struct iovec *iov, int iovcnt)
{
struct netmap_priv *priv = be->priv;
+ struct netmap_slot *slot = NULL;
struct netmap_ring *ring;
- int tot = 0;
- int copylen;
- int iov_avail;
- uint8_t *iov_buf;
+ void *iov_frag_buf;
+ int iov_frag_size;
+ int totlen = 0;
+ uint32_t head;
assert(iovcnt);
ring = priv->rx;
+ head = ring->head;
+ iov_frag_buf = iov->iov_base;
+ iov_frag_size = iov->iov_len;
- /* Init iovec pointers. */
- iov_buf = iov->iov_base;
- iov_avail = iov->iov_len;
-
- if (!priv->rx_continue) {
- /* Init netmap pointers. */
- priv->rx_idx = ring->cur;
- priv->rx_avail_slots = nm_ring_space(ring);
- priv->rx_buf = NETMAP_BUF(ring,
- ring->slot[priv->rx_idx].buf_idx);
- priv->rx_avail = ring->slot[priv->rx_idx].len;
- priv->rx_morefrag = (ring->slot[priv->rx_idx].flags
- & NS_MOREFRAG);
+ do {
+ int nm_buf_len;
+ void *nm_buf;
- if (!priv->rx_avail_slots) {
- goto out;
+ if (head == ring->tail) {
+ return 0;
}
- priv->rx_continue = 1;
- }
- for (;;) {
- copylen = priv->rx_avail;
- if (copylen > iov_avail) {
- copylen = iov_avail;
- }
+ slot = ring->slot + head;
+ nm_buf = NETMAP_BUF(ring, slot->buf_idx);
+ nm_buf_len = slot->len;
+
+ for (;;) {
+ int copylen = nm_buf_len < iov_frag_size ? nm_buf_len : iov_frag_size;
+
+ pkt_copy(nm_buf, iov_frag_buf, copylen);
+ nm_buf += copylen;
+ nm_buf_len -= copylen;
+ iov_frag_buf += copylen;
+ iov_frag_size -= copylen;
+ totlen += copylen;
- /* Copy and update pointers. */
- bcopy(priv->rx_buf, iov_buf, copylen);
- iov_buf += copylen;
- iov_avail -= copylen;
- priv->rx_buf += copylen;
- priv->rx_avail -= copylen;
- tot += copylen;
-
- if (!priv->rx_avail) {
- priv->rx_avail_slots--;
- if (!priv->rx_morefrag || !priv->rx_avail_slots) {
- priv->rx_continue = 0;
+ if (nm_buf_len == 0) {
break;
}
- /* Go to the next netmap slot. */
- priv->rx_idx = nm_ring_next(ring, priv->rx_idx);
- priv->rx_buf = NETMAP_BUF(ring,
- ring->slot[priv->rx_idx].buf_idx);
- priv->rx_avail = ring->slot[priv->rx_idx].len;
- priv->rx_morefrag =
- (ring->slot[priv->rx_idx].flags
- & NS_MOREFRAG);
- }
- if (!iov_avail) {
+ iov++;
iovcnt--;
- if (!iovcnt) {
- break;
+ if (iovcnt == 0) {
+ /* No space to receive. */
+ D("Short iov, drop %d bytes", totlen);
+ return -ENOSPC;
}
- /* Go to the next iovec descriptor. */
- iov++;
- iov_buf = iov->iov_base;
- iov_avail = iov->iov_len;
+ iov_frag_buf = iov->iov_base;
+ iov_frag_size = iov->iov_len;
}
- }
- if (!priv->rx_continue) {
- /* End of reception: Update the ring now. */
- ring->cur = ring->head = nm_ring_next(ring, priv->rx_idx);
- }
-out:
- *more = priv->rx_continue;
+ head = nm_ring_next(ring, head);
+
+ } while (slot->flags & NS_MOREFRAG);
+
+ /* Release slots to netmap. */
+ ring->head = ring->cur = head;
- return tot;
+ return totlen;
}
static struct net_backend netmap_backend = {
@@ -1020,7 +995,7 @@
}
int
-netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt, int *more)
+netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt)
{
int hlen = 0;
int ret;
@@ -1052,7 +1027,7 @@
}
}
- ret = be->recv(be, iov, iovcnt, more);
+ ret = be->recv(be, iov, iovcnt);
if (ret > 0) {
ret += hlen;
}
Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h
==============================================================================
--- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:16:10 2016 (r307240)
+++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:16:58 2016 (r307241)
@@ -47,8 +47,7 @@
unsigned vnet_hdr_len);
void netbe_send(struct net_backend *be, struct iovec *iov,
int iovcnt, int len, int more);
-int netbe_recv(struct net_backend *be, struct iovec *iov,
- int iovcnt, int *more);
+int netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt);
/*
Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c
==============================================================================
--- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:16:10 2016 (r307240)
+++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:16:58 2016 (r307241)
@@ -209,11 +209,10 @@
* We only make it large enough for TSO-sized segment.
*/
static uint8_t dummybuf[65536+64];
- int more;
iov[0].iov_base = dummybuf;
iov[0].iov_len = sizeof(dummybuf);
- netbe_recv(sc->vsc_be, iov, 1, &more);
+ netbe_recv(sc->vsc_be, iov, 1);
}
static void
@@ -223,7 +222,6 @@
struct vqueue_info *vq;
int len, n;
uint16_t idx;
- int more;
/*
* This will be called when the rx ring hasn't yet
@@ -258,7 +256,7 @@
n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL);
assert(n >= 1 && n <= VTNET_MAXSEGS);
- len = netbe_recv(sc->vsc_be, iov, n, &more);
+ len = netbe_recv(sc->vsc_be, iov, n);
if (len == 0) {
/*
More information about the svn-soc-all
mailing list