Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133027564
D26496.id77257.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D26496.id77257.diff
View Options
Index: sys/arm64/arm64/busdma_bounce.c
===================================================================
--- sys/arm64/arm64/busdma_bounce.c
+++ sys/arm64/arm64/busdma_bounce.c
@@ -139,6 +139,7 @@
#define DMAMAP_COULD_BOUNCE (1 << 0)
#define DMAMAP_FROM_DMAMEM (1 << 1)
#define DMAMAP_COHERENT (1 << 2)
+#define DMAMAP_MBUF (1 << 3)
int sync_count;
struct sync_list slist[];
};
@@ -164,20 +165,66 @@
static int _bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
int flags);
+/*
+ * Return true if the DMA should bounce because the start or end does not fall
+ * on a cacheline boundary (which would require a partial cacheline flush).
+ * COHERENT memory doesn't trigger cacheline flushes. Memory allocated by
+ * bus_dmamem_alloc() is always aligned to cacheline boundaries, and there's a
+ * strict rule that such memory cannot be accessed by the CPU while DMA is in
+ * progress (or by multiple DMA engines at once), so that it's always safe to do
+ * full cacheline flushes even if that affects memory outside the range of a
+ * given DMA operation that doesn't involve the full allocated buffer. If we're
+ * mapping an mbuf, that follows the same rules as a buffer we allocated.
+ */
+static bool
+cacheline_bounce(bus_dmamap_t map, bus_addr_t paddr, bus_size_t size)
+{
+
+ if ((map->flags & (DMAMAP_FROM_DMAMEM | DMAMAP_COHERENT | DMAMAP_MBUF))
+ != 0)
+ return (false);
+
+ return (((paddr | size) & (dcache_line_size - 1)) != 0);
+}
+
+/*
+ * Return true if the given address does not fall on the alignment boundary.
+ */
+static bool
+alignment_bounce(bus_dma_tag_t dmat, bus_addr_t addr)
+{
+
+ return ((addr & (dmat->common.alignment - 1)) == 0);
+}
+
static bool
-might_bounce(bus_dma_tag_t dmat)
+might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t paddr,
+ bus_size_t size)
{
if ((dmat->bounce_flags & BF_COULD_BOUNCE) != 0)
return (true);
+ if (cacheline_bounce(map, paddr, size))
+ return (true);
+
+ if (alignment_bounce(dmat, paddr))
+ return (true);
+
return (false);
}
static bool
-must_bounce(bus_dma_tag_t dmat, bus_addr_t paddr)
+must_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t paddr,
+ bus_size_t size)
{
+ if (cacheline_bounce(map, paddr, size))
+ return (true);
+
+ if (alignment_bounce(dmat, paddr))
+ return (true);
+
if ((dmat->bounce_flags & BF_COULD_BOUNCE) != 0 &&
bus_dma_run_filter(&dmat->common, paddr))
return (true);
@@ -768,7 +815,7 @@
if (segs == NULL)
segs = dmat->segments;
- if (might_bounce(dmat)) {
+ if (might_bounce(dmat, map, (bus_addr_t)buf, buflen)) {
_bus_dmamap_count_phys(dmat, map, buf, buflen, flags);
if (map->pagesneeded != 0) {
error = _bus_dmamap_reserve_pages(dmat, map, flags);
@@ -783,7 +830,8 @@
while (buflen > 0) {
curaddr = buf;
sgsize = MIN(buflen, dmat->common.maxsegsz);
- if (map->pagesneeded != 0 && must_bounce(dmat, curaddr)) {
+ if (map->pagesneeded != 0 &&
+ must_bounce(dmat, map, curaddr, sgsize)) {
sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK));
curaddr = add_bounce_page(dmat, map, 0, curaddr,
sgsize);
@@ -837,7 +885,10 @@
if (segs == NULL)
segs = dmat->segments;
- if (might_bounce(dmat)) {
+ if (flags & BUS_DMA_LOAD_MBUF)
+ map->flags |= DMAMAP_MBUF;
+
+ if (might_bounce(dmat, map, (bus_addr_t)buf, buflen)) {
_bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, flags);
if (map->pagesneeded != 0) {
error = _bus_dmamap_reserve_pages(dmat, map, flags);
@@ -868,7 +919,8 @@
*/
max_sgsize = MIN(buflen, dmat->common.maxsegsz);
sgsize = PAGE_SIZE - (curaddr & PAGE_MASK);
- if (map->pagesneeded != 0 && must_bounce(dmat, curaddr)) {
+ if (map->pagesneeded != 0 &&
+ must_bounce(dmat, map, curaddr, sgsize)) {
sgsize = roundup2(sgsize, dmat->common.alignment);
sgsize = MIN(sgsize, max_sgsize);
curaddr = add_bounce_page(dmat, map, kvaddr, curaddr,
@@ -955,6 +1007,7 @@
}
map->sync_count = 0;
+ map->flags &= ~DMAMAP_MBUF;
}
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Oct 23, 5:16 AM (1 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24083449
Default Alt Text
D26496.id77257.diff (3 KB)
Attached To
Mode
D26496: Bounce in more cases in the arm64 busdma
Attached
Detach File
Event Timeline
Log In to Comment