Date: Fri, 20 Jun 2014 02:49:03 +0000 (UTC) From: Bryan Venteicher <bryanv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r267662 - head/sys/dev/vmware/vmxnet3 Message-ID: <201406200249.s5K2n31p012027@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bryanv Date: Fri Jun 20 02:49:03 2014 New Revision: 267662 URL: http://svnweb.freebsd.org/changeset/base/267662 Log: Handle multiple calls to rxq_eof for single packet completion This requires the VMware vmxnet3 device to flip the start of packet descriptor's generation before the rest of the packet's descriptors have been loaded into the Rx ring. I've never observed this behavior, and it seems to make the most sense not to do it this way. But it is not a lot of work for the driver to handle this situation just in case. MFC after: 1 week Modified: head/sys/dev/vmware/vmxnet3/if_vmx.c head/sys/dev/vmware/vmxnet3/if_vmxvar.h Modified: head/sys/dev/vmware/vmxnet3/if_vmx.c ============================================================================== --- head/sys/dev/vmware/vmxnet3/if_vmx.c Fri Jun 20 02:31:52 2014 (r267661) +++ head/sys/dev/vmware/vmxnet3/if_vmx.c Fri Jun 20 02:49:03 2014 (r267662) @@ -2087,17 +2087,25 @@ vmxnet3_rxq_eof(struct vmxnet3_rxqueue * sc = rxq->vxrxq_sc; ifp = sc->vmx_ifp; rxc = &rxq->vxrxq_comp_ring; - m_head = m_tail = NULL; VMXNET3_RXQ_LOCK_ASSERT(rxq); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; + m_head = rxq->vxrxq_mhead; + rxq->vxrxq_mhead = NULL; + m_tail = rxq->vxrxq_mtail; + rxq->vxrxq_mtail = NULL; + MPASS(m_head == NULL || m_tail != NULL); + for (;;) { rxcd = &rxc->vxcr_u.rxcd[rxc->vxcr_next]; - if (rxcd->gen != rxc->vxcr_gen) + if (rxcd->gen != rxc->vxcr_gen) { + rxq->vxrxq_mhead = m_head; + rxq->vxrxq_mtail = m_tail; break; + } vmxnet3_barrier(sc, VMXNET3_BARRIER_RD); if (++rxc->vxcr_next == rxc->vxcr_ndesc) { @@ -2329,6 +2337,12 @@ vmxnet3_rxstop(struct vmxnet3_softc *sc, struct vmxnet3_rxbuf *rxb; int i, j; + if (rxq->vxrxq_mhead != NULL) { + m_freem(rxq->vxrxq_mhead); + rxq->vxrxq_mhead = NULL; + rxq->vxrxq_mtail = NULL; + } + for (i = 0; i < VMXNET3_RXRINGS_PERQ; i++) { rxr = &rxq->vxrxq_cmd_ring[i]; Modified: head/sys/dev/vmware/vmxnet3/if_vmxvar.h ============================================================================== --- head/sys/dev/vmware/vmxnet3/if_vmxvar.h Fri Jun 20 02:31:52 2014 (r267661) +++ head/sys/dev/vmware/vmxnet3/if_vmxvar.h Fri Jun 20 02:49:03 2014 (r267662) @@ -168,6 +168,8 @@ struct vmxnet3_rxqueue { struct vmxnet3_softc *vxrxq_sc; int vxrxq_id; int vxrxq_intr_idx; + struct mbuf *vxrxq_mhead; + struct mbuf *vxrxq_mtail; struct vmxnet3_rxring vxrxq_cmd_ring[VMXNET3_RXRINGS_PERQ]; struct vmxnet3_comp_ring vxrxq_comp_ring; struct vmxnet3_rxq_stats vxrxq_stats;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406200249.s5K2n31p012027>