[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-3.1-testing] Xen dma: avoid unnecessarily SWIOTLB bounce buffering.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1206978282 -3600
# Node ID 1866bf67b39cbedc53f9462f82459cec8d31c0a4
# Parent  d3a7ac9d8a5871638cfbbdb448e466c0e5983f39
Xen dma: avoid unnecessarily SWIOTLB bounce buffering.

On Xen kernels, BIOVEC_PHYS_MERGEABLE permits merging of disk IOs that
span multiple pages, provided that the pages are both
pseudophysically- AND machine-contiguous ---

        (((bvec_to_phys((vec1)) + (vec1)->bv_len) ==
        bvec_to_phys((vec2))) && \
         ((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) == \
          bvec_to_pseudophys((vec2))))

However, this best-effort merging of adjacent pages can occur in
regions of dom0 memory which just happen, by virtue of having been
initially set up that way, to be machine-contiguous.  Such pages
which occur outside of a range created by xen_create_contiguous_
region won't be seen as contiguous by range_straddles_page_boundary(),
so the pci-dma-xen.c code for dma_map_sg() will send these regions
to the swiotlb for bounce buffering.

This patch adds a new check, check_pages_physically_contiguous(),
to the test for pages stradding page boundaries both in
swiotlb_map_sg() and dma_map_sg(), to capture these ranges and map
them directly via virt_to_bus() mapping rather than through the
swiotlb.

Signed-off-by: Stephen Tweedie <sct@xxxxxxxxxx>
linux-2.6.18-xen changeset:   501:5486a234923da1fbab13eef6165f25c54ab63bd9
linux-2.6.18-xen date:        Mon Mar 31 10:32:25 2008 +0100
---
 linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c              |   33 
++++++++++
 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h |    8 --
 2 files changed, 34 insertions(+), 7 deletions(-)

diff -r d3a7ac9d8a58 -r 1866bf67b39c 
linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c       Mon Mar 31 
16:42:20 2008 +0100
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/pci-dma-xen.c       Mon Mar 31 
16:44:42 2008 +0100
@@ -74,6 +74,39 @@ do {                                                 \
                BUG();                                  \
        }                                               \
 } while (0)
+
+static int check_pages_physically_contiguous(unsigned long pfn, 
+                                            unsigned int offset,
+                                            size_t length)
+{
+       unsigned long next_mfn;
+       int i;
+       int nr_pages;
+       
+       next_mfn = pfn_to_mfn(pfn);
+       nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT;
+       
+       for (i = 1; i < nr_pages; i++) {
+               if (pfn_to_mfn(++pfn) != ++next_mfn) 
+                       return 0;
+       }
+       return 1;
+}
+
+int range_straddles_page_boundary(paddr_t p, size_t size)
+{
+       extern unsigned long *contiguous_bitmap;
+       unsigned long pfn = p >> PAGE_SHIFT;
+       unsigned int offset = p & ~PAGE_MASK;
+
+       if (offset + size <= PAGE_SIZE)
+               return 0;
+       if (test_bit(pfn, contiguous_bitmap))
+               return 0;
+       if (check_pages_physically_contiguous(pfn, offset, size))
+               return 0;
+       return 1;
+}
 
 int
 dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
diff -r d3a7ac9d8a58 -r 1866bf67b39c 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h  Mon Mar 
31 16:42:20 2008 +0100
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/dma-mapping.h  Mon Mar 
31 16:44:42 2008 +0100
@@ -22,13 +22,7 @@ address_needs_mapping(struct device *hwd
        return (addr & ~mask) != 0;
 }
 
-static inline int
-range_straddles_page_boundary(paddr_t p, size_t size)
-{
-       extern unsigned long *contiguous_bitmap;
-       return ((((p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
-               !test_bit(p >> PAGE_SHIFT, contiguous_bitmap));
-}
+extern int range_straddles_page_boundary(paddr_t p, size_t size);
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.