The new memblock_virt APIs are used to replaced old bootmem API.

We need to allocate page below 4G for swiotlb.

That should fix regression on Andrew's system that is using swiotlb.

Signed-off-by: Yinghai Lu <[email protected]>
Cc: Russell King <[email protected]>
Cc: Konrad Rzeszutek Wilk <[email protected]>

---
 arch/arm/kernel/setup.c |    2 +-
 include/linux/bootmem.h |   37 +++++++++++++++++++++++++++++++++++++
 lib/swiotlb.c           |    4 ++--
 3 files changed, 40 insertions(+), 3 deletions(-)

Index: linux-2.6/include/linux/bootmem.h
===================================================================
--- linux-2.6.orig/include/linux/bootmem.h
+++ linux-2.6/include/linux/bootmem.h
@@ -175,6 +175,27 @@ static inline void * __init memblock_vir
                                                    NUMA_NO_NODE);
 }
 
+#ifndef ARCH_LOW_ADDRESS_LIMIT
+#define ARCH_LOW_ADDRESS_LIMIT  0xffffffffUL
+#endif
+
+static inline void * __init memblock_virt_alloc_low(
+                                       phys_addr_t size, phys_addr_t align)
+{
+       return memblock_virt_alloc_try_nid(size, align,
+                                                  BOOTMEM_LOW_LIMIT,
+                                                  ARCH_LOW_ADDRESS_LIMIT,
+                                                  NUMA_NO_NODE);
+}
+static inline void * __init memblock_virt_alloc_low_nopanic(
+                                       phys_addr_t size, phys_addr_t align)
+{
+       return memblock_virt_alloc_try_nid_nopanic(size, align,
+                                                  BOOTMEM_LOW_LIMIT,
+                                                  ARCH_LOW_ADDRESS_LIMIT,
+                                                  NUMA_NO_NODE);
+}
+
 static inline void * __init memblock_virt_alloc_from_nopanic(
                phys_addr_t size, phys_addr_t align, phys_addr_t min_addr)
 {
@@ -238,6 +259,22 @@ static inline void * __init memblock_vir
        return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT);
 }
 
+static inline void * __init memblock_virt_alloc_low(
+                                       phys_addr_t size, phys_addr_t align)
+{
+       if (!align)
+               align = SMP_CACHE_BYTES;
+       return __alloc_bootmem_low(size, align, BOOTMEM_LOW_LIMIT);
+}
+
+static inline void * __init memblock_virt_alloc_low_nopanic(
+                                       phys_addr_t size, phys_addr_t align)
+{
+       if (!align)
+               align = SMP_CACHE_BYTES;
+       return __alloc_bootmem_low_nopanic(size, align, BOOTMEM_LOW_LIMIT);
+}
+
 static inline void * __init memblock_virt_alloc_from_nopanic(
                phys_addr_t size, phys_addr_t align, phys_addr_t min_addr)
 {
Index: linux-2.6/lib/swiotlb.c
===================================================================
--- linux-2.6.orig/lib/swiotlb.c
+++ linux-2.6/lib/swiotlb.c
@@ -172,7 +172,7 @@ int __init swiotlb_init_with_tbl(char *t
        /*
         * Get the overflow emergency buffer
         */
-       v_overflow_buffer = memblock_virt_alloc_nopanic(
+       v_overflow_buffer = memblock_virt_alloc_low_nopanic(
                                                PAGE_ALIGN(io_tlb_overflow),
                                                PAGE_SIZE);
        if (!v_overflow_buffer)
@@ -220,7 +220,7 @@ swiotlb_init(int verbose)
        bytes = io_tlb_nslabs << IO_TLB_SHIFT;
 
        /* Get IO TLB memory from the low pages */
-       vstart = memblock_virt_alloc_nopanic(PAGE_ALIGN(bytes), PAGE_SIZE);
+       vstart = memblock_virt_alloc_low_nopanic(PAGE_ALIGN(bytes), PAGE_SIZE);
        if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose))
                return;
 
Index: linux-2.6/arch/arm/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/arm/kernel/setup.c
+++ linux-2.6/arch/arm/kernel/setup.c
@@ -717,7 +717,7 @@ static void __init request_standard_reso
        kernel_data.end     = virt_to_phys(_end - 1);
 
        for_each_memblock(memory, region) {
-               res = memblock_virt_alloc(sizeof(*res), 0);
+               res = memblock_virt_alloc_low(sizeof(*res), 0);
                res->name  = "System RAM";
                res->start = 
__pfn_to_phys(memblock_region_memory_base_pfn(region));
                res->end = 
__pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to