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

[Xen-changelog] [linux-2.6.18-xen] x86: use custom dma_get_required_mask()


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-linux-2.6.18-xen <patchbot@xxxxxxx>
  • Date: Thu, 13 Nov 2014 14:11:02 +0000
  • Delivery-date: Thu, 13 Nov 2014 14:11:15 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User David Vrabel <david.vrabel@xxxxxxxxxx>
# Date 1415886941 -3600
# Node ID 78e400792c76811445c6a80dfebdbded116f1aad
# Parent  6d727f2dcc8386e9658d84082f45633c08d992d1
x86: use custom dma_get_required_mask()

On a Xen PV guest the DMA addresses and physical addresses are not 1:1
(such as Xen PV guests) and the generic dma_get_required_mask() does
not return the correct mask (since it uses max_pfn).

Some device drivers (such as mptsas, mpt2sas) use
dma_get_required_mask() to set the device's DMA mask to allow them to
use only 32-bit DMA addresses in hardware structures.  This results in
unnecessary use of the SWIOTLB if DMA addresses are more than 32-bits,
impacting performance significantly.

Provide a get_required_mask op that uses the maximum MFN to calculate
the DMA mask.

Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx>
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Committed-by: Jan Beulich <jbeulich@xxxxxxxx>
---


diff -r 6d727f2dcc83 -r 78e400792c76 arch/i386/kernel/pci-dma-xen.c
--- a/arch/i386/kernel/pci-dma-xen.c    Thu Nov 13 14:51:07 2014 +0100
+++ b/arch/i386/kernel/pci-dma-xen.c    Thu Nov 13 14:55:41 2014 +0100
@@ -22,6 +22,8 @@
 #include <asm-i386/mach-xen/asm/gnttab_dma.h>
 #include <asm/bug.h>
 
+#include <xen/interface/memory.h>
+
 #ifdef __x86_64__
 #include <asm/proto.h>
 
@@ -208,6 +210,16 @@ dma_supported(struct device *dev, u64 ma
 }
 EXPORT_SYMBOL(dma_supported);
 
+u64 dma_get_required_mask(struct device *dev)
+{
+       unsigned long max_mfn = HYPERVISOR_memory_op(XENMEM_maximum_ram_page,
+                                                    NULL);
+
+       return (((u64)1 << (__fls(max_mfn - 1) + 1 + PAGE_SHIFT)) - 1)
+              & *dev->dma_mask;
+}
+EXPORT_SYMBOL_GPL(dma_get_required_mask);
+
 void *dma_alloc_coherent(struct device *dev, size_t size,
                           dma_addr_t *dma_handle, gfp_t gfp)
 {
diff -r 6d727f2dcc83 -r 78e400792c76 include/asm-i386/bitops.h
--- a/include/asm-i386/bitops.h Thu Nov 13 14:51:07 2014 +0100
+++ b/include/asm-i386/bitops.h Thu Nov 13 14:55:41 2014 +0100
@@ -318,6 +318,20 @@ static inline unsigned long __ffs(unsign
        return word;
 }
 
+/*
+ * __fls: find last bit set.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+       __asm__("bsrl %1,%0"
+               :"=r" (word)
+               :"rm" (word));
+       return word;
+}
+
 /**
  * find_first_bit - find the first set bit in a memory region
  * @addr: The address to start the search at
diff -r 6d727f2dcc83 -r 78e400792c76 include/asm-i386/mach-xen/asm/dma-mapping.h
--- a/include/asm-i386/mach-xen/asm/dma-mapping.h       Thu Nov 13 14:51:07 
2014 +0100
+++ b/include/asm-i386/mach-xen/asm/dma-mapping.h       Thu Nov 13 14:55:41 
2014 +0100
@@ -12,6 +12,8 @@
 #include <asm/scatterlist.h>
 #include <asm/swiotlb.h>
 
+#define ARCH_HAS_DMA_GET_REQUIRED_MASK
+
 static inline int
 address_needs_mapping(struct device *hwdev, dma_addr_t addr)
 {
diff -r 6d727f2dcc83 -r 78e400792c76 
include/asm-x86_64/mach-xen/asm/dma-mapping.h
--- a/include/asm-x86_64/mach-xen/asm/dma-mapping.h     Thu Nov 13 14:51:07 
2014 +0100
+++ b/include/asm-x86_64/mach-xen/asm/dma-mapping.h     Thu Nov 13 14:55:41 
2014 +0100
@@ -11,6 +11,8 @@
 #include <asm/io.h>
 #include <asm/swiotlb.h>
 
+#define ARCH_HAS_DMA_GET_REQUIRED_MASK
+
 struct dma_mapping_ops {
        int             (*mapping_error)(dma_addr_t dma_addr);
        void*           (*alloc_coherent)(struct device *dev, size_t size,

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
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®.