* [PATCH] sparc32: refactor smp boot @ 2013-02-15 15:19 Sam Ravnborg 2013-02-15 19:37 ` Srivatsa S. Bhat 2013-02-19 5:57 ` David Miller 0 siblings, 2 replies; 11+ messages in thread From: Sam Ravnborg @ 2013-02-15 15:19 UTC (permalink / raw) To: sparclinux From 1bf0fa77f722275cf7c7be0fbb80e4399f60c734 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg <sam@ravnborg.org> Date: Fri, 15 Feb 2013 15:52:06 +0100 Subject: [PATCH] sparc32: refactor smp boot Introduce a common smp_callin() function to call from trampoline_32.S. Add platform specific functions to handle the platform details. This is in preparation for a patch that will unify the smp boot stuff for all architectures. sparc32 was significantly different to warrant this patch in preparation. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Acked-by: David S. Miller <davem@davemloft.net> Cc: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com> --- Hi David. I have had this patch lingering for a long time now. Can you please apply it to sparc. Then it has hopefully hit mainline before Srivatsa re-visits the smpboot stuff. Sam arch/sparc/kernel/kernel.h | 12 +++++ arch/sparc/kernel/leon_smp.c | 33 ++++---------- arch/sparc/kernel/smp_32.c | 86 +++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/sun4d_smp.c | 29 ++++--------- arch/sparc/kernel/sun4m_smp.c | 33 ++++---------- arch/sparc/kernel/trampoline_32.S | 17 +++---- 6 files changed, 132 insertions(+), 78 deletions(-) diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 291bb5d..a702d9a 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); +/* sun4m_smp.c */ +void sun4m_cpu_pre_starting(void *arg); +void sun4m_cpu_pre_online(void *arg); + /* sun4d_irq.c */ extern spinlock_t sun4d_imsk_lock; @@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); extern void sun4d_distribute_irqs(void); extern void sun4d_free_irq(unsigned int irq, void *dev_id); +/* sun4d_smp.c */ +void sun4d_cpu_pre_starting(void *arg); +void sun4d_cpu_pre_online(void *arg); + +/* leon_smp.c */ +void leon_cpu_pre_starting(void *arg); +void leon_cpu_pre_online(void *arg); + /* head_32.S */ extern unsigned int t_nmi[]; extern unsigned int linux_trap_ipi15_sun4d[]; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 0f3fb6d..9b40c9c 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -69,31 +69,19 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, return val; } -void __cpuinit leon_callin(void) +void __cpuinit leon_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); leon_configure_cache_smp(); +} - notify_cpu_starting(cpuid); - - /* Get our local ticker going. */ - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit leon_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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); @@ -110,9 +98,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/smp_32.c b/arch/sparc/kernel/smp_32.c index 79db45e..9e7e6d7 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -20,6 +20,7 @@ #include <linux/seq_file.h> #include <linux/cache.h> #include <linux/delay.h> +#include <linux/cpu.h> #include <asm/ptrace.h> #include <linux/atomic.h> @@ -32,8 +33,10 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/cpudata.h> +#include <asm/timer.h> #include <asm/leon.h> +#include "kernel.h" #include "irq.h" volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) return ret; } +void __cpuinit arch_cpu_pre_starting(void *arg) +{ + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_starting(arg); + break; + case sun4d: + sun4d_cpu_pre_starting(arg); + break; + case sparc_leon: + leon_cpu_pre_starting(arg); + break; + default: + BUG(); + } +} + +void __cpuinit arch_cpu_pre_online(void *arg) +{ + unsigned int cpuid = hard_smp_processor_id(); + + register_percpu_ce(cpuid); + + calibrate_delay(); + smp_store_cpu_info(cpuid); + + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_online(arg); + break; + case sun4d: + sun4d_cpu_pre_online(arg); + break; + case sparc_leon: + leon_cpu_pre_online(arg); + break; + default: + BUG(); + } +} + +void __cpuinit sparc_start_secondary(void *arg) +{ + unsigned int cpu; + + /* + * SMP booting is extremely fragile in some architectures. So run + * the cpu initialization code first before anything else. + */ + arch_cpu_pre_starting(arg); + + preempt_disable(); + cpu = smp_processor_id(); + + /* Invoke the CPU_STARTING notifier callbacks */ + notify_cpu_starting(cpu); + + arch_cpu_pre_online(arg); + + /* Set the CPU in the cpu_online_mask */ + set_cpu_online(cpu, true); + + /* Enable local interrupts now */ + local_irq_enable(); + + wmb(); + cpu_idle(); + + /* We should never reach here! */ + BUG(); +} + +void __cpuinit smp_callin(void) +{ + sparc_start_secondary(NULL); +} + void smp_bogo(struct seq_file *m) { int i; diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index ddaea31..c9eb82f 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) "i" (ASI_M_CTL)); } -void __cpuinit smp4d_callin(void) +void __cpuinit sun4d_cpu_pre_starting(void *arg) { int cpuid = hard_smp_processor_id(); - unsigned long flags; /* Show we are alive */ cpu_leds[cpuid] = 0x6; @@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) /* Enable level15 interrupt, disable level14 interrupt for now */ cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4d_cpu_pre_online(void *arg) +{ + unsigned long flags; + int cpuid; - notify_cpu_starting(cpuid); - /* - * Unblock the master CPU _only_ when the scheduler state + cpuid = hard_smp_processor_id(); + + /* 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); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); - - /* Allow master to continue. */ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); local_ops->cache_all(); local_ops->tlb_all(); @@ -106,16 +99,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..8a65f15 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) return val; } -void __cpuinit smp4m_callin(void) +void __cpuinit sun4m_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); - - notify_cpu_starting(cpuid); - - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4m_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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 +64,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 af27aca..6cdb08c 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -79,18 +79,15 @@ cpu3_startup: nop /* Start this processor. */ - call smp4m_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic .text .align 4 -smp_do_cpu_idle: - call cpu_idle - mov 0, %o0 - +smp_panic: call cpu_panic nop @@ -144,10 +141,10 @@ sun4d_cpu_startup: nop /* Start this processor. */ - call smp4d_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic __CPUINIT .align 4 @@ -201,7 +198,7 @@ leon_smp_cpu_startup: nop /* Start this processor. */ - call leon_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic -- 1.6.0.6 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] sparc32: refactor smp boot 2013-02-15 15:19 [PATCH] sparc32: refactor smp boot Sam Ravnborg @ 2013-02-15 19:37 ` Srivatsa S. Bhat 2013-02-19 5:57 ` David Miller 1 sibling, 0 replies; 11+ messages in thread From: Srivatsa S. Bhat @ 2013-02-15 19:37 UTC (permalink / raw) To: sparclinux On 02/15/2013 08:49 PM, Sam Ravnborg wrote: > From 1bf0fa77f722275cf7c7be0fbb80e4399f60c734 Mon Sep 17 00:00:00 2001 > From: Sam Ravnborg <sam@ravnborg.org> > Date: Fri, 15 Feb 2013 15:52:06 +0100 > Subject: [PATCH] sparc32: refactor smp boot > > Introduce a common smp_callin() function to call > from trampoline_32.S. > Add platform specific functions to handle the > platform details. > > This is in preparation for a patch that will > unify the smp boot stuff for all architectures. > sparc32 was significantly different to warrant > this patch in preparation. > > Signed-off-by: Sam Ravnborg <sam@ravnborg.org> > Acked-by: David S. Miller <davem@davemloft.net> > Cc: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com> > --- > > Hi David. > > I have had this patch lingering for a long time now. > Can you please apply it to sparc. > > Then it has hopefully hit mainline before Srivatsa re-visits > the smpboot stuff. > Hey Sam, Thanks a lot for following up with this! I really appreciate your work on making it easier to convert sparc to a common smpboot infrastructure. Thank you! Acked-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Regards, Srivatsa S. Bhat > Sam > > > arch/sparc/kernel/kernel.h | 12 +++++ > arch/sparc/kernel/leon_smp.c | 33 ++++---------- > arch/sparc/kernel/smp_32.c | 86 +++++++++++++++++++++++++++++++++++++ > arch/sparc/kernel/sun4d_smp.c | 29 ++++--------- > arch/sparc/kernel/sun4m_smp.c | 33 ++++---------- > arch/sparc/kernel/trampoline_32.S | 17 +++---- > 6 files changed, 132 insertions(+), 78 deletions(-) > > diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h > index 291bb5d..a702d9a 100644 > --- a/arch/sparc/kernel/kernel.h > +++ b/arch/sparc/kernel/kernel.h > @@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); > extern void sun4m_unmask_profile_irq(void); > extern void sun4m_clear_profile_irq(int cpu); > > +/* sun4m_smp.c */ > +void sun4m_cpu_pre_starting(void *arg); > +void sun4m_cpu_pre_online(void *arg); > + > /* sun4d_irq.c */ > extern spinlock_t sun4d_imsk_lock; > > @@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); > extern void sun4d_distribute_irqs(void); > extern void sun4d_free_irq(unsigned int irq, void *dev_id); > > +/* sun4d_smp.c */ > +void sun4d_cpu_pre_starting(void *arg); > +void sun4d_cpu_pre_online(void *arg); > + > +/* leon_smp.c */ > +void leon_cpu_pre_starting(void *arg); > +void leon_cpu_pre_online(void *arg); > + > /* head_32.S */ > extern unsigned int t_nmi[]; > extern unsigned int linux_trap_ipi15_sun4d[]; > diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c > index 0f3fb6d..9b40c9c 100644 > --- a/arch/sparc/kernel/leon_smp.c > +++ b/arch/sparc/kernel/leon_smp.c > @@ -69,31 +69,19 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, > return val; > } > > -void __cpuinit leon_callin(void) > +void __cpuinit leon_cpu_pre_starting(void *arg) > { > - int cpuid = hard_smp_processor_id(); > - > - local_ops->cache_all(); > - local_ops->tlb_all(); > leon_configure_cache_smp(); > +} > > - notify_cpu_starting(cpuid); > - > - /* Get our local ticker going. */ > - register_percpu_ce(cpuid); > - > - calibrate_delay(); > - smp_store_cpu_info(cpuid); > - > - local_ops->cache_all(); > - local_ops->tlb_all(); > +void __cpuinit leon_cpu_pre_online(void *arg) > +{ > + int cpuid = hard_smp_processor_id(); > > - /* > - * 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); > > @@ -110,9 +98,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/smp_32.c b/arch/sparc/kernel/smp_32.c > index 79db45e..9e7e6d7 100644 > --- a/arch/sparc/kernel/smp_32.c > +++ b/arch/sparc/kernel/smp_32.c > @@ -20,6 +20,7 @@ > #include <linux/seq_file.h> > #include <linux/cache.h> > #include <linux/delay.h> > +#include <linux/cpu.h> > > #include <asm/ptrace.h> > #include <linux/atomic.h> > @@ -32,8 +33,10 @@ > #include <asm/cacheflush.h> > #include <asm/tlbflush.h> > #include <asm/cpudata.h> > +#include <asm/timer.h> > #include <asm/leon.h> > > +#include "kernel.h" > #include "irq.h" > > volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; > @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) > return ret; > } > > +void __cpuinit arch_cpu_pre_starting(void *arg) > +{ > + local_ops->cache_all(); > + local_ops->tlb_all(); > + > + switch(sparc_cpu_model) { > + case sun4m: > + sun4m_cpu_pre_starting(arg); > + break; > + case sun4d: > + sun4d_cpu_pre_starting(arg); > + break; > + case sparc_leon: > + leon_cpu_pre_starting(arg); > + break; > + default: > + BUG(); > + } > +} > + > +void __cpuinit arch_cpu_pre_online(void *arg) > +{ > + unsigned int cpuid = hard_smp_processor_id(); > + > + register_percpu_ce(cpuid); > + > + calibrate_delay(); > + smp_store_cpu_info(cpuid); > + > + local_ops->cache_all(); > + local_ops->tlb_all(); > + > + switch(sparc_cpu_model) { > + case sun4m: > + sun4m_cpu_pre_online(arg); > + break; > + case sun4d: > + sun4d_cpu_pre_online(arg); > + break; > + case sparc_leon: > + leon_cpu_pre_online(arg); > + break; > + default: > + BUG(); > + } > +} > + > +void __cpuinit sparc_start_secondary(void *arg) > +{ > + unsigned int cpu; > + > + /* > + * SMP booting is extremely fragile in some architectures. So run > + * the cpu initialization code first before anything else. > + */ > + arch_cpu_pre_starting(arg); > + > + preempt_disable(); > + cpu = smp_processor_id(); > + > + /* Invoke the CPU_STARTING notifier callbacks */ > + notify_cpu_starting(cpu); > + > + arch_cpu_pre_online(arg); > + > + /* Set the CPU in the cpu_online_mask */ > + set_cpu_online(cpu, true); > + > + /* Enable local interrupts now */ > + local_irq_enable(); > + > + wmb(); > + cpu_idle(); > + > + /* We should never reach here! */ > + BUG(); > +} > + > +void __cpuinit smp_callin(void) > +{ > + sparc_start_secondary(NULL); > +} > + > void smp_bogo(struct seq_file *m) > { > int i; > diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c > index ddaea31..c9eb82f 100644 > --- a/arch/sparc/kernel/sun4d_smp.c > +++ b/arch/sparc/kernel/sun4d_smp.c > @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) > "i" (ASI_M_CTL)); > } > > -void __cpuinit smp4d_callin(void) > +void __cpuinit sun4d_cpu_pre_starting(void *arg) > { > int cpuid = hard_smp_processor_id(); > - unsigned long flags; > > /* Show we are alive */ > cpu_leds[cpuid] = 0x6; > @@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) > > /* Enable level15 interrupt, disable level14 interrupt for now */ > cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); > +} > > - local_ops->cache_all(); > - local_ops->tlb_all(); > +void __cpuinit sun4d_cpu_pre_online(void *arg) > +{ > + unsigned long flags; > + int cpuid; > > - notify_cpu_starting(cpuid); > - /* > - * Unblock the master CPU _only_ when the scheduler state > + cpuid = hard_smp_processor_id(); > + > + /* 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); > - > - calibrate_delay(); > - smp_store_cpu_info(cpuid); > - local_ops->cache_all(); > - local_ops->tlb_all(); > - > - /* Allow master to continue. */ > sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); > local_ops->cache_all(); > local_ops->tlb_all(); > @@ -106,16 +99,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..8a65f15 100644 > --- a/arch/sparc/kernel/sun4m_smp.c > +++ b/arch/sparc/kernel/sun4m_smp.c > @@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) > return val; > } > > -void __cpuinit smp4m_callin(void) > +void __cpuinit sun4m_cpu_pre_starting(void *arg) > { > - int cpuid = hard_smp_processor_id(); > - > - local_ops->cache_all(); > - local_ops->tlb_all(); > - > - notify_cpu_starting(cpuid); > - > - register_percpu_ce(cpuid); > - > - calibrate_delay(); > - smp_store_cpu_info(cpuid); > +} > > - local_ops->cache_all(); > - local_ops->tlb_all(); > +void __cpuinit sun4m_cpu_pre_online(void *arg) > +{ > + int cpuid = hard_smp_processor_id(); > > - /* > - * 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 +64,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 af27aca..6cdb08c 100644 > --- a/arch/sparc/kernel/trampoline_32.S > +++ b/arch/sparc/kernel/trampoline_32.S > @@ -79,18 +79,15 @@ cpu3_startup: > nop > > /* Start this processor. */ > - call smp4m_callin > + call smp_callin > nop > > - b,a smp_do_cpu_idle > + b,a smp_panic > > .text > .align 4 > > -smp_do_cpu_idle: > - call cpu_idle > - mov 0, %o0 > - > +smp_panic: > call cpu_panic > nop > > @@ -144,10 +141,10 @@ sun4d_cpu_startup: > nop > > /* Start this processor. */ > - call smp4d_callin > + call smp_callin > nop > > - b,a smp_do_cpu_idle > + b,a smp_panic > > __CPUINIT > .align 4 > @@ -201,7 +198,7 @@ leon_smp_cpu_startup: > nop > > /* Start this processor. */ > - call leon_callin > + call smp_callin > nop > > - b,a smp_do_cpu_idle > + b,a smp_panic > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sparc32: refactor smp boot 2013-02-15 15:19 [PATCH] sparc32: refactor smp boot Sam Ravnborg 2013-02-15 19:37 ` Srivatsa S. Bhat @ 2013-02-19 5:57 ` David Miller 1 sibling, 0 replies; 11+ messages in thread From: David Miller @ 2013-02-19 5:57 UTC (permalink / raw) To: sparclinux From: Sam Ravnborg <sam@ravnborg.org> Date: Fri, 15 Feb 2013 16:19:39 +0100 > I have had this patch lingering for a long time now. > Can you please apply it to sparc. I will toss it into sparc-next for this merge window when I get a chance, thanks Sam. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure
@ 2012-06-01 17:56 David Miller
2012-06-01 18:54 ` Sam Ravnborg
0 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2012-06-01 17:56 UTC (permalink / raw)
To: srivatsa.bhat
Cc: tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa,
rjw, linux-arch, linux-kernel, nikunj, sam, vapier, konrad, tkhai,
sparclinux
From: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>
Date: Fri, 01 Jun 2012 14:45:09 +0530
> smp_do_cpu_idle:
> - call cpu_idle
> mov 0, %o0
Just like the sparc64 patch, you need to remove the 'mov'
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-01 17:56 [PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure David Miller @ 2012-06-01 18:54 ` Sam Ravnborg 2012-06-01 22:47 ` [UPDATED PATCH " Srivatsa S. Bhat 0 siblings, 1 reply; 11+ messages in thread From: Sam Ravnborg @ 2012-06-01 18:54 UTC (permalink / raw) To: David Miller Cc: srivatsa.bhat, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux On Fri, Jun 01, 2012 at 01:56:12PM -0400, David Miller wrote: > From: "Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com> > Date: Fri, 01 Jun 2012 14:45:09 +0530 > > > smp_do_cpu_idle: > > - call cpu_idle > > mov 0, %o0 > > Just like the sparc64 patch, you need to remove the 'mov' And the other callers of cpu_idle in the same file should be updated/removed too. There is one for sun4m, sun4d and leon. Sam ^ permalink raw reply [flat|nested] 11+ messages in thread
* [UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-01 18:54 ` Sam Ravnborg @ 2012-06-01 22:47 ` Srivatsa S. Bhat 2012-06-02 6:52 ` Sam Ravnborg 0 siblings, 1 reply; 11+ messages in thread From: Srivatsa S. Bhat @ 2012-06-01 22:47 UTC (permalink / raw) To: David Miller Cc: Sam Ravnborg, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux 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@davemloft.net> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Mike Frysinger <vapier@gentoo.org> Cc: Konrad Eisele <konrad@gaisler.com> Cc: Tkhai Kirill <tkhai@yandex.ru> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: sparclinux@vger.kernel.org Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> --- 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 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-01 22:47 ` [UPDATED PATCH " Srivatsa S. Bhat @ 2012-06-02 6:52 ` Sam Ravnborg 2012-06-02 7:44 ` Sam Ravnborg 0 siblings, 1 reply; 11+ messages in thread From: Sam Ravnborg @ 2012-06-02 6:52 UTC (permalink / raw) To: Srivatsa S. Bhat Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux Hi Srivatsa. I cannot see how this would work for sparc32... [Did not notice before...] > --- a/arch/sparc/kernel/leon_smp.c > +++ b/arch/sparc/kernel/leon_smp.c > +void __cpuinit __cpu_pre_starting(void *unused) > +{ > + unsigned int cpuid = hard_smp_processor_id(); > > 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 > +void __cpuinit __cpu_pre_starting(void *unused) > +{ > + unsigned int cpuid = hard_smp_processor_id(); > > 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 > +void __cpuinit __cpu_pre_starting(void *unused) > +{ > + unsigned int cpuid = hard_smp_processor_id(); See how you define a function with the same name three times. On sparc32 we include all of the above files in the kernel, and uses various tricks to determine at run-time which variant to use. We need to define these general functions in smp_32.c and then take relevant action depending on sparc_cpu_model. Sam ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-02 6:52 ` Sam Ravnborg @ 2012-06-02 7:44 ` Sam Ravnborg 2012-06-02 8:01 ` Srivatsa S. Bhat 0 siblings, 1 reply; 11+ messages in thread From: Sam Ravnborg @ 2012-06-02 7:44 UTC (permalink / raw) To: Srivatsa S. Bhat Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux On Sat, Jun 02, 2012 at 08:52:49AM +0200, Sam Ravnborg wrote: > Hi Srivatsa. > > I cannot see how this would work for sparc32... > [Did not notice before...] > > > --- a/arch/sparc/kernel/leon_smp.c > > +++ b/arch/sparc/kernel/leon_smp.c > > > +void __cpuinit __cpu_pre_starting(void *unused) > > +{ > > + unsigned int cpuid = hard_smp_processor_id(); > > > > 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 > > > +void __cpuinit __cpu_pre_starting(void *unused) > > +{ > > + unsigned int cpuid = hard_smp_processor_id(); > > > > 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 > > > +void __cpuinit __cpu_pre_starting(void *unused) > > +{ > > + unsigned int cpuid = hard_smp_processor_id(); > > See how you define a function with the same name three times. > On sparc32 we include all of the above files in the kernel, > and uses various tricks to determine at run-time > which variant to use. > > We need to define these general functions in smp_32.c and > then take relevant action depending on sparc_cpu_model. I took a short look at this. And it is a bit complicated :-( leon is the odd-one here. For reasons I do not understand we have a call from head_32.S to leon_smp_cpu_startup: in trampoline_32.S. But sun4m and sun4d uses the normal path via start_kernel() etc. This has the side-effect that sparc_cpu_model is not set when we call leon_smp_cpu_startup. I will try to dive into this and see if I on the sparc32 side can make leon behave like the other platforms, and then unify some of the smp cpu boot stuff such that we then can introduce the generalization from your patch. Sam ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-02 7:44 ` Sam Ravnborg @ 2012-06-02 8:01 ` Srivatsa S. Bhat 2012-06-02 15:13 ` Sam Ravnborg 0 siblings, 1 reply; 11+ messages in thread From: Srivatsa S. Bhat @ 2012-06-02 8:01 UTC (permalink / raw) To: Sam Ravnborg Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux On 06/02/2012 01:14 PM, Sam Ravnborg wrote: > On Sat, Jun 02, 2012 at 08:52:49AM +0200, Sam Ravnborg wrote: >> Hi Srivatsa. >> >> I cannot see how this would work for sparc32... >> [Did not notice before...] >> >>> --- a/arch/sparc/kernel/leon_smp.c >>> +++ b/arch/sparc/kernel/leon_smp.c >> >>> +void __cpuinit __cpu_pre_starting(void *unused) >>> +{ >>> + unsigned int cpuid = hard_smp_processor_id(); >>> >>> 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 >> >>> +void __cpuinit __cpu_pre_starting(void *unused) >>> +{ >>> + unsigned int cpuid = hard_smp_processor_id(); >>> >>> 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 >> >>> +void __cpuinit __cpu_pre_starting(void *unused) >>> +{ >>> + unsigned int cpuid = hard_smp_processor_id(); >> >> See how you define a function with the same name three times. >> On sparc32 we include all of the above files in the kernel, >> and uses various tricks to determine at run-time >> which variant to use. >> >> We need to define these general functions in smp_32.c and >> then take relevant action depending on sparc_cpu_model. > > I took a short look at this. > And it is a bit complicated :-( > > leon is the odd-one here. For reasons I do not understand > we have a call from head_32.S to leon_smp_cpu_startup: > in trampoline_32.S. > > But sun4m and sun4d uses the normal path via start_kernel() etc. > > This has the side-effect that sparc_cpu_model is not set > when we call leon_smp_cpu_startup. > Yes, I saw that too now.. > I will try to dive into this and see if I on the sparc32 side > can make leon behave like the other platforms, and then > unify some of the smp cpu boot stuff such that we then > can introduce the generalization from your patch. > Thanks a lot for that Sam! Regards, Srivatsa S. Bhat ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-02 8:01 ` Srivatsa S. Bhat @ 2012-06-02 15:13 ` Sam Ravnborg 2012-06-02 15:58 ` Srivatsa S. Bhat 0 siblings, 1 reply; 11+ messages in thread From: Sam Ravnborg @ 2012-06-02 15:13 UTC (permalink / raw) To: Srivatsa S. Bhat Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux > > > I will try to dive into this and see if I on the sparc32 side > > can make leon behave like the other platforms, and then > > unify some of the smp cpu boot stuff such that we then > > can introduce the generalization from your patch. This is what I came up with. I modelled this over your patch-set to make it simpler to convert to the generic scheme. I realised a bit more how CPU's are started up on sparc32. So I think all of leon, sun4m and sun4d should work with this. But my SUN box is defunct atm. so I have not tested it. Comments appreciated! PS. I used the ugly __names for now. As soon as you have found a better set of names this should be fixed here too. Sam diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 291bb5d..2bc1c6d 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); +/* sun4m_smp.c */ +void sun4m_cpu_pre_starting(void); +void sun4m_cpu_pre_online(void); + /* sun4d_irq.c */ extern spinlock_t sun4d_imsk_lock; @@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); extern void sun4d_distribute_irqs(void); extern void sun4d_free_irq(unsigned int irq, void *dev_id); +/* sun4d_smp.c */ +void sun4d_cpu_pre_starting(void); +void sun4d_cpu_pre_online(void); + +/* leon_smp.c */ +void leon_cpu_pre_starting(void); +void leon_cpu_pre_online(void); + /* head_32.S */ extern unsigned int t_nmi[]; extern unsigned int linux_trap_ipi15_sun4d[]; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 0f3fb6d..0b028b3 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -69,31 +69,20 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, return val; } -void __cpuinit leon_callin(void) +void __cpuinit leon_cpu_pre_starting(void) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); leon_configure_cache_smp(); +} - notify_cpu_starting(cpuid); - - /* Get our local ticker going. */ - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit cpu_cpu_pre_starting(void *unused) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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); @@ -110,9 +99,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/smp_32.c b/arch/sparc/kernel/smp_32.c index 79db45e..2e2990f 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -20,6 +20,7 @@ #include <linux/seq_file.h> #include <linux/cache.h> #include <linux/delay.h> +#include <linux/cpu.h> #include <asm/ptrace.h> #include <linux/atomic.h> @@ -32,8 +33,10 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/cpudata.h> +#include <asm/timer.h> #include <asm/leon.h> +#include "kernel.h" #include "irq.h" volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) return ret; } +void __cpuinit __cpu_pre_starting(void *unused) +{ + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_starting(); + break; + case sun4d: + sun4d_cpu_pre_starting(); + break; + case sparc_leon: + leon_cpu_pre_starting(); + break; + default: + BUG(); + } +} + +void __cpuinit __cpu_pre_online(void *unused) +{ + unsigned int cpuid = hard_smp_processor_id(); + + register_percpu_ce(cpuid); + + calibrate_delay(); + smp_store_cpu_info(cpuid); + + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_online(); + break; + case sun4d: + sun4d_cpu_pre_online(); + break; + case sparc_leon: + leon_cpu_pre_starting(); + break; + default: + BUG(); + } +} + +void __cpuinit sparc_start_secondary(void *unused) +{ + unsigned int cpu; + + /* + * SMP booting is extremely fragile in some architectures. So run + * the cpu initialization code first before anything else. + */ + __cpu_pre_starting(NULL); + + preempt_disable(); + cpu = smp_processor_id(); + + /* Invoke the CPU_STARTING notifier callbacks */ + notify_cpu_starting(cpu); + + __cpu_pre_online(NULL); + + /* Set the CPU in the cpu_online_mask */ + set_cpu_online(cpu, true); + + /* Enable local interrupts now */ + local_irq_enable(); + + wmb(); + cpu_idle(); + + /* We should never reach here! */ + BUG(); +} + +void __cpuinit smp_callin(void) +{ + sparc_start_secondary(NULL); +} + void smp_bogo(struct seq_file *m) { int i; diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index ddaea31..bfbbc46 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) "i" (ASI_M_CTL)); } -void __cpuinit smp4d_callin(void) +void __cpuinit sun4d_cpu_pre_starting(void) { int cpuid = hard_smp_processor_id(); - unsigned long flags; /* Show we are alive */ cpu_leds[cpuid] = 0x6; @@ -61,24 +60,14 @@ void __cpuinit smp4d_callin(void) /* Enable level15 interrupt, disable level14 interrupt for now */ cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); +} - local_ops->cache_all(); - local_ops->tlb_all(); - - 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); +void __cpuinit sun4d_cpu_pre_online(void) +{ + unsigned long flags; + int cpuid; - calibrate_delay(); - smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); + cpuid = hard_smp_processor_id(); /* Allow master to continue. */ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); @@ -106,16 +95,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..0cf6b4f 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) return val; } -void __cpuinit smp4m_callin(void) +void __cpuinit sun4m_cpu_pre_starting(void) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); - - notify_cpu_starting(cpuid); - - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4m_cpu_pre_online(void) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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 +64,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 af27aca..6cdb08c 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -79,18 +79,15 @@ cpu3_startup: nop /* Start this processor. */ - call smp4m_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic .text .align 4 -smp_do_cpu_idle: - call cpu_idle - mov 0, %o0 - +smp_panic: call cpu_panic nop @@ -144,10 +141,10 @@ sun4d_cpu_startup: nop /* Start this processor. */ - call smp4d_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic __CPUINIT .align 4 @@ -201,7 +198,7 @@ leon_smp_cpu_startup: nop /* Start this processor. */ - call leon_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-02 15:13 ` Sam Ravnborg @ 2012-06-02 15:58 ` Srivatsa S. Bhat 2012-06-02 16:23 ` Sam Ravnborg 0 siblings, 1 reply; 11+ messages in thread From: Srivatsa S. Bhat @ 2012-06-02 15:58 UTC (permalink / raw) To: Sam Ravnborg Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux On 06/02/2012 08:43 PM, Sam Ravnborg wrote: >> >>> I will try to dive into this and see if I on the sparc32 side >>> can make leon behave like the other platforms, and then >>> unify some of the smp cpu boot stuff such that we then >>> can introduce the generalization from your patch. > > This is what I came up with. > I modelled this over your patch-set to make it > simpler to convert to the generic scheme. > Thanks a lot for doing this :-) > I realised a bit more how CPU's are started up on sparc32. > So I think all of leon, sun4m and sun4d should work with this. > > But my SUN box is defunct atm. so I have not tested it. > Comments appreciated! > > PS. I used the ugly __names for now. > As soon as you have found a better set of names this should > be fixed here too. > As I mentioned in my other mail, I am thinking of changing them to arch_cpu_pre_starting(), arch_cpu_pre_online() and arch_cpu_post_online(). Let me know what you think of those names. Would you kindly add a changelog and your sign-off to this patch? > > diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h > index 291bb5d..2bc1c6d 100644 > --- a/arch/sparc/kernel/kernel.h > +++ b/arch/sparc/kernel/kernel.h > @@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); > extern void sun4m_unmask_profile_irq(void); > extern void sun4m_clear_profile_irq(int cpu); > > +/* sun4m_smp.c */ > +void sun4m_cpu_pre_starting(void); > +void sun4m_cpu_pre_online(void); > + > /* sun4d_irq.c */ > extern spinlock_t sun4d_imsk_lock; > > @@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); > extern void sun4d_distribute_irqs(void); > extern void sun4d_free_irq(unsigned int irq, void *dev_id); > > +/* sun4d_smp.c */ > +void sun4d_cpu_pre_starting(void); > +void sun4d_cpu_pre_online(void); > + > +/* leon_smp.c */ > +void leon_cpu_pre_starting(void); > +void leon_cpu_pre_online(void); > + > /* head_32.S */ > extern unsigned int t_nmi[]; > extern unsigned int linux_trap_ipi15_sun4d[]; > diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c > index 0f3fb6d..0b028b3 100644 > --- a/arch/sparc/kernel/leon_smp.c > +++ b/arch/sparc/kernel/leon_smp.c > @@ -69,31 +69,20 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, > return val; > } > > -void __cpuinit leon_callin(void) > +void __cpuinit leon_cpu_pre_starting(void) > { > - int cpuid = hard_smp_processor_id(); > - > - local_ops->cache_all(); > - local_ops->tlb_all(); > leon_configure_cache_smp(); > +} > > - notify_cpu_starting(cpuid); > - > - /* Get our local ticker going. */ > - register_percpu_ce(cpuid); > - > - calibrate_delay(); > - smp_store_cpu_info(cpuid); > > - local_ops->cache_all(); > - local_ops->tlb_all(); > +void __cpuinit cpu_cpu_pre_starting(void *unused) Shouldn't this be leon_cpu_pre_online()? And the parameters should be consistent too (here it expects a void*, but it is called with no arguments...) > +{ > + int cpuid = hard_smp_processor_id(); > > - /* > - * 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); > > @@ -110,9 +99,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/smp_32.c b/arch/sparc/kernel/smp_32.c > index 79db45e..2e2990f 100644 > --- a/arch/sparc/kernel/smp_32.c > +++ b/arch/sparc/kernel/smp_32.c > @@ -20,6 +20,7 @@ > #include <linux/seq_file.h> > #include <linux/cache.h> > #include <linux/delay.h> > +#include <linux/cpu.h> > > #include <asm/ptrace.h> > #include <linux/atomic.h> > @@ -32,8 +33,10 @@ > #include <asm/cacheflush.h> > #include <asm/tlbflush.h> > #include <asm/cpudata.h> > +#include <asm/timer.h> > #include <asm/leon.h> > > +#include "kernel.h" > #include "irq.h" > > volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; > @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) > return ret; > } > > +void __cpuinit __cpu_pre_starting(void *unused) > +{ > + local_ops->cache_all(); > + local_ops->tlb_all(); > + > + switch(sparc_cpu_model) { > + case sun4m: > + sun4m_cpu_pre_starting(); Wouldn't it be better to have a provision to pass the pointer down to these functions as well? > + break; > + case sun4d: > + sun4d_cpu_pre_starting(); > + break; > + case sparc_leon: > + leon_cpu_pre_starting(); > + break; > + default: > + BUG(); > + } > +} > + > +void __cpuinit __cpu_pre_online(void *unused) > +{ > + unsigned int cpuid = hard_smp_processor_id(); > + > + register_percpu_ce(cpuid); > + > + calibrate_delay(); > + smp_store_cpu_info(cpuid); > + > + local_ops->cache_all(); > + local_ops->tlb_all(); > + > + switch(sparc_cpu_model) { > + case sun4m: > + sun4m_cpu_pre_online(); > + break; > + case sun4d: > + sun4d_cpu_pre_online(); > + break; > + case sparc_leon: > + leon_cpu_pre_starting(); Shouldn't this be leon_cpu_pre_online()? > + break; > + default: > + BUG(); > + } > +} > + > +void __cpuinit sparc_start_secondary(void *unused) > +{ > + unsigned int cpu; > + > + /* > + * SMP booting is extremely fragile in some architectures. So run > + * the cpu initialization code first before anything else. > + */ > + __cpu_pre_starting(NULL); > + Why not pass the pointer to __cpu_pre_starting() as well as the rest of the functions? > + preempt_disable(); > + cpu = smp_processor_id(); > + > + /* Invoke the CPU_STARTING notifier callbacks */ > + notify_cpu_starting(cpu); > + > + __cpu_pre_online(NULL); > + > + /* Set the CPU in the cpu_online_mask */ > + set_cpu_online(cpu, true); > + > + /* Enable local interrupts now */ > + local_irq_enable(); > + > + wmb(); > + cpu_idle(); > + > + /* We should never reach here! */ > + BUG(); > +} > + > +void __cpuinit smp_callin(void) > +{ > + sparc_start_secondary(NULL); > +} > + > void smp_bogo(struct seq_file *m) > { > int i; > diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c > index ddaea31..bfbbc46 100644 > --- a/arch/sparc/kernel/sun4d_smp.c > +++ b/arch/sparc/kernel/sun4d_smp.c > @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) > "i" (ASI_M_CTL)); > } > > -void __cpuinit smp4d_callin(void) > +void __cpuinit sun4d_cpu_pre_starting(void) > { > int cpuid = hard_smp_processor_id(); > - unsigned long flags; > > /* Show we are alive */ > cpu_leds[cpuid] = 0x6; > @@ -61,24 +60,14 @@ void __cpuinit smp4d_callin(void) > > /* Enable level15 interrupt, disable level14 interrupt for now */ > cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); > +} > > - local_ops->cache_all(); > - local_ops->tlb_all(); > - > - 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); > +void __cpuinit sun4d_cpu_pre_online(void) > +{ > + unsigned long flags; > + int cpuid; > > - calibrate_delay(); > - smp_store_cpu_info(cpuid); > - local_ops->cache_all(); > - local_ops->tlb_all(); > + cpuid = hard_smp_processor_id(); > > /* Allow master to continue. */ > sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); > @@ -106,16 +95,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..0cf6b4f 100644 > --- a/arch/sparc/kernel/sun4m_smp.c > +++ b/arch/sparc/kernel/sun4m_smp.c > @@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) > return val; > } > > -void __cpuinit smp4m_callin(void) > +void __cpuinit sun4m_cpu_pre_starting(void) > { > - int cpuid = hard_smp_processor_id(); > - > - local_ops->cache_all(); > - local_ops->tlb_all(); > - > - notify_cpu_starting(cpuid); > - > - register_percpu_ce(cpuid); > - > - calibrate_delay(); > - smp_store_cpu_info(cpuid); > +} > > - local_ops->cache_all(); > - local_ops->tlb_all(); > +void __cpuinit sun4m_cpu_pre_online(void) > +{ > + int cpuid = hard_smp_processor_id(); > > - /* > - * 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 +64,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 af27aca..6cdb08c 100644 > --- a/arch/sparc/kernel/trampoline_32.S > +++ b/arch/sparc/kernel/trampoline_32.S > @@ -79,18 +79,15 @@ cpu3_startup: > nop > > /* Start this processor. */ > - call smp4m_callin > + call smp_callin > nop > > - b,a smp_do_cpu_idle > + b,a smp_panic > > .text > .align 4 > > -smp_do_cpu_idle: > - call cpu_idle > - mov 0, %o0 > - > +smp_panic: > call cpu_panic > nop > > @@ -144,10 +141,10 @@ sun4d_cpu_startup: > nop > > /* Start this processor. */ > - call smp4d_callin > + call smp_callin > nop > > - b,a smp_do_cpu_idle > + b,a smp_panic > > __CPUINIT > .align 4 > @@ -201,7 +198,7 @@ leon_smp_cpu_startup: > nop > > /* Start this processor. */ > - call leon_callin > + call smp_callin I still didn't get how this solves the original problem of not having sparc_cpu_model set to sparc_leon. You mentioned that by the time we reach leon_smp_cpu_startup, that variable is not set. Even inside leon_smp_cpu_startup, I don't immediately see where it is set. Am I missing something? > nop > > - b,a smp_do_cpu_idle > + b,a smp_panic > Regards, Srivatsa S. Bhat ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-02 15:58 ` Srivatsa S. Bhat @ 2012-06-02 16:23 ` Sam Ravnborg 2012-06-02 16:34 ` Srivatsa S. Bhat 0 siblings, 1 reply; 11+ messages in thread From: Sam Ravnborg @ 2012-06-02 16:23 UTC (permalink / raw) To: Srivatsa S. Bhat Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux > > As I mentioned in my other mail, I am thinking of changing them to > arch_cpu_pre_starting(), arch_cpu_pre_online() and arch_cpu_post_online(). > Let me know what you think of those names. Much better than "__" - so if none of the guys that excel in core code objects go for that. > Would you kindly add a changelog and your sign-off to this patch? Will do in next revision. ... Thanks for the throughfull review. I will address all points - including passing the pointer down, as I assume you have some future plans with that pointer. > > I still didn't get how this solves the original problem of > not having sparc_cpu_model set to sparc_leon. You mentioned > that by the time we reach leon_smp_cpu_startup, that variable > is not set. Even inside leon_smp_cpu_startup, I don't immediately > see where it is set. Am I missing something? After looking more closely at the code it is my understanding that a leon CPU when started will actually jump to the reset vector and start from there. So the secondary CPU's will run long time after sparc_cpu_model is set so we can safely use it. The sun based cpu will in comparsion jump to an address supplied to a prom call - so they do not jump to the reset vector. But they also have sparc_cpu_model set so no problem there either. All this are my deductions from reading the code - but this is not an area I have looked at otherwise.. I may not find time today to cook up a new version of the patch - but then you will have it tomorrow. Sam ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [UPDATED PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure 2012-06-02 16:23 ` Sam Ravnborg @ 2012-06-02 16:34 ` Srivatsa S. Bhat 2012-06-03 21:17 ` Sam Ravnborg 0 siblings, 1 reply; 11+ messages in thread From: Srivatsa S. Bhat @ 2012-06-02 16:34 UTC (permalink / raw) To: Sam Ravnborg Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux On 06/02/2012 09:53 PM, Sam Ravnborg wrote: >> >> As I mentioned in my other mail, I am thinking of changing them to >> arch_cpu_pre_starting(), arch_cpu_pre_online() and arch_cpu_post_online(). >> Let me know what you think of those names. > Much better than "__" - so if none of the guys that excel in core > code objects go for that. > Ok.. >> Would you kindly add a changelog and your sign-off to this patch? > Will do in next revision. > Great! > ... > > Thanks for the throughfull review. > I will address all points - including passing the pointer down, > as I assume you have some future plans with that pointer. > >> >> I still didn't get how this solves the original problem of >> not having sparc_cpu_model set to sparc_leon. You mentioned >> that by the time we reach leon_smp_cpu_startup, that variable >> is not set. Even inside leon_smp_cpu_startup, I don't immediately >> see where it is set. Am I missing something? > > After looking more closely at the code it is my understanding > that a leon CPU when started will actually jump to the reset > vector and start from there. > So the secondary CPU's will run long time after > sparc_cpu_model is set so we can safely use it. > > The sun based cpu will in comparsion jump to > an address supplied to a prom call - so they do not > jump to the reset vector. > But they also have sparc_cpu_model set so no problem there > either. > Ok.. > All this are my deductions from reading the code - but this > is not an area I have looked at otherwise.. > > I may not find time today to cook up a new version of > the patch - but then you will have it tomorrow. > Sure! Once again, thanks a lot for your time and efforts :-) Regards, Srivatsa S. Bhat ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] sparc32: refactor smp boot @ 2012-06-03 21:17 ` Sam Ravnborg 0 siblings, 0 replies; 11+ messages in thread From: Sam Ravnborg @ 2012-06-03 21:17 UTC (permalink / raw) To: Srivatsa S. Bhat Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux From 531d9c538fc60c15363890768ea416897853d6af Mon Sep 17 00:00:00 2001 From: Sam Ravnborg <sam@ravnborg.org> Date: Sun, 3 Jun 2012 23:08:18 +0200 Subject: [PATCH] sparc32: refactor smp boot Introduce a common smp_callin() function to call from trampoline_32.S. Add platform specific functions to handle the platform details. This is in preparation for a patch that will unify the smp boot stuff for all architectures. sparc32 was significantly different to warrant this patch in preparation. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> --- Hi Srivatsa. This should address all your comemnts (thanks!). I assume you will include this patch in your serie. @davem: please ack this patch (if it is OK that is) Note: It has not seen much testing. But I have tried to review it carefully. Sam arch/sparc/kernel/kernel.h | 12 +++++ arch/sparc/kernel/leon_smp.c | 33 ++++---------- arch/sparc/kernel/smp_32.c | 86 +++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/sun4d_smp.c | 29 ++++--------- arch/sparc/kernel/sun4m_smp.c | 33 ++++---------- arch/sparc/kernel/trampoline_32.S | 17 +++---- 6 files changed, 132 insertions(+), 78 deletions(-) diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 291bb5d..a702d9a 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); +/* sun4m_smp.c */ +void sun4m_cpu_pre_starting(void *arg); +void sun4m_cpu_pre_online(void *arg); + /* sun4d_irq.c */ extern spinlock_t sun4d_imsk_lock; @@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); extern void sun4d_distribute_irqs(void); extern void sun4d_free_irq(unsigned int irq, void *dev_id); +/* sun4d_smp.c */ +void sun4d_cpu_pre_starting(void *arg); +void sun4d_cpu_pre_online(void *arg); + +/* leon_smp.c */ +void leon_cpu_pre_starting(void *arg); +void leon_cpu_pre_online(void *arg); + /* head_32.S */ extern unsigned int t_nmi[]; extern unsigned int linux_trap_ipi15_sun4d[]; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 0f3fb6d..9b40c9c 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -69,31 +69,19 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, return val; } -void __cpuinit leon_callin(void) +void __cpuinit leon_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); leon_configure_cache_smp(); +} - notify_cpu_starting(cpuid); - - /* Get our local ticker going. */ - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit leon_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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); @@ -110,9 +98,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/smp_32.c b/arch/sparc/kernel/smp_32.c index 79db45e..9e7e6d7 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -20,6 +20,7 @@ #include <linux/seq_file.h> #include <linux/cache.h> #include <linux/delay.h> +#include <linux/cpu.h> #include <asm/ptrace.h> #include <linux/atomic.h> @@ -32,8 +33,10 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/cpudata.h> +#include <asm/timer.h> #include <asm/leon.h> +#include "kernel.h" #include "irq.h" volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) return ret; } +void __cpuinit arch_cpu_pre_starting(void *arg) +{ + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_starting(arg); + break; + case sun4d: + sun4d_cpu_pre_starting(arg); + break; + case sparc_leon: + leon_cpu_pre_starting(arg); + break; + default: + BUG(); + } +} + +void __cpuinit arch_cpu_pre_online(void *arg) +{ + unsigned int cpuid = hard_smp_processor_id(); + + register_percpu_ce(cpuid); + + calibrate_delay(); + smp_store_cpu_info(cpuid); + + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_online(arg); + break; + case sun4d: + sun4d_cpu_pre_online(arg); + break; + case sparc_leon: + leon_cpu_pre_online(arg); + break; + default: + BUG(); + } +} + +void __cpuinit sparc_start_secondary(void *arg) +{ + unsigned int cpu; + + /* + * SMP booting is extremely fragile in some architectures. So run + * the cpu initialization code first before anything else. + */ + arch_cpu_pre_starting(arg); + + preempt_disable(); + cpu = smp_processor_id(); + + /* Invoke the CPU_STARTING notifier callbacks */ + notify_cpu_starting(cpu); + + arch_cpu_pre_online(arg); + + /* Set the CPU in the cpu_online_mask */ + set_cpu_online(cpu, true); + + /* Enable local interrupts now */ + local_irq_enable(); + + wmb(); + cpu_idle(); + + /* We should never reach here! */ + BUG(); +} + +void __cpuinit smp_callin(void) +{ + sparc_start_secondary(NULL); +} + void smp_bogo(struct seq_file *m) { int i; diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index ddaea31..c9eb82f 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) "i" (ASI_M_CTL)); } -void __cpuinit smp4d_callin(void) +void __cpuinit sun4d_cpu_pre_starting(void *arg) { int cpuid = hard_smp_processor_id(); - unsigned long flags; /* Show we are alive */ cpu_leds[cpuid] = 0x6; @@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) /* Enable level15 interrupt, disable level14 interrupt for now */ cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4d_cpu_pre_online(void *arg) +{ + unsigned long flags; + int cpuid; - notify_cpu_starting(cpuid); - /* - * Unblock the master CPU _only_ when the scheduler state + cpuid = hard_smp_processor_id(); + + /* 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); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); - - /* Allow master to continue. */ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); local_ops->cache_all(); local_ops->tlb_all(); @@ -106,16 +99,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..8a65f15 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) return val; } -void __cpuinit smp4m_callin(void) +void __cpuinit sun4m_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); - - notify_cpu_starting(cpuid); - - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4m_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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 +64,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 af27aca..6cdb08c 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -79,18 +79,15 @@ cpu3_startup: nop /* Start this processor. */ - call smp4m_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic .text .align 4 -smp_do_cpu_idle: - call cpu_idle - mov 0, %o0 - +smp_panic: call cpu_panic nop @@ -144,10 +141,10 @@ sun4d_cpu_startup: nop /* Start this processor. */ - call smp4d_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic __CPUINIT .align 4 @@ -201,7 +198,7 @@ leon_smp_cpu_startup: nop /* Start this processor. */ - call leon_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic -- 1.6.0.6 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH] sparc32: refactor smp boot @ 2012-06-03 21:17 ` Sam Ravnborg 0 siblings, 0 replies; 11+ messages in thread From: Sam Ravnborg @ 2012-06-03 21:17 UTC (permalink / raw) To: Srivatsa S. Bhat, David S. Miller Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux >From 531d9c538fc60c15363890768ea416897853d6af Mon Sep 17 00:00:00 2001 From: Sam Ravnborg <sam@ravnborg.org> Date: Sun, 3 Jun 2012 23:08:18 +0200 Subject: [PATCH] sparc32: refactor smp boot Introduce a common smp_callin() function to call from trampoline_32.S. Add platform specific functions to handle the platform details. This is in preparation for a patch that will unify the smp boot stuff for all architectures. sparc32 was significantly different to warrant this patch in preparation. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> --- Hi Srivatsa. This should address all your comemnts (thanks!). I assume you will include this patch in your serie. @davem: please ack this patch (if it is OK that is) Note: It has not seen much testing. But I have tried to review it carefully. Sam arch/sparc/kernel/kernel.h | 12 +++++ arch/sparc/kernel/leon_smp.c | 33 ++++---------- arch/sparc/kernel/smp_32.c | 86 +++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/sun4d_smp.c | 29 ++++--------- arch/sparc/kernel/sun4m_smp.c | 33 ++++---------- arch/sparc/kernel/trampoline_32.S | 17 +++---- 6 files changed, 132 insertions(+), 78 deletions(-) diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 291bb5d..a702d9a 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); +/* sun4m_smp.c */ +void sun4m_cpu_pre_starting(void *arg); +void sun4m_cpu_pre_online(void *arg); + /* sun4d_irq.c */ extern spinlock_t sun4d_imsk_lock; @@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); extern void sun4d_distribute_irqs(void); extern void sun4d_free_irq(unsigned int irq, void *dev_id); +/* sun4d_smp.c */ +void sun4d_cpu_pre_starting(void *arg); +void sun4d_cpu_pre_online(void *arg); + +/* leon_smp.c */ +void leon_cpu_pre_starting(void *arg); +void leon_cpu_pre_online(void *arg); + /* head_32.S */ extern unsigned int t_nmi[]; extern unsigned int linux_trap_ipi15_sun4d[]; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 0f3fb6d..9b40c9c 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -69,31 +69,19 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, return val; } -void __cpuinit leon_callin(void) +void __cpuinit leon_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); leon_configure_cache_smp(); +} - notify_cpu_starting(cpuid); - - /* Get our local ticker going. */ - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit leon_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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); @@ -110,9 +98,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/smp_32.c b/arch/sparc/kernel/smp_32.c index 79db45e..9e7e6d7 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -20,6 +20,7 @@ #include <linux/seq_file.h> #include <linux/cache.h> #include <linux/delay.h> +#include <linux/cpu.h> #include <asm/ptrace.h> #include <linux/atomic.h> @@ -32,8 +33,10 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/cpudata.h> +#include <asm/timer.h> #include <asm/leon.h> +#include "kernel.h" #include "irq.h" volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) return ret; } +void __cpuinit arch_cpu_pre_starting(void *arg) +{ + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_starting(arg); + break; + case sun4d: + sun4d_cpu_pre_starting(arg); + break; + case sparc_leon: + leon_cpu_pre_starting(arg); + break; + default: + BUG(); + } +} + +void __cpuinit arch_cpu_pre_online(void *arg) +{ + unsigned int cpuid = hard_smp_processor_id(); + + register_percpu_ce(cpuid); + + calibrate_delay(); + smp_store_cpu_info(cpuid); + + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_online(arg); + break; + case sun4d: + sun4d_cpu_pre_online(arg); + break; + case sparc_leon: + leon_cpu_pre_online(arg); + break; + default: + BUG(); + } +} + +void __cpuinit sparc_start_secondary(void *arg) +{ + unsigned int cpu; + + /* + * SMP booting is extremely fragile in some architectures. So run + * the cpu initialization code first before anything else. + */ + arch_cpu_pre_starting(arg); + + preempt_disable(); + cpu = smp_processor_id(); + + /* Invoke the CPU_STARTING notifier callbacks */ + notify_cpu_starting(cpu); + + arch_cpu_pre_online(arg); + + /* Set the CPU in the cpu_online_mask */ + set_cpu_online(cpu, true); + + /* Enable local interrupts now */ + local_irq_enable(); + + wmb(); + cpu_idle(); + + /* We should never reach here! */ + BUG(); +} + +void __cpuinit smp_callin(void) +{ + sparc_start_secondary(NULL); +} + void smp_bogo(struct seq_file *m) { int i; diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index ddaea31..c9eb82f 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) "i" (ASI_M_CTL)); } -void __cpuinit smp4d_callin(void) +void __cpuinit sun4d_cpu_pre_starting(void *arg) { int cpuid = hard_smp_processor_id(); - unsigned long flags; /* Show we are alive */ cpu_leds[cpuid] = 0x6; @@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) /* Enable level15 interrupt, disable level14 interrupt for now */ cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4d_cpu_pre_online(void *arg) +{ + unsigned long flags; + int cpuid; - notify_cpu_starting(cpuid); - /* - * Unblock the master CPU _only_ when the scheduler state + cpuid = hard_smp_processor_id(); + + /* 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); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); - - /* Allow master to continue. */ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); local_ops->cache_all(); local_ops->tlb_all(); @@ -106,16 +99,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..8a65f15 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) return val; } -void __cpuinit smp4m_callin(void) +void __cpuinit sun4m_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); - - notify_cpu_starting(cpuid); - - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4m_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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 +64,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 af27aca..6cdb08c 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -79,18 +79,15 @@ cpu3_startup: nop /* Start this processor. */ - call smp4m_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic .text .align 4 -smp_do_cpu_idle: - call cpu_idle - mov 0, %o0 - +smp_panic: call cpu_panic nop @@ -144,10 +141,10 @@ sun4d_cpu_startup: nop /* Start this processor. */ - call smp4d_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic __CPUINIT .align 4 @@ -201,7 +198,7 @@ leon_smp_cpu_startup: nop /* Start this processor. */ - call leon_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic -- 1.6.0.6 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH] sparc32: refactor smp boot @ 2012-06-03 21:17 ` Sam Ravnborg 0 siblings, 0 replies; 11+ messages in thread From: Sam Ravnborg @ 2012-06-03 21:17 UTC (permalink / raw) To: Srivatsa S. Bhat Cc: David Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux From 531d9c538fc60c15363890768ea416897853d6af Mon Sep 17 00:00:00 2001 From: Sam Ravnborg <sam@ravnborg.org> Date: Sun, 3 Jun 2012 23:08:18 +0200 Subject: [PATCH] sparc32: refactor smp boot Introduce a common smp_callin() function to call from trampoline_32.S. Add platform specific functions to handle the platform details. This is in preparation for a patch that will unify the smp boot stuff for all architectures. sparc32 was significantly different to warrant this patch in preparation. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> --- Hi Srivatsa. This should address all your comemnts (thanks!). I assume you will include this patch in your serie. @davem: please ack this patch (if it is OK that is) Note: It has not seen much testing. But I have tried to review it carefully. Sam arch/sparc/kernel/kernel.h | 12 +++++ arch/sparc/kernel/leon_smp.c | 33 ++++---------- arch/sparc/kernel/smp_32.c | 86 +++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/sun4d_smp.c | 29 ++++--------- arch/sparc/kernel/sun4m_smp.c | 33 ++++---------- arch/sparc/kernel/trampoline_32.S | 17 +++---- 6 files changed, 132 insertions(+), 78 deletions(-) diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 291bb5d..a702d9a 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); +/* sun4m_smp.c */ +void sun4m_cpu_pre_starting(void *arg); +void sun4m_cpu_pre_online(void *arg); + /* sun4d_irq.c */ extern spinlock_t sun4d_imsk_lock; @@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); extern void sun4d_distribute_irqs(void); extern void sun4d_free_irq(unsigned int irq, void *dev_id); +/* sun4d_smp.c */ +void sun4d_cpu_pre_starting(void *arg); +void sun4d_cpu_pre_online(void *arg); + +/* leon_smp.c */ +void leon_cpu_pre_starting(void *arg); +void leon_cpu_pre_online(void *arg); + /* head_32.S */ extern unsigned int t_nmi[]; extern unsigned int linux_trap_ipi15_sun4d[]; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 0f3fb6d..9b40c9c 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -69,31 +69,19 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, return val; } -void __cpuinit leon_callin(void) +void __cpuinit leon_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); leon_configure_cache_smp(); +} - notify_cpu_starting(cpuid); - - /* Get our local ticker going. */ - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit leon_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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); @@ -110,9 +98,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/smp_32.c b/arch/sparc/kernel/smp_32.c index 79db45e..9e7e6d7 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -20,6 +20,7 @@ #include <linux/seq_file.h> #include <linux/cache.h> #include <linux/delay.h> +#include <linux/cpu.h> #include <asm/ptrace.h> #include <linux/atomic.h> @@ -32,8 +33,10 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/cpudata.h> +#include <asm/timer.h> #include <asm/leon.h> +#include "kernel.h" #include "irq.h" volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) return ret; } +void __cpuinit arch_cpu_pre_starting(void *arg) +{ + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_starting(arg); + break; + case sun4d: + sun4d_cpu_pre_starting(arg); + break; + case sparc_leon: + leon_cpu_pre_starting(arg); + break; + default: + BUG(); + } +} + +void __cpuinit arch_cpu_pre_online(void *arg) +{ + unsigned int cpuid = hard_smp_processor_id(); + + register_percpu_ce(cpuid); + + calibrate_delay(); + smp_store_cpu_info(cpuid); + + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_online(arg); + break; + case sun4d: + sun4d_cpu_pre_online(arg); + break; + case sparc_leon: + leon_cpu_pre_online(arg); + break; + default: + BUG(); + } +} + +void __cpuinit sparc_start_secondary(void *arg) +{ + unsigned int cpu; + + /* + * SMP booting is extremely fragile in some architectures. So run + * the cpu initialization code first before anything else. + */ + arch_cpu_pre_starting(arg); + + preempt_disable(); + cpu = smp_processor_id(); + + /* Invoke the CPU_STARTING notifier callbacks */ + notify_cpu_starting(cpu); + + arch_cpu_pre_online(arg); + + /* Set the CPU in the cpu_online_mask */ + set_cpu_online(cpu, true); + + /* Enable local interrupts now */ + local_irq_enable(); + + wmb(); + cpu_idle(); + + /* We should never reach here! */ + BUG(); +} + +void __cpuinit smp_callin(void) +{ + sparc_start_secondary(NULL); +} + void smp_bogo(struct seq_file *m) { int i; diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index ddaea31..c9eb82f 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) "i" (ASI_M_CTL)); } -void __cpuinit smp4d_callin(void) +void __cpuinit sun4d_cpu_pre_starting(void *arg) { int cpuid = hard_smp_processor_id(); - unsigned long flags; /* Show we are alive */ cpu_leds[cpuid] = 0x6; @@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) /* Enable level15 interrupt, disable level14 interrupt for now */ cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4d_cpu_pre_online(void *arg) +{ + unsigned long flags; + int cpuid; - notify_cpu_starting(cpuid); - /* - * Unblock the master CPU _only_ when the scheduler state + cpuid = hard_smp_processor_id(); + + /* 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); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); - - /* Allow master to continue. */ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); local_ops->cache_all(); local_ops->tlb_all(); @@ -106,16 +99,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..8a65f15 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) return val; } -void __cpuinit smp4m_callin(void) +void __cpuinit sun4m_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); - - notify_cpu_starting(cpuid); - - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4m_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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 +64,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 af27aca..6cdb08c 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -79,18 +79,15 @@ cpu3_startup: nop /* Start this processor. */ - call smp4m_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic .text .align 4 -smp_do_cpu_idle: - call cpu_idle - mov 0, %o0 - +smp_panic: call cpu_panic nop @@ -144,10 +141,10 @@ sun4d_cpu_startup: nop /* Start this processor. */ - call smp4d_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic __CPUINIT .align 4 @@ -201,7 +198,7 @@ leon_smp_cpu_startup: nop /* Start this processor. */ - call leon_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic -- 1.6.0.6 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH] sparc32: refactor smp boot @ 2012-06-03 21:17 ` Sam Ravnborg 0 siblings, 0 replies; 11+ messages in thread From: Sam Ravnborg @ 2012-06-03 21:17 UTC (permalink / raw) To: Srivatsa S. Bhat, David S. Miller Cc: tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux From 531d9c538fc60c15363890768ea416897853d6af Mon Sep 17 00:00:00 2001 From: Sam Ravnborg <sam@ravnborg.org> Date: Sun, 3 Jun 2012 23:08:18 +0200 Subject: [PATCH] sparc32: refactor smp boot Introduce a common smp_callin() function to call from trampoline_32.S. Add platform specific functions to handle the platform details. This is in preparation for a patch that will unify the smp boot stuff for all architectures. sparc32 was significantly different to warrant this patch in preparation. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> --- Hi Srivatsa. This should address all your comemnts (thanks!). I assume you will include this patch in your serie. @davem: please ack this patch (if it is OK that is) Note: It has not seen much testing. But I have tried to review it carefully. Sam arch/sparc/kernel/kernel.h | 12 +++++ arch/sparc/kernel/leon_smp.c | 33 ++++---------- arch/sparc/kernel/smp_32.c | 86 +++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/sun4d_smp.c | 29 ++++--------- arch/sparc/kernel/sun4m_smp.c | 33 ++++---------- arch/sparc/kernel/trampoline_32.S | 17 +++---- 6 files changed, 132 insertions(+), 78 deletions(-) diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 291bb5d..a702d9a 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -48,6 +48,10 @@ extern void sun4m_init_IRQ(void); extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); +/* sun4m_smp.c */ +void sun4m_cpu_pre_starting(void *arg); +void sun4m_cpu_pre_online(void *arg); + /* sun4d_irq.c */ extern spinlock_t sun4d_imsk_lock; @@ -60,6 +64,14 @@ extern int show_sun4d_interrupts(struct seq_file *, void *); extern void sun4d_distribute_irqs(void); extern void sun4d_free_irq(unsigned int irq, void *dev_id); +/* sun4d_smp.c */ +void sun4d_cpu_pre_starting(void *arg); +void sun4d_cpu_pre_online(void *arg); + +/* leon_smp.c */ +void leon_cpu_pre_starting(void *arg); +void leon_cpu_pre_online(void *arg); + /* head_32.S */ extern unsigned int t_nmi[]; extern unsigned int linux_trap_ipi15_sun4d[]; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 0f3fb6d..9b40c9c 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -69,31 +69,19 @@ static inline unsigned long do_swap(volatile unsigned long *ptr, return val; } -void __cpuinit leon_callin(void) +void __cpuinit leon_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); leon_configure_cache_smp(); +} - notify_cpu_starting(cpuid); - - /* Get our local ticker going. */ - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit leon_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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); @@ -110,9 +98,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/smp_32.c b/arch/sparc/kernel/smp_32.c index 79db45e..9e7e6d7 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -20,6 +20,7 @@ #include <linux/seq_file.h> #include <linux/cache.h> #include <linux/delay.h> +#include <linux/cpu.h> #include <asm/ptrace.h> #include <linux/atomic.h> @@ -32,8 +33,10 @@ #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/cpudata.h> +#include <asm/timer.h> #include <asm/leon.h> +#include "kernel.h" #include "irq.h" volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,}; @@ -294,6 +297,89 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) return ret; } +void __cpuinit arch_cpu_pre_starting(void *arg) +{ + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_starting(arg); + break; + case sun4d: + sun4d_cpu_pre_starting(arg); + break; + case sparc_leon: + leon_cpu_pre_starting(arg); + break; + default: + BUG(); + } +} + +void __cpuinit arch_cpu_pre_online(void *arg) +{ + unsigned int cpuid = hard_smp_processor_id(); + + register_percpu_ce(cpuid); + + calibrate_delay(); + smp_store_cpu_info(cpuid); + + local_ops->cache_all(); + local_ops->tlb_all(); + + switch(sparc_cpu_model) { + case sun4m: + sun4m_cpu_pre_online(arg); + break; + case sun4d: + sun4d_cpu_pre_online(arg); + break; + case sparc_leon: + leon_cpu_pre_online(arg); + break; + default: + BUG(); + } +} + +void __cpuinit sparc_start_secondary(void *arg) +{ + unsigned int cpu; + + /* + * SMP booting is extremely fragile in some architectures. So run + * the cpu initialization code first before anything else. + */ + arch_cpu_pre_starting(arg); + + preempt_disable(); + cpu = smp_processor_id(); + + /* Invoke the CPU_STARTING notifier callbacks */ + notify_cpu_starting(cpu); + + arch_cpu_pre_online(arg); + + /* Set the CPU in the cpu_online_mask */ + set_cpu_online(cpu, true); + + /* Enable local interrupts now */ + local_irq_enable(); + + wmb(); + cpu_idle(); + + /* We should never reach here! */ + BUG(); +} + +void __cpuinit smp_callin(void) +{ + sparc_start_secondary(NULL); +} + void smp_bogo(struct seq_file *m) { int i; diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index ddaea31..c9eb82f 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) "i" (ASI_M_CTL)); } -void __cpuinit smp4d_callin(void) +void __cpuinit sun4d_cpu_pre_starting(void *arg) { int cpuid = hard_smp_processor_id(); - unsigned long flags; /* Show we are alive */ cpu_leds[cpuid] = 0x6; @@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) /* Enable level15 interrupt, disable level14 interrupt for now */ cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4d_cpu_pre_online(void *arg) +{ + unsigned long flags; + int cpuid; - notify_cpu_starting(cpuid); - /* - * Unblock the master CPU _only_ when the scheduler state + cpuid = hard_smp_processor_id(); + + /* 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); - - calibrate_delay(); - smp_store_cpu_info(cpuid); - local_ops->cache_all(); - local_ops->tlb_all(); - - /* Allow master to continue. */ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); local_ops->cache_all(); local_ops->tlb_all(); @@ -106,16 +99,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..8a65f15 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -34,30 +34,19 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) return val; } -void __cpuinit smp4m_callin(void) +void __cpuinit sun4m_cpu_pre_starting(void *arg) { - int cpuid = hard_smp_processor_id(); - - local_ops->cache_all(); - local_ops->tlb_all(); - - notify_cpu_starting(cpuid); - - register_percpu_ce(cpuid); - - calibrate_delay(); - smp_store_cpu_info(cpuid); +} - local_ops->cache_all(); - local_ops->tlb_all(); +void __cpuinit sun4m_cpu_pre_online(void *arg) +{ + int cpuid = hard_smp_processor_id(); - /* - * 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 +64,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 af27aca..6cdb08c 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -79,18 +79,15 @@ cpu3_startup: nop /* Start this processor. */ - call smp4m_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic .text .align 4 -smp_do_cpu_idle: - call cpu_idle - mov 0, %o0 - +smp_panic: call cpu_panic nop @@ -144,10 +141,10 @@ sun4d_cpu_startup: nop /* Start this processor. */ - call smp4d_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic __CPUINIT .align 4 @@ -201,7 +198,7 @@ leon_smp_cpu_startup: nop /* Start this processor. */ - call leon_callin + call smp_callin nop - b,a smp_do_cpu_idle + b,a smp_panic -- 1.6.0.6 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] sparc32: refactor smp boot 2012-06-03 21:17 ` Sam Ravnborg @ 2012-06-04 1:04 ` David Miller -1 siblings, 0 replies; 11+ messages in thread From: David Miller @ 2012-06-04 1:04 UTC (permalink / raw) To: sam Cc: srivatsa.bhat, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux From: Sam Ravnborg <sam@ravnborg.org> Date: Sun, 3 Jun 2012 23:17:52 +0200 > From 531d9c538fc60c15363890768ea416897853d6af Mon Sep 17 00:00:00 2001 > From: Sam Ravnborg <sam@ravnborg.org> > Date: Sun, 3 Jun 2012 23:08:18 +0200 > Subject: [PATCH] sparc32: refactor smp boot > > Introduce a common smp_callin() function to call > from trampoline_32.S. > Add platform specific functions to handle the > platform details. > > This is in preparation for a patch that will > unify the smp boot stuff for all architectures. > sparc32 was significantly different to warrant > this patch in preparation. > > Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Acked-by: David S. Miller <davem@davemloft.net> ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sparc32: refactor smp boot @ 2012-06-04 1:04 ` David Miller 0 siblings, 0 replies; 11+ messages in thread From: David Miller @ 2012-06-04 1:04 UTC (permalink / raw) To: sam Cc: srivatsa.bhat, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux From: Sam Ravnborg <sam@ravnborg.org> Date: Sun, 3 Jun 2012 23:17:52 +0200 > From 531d9c538fc60c15363890768ea416897853d6af Mon Sep 17 00:00:00 2001 > From: Sam Ravnborg <sam@ravnborg.org> > Date: Sun, 3 Jun 2012 23:08:18 +0200 > Subject: [PATCH] sparc32: refactor smp boot > > Introduce a common smp_callin() function to call > from trampoline_32.S. > Add platform specific functions to handle the > platform details. > > This is in preparation for a patch that will > unify the smp boot stuff for all architectures. > sparc32 was significantly different to warrant > this patch in preparation. > > Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Acked-by: David S. Miller <davem@davemloft.net> ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sparc32: refactor smp boot 2012-06-03 21:17 ` Sam Ravnborg @ 2012-06-04 6:53 ` Srivatsa S. Bhat -1 siblings, 0 replies; 11+ messages in thread From: Srivatsa S. Bhat @ 2012-06-04 6:48 UTC (permalink / raw) To: Sam Ravnborg Cc: David S. Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux On 06/04/2012 02:47 AM, Sam Ravnborg wrote: > From 531d9c538fc60c15363890768ea416897853d6af Mon Sep 17 00:00:00 2001 > From: Sam Ravnborg <sam@ravnborg.org> > Date: Sun, 3 Jun 2012 23:08:18 +0200 > Subject: [PATCH] sparc32: refactor smp boot > > Introduce a common smp_callin() function to call > from trampoline_32.S. > Add platform specific functions to handle the > platform details. > > This is in preparation for a patch that will > unify the smp boot stuff for all architectures. > sparc32 was significantly different to warrant > this patch in preparation. > > Signed-off-by: Sam Ravnborg <sam@ravnborg.org> > --- > > Hi Srivatsa. > > This should address all your comemnts (thanks!). > I assume you will include this patch in your serie. > Of course, thanks for your work! As soon as the Xen problem gets sorted out (patch 5), I will send out a v2 including your patch and addressing all the comments received so far. > diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c > index ddaea31..c9eb82f 100644 > --- a/arch/sparc/kernel/sun4d_smp.c > +++ b/arch/sparc/kernel/sun4d_smp.c > @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) > "i" (ASI_M_CTL)); > } > > -void __cpuinit smp4d_callin(void) > +void __cpuinit sun4d_cpu_pre_starting(void *arg) > { > int cpuid = hard_smp_processor_id(); > - unsigned long flags; > > /* Show we are alive */ > cpu_leds[cpuid] = 0x6; > @@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) > > /* Enable level15 interrupt, disable level14 interrupt for now */ > cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); > +} > > - local_ops->cache_all(); > - local_ops->tlb_all(); > +void __cpuinit sun4d_cpu_pre_online(void *arg) > +{ > + unsigned long flags; > + int cpuid; > > - notify_cpu_starting(cpuid); > - /* > - * Unblock the master CPU _only_ when the scheduler state > + cpuid = hard_smp_processor_id(); > + > + /* 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. > */ Looks like you forgot to update this comment. Its ok, I'll update your patch and include it in the series. Regards, Srivatsa S. Bhat > - /* Get our local ticker going. */ > - register_percpu_ce(cpuid); > - > - calibrate_delay(); > - smp_store_cpu_info(cpuid); > - local_ops->cache_all(); > - local_ops->tlb_all(); > - > - /* Allow master to continue. */ > sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); > local_ops->cache_all(); > local_ops->tlb_all(); > @@ -106,16 +99,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); > - > } > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] sparc32: refactor smp boot @ 2012-06-04 6:53 ` Srivatsa S. Bhat 0 siblings, 0 replies; 11+ messages in thread From: Srivatsa S. Bhat @ 2012-06-04 6:53 UTC (permalink / raw) To: Sam Ravnborg Cc: David S. Miller, tglx, peterz, paulmck, rusty, mingo, yong.zhang0, akpm, vatsa, rjw, linux-arch, linux-kernel, nikunj, vapier, konrad, tkhai, sparclinux On 06/04/2012 02:47 AM, Sam Ravnborg wrote: > From 531d9c538fc60c15363890768ea416897853d6af Mon Sep 17 00:00:00 2001 > From: Sam Ravnborg <sam@ravnborg.org> > Date: Sun, 3 Jun 2012 23:08:18 +0200 > Subject: [PATCH] sparc32: refactor smp boot > > Introduce a common smp_callin() function to call > from trampoline_32.S. > Add platform specific functions to handle the > platform details. > > This is in preparation for a patch that will > unify the smp boot stuff for all architectures. > sparc32 was significantly different to warrant > this patch in preparation. > > Signed-off-by: Sam Ravnborg <sam@ravnborg.org> > --- > > Hi Srivatsa. > > This should address all your comemnts (thanks!). > I assume you will include this patch in your serie. > Of course, thanks for your work! As soon as the Xen problem gets sorted out (patch 5), I will send out a v2 including your patch and addressing all the comments received so far. > diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c > index ddaea31..c9eb82f 100644 > --- a/arch/sparc/kernel/sun4d_smp.c > +++ b/arch/sparc/kernel/sun4d_smp.c > @@ -50,10 +50,9 @@ static inline void show_leds(int cpuid) > "i" (ASI_M_CTL)); > } > > -void __cpuinit smp4d_callin(void) > +void __cpuinit sun4d_cpu_pre_starting(void *arg) > { > int cpuid = hard_smp_processor_id(); > - unsigned long flags; > > /* Show we are alive */ > cpu_leds[cpuid] = 0x6; > @@ -61,26 +60,20 @@ void __cpuinit smp4d_callin(void) > > /* Enable level15 interrupt, disable level14 interrupt for now */ > cc_set_imsk((cc_get_imsk() & ~0x8000) | 0x4000); > +} > > - local_ops->cache_all(); > - local_ops->tlb_all(); > +void __cpuinit sun4d_cpu_pre_online(void *arg) > +{ > + unsigned long flags; > + int cpuid; > > - notify_cpu_starting(cpuid); > - /* > - * Unblock the master CPU _only_ when the scheduler state > + cpuid = hard_smp_processor_id(); > + > + /* 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. > */ Looks like you forgot to update this comment. Its ok, I'll update your patch and include it in the series. Regards, Srivatsa S. Bhat > - /* Get our local ticker going. */ > - register_percpu_ce(cpuid); > - > - calibrate_delay(); > - smp_store_cpu_info(cpuid); > - local_ops->cache_all(); > - local_ops->tlb_all(); > - > - /* Allow master to continue. */ > sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); > local_ops->cache_all(); > local_ops->tlb_all(); > @@ -106,16 +99,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); > - > } > ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2013-02-19 5:57 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-02-15 15:19 [PATCH] sparc32: refactor smp boot Sam Ravnborg 2013-02-15 19:37 ` Srivatsa S. Bhat 2013-02-19 5:57 ` David Miller -- strict thread matches above, loose matches on Subject: below -- 2012-06-01 17:56 [PATCH 21/27] sparc32, smpboot: Use generic SMP booting infrastructure David Miller 2012-06-01 18:54 ` Sam Ravnborg 2012-06-01 22:47 ` [UPDATED PATCH " Srivatsa S. Bhat 2012-06-02 6:52 ` Sam Ravnborg 2012-06-02 7:44 ` Sam Ravnborg 2012-06-02 8:01 ` Srivatsa S. Bhat 2012-06-02 15:13 ` Sam Ravnborg 2012-06-02 15:58 ` Srivatsa S. Bhat 2012-06-02 16:23 ` Sam Ravnborg 2012-06-02 16:34 ` Srivatsa S. Bhat 2012-06-03 21:17 ` [PATCH] sparc32: refactor smp boot Sam Ravnborg 2012-06-03 21:17 ` Sam Ravnborg 2012-06-03 21:17 ` Sam Ravnborg 2012-06-03 21:17 ` Sam Ravnborg 2012-06-04 1:04 ` David Miller 2012-06-04 1:04 ` David Miller 2012-06-04 6:48 ` Srivatsa S. Bhat 2012-06-04 6:53 ` Srivatsa S. Bhat
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.