Kernel gets deadlocked during smp booting
AYAN KUMAR HALDER
ayankumarh at gmail.com
Sun Jun 21 11:18:54 EDT 2015
> Cores 1,2 are the secondary cpus.
> Core1 :- It is in Abort mode
> Core 2 :- It is in 'cpu_v7_do_idle' function
I was able to resolve the issue. I am not sure if this is lack of my
understanding or a potential bug in the kernel.
1. In gic_init_bases(), gic_cpu_map for each core is initialized to
0xff. So in my case, gic_cpu_map[core0] = 0xff, gic_cpu_map[core1] =
0xff, and gic_cpu_map[core2] = 0xff.
2. gic_cpu_init() gets called for primary core (core0). Thus
gic_cpu_map[core0] = 0x1, gic_cpu_map[core1] = 0xfe, and
gic_cpu_map[core2] = 0xfe.
3. Primary core (core0) calls gic_raise_softirq to send interrupts to core1,2.
map |= gic_cpu_map[core1]; Thus map = 0xfe
So when this gets written to GIC distribution registers in the
writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data) +
This will send wake up interrupt to cores1 - 7 (in my case cores1,2)
at the same time. This is not intended as core1 should be send wake up
interrupt first, allowed to come online. Subsequently, core2 should be
send wake up interrupt. This would ensure that they boot one at a
In my case, cores1 and 2 were woken up at the same time, starts
booting simultaneously. Then, one of the core acquires a spinlock and
aborts(as I believe that secondary_start_kernel() is non-reentrant).
This causes deadlock for the other core.
I would be happy if someone can correct my misunderstanding or
identify if this is a potential issue in kernel 4.0.4
For my fix, I did the following:-
instead of map |= gic_cpu_map[cpu];
I used the following statement
map |= (0x1 << cpu );
More information about the Kernelnewbies