Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Nov 2016 08:41:02 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r308207 - stable/11/sys/dev/e1000
Message-ID:  <201611020841.uA28f2Xf006160@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Nov  2 08:41:01 2016
New Revision: 308207
URL: https://svnweb.freebsd.org/changeset/base/308207

Log:
  MFC r307649:
  Partial workaround for Intel PCI adapters reading past the end of the
  host-programmed DMA regions.

Modified:
  stable/11/sys/dev/e1000/if_lem.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/e1000/if_lem.c
==============================================================================
--- stable/11/sys/dev/e1000/if_lem.c	Wed Nov  2 08:12:37 2016	(r308206)
+++ stable/11/sys/dev/e1000/if_lem.c	Wed Nov  2 08:41:01 2016	(r308207)
@@ -591,8 +591,16 @@ lem_attach(device_t dev)
 	}
 #endif /* NIC_PARAVIRT */
 
-	tsize = roundup2(adapter->num_tx_desc * sizeof(struct e1000_tx_desc),
-	    EM_DBA_ALIGN);
+	/*
+	 * It seems that the descriptor DMA engine on some PCI cards
+	 * fetches memory past the end of the last descriptor in the
+	 * ring.  These reads are problematic when VT-d (DMAR) busdma
+	 * is used.  Allocate the scratch space to avoid getting
+	 * faults from DMAR, by requesting scratch memory for one more
+	 * descriptor.
+	 */
+	tsize = roundup2((adapter->num_tx_desc + 1) *
+	    sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
 
 	/* Allocate Transmit Descriptor ring */
 	if (lem_dma_malloc(adapter, tsize, &adapter->txdma, BUS_DMA_NOWAIT)) {
@@ -603,8 +611,11 @@ lem_attach(device_t dev)
 	adapter->tx_desc_base = 
 	    (struct e1000_tx_desc *)adapter->txdma.dma_vaddr;
 
-	rsize = roundup2(adapter->num_rx_desc * sizeof(struct e1000_rx_desc),
-	    EM_DBA_ALIGN);
+	/*
+	 * See comment above txdma allocation for rationale behind +1.
+	 */
+	rsize = roundup2((adapter->num_rx_desc + 1) *
+	    sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
 
 	/* Allocate Receive Descriptor ring */
 	if (lem_dma_malloc(adapter, rsize, &adapter->rxdma, BUS_DMA_NOWAIT)) {



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