linux devm_request_irq 引发BUG sleeping function called from invalid context问题

742 阅读1分钟

问题和log 同样的代码在user版本上正常,但在userdebug版本上就有问题,设备反复重启。

[ 29.288033] lm3492hc_bklt_timer_func limit backlight,default 84 percent

[ 29.293755] lm3492hc_bklt_timer_func come in

[ 29.297948] BUG: sleeping function called from invalid context at /home/chenky/debug/svn185/trunk/kernel/msm-3.18/mm/slub.c:1281

[ 29.309536] in_atomic(): 1, irqs_disabled(): 0, pid: 709, name: installd

[ 29.316176] Preemption disabled at:[] irq_exit+0x74/0xb0

[ 29.323046] ------------[ cut here ]------------

[ 29.327636] kernel BUG at /home/chenky/debug/svn185/trunk/kernel/msm-3.18/kernel/sched/qhmp_core.c:9180!

[ 29.337096] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP

[ 29.342565] Modules linked in:

[ 29.345607] CPU: 0 PID: 709 Comm: installd Tainted: G W 3.18.31-svn224 #13

[ 29.353502] Hardware name: Qualcomm Technologies, Inc. MSM8937-PMI8937 QRD SKU2 (DT)

[ 29.361231] task: ffffffc059228e00 ti: ffffffc0592e0000 task.ti: ffffffc0592e0000

[ 29.368698] PC is at __might_sleep+0x15c/0x16c

[ 29.373123] LR is at __might_sleep+0x15c/0x16c

[ 29.889266] Call trace:

[ 29.891703] [] __might_sleep+0x15c/0x16c

[ 29.897173] [] kmem_cache_alloc_trace+0x68/0x278

[ 29.903335] [] request_threaded_irq+0x90/0x118

[ 29.909326] [] lm3492hc_bklt_timer_func+0xbc/0x110

[ 29.915660] [] call_timer_fn+0x98/0x1c4

[ 29.921040] [] run_timer_softirq+0x55c/0x614

[ 29.926858] [] __do_softirq+0x178/0x350

[ 29.932237] [] irq_exit+0x74/0xb0

[ 29.937100] [] __handle_domain_irq+0xb4/0xec

[ 29.942915] [] gic_handle_irq+0x68/0xa8

表示代码在原子上下文中休眠了。

BUG: sleeping function called from invalid context at是kernel\msm-3.18\kernel\sched\qhmp_core.c的__might_sleep()打印的

__might_sleep被might_sleep()调用,如下:

#ifdef CONFIG_DEBUG_ATOMIC_SLEEP

void __might_sleep(const char *file, int line, int preempt_offset);

/**

  • might_sleep - annotation for functions that can sleep

  • this macro will print a stack trace if it is executed in an atomic

  • context (spinlock, irq-handler, ...).

  • This is a useful debugging help to be able to catch problems early and not

  • be bitten later when the calling function happens to sleep when it is not

  • supposed to.

*/

define might_sleep() \

   do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0)

#else

static inline void __might_sleep(const char *file, int line,

                           int preempt_offset) { }

define might_sleep() do { might_resched(); } while (0)

#endif

ret = devm_request_irq(&pdev->dev,

                        ctrl_pdata->bklt_comm_irq,

                        lm3492hc_interrupt_handler, IRQF_TRIGGER_HIGH,//IRQF_TRIGGER_FALLING,

                        "lm3492hc_interrupt_handler", ctrl_pdata);

2. 解决方法

mdss_dsi_ctrl_probe()--->lm3492hc_bklt_timer_func()函数

image.png

lm3492hc_bklt_timer_func()函数调用了devm_request_irq来申请中断

                 ret = devm_request_irq(&pdev->dev,

                        ctrl_pdata->bklt_comm_irq,

                        lm3492hc_interrupt_handler, IRQF_TRIGGER_HIGH,//IRQF_TRIGGER_FALLING,

                        "lm3492hc_interrupt_handler", ctrl_pdata);

(1) 注释掉CONFIG_DEBUG_ATOMIC_SLEEP

#CONFIG_DEBUG_ATOMIC_SLEEP=y,注释掉这项,后就正常了

(2) 把devm_request_irq放在mdss_dsi_ctrl_probe()即可。

参考链接

blog.csdn.net/hp0773/arti…

request_irq引发BUG: sleeping function called from invalid context at mm/slab.c

bbs.chinaunix.net/thread-1929…