kern/152818: commit references a PR

dfilter service dfilter at FreeBSD.ORG
Sun Dec 5 03:30:11 UTC 2010


The following reply was made to PR kern/152818; it has been noted by GNATS.

From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: kern/152818: commit references a PR
Date: Sun,  5 Dec 2010 03:21:00 +0000 (UTC)

 Author: cperciva
 Date: Sun Dec  5 03:20:55 2010
 New Revision: 216194
 URL: http://svn.freebsd.org/changeset/base/216194
 
 Log:
   MFamd64 r204214: Enforce stronger alignment semantics (require that the
   end of segments be aligned, not just the start of segments) in order to
   allow Xen's blkfront driver to operate correctly.
   
   PR:		kern/152818
   MFC after:	3 days
 
 Modified:
   head/sys/i386/i386/busdma_machdep.c
 
 Modified: head/sys/i386/i386/busdma_machdep.c
 ==============================================================================
 --- head/sys/i386/i386/busdma_machdep.c	Sun Dec  5 01:17:53 2010	(r216193)
 +++ head/sys/i386/i386/busdma_machdep.c	Sun Dec  5 03:20:55 2010	(r216194)
 @@ -246,8 +246,7 @@ bus_dma_tag_create(bus_dma_tag_t parent,
  	newtag->alignment = alignment;
  	newtag->boundary = boundary;
  	newtag->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1);
 -	newtag->highaddr = trunc_page((vm_paddr_t)highaddr) +
 -	    (PAGE_SIZE - 1);
 +	newtag->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1);
  	newtag->filter = filter;
  	newtag->filterarg = filterarg;
  	newtag->maxsize = maxsize;
 @@ -594,15 +593,19 @@ _bus_dmamap_count_pages(bus_dma_tag_t dm
  		vendaddr = (vm_offset_t)buf + buflen;
  
  		while (vaddr < vendaddr) {
 +			bus_size_t sg_len;
 +
 +			sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK);
  			if (pmap)
  				paddr = pmap_extract(pmap, vaddr);
  			else
  				paddr = pmap_kextract(vaddr);
  			if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
  			    run_filter(dmat, paddr) != 0) {
 +				sg_len = roundup2(sg_len, dmat->alignment);
  				map->pagesneeded++;
  			}
 -			vaddr += (PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK));
 +			vaddr += sg_len;
  		}
  		CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
  	}
 @@ -669,6 +672,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
  	bmask = ~(dmat->boundary - 1);
  
  	for (seg = *segp; buflen > 0 ; ) {
 +		bus_size_t max_sgsize;
 +
  		/*
  		 * Get the physical address for this segment.
  		 */
 @@ -680,11 +685,16 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
  		/*
  		 * Compute the segment size, and adjust counts.
  		 */
 -		sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
 -		if (sgsize > dmat->maxsegsz)
 -			sgsize = dmat->maxsegsz;
 -		if (buflen < sgsize)
 -			sgsize = buflen;
 +		max_sgsize = MIN(buflen, dmat->maxsegsz);
 +		sgsize = PAGE_SIZE - ((vm_offset_t)curaddr & PAGE_MASK);
 +		if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
 +		    map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
 +			sgsize = roundup2(sgsize, dmat->alignment);
 +			sgsize = MIN(sgsize, max_sgsize);
 +			curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
 +		} else {
 +			sgsize = MIN(sgsize, max_sgsize);
 +		}
  
  		/*
  		 * Make sure we don't cross any boundaries.
 @@ -695,10 +705,6 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
  				sgsize = (baddr - curaddr);
  		}
  
 -		if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
 -		    map->pagesneeded != 0 && run_filter(dmat, curaddr))
 -			curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
 -
  		/*
  		 * Insert chunk into a segment, coalescing with
  		 * previous segment if possible.
 _______________________________________________
 svn-src-all at freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
 


More information about the freebsd-xen mailing list