Hi,

This diff refactors the vio driver to use m_defrag when mbuf chains get
fragmented, thoughts?

Index: if_vio.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vio.c,v
retrieving revision 1.25
diff -u -p -r1.25 if_vio.c
--- if_vio.c    14 Mar 2015 03:38:48 -0000      1.25
+++ if_vio.c    27 Mar 2015 09:36:37 -0000
@@ -1149,40 +1149,27 @@ vio_encap(struct vio_softc *sc, int slot
 {
        struct virtio_softc     *vsc = sc->sc_virtio;
        bus_dmamap_t             dmap= sc->sc_tx_dmamaps[slot];
-       struct mbuf             *m0 = NULL;
        int                      r;
 
        r = bus_dmamap_load_mbuf(vsc->sc_dmat, dmap, m,
            BUS_DMA_WRITE|BUS_DMA_NOWAIT);
-       if (r == 0) {
-               *mnew = m;
-               return r;
-       }
-       if (r != EFBIG)
-               return r;
-       /* EFBIG: mbuf chain is too fragmented */
-       MGETHDR(m0, M_DONTWAIT, MT_DATA);
-       if (m0 == NULL)
-               return ENOBUFS;
-       if (m->m_pkthdr.len > MHLEN) {
-               MCLGETI(m0, M_DONTWAIT, NULL, m->m_pkthdr.len);
-               if (!(m0->m_flags & M_EXT)) {
-                       m_freem(m0);
-                       return ENOBUFS;
-               }
-       }
-       m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
-       m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
-       r = bus_dmamap_load_mbuf(vsc->sc_dmat, dmap, m0,
-           BUS_DMA_NOWAIT|BUS_DMA_WRITE);
-       if (r != 0) {
-               m_freem(m0);
+       switch (r) {
+       case 0:
+               break;
+       case EFBIG:
+               if ((r = m_defrag(m, M_DONTWAIT)) == 0 &&
+                   (r = bus_dmamap_load_mbuf(vsc->sc_dmat, dmap, m,
+                    BUS_DMA_WRITE|BUS_DMA_NOWAIT)) == 0)
+                       break;
+               
+               /* FALLTHROUGH */
+       default:
                printf("%s: tx dmamap load error %d\n", sc->sc_dev.dv_xname,
                    r);
                return ENOBUFS;
        }
-       *mnew = m0;
-       return 0;
+       *mnew = m;
+       return r;
 }
 
 /* free all the mbufs already put on vq; called from if_stop(disable) */

Reply via email to