This patch puts in the code to retry allocation in case it fails. By its
own, it does not make much sense but making the code look like x86_64.
But later patches in this series will make we try to allocate from
zones other than DMA first, which will possibly fail.

Signed-off-by: Glauber Costa <[EMAIL PROTECTED]>
---
 arch/x86/kernel/pci-dma_32.c |   34 +++++++++++++++++++++++++++++-----
 1 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c
index 0d630ae..f6cf434 100644
--- a/arch/x86/kernel/pci-dma_32.c
+++ b/arch/x86/kernel/pci-dma_32.c
@@ -66,6 +66,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
        struct page *page;
        dma_addr_t bus;
        int order = get_order(size);
+       unsigned long dma_mask = 0;
+
        /* ignore region specifiers */
        gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
 
@@ -75,15 +77,37 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
        if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
                gfp |= GFP_DMA;
 
+       dma_mask = dev->coherent_dma_mask;
+       if (dma_mask == 0)
+               dma_mask = DMA_32BIT_MASK;
+
+ again:
        page = dma_alloc_pages(dev, gfp, order);
        if (page == NULL)
                return NULL;
 
-       ret = page_address(page);
-       bus = page_to_phys(page);
-
-       memset(ret, 0, size);
-       *dma_handle = bus;
+       {
+               int high, mmu;
+               bus = page_to_phys(page);
+               ret = page_address(page);
+               high = (bus + size) >= dma_mask;
+               mmu = high;
+               if (force_iommu && !(gfp & GFP_DMA))
+                       mmu = 1;
+               else if (high) {
+                       free_pages((unsigned long)ret,
+                                  get_order(size));
+
+                       /* Don't use the 16MB ZONE_DMA unless absolutely
+                          needed. It's better to use remapping first. */
+                       if (dma_mask < DMA_32BIT_MASK && !(gfp & GFP_DMA)) {
+                               gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
+                               goto again;
+                       }
+               }
+               memset(ret, 0, size);
+               *dma_handle = bus;
+       }
 
        return ret;
 }
-- 
1.5.0.6


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Register now and save $200. Hurry, offer ends at 11:59 p.m., 
Monday, April 7! Use priority code J8TLD2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to