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

From: dfil...@freebsd.org (dfilter service)
To: bug-follo...@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-...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
 
_______________________________________________
freebsd-xen@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-xen
To unsubscribe, send any mail to "freebsd-xen-unsubscr...@freebsd.org"

Reply via email to