svn commit: r292255 - head/sys/x86/x86
Roger Pau Monné
royger at FreeBSD.org
Tue Dec 15 10:07:05 UTC 2015
Author: royger
Date: Tue Dec 15 10:07:03 2015
New Revision: 292255
URL: https://svnweb.freebsd.org/changeset/base/292255
Log:
x86/bounce: try to always completely fill bounce pages
Current code doesn't try to make use of the full page when bouncing because
the size is only expanded to be a multiple of the alignment. Instead try to
always create segments of PAGE_SIZE when using bounce pages.
This allows us to remove the specific casing done for
BUS_DMA_KEEP_PG_OFFSET, since the requirement is to make sure the offsets
into contiguous segments are aligned, and now this is done by default.
Sponsored by: Citrix Systems R&D
Reviewed by: hps, kib
Differential revision: https://reviews.freebsd.org/D4119
Modified:
head/sys/x86/x86/busdma_bounce.c
Modified: head/sys/x86/x86/busdma_bounce.c
==============================================================================
--- head/sys/x86/x86/busdma_bounce.c Tue Dec 15 09:02:05 2015 (r292254)
+++ head/sys/x86/x86/busdma_bounce.c Tue Dec 15 10:07:03 2015 (r292255)
@@ -476,8 +476,7 @@ _bus_dmamap_count_phys(bus_dma_tag_t dma
while (buflen != 0) {
sgsize = MIN(buflen, dmat->common.maxsegsz);
if (bus_dma_run_filter(&dmat->common, curaddr)) {
- sgsize = MIN(sgsize,
- PAGE_SIZE - (curaddr & PAGE_MASK));
+ sgsize = MIN(PAGE_SIZE, sgsize);
map->pagesneeded++;
}
curaddr += sgsize;
@@ -517,8 +516,7 @@ _bus_dmamap_count_pages(bus_dma_tag_t dm
else
paddr = pmap_extract(pmap, vaddr);
if (bus_dma_run_filter(&dmat->common, paddr) != 0) {
- sg_len = roundup2(sg_len,
- dmat->common.alignment);
+ sg_len = PAGE_SIZE;
map->pagesneeded++;
}
vaddr += sg_len;
@@ -554,9 +552,7 @@ _bus_dmamap_count_ma(bus_dma_tag_t dmat,
max_sgsize = MIN(buflen, dmat->common.maxsegsz);
sg_len = MIN(sg_len, max_sgsize);
if (bus_dma_run_filter(&dmat->common, paddr) != 0) {
- sg_len = roundup2(sg_len,
- dmat->common.alignment);
- sg_len = MIN(sg_len, max_sgsize);
+ sg_len = MIN(PAGE_SIZE, max_sgsize);
KASSERT((sg_len & (dmat->common.alignment - 1))
== 0, ("Segment size is not aligned"));
map->pagesneeded++;
@@ -652,7 +648,7 @@ bounce_bus_dmamap_load_phys(bus_dma_tag_
int *segp)
{
bus_size_t sgsize;
- bus_addr_t curaddr;
+ bus_addr_t curaddr, nextaddr;
int error;
if (map == NULL)
@@ -676,9 +672,12 @@ bounce_bus_dmamap_load_phys(bus_dma_tag_
if (((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) &&
map->pagesneeded != 0 &&
bus_dma_run_filter(&dmat->common, curaddr)) {
- sgsize = MIN(sgsize, PAGE_SIZE - (curaddr & PAGE_MASK));
- curaddr = add_bounce_page(dmat, map, 0, curaddr, 0,
- sgsize);
+ nextaddr = 0;
+ sgsize = MIN(PAGE_SIZE, sgsize);
+ if ((curaddr & PAGE_MASK) + sgsize > PAGE_SIZE)
+ nextaddr = roundup2(curaddr, PAGE_SIZE);
+ curaddr = add_bounce_page(dmat, map, 0, curaddr,
+ nextaddr, sgsize);
}
sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
segp);
@@ -744,8 +743,7 @@ bounce_bus_dmamap_load_buffer(bus_dma_ta
if (((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) &&
map->pagesneeded != 0 &&
bus_dma_run_filter(&dmat->common, curaddr)) {
- sgsize = roundup2(sgsize, dmat->common.alignment);
- sgsize = MIN(sgsize, max_sgsize);
+ sgsize = MIN(PAGE_SIZE, max_sgsize);
curaddr = add_bounce_page(dmat, map, kvaddr, curaddr, 0,
sgsize);
} else {
@@ -774,17 +772,6 @@ bounce_bus_dmamap_load_ma(bus_dma_tag_t
int error, page_index;
bus_size_t sgsize, max_sgsize;
- if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) {
- /*
- * If we have to keep the offset of each page this function
- * is not suitable, switch back to bus_dmamap_load_ma_triv
- * which is going to do the right thing in this case.
- */
- error = bus_dmamap_load_ma_triv(dmat, map, ma, buflen, ma_offs,
- flags, segs, segp);
- return (error);
- }
-
if (map == NULL)
map = &nobounce_dmamap;
@@ -811,10 +798,7 @@ bounce_bus_dmamap_load_ma(bus_dma_tag_t
if (((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) &&
map->pagesneeded != 0 &&
bus_dma_run_filter(&dmat->common, paddr)) {
- sgsize = roundup2(sgsize, dmat->common.alignment);
- sgsize = MIN(sgsize, max_sgsize);
- KASSERT((sgsize & (dmat->common.alignment - 1)) == 0,
- ("Segment size is not aligned"));
+ sgsize = MIN(PAGE_SIZE, max_sgsize);
/*
* Check if two pages of the user provided buffer
* are used.
@@ -1175,13 +1159,6 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
bz->active_bpages++;
mtx_unlock(&bounce_lock);
- if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) {
- /* Page offset needs to be preserved. */
- bpage->vaddr |= addr1 & PAGE_MASK;
- bpage->busaddr |= addr1 & PAGE_MASK;
- KASSERT(addr2 == 0,
- ("Trying to bounce multiple pages with BUS_DMA_KEEP_PG_OFFSET"));
- }
bpage->datavaddr = vaddr;
bpage->datapage[0] = PHYS_TO_VM_PAGE(addr1);
KASSERT((addr2 & PAGE_MASK) == 0, ("Second page is not aligned"));
@@ -1201,15 +1178,6 @@ free_bounce_page(bus_dma_tag_t dmat, str
bz = dmat->bounce_zone;
bpage->datavaddr = 0;
bpage->datacount = 0;
- if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) {
- /*
- * Reset the bounce page to start at offset 0. Other uses
- * of this bounce page may need to store a full page of
- * data and/or assume it starts on a page boundary.
- */
- bpage->vaddr &= ~PAGE_MASK;
- bpage->busaddr &= ~PAGE_MASK;
- }
mtx_lock(&bounce_lock);
STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links);
More information about the svn-src-head
mailing list