From 44fd22992cb76dc51c52cf4b8aff1bc7899bb23c Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Thu, 23 Mar 2006 02:59:44 -0800 Subject: [PATCH] Register the boot-cpu in the cpu maps earlier Register the boot-cpu in the cpu maps earlier to allow the early printk to work, and to fix an obscure deadlock at boot. Signed-off-by: Stas Sergeev Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'init/main.c') diff --git a/init/main.c b/init/main.c index 4c194c47395..141e8896d25 100644 --- a/init/main.c +++ b/init/main.c @@ -438,6 +438,15 @@ void __init parse_early_param(void) * Activate the first processor. */ +static void __init boot_cpu_init(void) +{ + int cpu = smp_processor_id(); + /* Mark the boot cpu "present", "online" etc for SMP and UP case */ + cpu_set(cpu, cpu_online_map); + cpu_set(cpu, cpu_present_map); + cpu_set(cpu, cpu_possible_map); +} + asmlinkage void __init start_kernel(void) { char * command_line; @@ -447,17 +456,13 @@ asmlinkage void __init start_kernel(void) * enable them */ lock_kernel(); + boot_cpu_init(); page_address_init(); printk(KERN_NOTICE); printk(linux_banner); setup_arch(&command_line); setup_per_cpu_areas(); - - /* - * Mark the boot cpu "online" so that it can call console drivers in - * printk() and can access its per-cpu storage. - */ - smp_prepare_boot_cpu(); + smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ /* * Set up the scheduler prior starting any interrupts (such as the -- cgit v1.2.3-70-g09d2 From 63872f87a151413100678f110d1556026002809e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Mar 2006 03:01:04 -0800 Subject: [PATCH] Only allocate percpu data for possible CPUs percpu_data blindly allocates bootmem memory to store NR_CPUS instances of cpudata, instead of allocating memory only for possible cpus. This patch saves ram, allocating num_possible_cpus() (instead of NR_CPUS) instances. Signed-off-by: Eric Dumazet Acked-by: "David S. Miller" Cc: James Bottomley Cc: Jens Axboe Acked-by: Ingo Molnar Cc: Jens Axboe Cc: Anton Blanchard Acked-by: William Irwin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'init/main.c') diff --git a/init/main.c b/init/main.c index 141e8896d25..9cf6b307bfd 100644 --- a/init/main.c +++ b/init/main.c @@ -333,6 +333,7 @@ static void __init setup_per_cpu_areas(void) { unsigned long size, i; char *ptr; + unsigned long nr_possible_cpus = num_possible_cpus(); /* Copy section for each CPU (we discard the original) */ size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); @@ -340,12 +341,16 @@ static void __init setup_per_cpu_areas(void) if (size < PERCPU_ENOUGH_ROOM) size = PERCPU_ENOUGH_ROOM; #endif + ptr = alloc_bootmem(size * nr_possible_cpus); - ptr = alloc_bootmem(size * NR_CPUS); - - for (i = 0; i < NR_CPUS; i++, ptr += size) { + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_possible(i)) { + __per_cpu_offset[i] = (char*)0 - __per_cpu_start; + continue; + } __per_cpu_offset[i] = ptr - __per_cpu_start; memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); + ptr += size; } } #endif /* !__GENERIC_PER_CPU */ -- cgit v1.2.3-70-g09d2 From b73b459f72f746a031d1ef4cc7659b20a1f1acb9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 23 Mar 2006 03:01:07 -0800 Subject: [PATCH] __GENERIC_PER_CPU changes Now CONFIG_DEBUG_INITDATA is in, initial percpu data [__per_cpu_start,__per_cpu_end] can be declared as a redzone, and invalid accesses after boot can be detected, at least for i386. We can let non possible cpus percpu data point to this 'redzone' instead of NULL . NULL was not a good choice because part of [0..32768] memory may be readable and invalid accesses may happen unnoticed. If CONFIG_DEBUG_INITDATA is not defined, each non possible cpu points to the initial percpu data (__per_cpu_offset[cpu] == 0), thus invalid accesses wont be detected/crash. This patch also moves __per_cpu_offset[] to read_mostly area to avoid false sharing. Signed-off-by: Eric Dumazet Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/main.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'init/main.c') diff --git a/init/main.c b/init/main.c index 9cf6b307bfd..2714e0e7cfe 100644 --- a/init/main.c +++ b/init/main.c @@ -325,7 +325,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { } #else #ifdef __GENERIC_PER_CPU -unsigned long __per_cpu_offset[NR_CPUS]; +unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; EXPORT_SYMBOL(__per_cpu_offset); @@ -343,11 +343,7 @@ static void __init setup_per_cpu_areas(void) #endif ptr = alloc_bootmem(size * nr_possible_cpus); - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_possible(i)) { - __per_cpu_offset[i] = (char*)0 - __per_cpu_start; - continue; - } + for_each_cpu(i) { __per_cpu_offset[i] = ptr - __per_cpu_start; memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); ptr += size; -- cgit v1.2.3-70-g09d2