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

平台:msm8937+android7.1

 

  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:[<ffffffc0000a72c8>] 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] [<ffffffc0000c7960>] __might_sleep+0x15c/0x16c

[   29.897173] [<ffffffc0001ad2e4>] kmem_cache_alloc_trace+0x68/0x278

[   29.903335] [<ffffffc0000f56e8>] request_threaded_irq+0x90/0x118

[   29.909326] [<ffffffc0004130c4>] lm3492hc_bklt_timer_func+0xbc/0x110

[   29.915660] [<ffffffc000103754>] call_timer_fn+0x98/0x1c4

[   29.921040] [<ffffffc0001049f0>] run_timer_softirq+0x55c/0x614

[   29.926858] [<ffffffc0000a6e8c>] __do_softirq+0x178/0x350

[   29.932237] [<ffffffc0000a72c8>] irq_exit+0x74/0xb0

[   29.937100] [<ffffffc0000f33c8>] __handle_domain_irq+0xb4/0xec

[   29.942915] [<ffffffc000082560>] 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()即可。

 

参考链接

https://blog.csdn.net/hp0773/article/details/12658501

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

http://bbs.chinaunix.net/thread-1929312-1-1.html

 

猜你喜欢

转载自blog.csdn.net/LoongEmbedded/article/details/81738083
今日推荐