mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-26 16:18:31 +00:00
Correct the sequence of busdma sync ops involved with PRE/POSTREAD syncs.
We used to invalidate the cache for PREREAD alone, or writeback+invalidate for PREREAD with PREWRITE, then treat POSTREAD as a no-op. Prefetching on modern systems can lead to parts of a DMA buffer getting pulled into the caches while DMA is in progress (due to access of "nearby" data), so it's mandatory to invalidate during the POSTREAD sync even if a PREREAD invalidate also happened. In the PREREAD case the invalidate is done to ensure that there are no dirty cache lines that might get automatically evicted during the DMA, corrupting the buffer. In a PREREAD+PREWRITE case the writeback which is required for PREWRITE handling is suffficient to avoid corruption caused by eviction and no invalidate need be done until POSTREAD time. Submitted by: Michal Meloun <meloun@miracle.cz>
This commit is contained in:
parent
1c716437d5
commit
0c4f0ef9ae
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=274604
@ -1416,6 +1416,7 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
|
||||
|
||||
switch (op) {
|
||||
case BUS_DMASYNC_PREWRITE:
|
||||
case BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD:
|
||||
while (sl != end) {
|
||||
cpu_dcache_wb_range(sl->vaddr, sl->datacount);
|
||||
l2cache_wb_range(sl->vaddr, sl->busaddr,
|
||||
@ -1433,19 +1434,19 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
|
||||
}
|
||||
break;
|
||||
|
||||
case BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD:
|
||||
case BUS_DMASYNC_POSTWRITE:
|
||||
break;
|
||||
|
||||
case BUS_DMASYNC_POSTREAD:
|
||||
case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE:
|
||||
while (sl != end) {
|
||||
cpu_dcache_wbinv_range(sl->vaddr, sl->datacount);
|
||||
l2cache_wbinv_range(sl->vaddr,
|
||||
sl->busaddr, sl->datacount);
|
||||
l2cache_inv_range(sl->vaddr, sl->busaddr,
|
||||
sl->datacount);
|
||||
cpu_dcache_inv_range(sl->vaddr, sl->datacount);
|
||||
sl++;
|
||||
}
|
||||
break;
|
||||
|
||||
case BUS_DMASYNC_POSTREAD:
|
||||
case BUS_DMASYNC_POSTWRITE:
|
||||
case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE:
|
||||
break;
|
||||
default:
|
||||
panic("unsupported combination of sync operations: 0x%08x\n", op);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user