[PATCH 1/2] ARM: calculate VMALLOC_END by probing in mdesc->map_io()
Eric Miao
eric.y.miao at gmail.com
Sat Jan 22 17:56:40 EST 2011
From: Eric Miao <eric.miao at linaro.org>
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 <eric.miao at linaro.org>
---
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
More information about the linux-arm-kernel
mailing list