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);
 }
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to