[UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure

From: Srivatsa S. Bhat
Date: Fri Jun 01 2012 - 18:48:42 EST



Convert sparc32 to use the generic framework to boot secondary CPUs.

Notes:
While removing the call to cpu_idle(), we can also remove the call to
cpu_panic() because we are calling BUG() in the generic code anyway.

Cc: "David S. Miller" <davem@xxxxxxxxxxxxx>
Cc: Sam Ravnborg <sam@xxxxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Mike Frysinger <vapier@xxxxxxxxxx>
Cc: Konrad Eisele <konrad@xxxxxxxxxxx>
Cc: Tkhai Kirill <tkhai@xxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: sparclinux@xxxxxxxxxxxxxxx
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@xxxxxxxxxxxxxxxxxx>
---

arch/sparc/kernel/leon_smp.c | 25 +++++++++++++++----------
arch/sparc/kernel/sun4d_smp.c | 26 +++++++++++++-------------
arch/sparc/kernel/sun4m_smp.c | 26 +++++++++++++++-----------
arch/sparc/kernel/trampoline_32.S | 12 ------------
4 files changed, 43 insertions(+), 46 deletions(-)

diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index a469090..498ca9b 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -25,6 +25,7 @@
#include <linux/gfp.h>
#include <linux/cpu.h>
#include <linux/clockchips.h>
+#include <linux/smpboot.h>

#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
@@ -73,13 +74,21 @@ static inline unsigned long do_swap(volatile unsigned long *ptr,

void __cpuinit leon_callin(void)
{
- int cpuid = hard_smp_processor_id();
+ smpboot_start_secondary(NULL);
+}
+
+void __cpuinit __cpu_pre_starting(void *unused)
+{
+ unsigned int cpuid = hard_smp_processor_id();

local_ops->cache_all();
local_ops->tlb_all();
leon_configure_cache_smp();
+}

- notify_cpu_starting(cpuid);
+void __cpuinit __cpu_pre_online(void *unused)
+{
+ unsigned int cpuid = hard_smp_processor_id();

/* Get our local ticker going. */
register_percpu_ce(cpuid);
@@ -91,11 +100,10 @@ void __cpuinit leon_callin(void)
local_ops->tlb_all();

/*
- * Unblock the master CPU _only_ when the scheduler state
- * of all secondary CPUs will be up-to-date, so after
- * the SMP initialization the master will be just allowed
- * to call the scheduler code.
- * Allow master to continue.
+ * Allow master to continue. The master will then give us the
+ * go-ahead by setting the smp_commenced_mask and will wait without
+ * timeouts until our setup is completed fully (signified by
+ * our bit being set in the cpu_online_mask).
*/
do_swap(&cpu_callin_map[cpuid], 1);

@@ -112,9 +120,6 @@ void __cpuinit leon_callin(void)

while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
mb();
-
- local_irq_enable();
- set_cpu_online(cpuid, true);
}

/*
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index ddaea31..cd5367a 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/cpu.h>
+#include <linux/smpboot.h>

#include <asm/cacheflush.h>
#include <asm/switch_to.h>
@@ -52,8 +53,12 @@ static inline void show_leds(int cpuid)

void __cpuinit smp4d_callin(void)
{
- int cpuid = hard_smp_processor_id();
- unsigned long flags;
+ smpboot_start_secondary(NULL);
+}
+
+void __cpuinit __cpu_pre_starting(void *unused)
+{
+ unsigned int cpuid = hard_smp_processor_id();

/* Show we are alive */
cpu_leds[cpuid] = 0x6;
@@ -64,14 +69,13 @@ void __cpuinit smp4d_callin(void)

local_ops->cache_all();
local_ops->tlb_all();
+}
+
+void __cpuinit __cpu_pre_online(void *unused)
+{
+ unsigned int cpuid = hard_smp_processor_id();
+ unsigned long flags;

- notify_cpu_starting(cpuid);
- /*
- * Unblock the master CPU _only_ when the scheduler state
- * of all secondary CPUs will be up-to-date, so after
- * the SMP initialization the master will be just allowed
- * to call the scheduler code.
- */
/* Get our local ticker going. */
register_percpu_ce(cpuid);

@@ -106,16 +110,12 @@ void __cpuinit smp4d_callin(void)
local_ops->cache_all();
local_ops->tlb_all();

- local_irq_enable(); /* We don't allow PIL 14 yet */
-
while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
barrier();

spin_lock_irqsave(&sun4d_imsk_lock, flags);
cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */
spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
- set_cpu_online(cpuid, true);
-
}

/*
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 128af73..ed05f54 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/cpu.h>
+#include <linux/smpboot.h>

#include <asm/cacheflush.h>
#include <asm/switch_to.h>
@@ -36,12 +37,20 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val)

void __cpuinit smp4m_callin(void)
{
- int cpuid = hard_smp_processor_id();
+ smpboot_start_secondary(NULL);
+}
+
+void __cpuinit __cpu_pre_starting(void *unused)
+{
+ unsigned int cpuid = hard_smp_processor_id();

local_ops->cache_all();
local_ops->tlb_all();
+}

- notify_cpu_starting(cpuid);
+void __cpuinit __cpu_pre_online(void *unused)
+{
+ unsigned int cpuid = hard_smp_processor_id();

register_percpu_ce(cpuid);

@@ -52,12 +61,11 @@ void __cpuinit smp4m_callin(void)
local_ops->tlb_all();

/*
- * Unblock the master CPU _only_ when the scheduler state
- * of all secondary CPUs will be up-to-date, so after
- * the SMP initialization the master will be just allowed
- * to call the scheduler code.
+ * Allow master to continue. The master will then give us the
+ * go-ahead by setting the smp_commenced_mask and will wait without
+ * timeouts until our setup is completed fully (signified by
+ * our bit being set in the cpu_online_mask).
*/
- /* Allow master to continue. */
swap_ulong(&cpu_callin_map[cpuid], 1);

/* XXX: What's up with all the flushes? */
@@ -75,10 +83,6 @@ void __cpuinit smp4m_callin(void)

while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
mb();
-
- local_irq_enable();
-
- set_cpu_online(cpuid, true);
}

/*
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S
index 7364ddc..75b659e 100644
--- a/arch/sparc/kernel/trampoline_32.S
+++ b/arch/sparc/kernel/trampoline_32.S
@@ -82,17 +82,9 @@ cpu3_startup:
call smp4m_callin
nop

- b,a smp_do_cpu_idle
-
.text
.align 4

-smp_do_cpu_idle:
- call cpu_idle
- mov 0, %o0
-
- call cpu_panic
- nop

/* CPUID in bootbus can be found at PA 0xff0140000 */
#define SUN4D_BOOTBUS_CPUID 0xf0140000
@@ -147,8 +139,6 @@ sun4d_cpu_startup:
call smp4d_callin
nop

- b,a smp_do_cpu_idle
-
#ifdef CONFIG_SPARC_LEON

__CPUINIT
@@ -206,6 +196,4 @@ leon_smp_cpu_startup:
call leon_callin
nop

- b,a smp_do_cpu_idle
-
#endif

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/