[parisc-linux-cvs] linux-2.6 tausq
Randolph Chung
randolph at tausq.org
Thu Jul 15 10:55:29 MDT 2004
> 2.6.7-pa15
> - remove nosmp and maxcpus handling in arch/parisc/kernel/smp.c, it is
> handled by generic code
> - hook up processor_probe() to bring up slave cpus
> - don't assign irqs to CPUs that are not yet online
>
> On a a500, boots with either one cpu (one disabled in PDC), or with
> 2 CPUs enabled, and nosmp. However, with full smp enabled, the machine
> will HPMC when the 2nd CPU is brought online.
Thanks to Grant for pointing out the problems with IRQs being
assigned to the wrong CPU :)
Index: Makefile
===================================================================
RCS file: /var/cvs/linux-2.6/Makefile,v
retrieving revision 1.221
diff -u -p -r1.221 Makefile
--- Makefile 13 Jul 2004 05:36:35 -0000 1.221
+++ Makefile 15 Jul 2004 16:40:58 -0000
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 7
-EXTRAVERSION = -pa14
+EXTRAVERSION = -pa15
NAME=Zonked Quokka
# *DOCUMENTATION*
Index: arch/parisc/kernel/irq.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/irq.c,v
retrieving revision 1.13
diff -u -p -r1.13 irq.c
--- arch/parisc/kernel/irq.c 4 Jun 2004 19:36:53 -0000 1.13
+++ arch/parisc/kernel/irq.c 15 Jul 2004 16:40:59 -0000
@@ -332,7 +332,8 @@ txn_alloc_addr(int virt_irq)
next_cpu++; /* assign to "next" CPU we want this bugger on */
/* validate entry */
- while ((next_cpu < NR_CPUS) && !cpu_data[next_cpu].txn_addr)
+ while ((next_cpu < NR_CPUS) && (!cpu_data[next_cpu].txn_addr ||
+ !cpu_online(next_cpu)))
next_cpu++;
if (next_cpu >= NR_CPUS)
Index: arch/parisc/kernel/processor.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/processor.c,v
retrieving revision 1.6
diff -u -p -r1.6 processor.c
--- arch/parisc/kernel/processor.c 4 Jun 2004 19:36:53 -0000 1.6
+++ arch/parisc/kernel/processor.c 15 Jul 2004 16:40:59 -0000
@@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
+#include <linux/cpu.h>
#include <asm/cache.h>
#include <asm/hardware.h> /* for register_parisc_driver() stuff */
@@ -188,6 +189,15 @@ static int __init processor_probe(struct
cpu_irq_actions[cpuid] = actions;
}
#endif
+
+ /*
+ * Bring this CPU up now! (ignore bootstrap cpuid == 0)
+ */
+ if (cpuid) {
+ cpu_set(cpuid, cpu_present_map);
+ cpu_up(cpuid);
+ }
+
return 0;
}
Index: arch/parisc/kernel/smp.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/smp.c,v
retrieving revision 1.9
diff -u -p -r1.9 smp.c
--- arch/parisc/kernel/smp.c 11 Jul 2004 17:31:33 -0000 1.9
+++ arch/parisc/kernel/smp.c 15 Jul 2004 16:40:59 -0000
@@ -59,9 +59,20 @@ 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_NONE; /* Bitmap of Present CPUs */
@@ -287,7 +298,7 @@ send_IPI_allbutself(enum ipi_message_typ
{
int i;
- for (i = 0; i < parisc_max_cpus; i++) {
+ for (i = 0; i < NR_CPUS; i++) {
if (cpu_online(i) && i != smp_processor_id())
send_IPI_single(i, op);
}
@@ -323,6 +334,9 @@ smp_call_function (void (*func) (void *i
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());
@@ -375,35 +389,6 @@ smp_call_function (void (*func) (void *i
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=<NUM>", where <NUM> is an integer
- * greater than 0, limits the maximum number of CPUs activated in
- * SMP mode to <NUM>.
- */
-
-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.
@@ -500,7 +485,6 @@ 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
@@ -522,7 +506,7 @@ static struct task_struct *fork_by_hand(
/*
* Bring one cpu online.
*/
-int __init smp_boot_one_cpu(int cpuid, int cpunum)
+int __init smp_boot_one_cpu(int cpuid)
{
struct task_struct *idle;
long timeout;
@@ -542,14 +526,14 @@ int __init smp_boot_one_cpu(int cpuid, i
panic("SMP: fork failed for CPU:%d", cpuid);
wake_up_forked_process(idle);
- init_idle(idle, cpunum);
+ init_idle(idle, cpuid);
unhash_process(idle);
- idle->thread_info->cpu = cpunum;
+ idle->thread_info->cpu = cpuid;
/* Let _start know what logical CPU we're booting
** (offset into init_tasks[],cpu_data[])
*/
- cpu_now_booting = cpunum;
+ cpu_now_booting = cpuid;
/*
** boot strap code needs to know the task address since
@@ -558,11 +542,13 @@ int __init smp_boot_one_cpu(int cpuid, i
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.
** See MEM_RENDEZ comments in head.S.
*/
- __raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpunum].hpa);
+ __raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpuid].hpa);
mb();
/*
@@ -571,7 +557,7 @@ int __init smp_boot_one_cpu(int cpuid, i
* Once the "monarch CPU" sees the bit change, it can move on.
*/
for (timeout = 0; timeout < 10000; timeout++) {
- if(cpu_online(cpunum)) {
+ if(cpu_online(cpuid)) {
/* Which implies Slave has started up */
cpu_now_booting = 0;
smp_init_current_idle_task = NULL;
@@ -590,16 +576,14 @@ int __init smp_boot_one_cpu(int cpuid, i
alive:
/* Remember the Slave data */
#if (kDEBUG>=100)
- printk(KERN_DEBUG "SMP: CPU:%d (num %d) came alive after %ld _us\n",
- cpuid, cpunum, timeout * 100);
+ printk(KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n",
+ cpuid, timeout * 100);
#endif /* kDEBUG */
#ifdef ENTRY_SYS_CPUS
- cpu_data[cpunum].state = STATE_RUNNING;
+ cpu_data[cpuid].state = STATE_RUNNING;
#endif
return 0;
}
-#endif
-
void __devinit smp_prepare_boot_cpu(void)
{
@@ -615,7 +599,7 @@ void __devinit smp_prepare_boot_cpu(void
current->thread_info->cpu = bootstrap_processor;
cpu_set(bootstrap_processor, cpu_online_map);
- cpu_set(bootstrap_processor, cpu_possible_map);
+ cpu_set(bootstrap_processor, cpu_present_map);
/* Mark Boostrap processor as present */
current->active_mm = &init_mm;
@@ -631,15 +615,14 @@ void __devinit smp_prepare_boot_cpu(void
*/
void __init smp_prepare_cpus(unsigned int max_cpus)
{
-
- 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;
+ cpus_clear(cpu_possible_map);
+ cpus_clear(cpu_present_map);
+ cpu_set(0, cpu_possible_map);
+ cpu_set(0, cpu_present_map);
+
+ parisc_max_cpus = max_cpus;
+ if (!max_cpus)
+ printk(KERN_INFO "SMP mode deactivated.\n");
}
@@ -651,6 +634,9 @@ 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;
}
More information about the parisc-linux-cvs
mailing list