[PATCH 1/2] ARM: calculate VMALLOC_END by probing in mdesc->map_io()
From: Eric Miao <hidden>
Date: 2011-01-22 22:56:40
Subsystem:
arm port, the rest · Maintainers:
Russell King, Linus Torvalds
From: Eric Miao <redacted> Provided that the only place initializing the fixed IO mapping is in mdesc->map_io(), the VMALLOC_END can actually be calculated by first invoking the function without actually doing the map. The original idea of auto-calculating the VMALLOC_END came from Nicolas Pitre. Signed-off-by: Eric Miao <redacted> --- arch/arm/include/asm/pgtable.h | 6 ++++- arch/arm/mm/init.c | 1 - arch/arm/mm/mmu.c | 44 ++++++++++++++++++++++++++++----------- 3 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index ebcb643..276972f 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h@@ -21,7 +21,6 @@ #else #include <asm/memory.h> -#include <mach/vmalloc.h> #include <asm/pgtable-hwdef.h> /*
@@ -41,6 +40,11 @@ #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) #endif +#ifndef __ASSEMBLY__ +extern unsigned long vmalloc_end; +#endif +#define VMALLOC_END (vmalloc_end) + /* * Hardware-wise, we have a two level page table structure, where the first * level has 4096 entries, and the second level has 256 entries. Each entry
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 5164069..da870df 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c@@ -614,7 +614,6 @@ void __init mem_init(void) * be detected at build time already. */ #ifdef CONFIG_MMU - BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE); BUG_ON(VMALLOC_END > CONSISTENT_BASE); BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 3c67e92..98cdb35 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c@@ -703,6 +703,12 @@ static void __init create_mapping(struct map_desc *md) } while (pgd++, addr != end); } +unsigned long vmalloc_end = 0xff000000ul; +EXPORT_SYMBOL(vmalloc_end); + +static int __initdata probe_vmalloc_end; +static unsigned long vmalloc_reserve = SZ_128M; + /* * Create the architecture specific mappings */
@@ -710,11 +716,16 @@ void __init iotable_init(struct map_desc *io_desc, int nr) { int i; - for (i = 0; i < nr; i++) - create_mapping(io_desc + i); + for (i = 0; i < nr; i++) { + if (probe_vmalloc_end) { + /* align vmalloc_end to PGDIR_SIZE */ + if (io_desc->virtual < vmalloc_end) + vmalloc_end = io_desc->virtual & PGDIR_MASK; + } else + create_mapping(io_desc + i); + } } -static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M); /* * vmalloc=size forces the vmalloc area to be exactly 'size'
@@ -723,7 +734,7 @@ static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M); */ static int __init early_vmalloc(char *arg) { - unsigned long vmalloc_reserve = memparse(arg, NULL); + vmalloc_reserve = memparse(arg, NULL); if (vmalloc_reserve < SZ_16M) { vmalloc_reserve = SZ_16M;
@@ -731,15 +742,6 @@ static int __init early_vmalloc(char *arg) "vmalloc area too small, limiting to %luMB\n", vmalloc_reserve >> 20); } - - if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) { - vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M); - printk(KERN_WARNING - "vmalloc area is too big, limiting to %luMB\n", - vmalloc_reserve >> 20); - } - - vmalloc_min = (void *)(VMALLOC_END - vmalloc_reserve); return 0; } early_param("vmalloc", early_vmalloc);
@@ -749,6 +751,16 @@ static phys_addr_t lowmem_limit __initdata = 0; static void __init sanity_check_meminfo(void) { int i, j, highmem = 0; + void *vmalloc_min; + + if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) { + vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M); + printk(KERN_WARNING + "vmalloc area is too big, limiting to %luMB\n", + vmalloc_reserve >> 20); + } + + vmalloc_min = (void *)(VMALLOC_END - vmalloc_reserve); lowmem_limit = __pa(vmalloc_min - 1) + 1; memblock_set_current_limit(lowmem_limit);
@@ -1026,6 +1038,12 @@ void __init paging_init(struct machine_desc *mdesc) { void *zero_page; + if (mdesc->map_io) { + probe_vmalloc_end = 1; + mdesc->map_io(); + probe_vmalloc_end = 0; + } + build_mem_type_table(); sanity_check_meminfo(); prepare_page_table();
--
1.7.1