diff options
Diffstat (limited to 'init/main.c')
| -rw-r--r-- | init/main.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/init/main.c b/init/main.c index 4c194c47395f..006dcd547dc2 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -306,8 +306,6 @@ static int __init rdinit_setup(char *str) | |||
| 306 | } | 306 | } |
| 307 | __setup("rdinit=", rdinit_setup); | 307 | __setup("rdinit=", rdinit_setup); |
| 308 | 308 | ||
| 309 | extern void setup_arch(char **); | ||
| 310 | |||
| 311 | #ifndef CONFIG_SMP | 309 | #ifndef CONFIG_SMP |
| 312 | 310 | ||
| 313 | #ifdef CONFIG_X86_LOCAL_APIC | 311 | #ifdef CONFIG_X86_LOCAL_APIC |
| @@ -325,7 +323,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { } | |||
| 325 | #else | 323 | #else |
| 326 | 324 | ||
| 327 | #ifdef __GENERIC_PER_CPU | 325 | #ifdef __GENERIC_PER_CPU |
| 328 | unsigned long __per_cpu_offset[NR_CPUS]; | 326 | unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; |
| 329 | 327 | ||
| 330 | EXPORT_SYMBOL(__per_cpu_offset); | 328 | EXPORT_SYMBOL(__per_cpu_offset); |
| 331 | 329 | ||
| @@ -333,6 +331,7 @@ static void __init setup_per_cpu_areas(void) | |||
| 333 | { | 331 | { |
| 334 | unsigned long size, i; | 332 | unsigned long size, i; |
| 335 | char *ptr; | 333 | char *ptr; |
| 334 | unsigned long nr_possible_cpus = num_possible_cpus(); | ||
| 336 | 335 | ||
| 337 | /* Copy section for each CPU (we discard the original) */ | 336 | /* Copy section for each CPU (we discard the original) */ |
| 338 | size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); | 337 | size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); |
| @@ -340,12 +339,12 @@ static void __init setup_per_cpu_areas(void) | |||
| 340 | if (size < PERCPU_ENOUGH_ROOM) | 339 | if (size < PERCPU_ENOUGH_ROOM) |
| 341 | size = PERCPU_ENOUGH_ROOM; | 340 | size = PERCPU_ENOUGH_ROOM; |
| 342 | #endif | 341 | #endif |
| 342 | ptr = alloc_bootmem(size * nr_possible_cpus); | ||
| 343 | 343 | ||
| 344 | ptr = alloc_bootmem(size * NR_CPUS); | 344 | for_each_cpu(i) { |
| 345 | |||
| 346 | for (i = 0; i < NR_CPUS; i++, ptr += size) { | ||
| 347 | __per_cpu_offset[i] = ptr - __per_cpu_start; | 345 | __per_cpu_offset[i] = ptr - __per_cpu_start; |
| 348 | memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); | 346 | memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); |
| 347 | ptr += size; | ||
| 349 | } | 348 | } |
| 350 | } | 349 | } |
| 351 | #endif /* !__GENERIC_PER_CPU */ | 350 | #endif /* !__GENERIC_PER_CPU */ |
| @@ -438,6 +437,15 @@ void __init parse_early_param(void) | |||
| 438 | * Activate the first processor. | 437 | * Activate the first processor. |
| 439 | */ | 438 | */ |
| 440 | 439 | ||
| 440 | static void __init boot_cpu_init(void) | ||
| 441 | { | ||
| 442 | int cpu = smp_processor_id(); | ||
| 443 | /* Mark the boot cpu "present", "online" etc for SMP and UP case */ | ||
| 444 | cpu_set(cpu, cpu_online_map); | ||
| 445 | cpu_set(cpu, cpu_present_map); | ||
| 446 | cpu_set(cpu, cpu_possible_map); | ||
| 447 | } | ||
| 448 | |||
| 441 | asmlinkage void __init start_kernel(void) | 449 | asmlinkage void __init start_kernel(void) |
| 442 | { | 450 | { |
| 443 | char * command_line; | 451 | char * command_line; |
| @@ -447,17 +455,13 @@ asmlinkage void __init start_kernel(void) | |||
| 447 | * enable them | 455 | * enable them |
| 448 | */ | 456 | */ |
| 449 | lock_kernel(); | 457 | lock_kernel(); |
| 458 | boot_cpu_init(); | ||
| 450 | page_address_init(); | 459 | page_address_init(); |
| 451 | printk(KERN_NOTICE); | 460 | printk(KERN_NOTICE); |
| 452 | printk(linux_banner); | 461 | printk(linux_banner); |
| 453 | setup_arch(&command_line); | 462 | setup_arch(&command_line); |
| 454 | setup_per_cpu_areas(); | 463 | setup_per_cpu_areas(); |
| 455 | 464 | smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ | |
| 456 | /* | ||
| 457 | * Mark the boot cpu "online" so that it can call console drivers in | ||
| 458 | * printk() and can access its per-cpu storage. | ||
| 459 | */ | ||
| 460 | smp_prepare_boot_cpu(); | ||
| 461 | 465 | ||
| 462 | /* | 466 | /* |
| 463 | * Set up the scheduler prior starting any interrupts (such as the | 467 | * Set up the scheduler prior starting any interrupts (such as the |
| @@ -565,17 +569,23 @@ static void __init do_initcalls(void) | |||
| 565 | int count = preempt_count(); | 569 | int count = preempt_count(); |
| 566 | 570 | ||
| 567 | for (call = __initcall_start; call < __initcall_end; call++) { | 571 | for (call = __initcall_start; call < __initcall_end; call++) { |
| 568 | char *msg; | 572 | char *msg = NULL; |
| 573 | char msgbuf[40]; | ||
| 574 | int result; | ||
| 569 | 575 | ||
| 570 | if (initcall_debug) { | 576 | if (initcall_debug) { |
| 571 | printk(KERN_DEBUG "Calling initcall 0x%p", *call); | 577 | printk("Calling initcall 0x%p", *call); |
| 572 | print_fn_descriptor_symbol(": %s()", (unsigned long) *call); | 578 | print_fn_descriptor_symbol(": %s()", |
| 579 | (unsigned long) *call); | ||
| 573 | printk("\n"); | 580 | printk("\n"); |
| 574 | } | 581 | } |
| 575 | 582 | ||
| 576 | (*call)(); | 583 | result = (*call)(); |
| 577 | 584 | ||
| 578 | msg = NULL; | 585 | if (result && (result != -ENODEV || initcall_debug)) { |
| 586 | sprintf(msgbuf, "error code %d", result); | ||
| 587 | msg = msgbuf; | ||
| 588 | } | ||
| 579 | if (preempt_count() != count) { | 589 | if (preempt_count() != count) { |
| 580 | msg = "preemption imbalance"; | 590 | msg = "preemption imbalance"; |
| 581 | preempt_count() = count; | 591 | preempt_count() = count; |
| @@ -585,8 +595,10 @@ static void __init do_initcalls(void) | |||
| 585 | local_irq_enable(); | 595 | local_irq_enable(); |
| 586 | } | 596 | } |
| 587 | if (msg) { | 597 | if (msg) { |
| 588 | printk(KERN_WARNING "error in initcall at 0x%p: " | 598 | printk(KERN_WARNING "initcall at 0x%p", *call); |
| 589 | "returned with %s\n", *call, msg); | 599 | print_fn_descriptor_symbol(": %s()", |
| 600 | (unsigned long) *call); | ||
| 601 | printk(": returned with %s\n", msg); | ||
| 590 | } | 602 | } |
| 591 | } | 603 | } |
| 592 | 604 | ||
