[linux-yocto] [PATCH 1/1] xilinx-zyqn: Move disable_nonboot_cpus() in front of local_irq_disable()

quanyang.wang at windriver.com quanyang.wang at windriver.com
Sun Oct 20 22:50:45 PDT 2019


From: Quanyang Wang <quanyang.wang at windriver.com>

When run kdump with enabling CONFIG_DEBUG_PREEMPT, there is a calltrace
as below:

BUG: using smp_processor_id() in preemptible [00000000] code: sh/303
caller is machine_crash_shutdown+0x2c/0xe8
CPU: 0 PID: 303 Comm: sh Kdump: loaded Not tainted 5.2.20-yocto-standard #1
Hardware name: Xilinx Zynq Platform
[<80112ff4>] (unwind_backtrace) from [<8010ca4c>] (show_stack+0x18/0x1c)
[<8010ca4c>] (show_stack) from [<809b000c>] (dump_stack+0x70/0x8c)
[<809b000c>] (dump_stack) from [<80549a14>] (debug_smp_processor_id+0xd4/0x118)
[<80549a14>] (debug_smp_processor_id) from [<80111428>] (machine_crash_shutdown+0x2c/0xe8)
[<80111428>] (machine_crash_shutdown) from [<801afe24>] (__crash_kexec+0x70/0xd0)
[<801afe24>] (__crash_kexec) from [<801259b4>] (panic+0x110/0x324)
[<801259b4>] (panic) from [<805f7018>] (sysrq_handle_crash+0x18/0x1c)
[<805f7018>] (sysrq_handle_crash) from [<805f7584>] (__handle_sysrq+0x9c/0x14c)
[<805f7584>] (__handle_sysrq) from [<805f79e8>] (write_sysrq_trigger+0x5c/0x6c)
[<805f79e8>] (write_sysrq_trigger) from [<8031e850>] (proc_reg_write+0x78/0x8c)
[<8031e850>] (proc_reg_write) from [<802b1b28>] (vfs_write+0xc0/0x154)
[<802b1b28>] (vfs_write) from [<802b2a64>] (ksys_write+0x6c/0xd4)
[<802b2a64>] (ksys_write) from [<80101000>] (ret_fast_syscall+0x0/0x54)
Exception stack(0xba157fa8 to 0xba157ff0)
7fa0: 00000002 005ab930 00000001 005ab930 00000002 00000000
7fc0: 00000002 005ab930 76fa2290 00000004 76f3d124 76f3cc8c 00000000 00000000
7fe0: 00000004 7edec940 76edbfff 76e67d16

This is because that the function disable_nonboot_cpus is called in
order to make sure that the crash kernel runs in the boot CPU(cpu0).
And it will enable local irq by calling as below:

disable_nonboot_cpus
 -> freeze_secondary_cpus
  -> _cpu_down
   -> percpu_down_write
    -> rcu_sync_enter
     -> spin_unlock_irq(&rsp->rss_lock)
      -> local_irq_enable()

Then the functions including smp_processor_id() behind disable_nonboot_cpus
will run at the irq-enabled context, and this will trigger the calltrace.

So move disable_nonboot_cpus() in front of local_irq_disable() to avoid
it since disable_nonboot_cpus() not need run at an atomic context.

Signed-off-by: Quanyang Wang <quanyang.wang at windriver.com>
---
 arch/arm/kernel/machine_kexec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 654f2b1f9ac0..83d2025a4ab1 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -145,9 +145,10 @@ static void machine_kexec_mask_interrupts(void)
 
 void machine_crash_shutdown(struct pt_regs *regs)
 {
-	local_irq_disable();
 	disable_nonboot_cpus();
 
+	local_irq_disable();
+
 	crash_smp_send_stop();
 
 	crash_save_cpu(regs, smp_processor_id());
-- 
2.17.1



More information about the linux-yocto mailing list