aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/smpboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/smpboot.c')
-rw-r--r--arch/x86_64/kernel/smpboot.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 62c2e747af58..daf19332f0dd 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -60,6 +60,7 @@
60#include <asm/irq.h> 60#include <asm/irq.h>
61#include <asm/hw_irq.h> 61#include <asm/hw_irq.h>
62#include <asm/numa.h> 62#include <asm/numa.h>
63#include <asm/genapic.h>
63 64
64/* Number of siblings per CPU package */ 65/* Number of siblings per CPU package */
65int smp_num_siblings = 1; 66int smp_num_siblings = 1;
@@ -753,14 +754,16 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
753} 754}
754 755
755struct create_idle { 756struct create_idle {
757 struct work_struct work;
756 struct task_struct *idle; 758 struct task_struct *idle;
757 struct completion done; 759 struct completion done;
758 int cpu; 760 int cpu;
759}; 761};
760 762
761void do_fork_idle(void *_c_idle) 763void do_fork_idle(struct work_struct *work)
762{ 764{
763 struct create_idle *c_idle = _c_idle; 765 struct create_idle *c_idle =
766 container_of(work, struct create_idle, work);
764 767
765 c_idle->idle = fork_idle(c_idle->cpu); 768 c_idle->idle = fork_idle(c_idle->cpu);
766 complete(&c_idle->done); 769 complete(&c_idle->done);
@@ -775,10 +778,10 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
775 int timeout; 778 int timeout;
776 unsigned long start_rip; 779 unsigned long start_rip;
777 struct create_idle c_idle = { 780 struct create_idle c_idle = {
781 .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle),
778 .cpu = cpu, 782 .cpu = cpu,
779 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), 783 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
780 }; 784 };
781 DECLARE_WORK(work, do_fork_idle, &c_idle);
782 785
783 /* allocate memory for gdts of secondary cpus. Hotplug is considered */ 786 /* allocate memory for gdts of secondary cpus. Hotplug is considered */
784 if (!cpu_gdt_descr[cpu].address && 787 if (!cpu_gdt_descr[cpu].address &&
@@ -825,9 +828,9 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
825 * thread. 828 * thread.
826 */ 829 */
827 if (!keventd_up() || current_is_keventd()) 830 if (!keventd_up() || current_is_keventd())
828 work.func(work.data); 831 c_idle.work.func(&c_idle.work);
829 else { 832 else {
830 schedule_work(&work); 833 schedule_work(&c_idle.work);
831 wait_for_completion(&c_idle.done); 834 wait_for_completion(&c_idle.done);
832 } 835 }
833 836
@@ -1167,6 +1170,13 @@ int __cpuinit __cpu_up(unsigned int cpu)
1167 1170
1168 while (!cpu_isset(cpu, cpu_online_map)) 1171 while (!cpu_isset(cpu, cpu_online_map))
1169 cpu_relax(); 1172 cpu_relax();
1173
1174 if (num_online_cpus() > 8 && genapic == &apic_flat) {
1175 printk(KERN_WARNING
1176 "flat APIC routing can't be used with > 8 cpus\n");
1177 BUG();
1178 }
1179
1170 err = 0; 1180 err = 0;
1171 1181
1172 return err; 1182 return err;