问题和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()函数
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()即可。
参考链接
request_irq引发BUG: sleeping function called from invalid context at mm/slab.c