aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kernel/early.c1
-rw-r--r--arch/s390/kernel/setup.c1
-rw-r--r--arch/s390/kernel/smp.c180
3 files changed, 76 insertions, 106 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c7cbb0114147..9f7b73b180f0 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -278,7 +278,6 @@ void __init startup_init(void)
278 setup_lowcore_early(); 278 setup_lowcore_early();
279 sclp_read_info_early(); 279 sclp_read_info_early();
280 sclp_facilities_detect(); 280 sclp_facilities_detect();
281 sclp_read_cpu_info_early();
282 memsize = sclp_memory_detect(); 281 memsize = sclp_memory_detect();
283#ifndef CONFIG_64BIT 282#ifndef CONFIG_64BIT
284 /* 283 /*
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 3a61bfc2c4fb..cbdf3fb05e81 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -922,7 +922,6 @@ setup_arch(char **cmdline_p)
922 922
923 cpu_init(); 923 cpu_init();
924 __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; 924 __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
925 smp_setup_cpu_possible_map();
926 925
927 /* 926 /*
928 * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). 927 * Setup capabilities (ELF_HWCAP & ELF_PLATFORM).
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 66fe28930d82..320e4e97bf52 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -54,7 +54,7 @@ EXPORT_SYMBOL(lowcore_ptr);
54cpumask_t cpu_online_map = CPU_MASK_NONE; 54cpumask_t cpu_online_map = CPU_MASK_NONE;
55EXPORT_SYMBOL(cpu_online_map); 55EXPORT_SYMBOL(cpu_online_map);
56 56
57cpumask_t cpu_possible_map = CPU_MASK_NONE; 57cpumask_t cpu_possible_map = CPU_MASK_ALL;
58EXPORT_SYMBOL(cpu_possible_map); 58EXPORT_SYMBOL(cpu_possible_map);
59 59
60static struct task_struct *current_set[NR_CPUS]; 60static struct task_struct *current_set[NR_CPUS];
@@ -399,7 +399,7 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
399 "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS); 399 "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS);
400 return; 400 return;
401 } 401 }
402 zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area)); 402 zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL);
403 __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu; 403 __cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu;
404 while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) == 404 while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
405 sigp_busy) 405 sigp_busy)
@@ -435,67 +435,6 @@ static int cpu_stopped(int cpu)
435 return 0; 435 return 0;
436} 436}
437 437
438/*
439 * Lets check how many CPUs we have.
440 */
441static void __init smp_count_cpus(unsigned int *configured_cpus,
442 unsigned int *standby_cpus)
443{
444 unsigned int cpu;
445 struct sclp_cpu_info *info;
446 u16 boot_cpu_addr, cpu_addr;
447
448 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
449 current_thread_info()->cpu = 0;
450 *configured_cpus = 1;
451 *standby_cpus = 0;
452
453 info = alloc_bootmem_pages(sizeof(*info));
454 if (!info)
455 disabled_wait((unsigned long) __builtin_return_address(0));
456
457 /* Use sigp detection algorithm if sclp doesn't work. */
458 if (sclp_get_cpu_info(info)) {
459 smp_use_sigp_detection = 1;
460 for (cpu = 0; cpu <= 65535; cpu++) {
461 if (cpu == boot_cpu_addr)
462 continue;
463 __cpu_logical_map[CPU_INIT_NO] = cpu;
464 if (cpu_stopped(CPU_INIT_NO))
465 (*configured_cpus)++;
466 }
467 goto out;
468 }
469
470 if (info->has_cpu_type) {
471 for (cpu = 0; cpu < info->combined; cpu++) {
472 if (info->cpu[cpu].address == boot_cpu_addr) {
473 smp_cpu_type = info->cpu[cpu].type;
474 break;
475 }
476 }
477 }
478 /* Count cpus. */
479 for (cpu = 0; cpu < info->combined; cpu++) {
480 if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
481 continue;
482 cpu_addr = info->cpu[cpu].address;
483 if (cpu_addr == boot_cpu_addr)
484 continue;
485 __cpu_logical_map[CPU_INIT_NO] = cpu_addr;
486 if (!cpu_stopped(CPU_INIT_NO)) {
487 (*standby_cpus)++;
488 continue;
489 }
490 smp_get_save_area(*configured_cpus, cpu_addr);
491 (*configured_cpus)++;
492 }
493out:
494 printk(KERN_INFO "CPUs: %d configured, %d standby\n",
495 *configured_cpus, *standby_cpus);
496 free_bootmem((unsigned long) info, sizeof(*info));
497}
498
499static int cpu_known(int cpu_id) 438static int cpu_known(int cpu_id)
500{ 439{
501 int cpu; 440 int cpu;
@@ -529,7 +468,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
529 return 0; 468 return 0;
530} 469}
531 470
532static int __init_refok smp_rescan_cpus_sclp(cpumask_t avail) 471static int smp_rescan_cpus_sclp(cpumask_t avail)
533{ 472{
534 struct sclp_cpu_info *info; 473 struct sclp_cpu_info *info;
535 int cpu_id, logical_cpu, cpu; 474 int cpu_id, logical_cpu, cpu;
@@ -538,10 +477,7 @@ static int __init_refok smp_rescan_cpus_sclp(cpumask_t avail)
538 logical_cpu = first_cpu(avail); 477 logical_cpu = first_cpu(avail);
539 if (logical_cpu == NR_CPUS) 478 if (logical_cpu == NR_CPUS)
540 return 0; 479 return 0;
541 if (slab_is_available()) 480 info = kmalloc(sizeof(*info), GFP_KERNEL);
542 info = kmalloc(sizeof(*info), GFP_KERNEL);
543 else
544 info = alloc_bootmem(sizeof(*info));
545 if (!info) 481 if (!info)
546 return -ENOMEM; 482 return -ENOMEM;
547 rc = sclp_get_cpu_info(info); 483 rc = sclp_get_cpu_info(info);
@@ -564,10 +500,7 @@ static int __init_refok smp_rescan_cpus_sclp(cpumask_t avail)
564 break; 500 break;
565 } 501 }
566out: 502out:
567 if (slab_is_available()) 503 kfree(info);
568 kfree(info);
569 else
570 free_bootmem((unsigned long) info, sizeof(*info));
571 return rc; 504 return rc;
572} 505}
573 506
@@ -575,15 +508,71 @@ static int smp_rescan_cpus(void)
575{ 508{
576 cpumask_t avail; 509 cpumask_t avail;
577 510
578 cpus_setall(avail); 511 cpus_xor(avail, cpu_possible_map, cpu_present_map);
579 cpus_and(avail, avail, cpu_possible_map);
580 cpus_andnot(avail, avail, cpu_present_map);
581 if (smp_use_sigp_detection) 512 if (smp_use_sigp_detection)
582 return smp_rescan_cpus_sigp(avail); 513 return smp_rescan_cpus_sigp(avail);
583 else 514 else
584 return smp_rescan_cpus_sclp(avail); 515 return smp_rescan_cpus_sclp(avail);
585} 516}
586 517
518static void __init smp_detect_cpus(void)
519{
520 unsigned int cpu, c_cpus, s_cpus;
521 struct sclp_cpu_info *info;
522 u16 boot_cpu_addr, cpu_addr;
523
524 c_cpus = 1;
525 s_cpus = 0;
526 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
527 info = kmalloc(sizeof(*info), GFP_KERNEL);
528 if (!info)
529 panic("smp_detect_cpus failed to allocate memory\n");
530 /* Use sigp detection algorithm if sclp doesn't work. */
531 if (sclp_get_cpu_info(info)) {
532 smp_use_sigp_detection = 1;
533 for (cpu = 0; cpu <= 65535; cpu++) {
534 if (cpu == boot_cpu_addr)
535 continue;
536 __cpu_logical_map[CPU_INIT_NO] = cpu;
537 if (!cpu_stopped(CPU_INIT_NO))
538 continue;
539 smp_get_save_area(c_cpus, cpu);
540 c_cpus++;
541 }
542 goto out;
543 }
544
545 if (info->has_cpu_type) {
546 for (cpu = 0; cpu < info->combined; cpu++) {
547 if (info->cpu[cpu].address == boot_cpu_addr) {
548 smp_cpu_type = info->cpu[cpu].type;
549 break;
550 }
551 }
552 }
553
554 for (cpu = 0; cpu < info->combined; cpu++) {
555 if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
556 continue;
557 cpu_addr = info->cpu[cpu].address;
558 if (cpu_addr == boot_cpu_addr)
559 continue;
560 __cpu_logical_map[CPU_INIT_NO] = cpu_addr;
561 if (!cpu_stopped(CPU_INIT_NO)) {
562 s_cpus++;
563 continue;
564 }
565 smp_get_save_area(c_cpus, cpu_addr);
566 c_cpus++;
567 }
568out:
569 kfree(info);
570 printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus);
571 lock_cpu_hotplug();
572 smp_rescan_cpus();
573 unlock_cpu_hotplug();
574}
575
587/* 576/*
588 * Activate a secondary processor. 577 * Activate a secondary processor.
589 */ 578 */
@@ -674,41 +663,20 @@ int __cpu_up(unsigned int cpu)
674 return 0; 663 return 0;
675} 664}
676 665
677static unsigned int __initdata additional_cpus;
678static unsigned int __initdata possible_cpus;
679
680void __init smp_setup_cpu_possible_map(void)
681{
682 unsigned int pos_cpus, cpu;
683 unsigned int configured_cpus, standby_cpus;
684
685 smp_count_cpus(&configured_cpus, &standby_cpus);
686 pos_cpus = min(configured_cpus + standby_cpus + additional_cpus,
687 (unsigned int) NR_CPUS);
688 if (possible_cpus)
689 pos_cpus = min(possible_cpus, (unsigned int) NR_CPUS);
690 for (cpu = 0; cpu < pos_cpus; cpu++)
691 cpu_set(cpu, cpu_possible_map);
692 cpu_present_map = cpumask_of_cpu(0);
693 smp_rescan_cpus();
694}
695
696#ifdef CONFIG_HOTPLUG_CPU
697
698static int __init setup_additional_cpus(char *s)
699{
700 additional_cpus = simple_strtoul(s, NULL, 0);
701 return 0;
702}
703early_param("additional_cpus", setup_additional_cpus);
704
705static int __init setup_possible_cpus(char *s) 666static int __init setup_possible_cpus(char *s)
706{ 667{
707 possible_cpus = simple_strtoul(s, NULL, 0); 668 int pcpus, cpu;
669
670 pcpus = simple_strtoul(s, NULL, 0);
671 cpu_possible_map = cpumask_of_cpu(0);
672 for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++)
673 cpu_set(cpu, cpu_possible_map);
708 return 0; 674 return 0;
709} 675}
710early_param("possible_cpus", setup_possible_cpus); 676early_param("possible_cpus", setup_possible_cpus);
711 677
678#ifdef CONFIG_HOTPLUG_CPU
679
712int __cpu_disable(void) 680int __cpu_disable(void)
713{ 681{
714 struct ec_creg_mask_parms cr_parms; 682 struct ec_creg_mask_parms cr_parms;
@@ -768,6 +736,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
768 unsigned int cpu; 736 unsigned int cpu;
769 int i; 737 int i;
770 738
739 smp_detect_cpus();
740
771 /* request the 0x1201 emergency signal external interrupt */ 741 /* request the 0x1201 emergency signal external interrupt */
772 if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0) 742 if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
773 panic("Couldn't request external interrupt 0x1201"); 743 panic("Couldn't request external interrupt 0x1201");
@@ -816,6 +786,8 @@ void __init smp_prepare_boot_cpu(void)
816{ 786{
817 BUG_ON(smp_processor_id() != 0); 787 BUG_ON(smp_processor_id() != 0);
818 788
789 current_thread_info()->cpu = 0;
790 cpu_set(0, cpu_present_map);
819 cpu_set(0, cpu_online_map); 791 cpu_set(0, cpu_online_map);
820 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 792 S390_lowcore.percpu_offset = __per_cpu_offset[0];
821 current_set[0] = current; 793 current_set[0] = current;