Page MenuHomeFreeBSD

D26496.id77257.diff
No OneTemporary

D26496.id77257.diff

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

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)

Event Timeline