From 83b519e8b9572c319c8e0c615ee5dd7272856090 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 10 Jun 2009 19:40:04 +0300 Subject: slab: setup allocators earlier in the boot sequence This patch makes kmalloc() available earlier in the boot sequence so we can get rid of some bootmem allocations. The bulk of the changes are due to kmem_cache_init() being called with interrupts disabled which requires some changes to allocator boostrap code. Note: 32-bit x86 does WP protect test in mem_init() so we must setup traps before we call mem_init() during boot as reported by Ingo Molnar: We have a hard crash in the WP-protect code: [ 0.000000] Checking if this processor honours the WP bit even in supervisor mode...BUG: Int 14: CR2 ffcff000 [ 0.000000] EDI 00000188 ESI 00000ac7 EBP c17eaf9c ESP c17eaf8c [ 0.000000] EBX 000014e0 EDX 0000000e ECX 01856067 EAX 00000001 [ 0.000000] err 00000003 EIP c10135b1 CS 00000060 flg 00010002 [ 0.000000] Stack: c17eafa8 c17fd410 c16747bc c17eafc4 c17fd7e5 000011fd f8616000 c18237cc [ 0.000000] 00099800 c17bb000 c17eafec c17f1668 000001c5 c17f1322 c166e039 c1822bf0 [ 0.000000] c166e033 c153a014 c18237cc 00020800 c17eaff8 c17f106a 00020800 01ba5003 [ 0.000000] Pid: 0, comm: swapper Not tainted 2.6.30-tip-02161-g7a74539-dirty #52203 [ 0.000000] Call Trace: [ 0.000000] [] ? printk+0x14/0x16 [ 0.000000] [] ? do_test_wp_bit+0x19/0x23 [ 0.000000] [] ? test_wp_bit+0x26/0x64 [ 0.000000] [] ? mem_init+0x1ba/0x1d8 [ 0.000000] [] ? start_kernel+0x164/0x2f7 [ 0.000000] [] ? unknown_bootoption+0x0/0x19c [ 0.000000] [] ? __init_begin+0x6a/0x6f Acked-by: Johannes Weiner Acked-by Linus Torvalds Cc: Christoph Lameter Cc: Ingo Molnar Cc: Matt Mackall Cc: Nick Piggin Cc: Yinghai Lu Signed-off-by: Pekka Enberg --- init/main.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index bb7dc57eee36..0ab82a453de5 100644 --- a/init/main.c +++ b/init/main.c @@ -574,6 +574,28 @@ asmlinkage void __init start_kernel(void) setup_nr_cpu_ids(); smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ + build_all_zonelists(); + page_alloc_init(); + + printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); + parse_early_param(); + parse_args("Booting kernel", static_command_line, __start___param, + __stop___param - __start___param, + &unknown_bootoption); + /* + * These use large bootmem allocations and must precede + * kmem_cache_init() + */ + pidhash_init(); + vmalloc_init(); + vfs_caches_init_early(); + sort_main_extable(); + trap_init(); + /* + * Set up kernel memory allocators + */ + mem_init(); + kmem_cache_init(); /* * Set up the scheduler prior starting any interrupts (such as the * timer interrupt). Full topology setup happens at smp_init() @@ -585,25 +607,15 @@ asmlinkage void __init start_kernel(void) * fragile until we cpu_idle() for the first time. */ preempt_disable(); - build_all_zonelists(); - page_alloc_init(); - printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); - parse_early_param(); - parse_args("Booting kernel", static_command_line, __start___param, - __stop___param - __start___param, - &unknown_bootoption); if (!irqs_disabled()) { printk(KERN_WARNING "start_kernel(): bug: interrupts were " "enabled *very* early, fixing it\n"); local_irq_disable(); } - sort_main_extable(); - trap_init(); rcu_init(); /* init some links before init_ISA_irqs() */ early_irq_init(); init_IRQ(); - pidhash_init(); init_timers(); hrtimers_init(); softirq_init(); @@ -645,14 +657,10 @@ asmlinkage void __init start_kernel(void) initrd_start = 0; } #endif - vmalloc_init(); - vfs_caches_init_early(); cpuset_init_early(); page_cgroup_init(); - mem_init(); enable_debug_pagealloc(); cpu_hotplug_init(); - kmem_cache_init(); kmemtrace_init(); debug_objects_mem_init(); idr_init_cache(); -- cgit v1.2.3 From 43ebdac42f16037263b52a5aeedcd1bfa4a9bb29 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 25 May 2009 15:01:35 +0300 Subject: vmalloc: use kzalloc() instead of alloc_bootmem() We can call vmalloc_init() after kmem_cache_init() and use kzalloc() instead of the bootmem allocator when initializing vmalloc data structures. Acked-by: Johannes Weiner Acked-by: Linus Torvalds Acked-by: Nick Piggin Cc: Ingo Molnar Cc: Yinghai Lu Signed-off-by: Pekka Enberg --- init/main.c | 2 +- mm/vmalloc.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index 0ab82a453de5..6d38f9607d14 100644 --- a/init/main.c +++ b/init/main.c @@ -587,7 +587,6 @@ asmlinkage void __init start_kernel(void) * kmem_cache_init() */ pidhash_init(); - vmalloc_init(); vfs_caches_init_early(); sort_main_extable(); trap_init(); @@ -596,6 +595,7 @@ asmlinkage void __init start_kernel(void) */ mem_init(); kmem_cache_init(); + vmalloc_init(); /* * Set up the scheduler prior starting any interrupts (such as the * timer interrupt). Full topology setup happens at smp_init() diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 083716ea38c9..323513858c20 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -1032,7 +1031,7 @@ void __init vmalloc_init(void) /* Import existing vmlist entries. */ for (tmp = vmlist; tmp; tmp = tmp->next) { - va = alloc_bootmem(sizeof(struct vmap_area)); + va = kzalloc(sizeof(struct vmap_area), GFP_NOWAIT); va->flags = tmp->flags | VM_VM_AREA; va->va_start = (unsigned long)tmp->addr; va->va_end = va->va_start + tmp->size; -- cgit v1.2.3 From 444f478f65c7ca4606f9965b31feed13fe2bc9fa Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 11 Jun 2009 18:29:06 +0300 Subject: init: introduce mm_init() As suggested by Christoph Lameter, introduce mm_init() now that we initialize all the kernel memory allocations together. Cc: Christoph Lameter Signed-off-by: Pekka Enberg --- init/main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'init') diff --git a/init/main.c b/init/main.c index 6d38f9607d14..7917695bf71e 100644 --- a/init/main.c +++ b/init/main.c @@ -533,6 +533,16 @@ void __init __weak thread_info_cache_init(void) { } +/* + * Set up kernel memory allocators + */ +static void __init mm_init(void) +{ + mem_init(); + kmem_cache_init(); + vmalloc_init(); +} + asmlinkage void __init start_kernel(void) { char * command_line; @@ -590,12 +600,7 @@ asmlinkage void __init start_kernel(void) vfs_caches_init_early(); sort_main_extable(); trap_init(); - /* - * Set up kernel memory allocators - */ - mem_init(); - kmem_cache_init(); - vmalloc_init(); + mm_init(); /* * Set up the scheduler prior starting any interrupts (such as the * timer interrupt). Full topology setup happens at smp_init() -- cgit v1.2.3