Date: Fri, 5 Aug 2016 14:16:58 GMT From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307241 - soc2016/vincenzo/head/usr.sbin/bhyve Message-ID: <201608051416.u75EGweL022460@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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) { /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608051416.u75EGweL022460>