Date: Tue, 15 Dec 2015 10:07:03 +0000 (UTC) From: =?UTF-8?Q?Roger_Pau_Monn=c3=a9?= <royger@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r292255 - head/sys/x86/x86 Message-ID: <201512151007.tBFA73tp082481@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512151007.tBFA73tp082481>