[parisc-linux-cvs] smp.c patch
Grant Grundler
grundler@cup.hp.com
Tue, 13 Feb 2001 14:23:15 -0800 (PST)
Fix the problem with IPI not working.
bits in cpu_data[].pending_ipi weren't getting set correctly.
Other stuff is just debug output cleanup.
ipi_interrupt() output is wrong and I don't understand why.
The "ipiIRQ" output line "pending_ipi" doesn't match the
behaviour later in the switch() statement.
grant
Index: arch/parisc/kernel/smp.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/smp.c,v
retrieving revision 1.6
diff -u -p -r1.6 smp.c
--- smp.c 2001/02/08 12:49:42 1.6
+++ smp.c 2001/02/13 22:02:04
@@ -72,7 +72,6 @@ static volatile unsigned long cpu_callin
int smp_num_cpus = 1;
int smp_threads_ready = 0;
static int max_cpus = -1; /* Command line */
-static unsigned long ipi_op[NR_CPUS];
struct smp_call_struct {
void (*func) (void *info);
void *info;
@@ -83,7 +82,8 @@ struct smp_call_struct {
static volatile struct smp_call_struct *smp_call_function_data;
enum ipi_message_type {
- IPI_RESCHEDULE,
+ IPI_NOP=0,
+ IPI_RESCHEDULE=1,
IPI_CALL_FUNC,
IPI_CPU_START,
IPI_CPU_STOP,
@@ -147,37 +147,38 @@ void
ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int this_cpu = smp_processor_id();
- unsigned long *pending_ipis = &ipi_op[this_cpu];
+ unsigned long *ipis = &(cpu_data[this_cpu].pending_ipi);
unsigned long ops;
/* Count this now; we may make a call that never returns. */
cpu_data[this_cpu].ipi_count++;
mb(); /* Order interrupt and bit testing. */
- while ((ops = xchg(pending_ipis, 0)) != 0) {
+printk("ipiIRQ() CPU%d %lx\n", this_cpu, *ipis);
+mdelay(200);
+
+ while ((ops = xchg(ipis, 0)) != 0) {
mb(); /* Order bit clearing and data access. */
do {
- unsigned long which;
-
-printk("ipi_interrupt(%d,...) on %d ops = 0x%lx ", irq, this_cpu, ops);
+ unsigned long which = ffz(~ops);
- which = ffz(~ops);
- ops &= ~(1 << which);
-
-printk("(which = %ld)\n", which);
-
switch (which) {
case IPI_RESCHEDULE:
#if (kDEBUG>=100)
- printk("CPU:%d got reschedule interrupt\n",this_cpu);
+ printk("CPU%d IPI_RESCHEDULE\n",this_cpu);
#endif /* kDEBUG */
+ ops &= ~(1 << IPI_RESCHEDULE);
/*
- * Reschedule callback. Everything to be done is done by the
- * interrupt return path.
+ * Reschedule callback. Everything to be done is
+ * done by the interrupt return path.
*/
break;
case IPI_CALL_FUNC:
+#if (kDEBUG>=100)
+ printk("CPU%d IPI_CALL_FUNC\n",this_cpu);
+#endif /* kDEBUG */
+ ops &= ~(1 << IPI_CALL_FUNC);
{
volatile struct smp_call_struct *data;
void (*func)(void *info);
@@ -203,12 +204,20 @@ printk("(which = %ld)\n", which);
break;
case IPI_CPU_START:
+#if (kDEBUG>=100)
+ printk("CPU%d IPI_CPU_START\n",this_cpu);
+#endif /* kDEBUG */
+ ops &= ~(1 << IPI_CPU_START);
#ifdef ENTRY_SYS_CPUS
cpu_data[this_cpu].state = STATE_RUNNING;
#endif
break;
case IPI_CPU_STOP:
+#if (kDEBUG>=100)
+ printk("CPU%d IPI_CPU_STOP\n",this_cpu);
+#endif /* kDEBUG */
+ ops &= ~(1 << IPI_CPU_STOP);
#ifdef ENTRY_SYS_CPUS
#else
halt_processor();
@@ -217,12 +226,14 @@ printk("(which = %ld)\n", which);
case IPI_CPU_TEST:
#if (kDEBUG>=100)
- printk("CPU:%d is alive\n",this_cpu);
+ printk("CPU%d is alive!\n",this_cpu);
#endif /* kDEBUG */
+ ops &= ~(1 << IPI_CPU_TEST);
break;
default:
- printk(KERN_CRIT "Unknown IPI num on CPU %d: %lu\n", this_cpu, which);
+ printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n", this_cpu, which);
+ ops &= ~(1 << which);
return;
} /* Switch */
} while (ops);
@@ -236,25 +247,28 @@ printk("(which = %ld)\n", which);
static inline void
ipi_send(int cpu, enum ipi_message_type op)
{
- set_bit(1<< op, &(cpu_data[cpu].pending_ipi));
+#if 0
+ set_bit(op, &(cpu_data[cpu].pending_ipi));
+#else
+ cpu_data[cpu].pending_ipi |= 1 << op;
+#endif
- /*
- ** Just in case it's directed at ourselves, we want to make
- ** sure the interrupt doesn't get delivered until we are out
- ** of real mode again. I think it's cheaper to disable IRQ's
- ** briefly than test for it.
- */
- local_irq_disable();
+#if 0
+printk("ipi_send() CPU%d sending %d/%d to CPU%d (%lx)\n", smp_processor_id(),
+ IRQ_OFFSET(IPI_IRQ), op, cpu, cpu_data[cpu].hpa);
+#endif
+
gsc_writel(IRQ_OFFSET(IPI_IRQ), cpu_data[cpu].hpa);
- local_irq_enable();
}
static inline void
send_IPI_single(int dest_cpu, enum ipi_message_type op)
{
- if (dest_cpu == NO_PROC_ID)
+ if (dest_cpu == NO_PROC_ID) {
+ BUG();
return;
+ }
ipi_send(dest_cpu, op);
}
@@ -483,27 +497,15 @@ void __init smp_callin(unsigned long pdc
int slave_id = cpu_now_booting;
smp_cpu_init(slave_id);
-
+ current->active_mm = &init_mm;
-printk("SMP: CPU:%d CR15 %lx CR22 %lx CR23 %lx\n", slave_id,
- mfctl(15), mfctl(22), mfctl(23));
+ local_irq_enable(); /* Interrupts have been off until now */
/* Slave's wait here until Big Poppa daddy say "jump" */
mb(); /* PARANOID */
while (!smp_commenced) ;
mb(); /* PARANOID */
- local_irq_enable(); /* Interrupts have been off until now */
-
-printk("SMP: CPU:%d CR15 %lx CR22 %lx CR23 %lx\n", slave_id,
- mfctl(15), mfctl(22), mfctl(23));
-
-mdelay(300);
-/* spin_lock (&smp_lock); */
-
-printk("SMP: CPU:%d calling cpu_idle()\n", slave_id);
-mdelay(300);
-/* spin_unlock (&smp_lock); */
cpu_idle(); /* Wait for timer to schedule some work */
/* NOTREACHED */
panic("smp_callin() AAAAaaaaahhhh....\n");
@@ -571,8 +573,6 @@ STATIC int smp_boot_one_cpu(int cpuid, i
if (!idle)
panic("SMP: No idle process for CPU:%d", cpuid);
-printk("sboc: task 0x%p for %d/%d\n", idle, cpuid, cpunum);
-
__cpu_number_map[cpuid] = cpunum;
__cpu_logical_map[cpunum] = cpuid;
@@ -583,9 +583,6 @@ printk("sboc: task 0x%p for %d/%d\n", id
idle->processor = cpunum;
idle->has_cpu = 1; /* Schedule the first task manually */
-printk("sboc: CPU %d state 0x%lx flags 0x%lx\n",
- cpunum, idle->state, idle->flags);
-
/* Let _start know what logical CPU we're booting
** (offset into init_tasks[],cpu_data[])
*/
@@ -631,6 +628,8 @@ printk("sboc: CPU %d state 0x%lx flags 0
return -1;
alive:
+ __cpu_logical_map[cpunum] = cpuid;
+ __cpu_number_map[cpuid] = cpunum;
/* Remember the Slave data */
#if (kDEBUG>=100)
printk("SMP: CPU:%d (num %d) came alive after %ld _us\n",
@@ -674,13 +673,13 @@ void __init smp_boot_cpus(void)
printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor);
init_task.processor = 0;
current->processor = 0; /*These are set already*/
+ current->active_mm = &init_mm;
cpu_callin_map = 1; /* Mark Boostrap processor as present */
#ifdef ENTRY_SYS_CPUS
cpu_data[0].state = STATE_RUNNING;
#endif
- init_idle();
/* Nothing to do when told not to. */
if (max_cpus == 0) {
@@ -727,20 +726,13 @@ void __init smp_boot_cpus(void)
}
/*
- * Called from main.c by each Monarch Processor.
+ * Called from main.c by Monarch Processor.
* After this, any CPU can schedule any task.
*/
void smp_commence(void)
{
-printk("SMP: BSP before\n");
-mdelay(1000);
-
smp_commenced = 1;
mb();
-
-mdelay(10000);
-printk("SMP: BSP proceeding\n");
-mdelay(300);
return;
}