Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Jan 2015 16:43:23 +0000 (UTC)
From:      Ruslan Bukin <br@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r276710 - in head/sys/dev/beri/virtio: . network
Message-ID:  <201501051643.t05GhNn7012291@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: br
Date: Mon Jan  5 16:43:22 2015
New Revision: 276710
URL: https://svnweb.freebsd.org/changeset/base/276710

Log:
  o Switch to use non-mergeable RX buffers to avoid mbuf adjustment needs
  o Operate with copy of iov as we expect later it was not modified

Modified:
  head/sys/dev/beri/virtio/network/if_vtbe.c
  head/sys/dev/beri/virtio/virtio.c
  head/sys/dev/beri/virtio/virtio.h
  head/sys/dev/beri/virtio/virtio_block.c

Modified: head/sys/dev/beri/virtio/network/if_vtbe.c
==============================================================================
--- head/sys/dev/beri/virtio/network/if_vtbe.c	Mon Jan  5 16:10:54 2015	(r276709)
+++ head/sys/dev/beri/virtio/network/if_vtbe.c	Mon Jan  5 16:43:22 2015	(r276710)
@@ -138,17 +138,16 @@ static int pio_enable_irq(struct vtbe_so
 static void
 vtbe_txstart_locked(struct vtbe_softc *sc)
 {
-	struct virtio_net_hdr_mrg_rxbuf *vnh;
 	struct iovec iov[DESC_COUNT];
+	struct virtio_net_hdr *vnh;
 	struct vqueue_info *vq;
-	struct iovec *riov;
+	struct iovec *tiov;
 	struct ifnet *ifp;
 	struct mbuf *m;
 	struct uio uio;
 	int enqueued;
 	int iolen;
 	int error;
-	int *addr;
 	int reg;
 	int len;
 	int n;
@@ -186,24 +185,16 @@ vtbe_txstart_locked(struct vtbe_softc *s
 
 		n = vq_getchain(sc->beri_mem_offset, vq, iov,
 			DESC_COUNT, NULL);
+		KASSERT(n == 2,
+			("Unexpected amount of descriptors (%d)", n));
 
-		KASSERT(n >= 1 && n <= DESC_COUNT,
-			("wrong descriptors num %d", n));
-
-		addr = iov[0].iov_base;
-		len = iov[0].iov_len;
-
+		tiov = getcopy(iov, n);
 		vnh = iov[0].iov_base;
 		memset(vnh, 0, sc->hdrsize);
-		vnh->num_buffers = htobe16(1);
-
-		iov[0].iov_len -= sc->hdrsize;
-		iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base +
-					sc->hdrsize);
-		riov = &iov[0];
 
-		uio.uio_resid = iov[0].iov_len;
-		uio.uio_iov = riov;
+		len = iov[1].iov_len;
+		uio.uio_resid = len;
+		uio.uio_iov = &tiov[1];
 		uio.uio_segflg = UIO_SYSSPACE;
 		uio.uio_iovcnt = 1;
 		uio.uio_offset = 0;
@@ -213,9 +204,10 @@ vtbe_txstart_locked(struct vtbe_softc *s
 		if (error)
 			panic("m_mbuftouio failed\n");
 
-		iolen = (len - iov[0].iov_len - sc->hdrsize);
-		vq_relchain(vq, iov, 0, iolen + sc->hdrsize);
-		paddr_unmap((void *)addr, len);
+		iolen = (len - uio.uio_resid + sc->hdrsize);
+
+		free(tiov, M_DEVBUF);
+		vq_relchain(vq, iov, n, iolen);
 
 		if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
 
@@ -391,6 +383,7 @@ static void
 vtbe_proc_rx(struct vtbe_softc *sc, struct vqueue_info *vq)
 {
 	struct iovec iov[DESC_COUNT];
+	struct iovec *tiov;
 	struct ifnet *ifp;
 	struct uio uio;
 	struct mbuf *m;
@@ -406,13 +399,15 @@ vtbe_proc_rx(struct vtbe_softc *sc, stru
 	KASSERT(n >= 1 && n <= DESC_COUNT,
 		("wrong n %d", n));
 
+	tiov = getcopy(iov, n);
+
 	iolen = 0;
 	for (i = 1; i < n; i++) {
 		iolen += iov[i].iov_len;
 	}
 
 	uio.uio_resid = iolen;
-	uio.uio_iov = &iov[1];
+	uio.uio_iov = &tiov[1];
 	uio.uio_segflg = UIO_SYSSPACE;
 	uio.uio_iovcnt = (n - 1);
 	uio.uio_rw = UIO_WRITE;
@@ -434,6 +429,7 @@ vtbe_proc_rx(struct vtbe_softc *sc, stru
 	CURVNET_RESTORE();
 
 done:
+	free(tiov, M_DEVBUF);
 	vq_relchain(vq, iov, n, iolen + sc->hdrsize);
 }
 
@@ -569,7 +565,7 @@ vtbe_attach(device_t dev)
 	sc = device_get_softc(dev);
 	sc->dev = dev;
 
-	sc->hdrsize = sizeof(struct virtio_net_hdr_mrg_rxbuf);
+	sc->hdrsize = sizeof(struct virtio_net_hdr);
 
 	if (bus_alloc_resources(dev, vtbe_spec, sc->res)) {
 		device_printf(dev, "could not allocate resources\n");
@@ -602,7 +598,6 @@ vtbe_attach(device_t dev)
 
 	/* Our features */
 	reg = htobe32(VIRTIO_NET_F_MAC |
-			VIRTIO_NET_F_MRG_RXBUF |
     			VIRTIO_F_NOTIFY_ON_EMPTY);
 	WRITE4(sc, VIRTIO_MMIO_HOST_FEATURES, reg);
 

Modified: head/sys/dev/beri/virtio/virtio.c
==============================================================================
--- head/sys/dev/beri/virtio/virtio.c	Mon Jan  5 16:10:54 2015	(r276709)
+++ head/sys/dev/beri/virtio/virtio.c	Mon Jan  5 16:43:22 2015	(r276710)
@@ -186,7 +186,7 @@ vq_relchain(struct vqueue_info *vq, stru
 	vu->idx = htobe16(uidx);
 
 	/* Clean up */
-	for (i = 1; i < (n-1); i++) {
+	for (i = 0; i < n; i++) {
 		paddr_unmap((void *)iov[i].iov_base, iov[i].iov_len);
 	}
 }
@@ -244,3 +244,17 @@ setup_offset(device_t dev, uint32_t *off
 	return (0);
 }
 
+struct iovec *
+getcopy(struct iovec *iov, int n)
+{
+	struct iovec *tiov;
+	int i;
+
+	tiov = malloc(n * sizeof(struct iovec), M_DEVBUF, M_NOWAIT);
+	for (i = 0; i < n; i++) {
+		tiov[i].iov_base = iov[i].iov_base;
+		tiov[i].iov_len = iov[i].iov_len;
+	}
+
+	return (tiov);
+}

Modified: head/sys/dev/beri/virtio/virtio.h
==============================================================================
--- head/sys/dev/beri/virtio/virtio.h	Mon Jan  5 16:10:54 2015	(r276709)
+++ head/sys/dev/beri/virtio/virtio.h	Mon Jan  5 16:43:22 2015	(r276710)
@@ -65,6 +65,7 @@ void paddr_unmap(void *phys, uint32_t si
 int vq_getchain(uint32_t beri_mem_offset, struct vqueue_info *vq,
 		struct iovec *iov, int n_iov, uint16_t *flags);
 void vq_relchain(struct vqueue_info *vq, struct iovec *iov, int n, uint32_t iolen);
+struct iovec * getcopy(struct iovec *iov, int n);
 
 int setup_pio(device_t dev, char *name, device_t *pio_dev);
 int setup_offset(device_t dev, uint32_t *offset);

Modified: head/sys/dev/beri/virtio/virtio_block.c
==============================================================================
--- head/sys/dev/beri/virtio/virtio_block.c	Mon Jan  5 16:10:54 2015	(r276709)
+++ head/sys/dev/beri/virtio/virtio_block.c	Mon Jan  5 16:43:22 2015	(r276710)
@@ -151,6 +151,7 @@ vtblk_proc(struct beri_vtblk_softc *sc, 
 	struct iovec iov[VTBLK_MAXSEGS + 2];
 	uint16_t flags[VTBLK_MAXSEGS + 2];
 	struct virtio_blk_outhdr *vbh;
+	struct iovec *tiov;
 	uint8_t *status;
 	off_t offset;
 	int iolen;
@@ -160,10 +161,10 @@ vtblk_proc(struct beri_vtblk_softc *sc, 
 
 	n = vq_getchain(sc->beri_mem_offset, vq, iov,
 		VTBLK_MAXSEGS + 2, flags);
-
 	KASSERT(n >= 2 && n <= VTBLK_MAXSEGS + 2,
 		("wrong n value %d", n));
 
+	tiov = getcopy(iov, n);
 	vbh = iov[0].iov_base;
 
 	status = iov[n-1].iov_base;
@@ -181,7 +182,7 @@ vtblk_proc(struct beri_vtblk_softc *sc, 
 	switch (type) {
 	case VIRTIO_BLK_T_OUT:
 	case VIRTIO_BLK_T_IN:
-		err = vtblk_rdwr(sc, iov + 1, i - 1,
+		err = vtblk_rdwr(sc, tiov + 1, i - 1,
 			offset, type, iolen);
 		break;
 	case VIRTIO_BLK_T_GET_ID:
@@ -205,6 +206,7 @@ vtblk_proc(struct beri_vtblk_softc *sc, 
 	} else
 		*status = VIRTIO_BLK_S_OK;
 
+	free(tiov, M_DEVBUF);
 	vq_relchain(vq, iov, n, 1);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501051643.t05GhNn7012291>