diff options
author | Ming Lei <tom.leiming@gmail.com> | 2013-03-11 08:52:12 -0400 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:58:14 -0400 |
commit | 77ad4ad2b07953e6d2dd434feed5e917aa27759a (patch) | |
tree | c9e8662d736befd5a6ac959d98e477db77f268e9 | |
parent | e41f9fdf39fd97adcc180b90fc72b2edcde8e89d (diff) |
ARM: 7669/1: keep __my_cpu_offset consistent with generic one
Commit 14318efb(ARM: 7587/1: implement optimized percpu variable access)
introduces arm's __my_cpu_offset to optimize percpu vaiable access,
which really works well on hackbench, but will cause __my_cpu_offset
to return garbage value before it is initialized in cpu_init() called
by setup_arch, so accessing percpu variable before setup_arch may cause
kernel hang. But generic __my_cpu_offset always returns zero before
percpu area is brought up, and won't hang kernel.
So the patch tries to clear __my_cpu_offset on boot CPU early
to avoid boot hang.
At least now percpu variable is accessed by lockdep before
setup_arch(), and enabling CONFIG_LOCK_STAT or CONFIG_DEBUG_LOCKDEP
can trigger kernel hang.
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
(cherry picked from commit 9394c1c65e61eb6f4c1c99f342b49e451ec337b6)
-rw-r--r-- | arch/arm/kernel/setup.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b4b1d397592b..0cde326f5542 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -456,6 +456,13 @@ void __init smp_setup_processor_id(void) | |||
456 | for (i = 1; i < nr_cpu_ids; ++i) | 456 | for (i = 1; i < nr_cpu_ids; ++i) |
457 | cpu_logical_map(i) = i == cpu ? 0 : i; | 457 | cpu_logical_map(i) = i == cpu ? 0 : i; |
458 | 458 | ||
459 | /* | ||
460 | * clear __my_cpu_offset on boot CPU to avoid hang caused by | ||
461 | * using percpu variable early, for example, lockdep will | ||
462 | * access percpu variable inside lock_release | ||
463 | */ | ||
464 | set_my_cpu_offset(0); | ||
465 | |||
459 | printk(KERN_INFO "Booting Linux on physical CPU 0x%x\n", mpidr); | 466 | printk(KERN_INFO "Booting Linux on physical CPU 0x%x\n", mpidr); |
460 | } | 467 | } |
461 | 468 | ||