diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-06 01:48:13 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-04-06 01:48:13 +0000 |
commit | baf53a8667f9b9bf9b4ff3ef272caabf5372a4f0 (patch) | |
tree | b580461583907fef56a0139ea5806689a5956b60 /arch | |
parent | 3e91b5dd87a280a583adcd976853c6f756a6d45e (diff) |
Create idle threads for the slave processors and put them in their
resched loops.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips64/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-init.c | 88 |
2 files changed, 78 insertions, 12 deletions
diff --git a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c index bf74a983e..2ed180820 100644 --- a/arch/mips64/kernel/smp.c +++ b/arch/mips64/kernel/smp.c @@ -50,7 +50,7 @@ static void sendintr(int destid, unsigned char status) /* The 'big kernel lock' */ spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; int smp_threads_ready = 0; /* Not used */ -static atomic_t smp_commenced = ATOMIC_INIT(0); +atomic_t smp_commenced = ATOMIC_INIT(0); struct cpuinfo_mips cpu_data[NR_CPUS]; int smp_num_cpus; /* Number that came online. */ int __cpu_number_map[NR_CPUS]; diff --git a/arch/mips64/sgi-ip27/ip27-init.c b/arch/mips64/sgi-ip27/ip27-init.c index fa008dcb6..882e58f33 100644 --- a/arch/mips64/sgi-ip27/ip27-init.c +++ b/arch/mips64/sgi-ip27/ip27-init.c @@ -1,4 +1,5 @@ #include <linux/kernel.h> +#include <linux/init.h> #include <linux/sched.h> #include <linux/mmzone.h> /* for numnodes */ #include <asm/sn/types.h> @@ -281,19 +282,53 @@ void per_cpu_init(void) #endif } +/* + * This is similar to hard_smp_processor_id(). + */ +cpuid_t getcpuid(void) +{ + klcpu_t *klcpu; + + klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM)); + return klcpu->cpu_info.virtid; +} + +#ifdef CONFIG_SMP + +void __init smp_callin(void) +{ +#if 0 + calibrate_delay(); + smp_store_cpu_info(cpuid); +#endif +} + +int __init start_secondary(void) +{ + extern int cpu_idle(void); + extern atomic_t smp_commenced; + + smp_callin(); + while (!atomic_read(&smp_commenced)); + return cpu_idle(); +} static atomic_t numstarted = ATOMIC_INIT(0); void cboot(void) { atomic_inc(&numstarted); - /* printk("Child!\n"); */ - while(1); + CPUMASK_CLRB(boot_barrier, getcpuid()); /* needs atomicity */ +#if 0 + per_cpu_init(); + ecc_init(); + bte_lateinit(); + init_mfhi_war(); + flush_tlb(); + flush_cache(); +#endif + start_secondary(); } -#ifdef CONFIG_SMP - -static long bootstacks[MAXCPUS][128]; - void allowboot(void) { int num_cpus = 0; @@ -320,15 +355,44 @@ void allowboot(void) /* Skip holes in CPU space */ if (CPUMASK_TSTB(boot_cpumask, cpu)) { - num_cpus++; + struct task_struct *p; /* + * The following code is purely to make sure + * Linux can schedule processes on this slave. + */ + kernel_thread(0, NULL, CLONE_PID); + p = init_task.prev_task; + init_tasks[num_cpus] = p; + p->processor = num_cpus; + p->has_cpu = 1; /* we schedule the first task manually */ + del_from_runqueue(p); + unhash_process(p); + /* Attach to the address space of init_task. */ + atomic_inc(&init_mm.mm_count); + p->active_mm = &init_mm; + + /* * Launch a slave into bootstrap(). - * It doesn't take an argument, and we'll - * take care of sp and gp when we get there. + * It doesn't take an argument, and we + * set sp to the kernel stack of the newly + * created idle process, gp to the proc struct + * (so that current-> works). */ LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), - (launch_proc_t)bootstrap, 0, bootstacks[cpu], 0); + (launch_proc_t)bootstrap, 0, + (void *)((unsigned long)p+KERNEL_STACK_SIZE - 32), + (void *)p); + + /* + * Now optimistically set the mapping arrays. We + * need to wait here, verify the cpu booted up, then + * fire up the next cpu. + */ + __cpu_number_map[cpu] = num_cpus; + __cpu_logical_map[num_cpus] = cpu; + num_cpus++; + /* smp_num_cpus++; Do after smp_send_reschedule works */ } } @@ -353,4 +417,6 @@ void allowboot(void) #endif } -#endif +#else /* CONFIG_SMP */ +void cboot(void) {} +#endif /* CONFIG_SMP */ |