[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