diff options
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 39 |
1 files changed, 7 insertions, 32 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 1f77227669e8..647ba9425893 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -85,7 +85,6 @@ enum { | |||
85 | 85 | ||
86 | struct pcpu { | 86 | struct pcpu { |
87 | struct cpu cpu; | 87 | struct cpu cpu; |
88 | struct task_struct *idle; /* idle process for the cpu */ | ||
89 | struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ | 88 | struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ |
90 | unsigned long async_stack; /* async stack for the cpu */ | 89 | unsigned long async_stack; /* async stack for the cpu */ |
91 | unsigned long panic_stack; /* panic stack for the cpu */ | 90 | unsigned long panic_stack; /* panic stack for the cpu */ |
@@ -226,6 +225,8 @@ out: | |||
226 | return -ENOMEM; | 225 | return -ENOMEM; |
227 | } | 226 | } |
228 | 227 | ||
228 | #ifdef CONFIG_HOTPLUG_CPU | ||
229 | |||
229 | static void pcpu_free_lowcore(struct pcpu *pcpu) | 230 | static void pcpu_free_lowcore(struct pcpu *pcpu) |
230 | { | 231 | { |
231 | pcpu_sigp_retry(pcpu, sigp_set_prefix, 0); | 232 | pcpu_sigp_retry(pcpu, sigp_set_prefix, 0); |
@@ -247,6 +248,8 @@ static void pcpu_free_lowcore(struct pcpu *pcpu) | |||
247 | } | 248 | } |
248 | } | 249 | } |
249 | 250 | ||
251 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
252 | |||
250 | static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) | 253 | static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) |
251 | { | 254 | { |
252 | struct _lowcore *lc = pcpu->lowcore; | 255 | struct _lowcore *lc = pcpu->lowcore; |
@@ -721,26 +724,9 @@ static void __cpuinit smp_start_secondary(void *cpuvoid) | |||
721 | cpu_idle(); | 724 | cpu_idle(); |
722 | } | 725 | } |
723 | 726 | ||
724 | struct create_idle { | ||
725 | struct work_struct work; | ||
726 | struct task_struct *idle; | ||
727 | struct completion done; | ||
728 | int cpu; | ||
729 | }; | ||
730 | |||
731 | static void __cpuinit smp_fork_idle(struct work_struct *work) | ||
732 | { | ||
733 | struct create_idle *c_idle; | ||
734 | |||
735 | c_idle = container_of(work, struct create_idle, work); | ||
736 | c_idle->idle = fork_idle(c_idle->cpu); | ||
737 | complete(&c_idle->done); | ||
738 | } | ||
739 | |||
740 | /* Upping and downing of CPUs */ | 727 | /* Upping and downing of CPUs */ |
741 | int __cpuinit __cpu_up(unsigned int cpu) | 728 | int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) |
742 | { | 729 | { |
743 | struct create_idle c_idle; | ||
744 | struct pcpu *pcpu; | 730 | struct pcpu *pcpu; |
745 | int rc; | 731 | int rc; |
746 | 732 | ||
@@ -750,22 +736,12 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
750 | if (pcpu_sigp_retry(pcpu, sigp_initial_cpu_reset, 0) != | 736 | if (pcpu_sigp_retry(pcpu, sigp_initial_cpu_reset, 0) != |
751 | sigp_order_code_accepted) | 737 | sigp_order_code_accepted) |
752 | return -EIO; | 738 | return -EIO; |
753 | if (!pcpu->idle) { | 739 | |
754 | c_idle.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done); | ||
755 | INIT_WORK_ONSTACK(&c_idle.work, smp_fork_idle); | ||
756 | c_idle.cpu = cpu; | ||
757 | schedule_work(&c_idle.work); | ||
758 | wait_for_completion(&c_idle.done); | ||
759 | if (IS_ERR(c_idle.idle)) | ||
760 | return PTR_ERR(c_idle.idle); | ||
761 | pcpu->idle = c_idle.idle; | ||
762 | } | ||
763 | init_idle(pcpu->idle, cpu); | ||
764 | rc = pcpu_alloc_lowcore(pcpu, cpu); | 740 | rc = pcpu_alloc_lowcore(pcpu, cpu); |
765 | if (rc) | 741 | if (rc) |
766 | return rc; | 742 | return rc; |
767 | pcpu_prepare_secondary(pcpu, cpu); | 743 | pcpu_prepare_secondary(pcpu, cpu); |
768 | pcpu_attach_task(pcpu, pcpu->idle); | 744 | pcpu_attach_task(pcpu, tidle); |
769 | pcpu_start_fn(pcpu, smp_start_secondary, NULL); | 745 | pcpu_start_fn(pcpu, smp_start_secondary, NULL); |
770 | while (!cpu_online(cpu)) | 746 | while (!cpu_online(cpu)) |
771 | cpu_relax(); | 747 | cpu_relax(); |
@@ -852,7 +828,6 @@ void __init smp_prepare_boot_cpu(void) | |||
852 | struct pcpu *pcpu = pcpu_devices; | 828 | struct pcpu *pcpu = pcpu_devices; |
853 | 829 | ||
854 | boot_cpu_address = stap(); | 830 | boot_cpu_address = stap(); |
855 | pcpu->idle = current; | ||
856 | pcpu->state = CPU_STATE_CONFIGURED; | 831 | pcpu->state = CPU_STATE_CONFIGURED; |
857 | pcpu->address = boot_cpu_address; | 832 | pcpu->address = boot_cpu_address; |
858 | pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); | 833 | pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); |