aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2012-03-01 19:43:28 +0000
committerEd Maste <emaste@FreeBSD.org>2012-03-01 19:43:28 +0000
commitd4f6035bf093edb31070e49d0be6cdf625064923 (patch)
treebdbacffbecae2ca6570da6c00629c5fe445e3f94
parent2f121f392b1aad76e7662cb626ccd7cc4e605570 (diff)
downloadsrc-d4f6035bf093edb31070e49d0be6cdf625064923.tar.gz
src-d4f6035bf093edb31070e49d0be6cdf625064923.zip
MFC r232267:
Workaround for PCIe 4GB boundary issue Enforce a boundary of no more than 4GB - transfers crossing a 4GB boundary can lead to data corruption due to PCIe limitations. This change is a less-intrusive workaround that can be quickly merged back to older branches; a cleaner implementation will arrive in HEAD later but may require KPI changes. This change is based on a suggestion by jhb@. Approved by: re Reviewed by: jhb (MFC) Reviewed by: jhb, scottl (original) Sponsored by: Sandvine Incorporated
Notes
Notes: svn path=/stable/8/; revision=232354
-rw-r--r--sys/amd64/amd64/busdma_machdep.c4
-rw-r--r--sys/i386/i386/busdma_machdep.c6
2 files changed, 10 insertions, 0 deletions
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c
index fae6ef36687b..1c808093c720 100644
--- a/sys/amd64/amd64/busdma_machdep.c
+++ b/sys/amd64/amd64/busdma_machdep.c
@@ -216,6 +216,10 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
bus_dma_tag_t newtag;
int error = 0;
+ /* Always enforce at least a 4GB boundary. */
+ if (boundary == 0 || boundary > ((bus_addr_t)1 << 32))
+ boundary = (bus_size_t)1 << 32;
+
/* Basic sanity checking */
if (boundary != 0 && boundary < maxsegsz)
maxsegsz = boundary;
diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c
index 86921269acd3..4f44e988708a 100644
--- a/sys/i386/i386/busdma_machdep.c
+++ b/sys/i386/i386/busdma_machdep.c
@@ -226,6 +226,12 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
bus_dma_tag_t newtag;
int error = 0;
+#if defined(PAE)
+ /* Need at least a 4GB boundary, PAE limitations require 2GB */
+ if (boundary == 0 || boundary > ((bus_addr_t)1 << 31))
+ boundary = (bus_size_t)1 << 31;
+#endif
+
/* Basic sanity checking */
if (boundary != 0 && boundary < maxsegsz)
maxsegsz = boundary;