From 578d36f5e160208821e8f51037ac1038e065ecaf Mon Sep 17 00:00:00 2001 From: Yi Li Date: Wed, 2 Dec 2009 07:58:12 +0000 Subject: Blackfin: SMP: don't start up core b until its state has been completely onlined When testing PREEMPT_RT kernel on BF561-EZKit, the kernel blocks while booting. When the kernel initializes the ethernet driver, it sleeps and never wakes up. The issue happens when the kernel waits for a timer for Core B to timeout (the timers are per-cpu based: static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases). However, the ksoftirqd thread for Core B (note, the ksoftirqd thread is also per-cpu based) cannot work properly, and the timers for Core B never times out. When ksoftirqd() for the first time runs on core B, it is possible core A is still initializing core B (see smp_init() -> cpu_up() -> __cpu_up()). So the "cpu_is_offline()" check may return true and ksoftirqd moves to "wait_to_die". So delay the core b start up until the per-cpu timers have been set up fully. Signed-off-by: Yi Li Signed-off-by: Mike Frysinger --- arch/blackfin/mach-common/smp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'arch/blackfin/mach-common') diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index d92b168c8328..369e687582b7 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c @@ -336,13 +336,6 @@ int __cpuinit __cpu_up(unsigned int cpu) ret = platform_boot_secondary(cpu, idle); - if (ret) { - cpu_clear(cpu, cpu_present_map); - printk(KERN_CRIT "CPU%u: processor failed to boot (%d)\n", cpu, ret); - free_task(idle); - } else - cpu_set(cpu, cpu_online_map); - secondary_stack = NULL; return ret; @@ -418,9 +411,16 @@ void __cpuinit secondary_start_kernel(void) setup_secondary(cpu); + platform_secondary_init(cpu); + local_irq_enable(); - platform_secondary_init(cpu); + /* + * Calibrate loops per jiffy value. + * IRQs need to be enabled here - D-cache can be invalidated + * in timer irq handler, so core B can read correct jiffies. + */ + calibrate_delay(); cpu_idle(); } -- cgit v1.2.3-58-ga151