socsvn commit: r307240 - soc2016/vincenzo/head/usr.sbin/bhyve
vincenzo at FreeBSD.org
vincenzo at FreeBSD.org
Fri Aug 5 14:16:12 UTC 2016
Author: vincenzo
Date: Fri Aug 5 14:16:10 2016
New Revision: 307240
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307240
Log:
bhyve: netmap_send: rewrite it from scratch
Modified:
soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c
Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c
==============================================================================
--- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:14:40 2016 (r307239)
+++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:16:10 2016 (r307240)
@@ -659,81 +659,81 @@
static int
netmap_send(struct net_backend *be, struct iovec *iov,
- int iovcnt, int size, int more)
+ int iovcnt, int size, int more)
{
struct netmap_priv *priv = be->priv;
struct netmap_ring *ring;
- uint32_t last;
- uint32_t idx;
- uint8_t *dst;
+ int nm_buf_size;
+ int nm_buf_len;
+ uint32_t head;
+ void *nm_buf;
int j;
- uint32_t i;
- if (iovcnt <= 0)
- goto txsync;
+ if (iovcnt <= 0 || size <= 0) {
+ D("Wrong iov: iovcnt %d size %d", iovcnt, size);
+ return 0;
+ }
ring = priv->tx;
- last = i = ring->cur;
-
- if (nm_ring_space(ring) < iovcnt) {
- static int c;
- c++;
- RD(5, "no space, txsync %d", c);
- /* Not enough netmap slots. */
+ head = ring->head;
+ if (head == ring->tail) {
+ RD(1, "No space, drop %d bytes", size);
goto txsync;
}
+ nm_buf = NETMAP_BUF(ring, ring->slot[head].buf_idx);
+ nm_buf_size = ring->nr_buf_size;
+ nm_buf_len = 0;
for (j = 0; j < iovcnt; j++) {
int iov_frag_size = iov[j].iov_len;
- int offset = 0;
- int nm_frag_size;
+ void *iov_frag_buf = iov[j].iov_base;
/* Split each iovec fragment over more netmap slots, if
- necessary (without performing data copy). */
- while (iov_frag_size) {
- nm_frag_size = iov_frag_size;
- if (nm_frag_size > ring->nr_buf_size) {
- nm_frag_size = ring->nr_buf_size;
+ necessary. */
+ for (;;) {
+ int copylen;
+
+ copylen = iov_frag_size < nm_buf_size ? iov_frag_size : nm_buf_size;
+ pkt_copy(iov_frag_buf, nm_buf, copylen);
+
+ iov_frag_buf += copylen;
+ iov_frag_size -= copylen;
+ nm_buf += copylen;
+ nm_buf_size -= copylen;
+ nm_buf_len += copylen;
+
+ if (iov_frag_size == 0) {
+ break;
}
- if (nm_ring_empty(ring)) {
- /* We run out of netmap slots while splitting the
- iovec fragments. */
+ ring->slot[head].len = nm_buf_len;
+ ring->slot[head].flags = NS_MOREFRAG;
+ head = nm_ring_next(ring, head);
+ if (head == ring->tail) {
+ /* We ran out of netmap slots while
+ * splitting the iovec fragments. */
+ RD(1, "No space, drop %d bytes", size);
goto txsync;
}
-
- idx = ring->slot[i].buf_idx;
- dst = (uint8_t *)NETMAP_BUF(ring, idx);
-
- ring->slot[i].len = nm_frag_size;
-// #define USE_INDIRECT_BUFFERS
-#ifdef USE_INDIRECT_BUFFERS
- ring->slot[i].flags = NS_MOREFRAG | NS_INDIRECT;
- ring->slot[i].ptr = (uintptr_t)(iov[j].iov_base + offset);
-#else /* !USE_INDIRECT_BUFFERS */
- ring->slot[i].flags = NS_MOREFRAG;
- pkt_copy(iov[j].iov_base + offset, dst, nm_frag_size);
-#endif /* !USING_INDIRECT_BUFFERS */
-
- last = i;
- i = nm_ring_next(ring, i);
-
- offset += nm_frag_size;
- iov_frag_size -= nm_frag_size;
+ nm_buf = NETMAP_BUF(ring, ring->slot[head].buf_idx);
+ nm_buf_size = ring->nr_buf_size;
+ nm_buf_len = 0;
}
}
- /* The last slot must not have NS_MOREFRAG set. */
- ring->slot[last].flags &= ~NS_MOREFRAG;
- /* Now update ring->cur and ring->avail. */
- ring->cur = ring->head = i;
+ /* Complete the last slot, which must not have NS_MOREFRAG set. */
+ ring->slot[head].len = nm_buf_len;
+ ring->slot[head].flags = 0;
+ head = nm_ring_next(ring, head);
-txsync:
- if (!more) {// || nm_ring_space(ring) < 64) {
- // IFRATE(vq->vq_vs->rate.cur.var2[vq->vq_num]++);
- // netmap_ioctl_counter++;
- ioctl(be->fd, NIOCTXSYNC, NULL);
+ /* Now update ring->head and ring->cur. */
+ ring->head = ring->cur = head;
+
+ if (more) {// && nm_ring_space(ring) > 64
+ return 0;
}
+txsync:
+ ioctl(be->fd, NIOCTXSYNC, NULL);
return 0;
}
More information about the svn-soc-all
mailing list