1、崩溃log
[ 5.839319] BUG: sleeping function called from invalid context at /home/deanji/hd/sc60_gerrit/F80X/kernel/msm-3.18/kernel/workqueue.c:2644
[ 5.839321] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0
[ 5.839330] Preemption disabled at:[<ffffffc0000e7344>] cpu_startup_entry+0x33c/0x3a0
[ 5.839331]
[ 5.839338] ------------[ cut here ]------------
[ 5.839340] kernel BUG at /home/deanji/hd/sc60_gerrit/F80X/kernel/msm-3.18/kernel/sched/core.c:10843!
[ 5.839342] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
[ 5.839346] Modules linked in:
[ 5.839351] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 3.18.31 #35
省略....................
[ 5.839725] Call trace:
[ 5.839728] [<ffffffc0000c820c>] __might_sleep+0x15c/0x16c
[ 5.839732] [<ffffffc0000b9304>] flush_work+0x38/0x154
[ 5.839735] [<ffffffc0000b94dc>] flush_delayed_work+0x3c/0x48
[ 5.839741] [<ffffffc0006e7c88>] dwc3_ext_event_notify+0x28/0x1c0
[ 5.839745] [<ffffffc0006eb020>] dwc3_msm_power_set_property_usb+0x1e0/0x3c0
[ 5.839750] [<ffffffc0008b2f1c>] power_supply_set_present+0x40/0x68
[ 5.839754] [<ffffffc000af2e90>] gpio_usbdetect_vbus_irq+0x3c/0x4c
[ 5.839758] [<ffffffc0000f5b68>] handle_irq_event_percpu+0xb4/0x25c
[ 5.839761] [<ffffffc0000f5d5c>] handle_irq_event+0x4c/0x78
[ 5.839764] [<ffffffc0000f9108>] handle_edge_irq+0x120/0x148
[ 5.839767] [<ffffffc0000f51b0>] generic_handle_irq+0x2c/0x3c
[ 5.839773] [<ffffffc0009d8b48>] __qpnpint_handle_irq+0x120/0x134
[ 5.839776] [<ffffffc0009d8b6c>] qpnpint_handle_irq+0x10/0x18
[ 5.839779] [<ffffffc0009d7520>] periph_interrupt+0x19c/0x1c4
[ 5.839782] [<ffffffc0009d7738>] __pmic_arb_periph_irq.isra.7+0x13c/0x24c
[ 5.839785] [<ffffffc0009d785c>] pmic_arb_periph_irq+0x14/0x1c
[ 5.839787] [<ffffffc0000f5b68>] handle_irq_event_percpu+0xb4/0x25c
[ 5.839790] [<ffffffc0000f5d5c>] handle_irq_event+0x4c/0x78
[ 5.839793] [<ffffffc0000f8f7c>] handle_fasteoi_irq+0xcc/0x138
[ 5.839795] [<ffffffc0000f51b0>] generic_handle_irq+0x2c/0x3c
[ 5.839798] [<ffffffc0000f5514>] __handle_domain_irq+0xb0/0xec
[ 5.839801] [<ffffffc000082560>] gic_handle_irq+0x68/0xa8
2、分析
主要有两处地方提供有用信息:
(1)BUG: sleeping function called from invalid context at /home/deanji/hd/sc60_gerrit/F80X/kernel/msm-3.18/kernel/workqueue.c:2644 是说在原子上下文中调用会引起休眠的函数,主要怀疑在中断里调用的函数会引起sleep,但检查代码未能发现此类函数
(2)此处为崩溃调用堆栈,从下往上执行,gpio_usbdetect_vbus_irq这个函数为USB vbus产生中断的中断处理函数,本人程序中会控制VBUS上电操作,驱动为iic驱动,iic驱动会比usb驱动先执行,可能是此处引起的。
[ 5.839728] [<ffffffc0000c820c>] __might_sleep+0x15c/0x16c
[ 5.839732] [<ffffffc0000b9304>] flush_work+0x38/0x154
[ 5.839735] [<ffffffc0000b94dc>] flush_delayed_work+0x3c/0x48
[ 5.839741] [<ffffffc0006e7c88>] dwc3_ext_event_notify+0x28/0x1c0
[ 5.839745] [<ffffffc0006eb020>] dwc3_msm_power_set_property_usb+0x1e0/0x3c0
[ 5.839750] [<ffffffc0008b2f1c>] power_supply_set_present+0x40/0x68
[ 5.839754] [<ffffffc000af2e90>] gpio_usbdetect_vbus_irq+0x3c/0x4c
[ 5.839758] [<ffffffc0000f5b68>] handle_irq_event_percpu+0xb4/0x25c
[ 5.839761] [<ffffffc0000f5d5c>] handle_irq_event+0x4c/0x78
[ 5.839764] [<ffffffc0000f9108>] handle_edge_irq+0x120/0x148
[ 5.839767] [<ffffffc0000f51b0>] generic_handle_irq+0x2c/0x3c
[ 5.839773] [<ffffffc0009d8b48>] __qpnpint_handle_irq+0x120/0x134
[ 5.839776] [<ffffffc0009d8b6c>] qpnpint_handle_irq+0x10/0x18
[ 5.839779] [<ffffffc0009d7520>] periph_interrupt+0x19c/0x1c4
[ 5.839782] [<ffffffc0009d7738>] __pmic_arb_periph_irq.isra.7+0x13c/0x24c
[ 5.839785] [<ffffffc0009d785c>] pmic_arb_periph_irq+0x14/0x1c
[ 5.839787] [<ffffffc0000f5b68>] handle_irq_event_percpu+0xb4/0x25c
[ 5.839790] [<ffffffc0000f5d5c>] handle_irq_event+0x4c/0x78
[ 5.839793] [<ffffffc0000f8f7c>] handle_fasteoi_irq+0xcc/0x138
[ 5.839795] [<ffffffc0000f51b0>] generic_handle_irq+0x2c/0x3c
[ 5.839798] [<ffffffc0000f5514>] __handle_domain_irq+0xb0/0xec
[ 5.839801] [<ffffffc000082560>] gic_handle_irq+0x68/0xa8
(3)在iic程序里,下面第一次程序执行会失败,此处返回 -EPROBE_DEFER,等usb core准备好之后会被再次调用,修改此处代码后再重新测试,发现reboot recovery 出现crash现象,继续分析
usb_psy = power_supply_get_by_name("usb");
if (!usb_psy) {
printk("deanji USB power_supply not found, deferring probe\n");
return -EPROBE_DEFER;
}
(4)由于vbus产生中断设置otg状态机,将vbus中断里面的处理使用delayed work来处理,recovery 不在出现crash,代码如下,