Skip site navigation (1)Skip section navigation (2)
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>