X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fparisc%2Fkernel%2Fsmp.c;h=77be8d41e66c1108aa52cba910824d0c677a0334;hb=2cf7311f007833d5818fc9241c09a372c0325a4a;hp=0f1daa584c9ae36a64e0509e6664d5701c1aace2;hpb=a91482bdcc2e0f6035702e46f1b99043a0893346;p=linux-2.6.git diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 0f1daa584..77be8d41e 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -54,27 +54,18 @@ #define kDEBUG 0 +spinlock_t pa_dbit_lock = SPIN_LOCK_UNLOCKED; + spinlock_t smp_lock = SPIN_LOCK_UNLOCKED; volatile struct task_struct *smp_init_current_idle_task; static volatile int cpu_now_booting = 0; /* track which CPU is booting */ +static int parisc_max_cpus = -1; /* Command line */ unsigned long cache_decay_ticks; /* declared by include/linux/sched.h */ - -static int parisc_max_cpus = 1; - -/* online cpus are ones that we've managed to bring up completely - * possible cpus are all valid cpu - * present cpus are all detected cpu - * - * On startup we bring up the "possible" cpus. Since we discover - * CPUs later, we add them as hotplug, so the possible cpu mask is - * empty in the beginning. - */ - cpumask_t cpu_online_map = CPU_MASK_NONE; /* Bitmap of online CPUs */ -cpumask_t cpu_possible_map = CPU_MASK_ALL; /* Bitmap of Present CPUs */ +cpumask_t cpu_possible_map = CPU_MASK_NONE; /* Bitmap of Present CPUs */ EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(cpu_possible_map); @@ -298,7 +289,7 @@ send_IPI_allbutself(enum ipi_message_type op) { int i; - for (i = 0; i < NR_CPUS; i++) { + for (i = 0; i < parisc_max_cpus; i++) { if (cpu_online(i) && i != smp_processor_id()) send_IPI_single(i, op); } @@ -334,9 +325,6 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait) unsigned long timeout; static spinlock_t lock = SPIN_LOCK_UNLOCKED; - if (num_online_cpus() < 2) - return 0; - /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); @@ -389,6 +377,35 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait) EXPORT_SYMBOL(smp_call_function); + + +/* + * Setup routine for controlling SMP activation + * + * Command-line option of "nosmp" or "maxcpus=0" will disable SMP + * activation entirely (the MPS table probe still happens, though). + * + * Command-line option of "maxcpus=", where is an integer + * greater than 0, limits the maximum number of CPUs activated in + * SMP mode to . + */ + +static int __init nosmp(char *str) +{ + parisc_max_cpus = 0; + return 1; +} + +__setup("nosmp", nosmp); + +static int __init maxcpus(char *str) +{ + get_option(&str, &parisc_max_cpus); + return 1; +} + +__setup("maxcpus=", maxcpus); + /* * Flush all other CPU's tlb and then mine. Do this with on_each_cpu() * as we want to ensure all TLB's flushed before proceeding. @@ -485,6 +502,7 @@ void __init smp_callin(void) panic("smp_callin() AAAAaaaaahhhh....\n"); } +#if 0 /* * Create the idle task for a new Slave CPU. DO NOT use kernel_thread() * because that could end up calling schedule(). If it did, the new idle @@ -506,7 +524,7 @@ static struct task_struct *fork_by_hand(void) /* * Bring one cpu online. */ -int __init smp_boot_one_cpu(int cpuid) +int __init smp_boot_one_cpu(int cpuid, int cpunum) { struct task_struct *idle; long timeout; @@ -526,14 +544,14 @@ int __init smp_boot_one_cpu(int cpuid) panic("SMP: fork failed for CPU:%d", cpuid); wake_up_forked_process(idle); - init_idle(idle, cpuid); + init_idle(idle, cpunum); unhash_process(idle); - idle->thread_info->cpu = cpuid; + idle->thread_info->cpu = cpunum; /* Let _start know what logical CPU we're booting ** (offset into init_tasks[],cpu_data[]) */ - cpu_now_booting = cpuid; + cpu_now_booting = cpunum; /* ** boot strap code needs to know the task address since @@ -542,18 +560,11 @@ int __init smp_boot_one_cpu(int cpuid) smp_init_current_idle_task = idle ; mb(); - printk("Releasing cpu %d now, hpa=%lx\n", cpuid, cpu_data[cpuid].hpa); - /* ** This gets PDC to release the CPU from a very tight loop. - ** - ** From the PA-RISC 2.0 Firmware Architecture Reference Specification: - ** "The MEM_RENDEZ vector specifies the location of OS_RENDEZ which - ** is executed after receiving the rendezvous signal (an interrupt to - ** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the - ** contents of memory are valid." + ** See MEM_RENDEZ comments in head.S. */ - __raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpuid].hpa); + __raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpunum].hpa); mb(); /* @@ -562,7 +573,7 @@ int __init smp_boot_one_cpu(int cpuid) * Once the "monarch CPU" sees the bit change, it can move on. */ for (timeout = 0; timeout < 10000; timeout++) { - if(cpu_online(cpuid)) { + if(cpu_online(cpunum)) { /* Which implies Slave has started up */ cpu_now_booting = 0; smp_init_current_idle_task = NULL; @@ -581,14 +592,16 @@ int __init smp_boot_one_cpu(int cpuid) alive: /* Remember the Slave data */ #if (kDEBUG>=100) - printk(KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n", - cpuid, timeout * 100); + printk(KERN_DEBUG "SMP: CPU:%d (num %d) came alive after %ld _us\n", + cpuid, cpunum, timeout * 100); #endif /* kDEBUG */ #ifdef ENTRY_SYS_CPUS - cpu_data[cpuid].state = STATE_RUNNING; + cpu_data[cpunum].state = STATE_RUNNING; #endif return 0; } +#endif + void __devinit smp_prepare_boot_cpu(void) { @@ -599,10 +612,15 @@ void __devinit smp_prepare_boot_cpu(void) #endif /* Setup BSP mappings */ - printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor); + printk(KERN_DEBUG "SMP: bootstrap CPU ID is %d\n",bootstrap_processor); + init_task.thread_info->cpu = bootstrap_processor; + current->thread_info->cpu = bootstrap_processor; cpu_set(bootstrap_processor, cpu_online_map); - cpu_set(bootstrap_processor, cpu_present_map); + cpu_set(bootstrap_processor, cpu_possible_map); + + /* Mark Boostrap processor as present */ + current->active_mm = &init_mm; cache_decay_ticks = HZ/100; /* FIXME very rough. */ } @@ -615,12 +633,15 @@ void __devinit smp_prepare_boot_cpu(void) */ void __init smp_prepare_cpus(unsigned int max_cpus) { - cpus_clear(cpu_present_map); - cpu_set(0, cpu_present_map); - parisc_max_cpus = max_cpus; - if (!max_cpus) - printk(KERN_INFO "SMP mode deactivated.\n"); + if (max_cpus != -1) + printk(KERN_INFO "SMP: Limited to %d CPUs\n", max_cpus); + + printk(KERN_INFO "SMP: Monarch CPU activated (%lu.%02lu BogoMIPS)\n", + (cpu_data[0].loops_per_jiffy + 25) / 5000, + ((cpu_data[0].loops_per_jiffy + 25) / 50) % 100); + + return; } @@ -632,9 +653,6 @@ void smp_cpus_done(unsigned int cpu_max) int __devinit __cpu_up(unsigned int cpu) { - if (cpu != 0 && cpu < parisc_max_cpus) - smp_boot_one_cpu(cpu); - return cpu_online(cpu) ? 0 : -ENOSYS; }