AnsweredAssumed Answered

spin_lock_irq lead linux kernel crash on i.MX6 Dual Lite Hydra board

Question asked by weixiao chang on Jan 10, 2018
Latest reply on Jan 10, 2018 by igorpadykov


      spin_lock_irq & spin_unlock_irq lead kernel to crash when they are used in interrupt context but just at first time.

      The next is my code context:


      software: linux verison 4.1.15

      hardware: i.MX6 Dual Lite Hydra Board

      our system kernel was ported by Freescale, and added CONFIG_IMX_FIQ config,


      static DEFINE_SPINLOCK(_lock);

      static irqreturn_t buttons_irq(int irq, void *_buttons)
          buttons_t *buttons = _buttons;

          BUG_ON(irq != buttons->irq);
          mod_delayed_work(system_wq, &buttons->work, msecs_to_jiffies(buttons->software_debounce));
          return IRQ_HANDLED;

    devm_request_any_context_irq(&pdev->dev, venice_button->irq,buttons_irq, IRQF_TRIGGER_RISING |                IRQF_TRIGGER_FALLING,  "blue-but", venice_button);


 WARNING: CPU: 0 PID: 0 at kernel/irq/handle.c:147 handle_irq_event_percpu+0x134/0x140()
irq 150 handler buttons_irq+0x0/0x7c [ui_buttons] enabled interrupts
Modules linked in: g_serial(O) usb_f_serial(O) u_serial(O) libcomposite(O) tm(PO) sensor(O) motor(O) pe(O) beep(O) doorbell(O) psu(O) ui_buttons(O) modules(O) [last unloaded: btle_dev]
CPU: 0 PID: 0 Comm: swapper/0 Tainted: P           O    4.1.15+ #87
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[<80016c10>] (unwind_backtrace) from [<80013328>] (show_stack+0x10/0x14)
[<80013328>] (show_stack) from [<80552900>] (dump_stack+0x74/0xb4)
[<80552900>] (dump_stack) from [<8002f82c>] (warn_slowpath_common+0x80/0xb0)
[<8002f82c>] (warn_slowpath_common) from [<8002f88c>] (warn_slowpath_fmt+0x30/0x40)
[<8002f88c>] (warn_slowpath_fmt) from [<80067af4>] (handle_irq_event_percpu+0x134/0x140)
[<80067af4>] (handle_irq_event_percpu) from [<80067b3c>] (handle_irq_event+0x3c/0x5c)
[<80067b3c>] (handle_irq_event) from [<8006a6f4>] (handle_level_irq+0xc4/0x13c)
[<8006a6f4>] (handle_level_irq) from [<800670d8>] (generic_handle_irq+0x2c/0x3c)
[<800670d8>] (generic_handle_irq) from [<8023f44c>] (mxc_gpio_irq_handler+0x48/0x16c)
[<8023f44c>] (mxc_gpio_irq_handler) from [<8023f5f0>] (mx3_gpio_irq_handler+0x80/0xcc)
[<8023f5f0>] (mx3_gpio_irq_handler) from [<800670d8>] (generic_handle_irq+0x2c/0x3c)
[<800670d8>] (generic_handle_irq) from [<80067390>] (__handle_domain_irq+0x7c/0xec)
[<80067390>] (__handle_domain_irq) from [<800093e8>] (gic_handle_irq+0x2c/0x7c)
[<800093e8>] (gic_handle_irq) from [<80013e00>] (__irq_svc+0x40/0x74)
Exception stack(0x80791f18 to 0x80791f60)
1f00:                                                       80791f60 fffffff7
1f20: 07c160f4 00000003 07c160f4 00000003 ab726c68 00000000 07700386 00000003
1f40: 00000001 00000000 00000017 80791f60 a6aaaaab 803a1450 00040013 ffffffff
[<80013e00>] (__irq_svc) from [<803a1450>] (cpuidle_enter_state+0xc4/0x1f4)
[<803a1450>] (cpuidle_enter_state) from [<8005f174>] (cpu_startup_entry+0x1f8/0x318)
[<8005f174>] (cpu_startup_entry) from [<8074ac74>] (start_kernel+0x388/0x394)
---[ end trace 23bfa789e841c4bd ]---



spin_lock_irq and spin_unlock_irq is the common interface in linux kernel, so i don't think it's the interface's problem. And if use  spin_lock_irqsave and spin_unlock_irqsave replace the spin_lock_irq and spin_unlock_irq , it works well.

And this bug just happens at the first time when interrupt come.