We got a very nice bug report from Naoki Aizu on our Github repository:
imx6_pcie_link_up: scheduling while atomic · Issue #9 · boundarydevices/linux-imx6 · GitHub
The details are also there, but the PCI_OP_WRITE macro is calling the imx6_pcie_link_up() routine while holding an IRQ spinlock. Since imx6_pcie_link_up() calls usleep_range(), this results in the following kernel message:
PCI: enabling device 0000:01:00.0 (0140 -> 0142) BUG: scheduling while atomic: udevd/163/0x00000002 Modules linked in: ath9k(+) ath9k_common ath9k_hw ath CPU: 0 PID: 163 Comm: udevd Not tainted 3.10.17-1.0.0-wandboard-02558-g41aacad #13 [<80014600>] (unwind_backtrace+0x0/0xf8) from [<80011460>] (show_stack+0x10/0x14) [<80011460>] (show_stack+0x10/0x14) from [<8065d720>] (__schedule_bug+0x44/0x5c) [<8065d720>] (__schedule_bug+0x44/0x5c) from [<80663340>] (__schedule+0x4e4/0x58c) [<80663340>] (__schedule+0x4e4/0x58c) from [<80662780>] (schedule_hrtimeout_range_clock+0xd8/0x144) [<80662780>] (schedule_hrtimeout_range_clock+0xd8/0x144) from [<80033d84>] (usleep_range+0x48/0x50) [<80033d84>] (usleep_range+0x48/0x50) from [<802a24d8>] (imx6_pcie_link_up+0x38/0x150) [<802a24d8>] (imx6_pcie_link_up+0x38/0x150) from [<802a1898>] (dw_pcie_valid_config.isra.3+0x3c/0x8c) [<802a1898>] (dw_pcie_valid_config.isra.3+0x3c/0x8c) from [<802a1bc0>] (dw_pcie_wr_conf+0x3c/0xf8) [<802a1bc0>] (dw_pcie_wr_conf+0x3c/0xf8) from [<80291fdc>] (pci_bus_write_config_word+0x60/0x78) [<80291fdc>] (pci_bus_write_config_word+0x60/0x78) from [<802950c4>] (__pci_set_master+0x50/0x64) [<802950c4>] (__pci_set_master+0x50/0x64) from [<80298380>] (pci_set_master+0x10/0x1c) [<80298380>] (pci_set_master+0x10/0x1c) from [<7f081bfc>] (ath_pci_probe+0xe4/0x2b4 [ath9k]) [<7f081bfc>] (ath_pci_probe+0xe4/0x2b4 [ath9k]) from [<80299750>] (pci_device_probe+0x74/0xac) [<80299750>] (pci_device_probe+0x74/0xac) from [<8031b56c>] (driver_probe_device+0x104/0x214) [<8031b56c>] (driver_probe_device+0x104/0x214) from [<8031b708>] (__driver_attach+0x8c/0x90) [<8031b708>] (__driver_attach+0x8c/0x90) from [<80319da4>] (bus_for_each_dev+0x54/0x88) [<80319da4>] (bus_for_each_dev+0x54/0x88) from [<8031ac90>] (bus_add_driver+0xd8/0x228) [<8031ac90>] (bus_add_driver+0xd8/0x228) from [<8031bbbc>] (driver_register+0x78/0x144) [<8031bbbc>] (driver_register+0x78/0x144) from [<7f088008>] (ath9k_init+0x8/0x2c [ath9k]) [<7f088008>] (ath9k_init+0x8/0x2c [ath9k]) from [<8000862c>] (do_one_initcall+0x34/0x15c) [<8000862c>] (do_one_initcall+0x34/0x15c) from [<8006b8b0>] (load_module+0x1a44/0x1e5c) [<8006b8b0>] (load_module+0x1a44/0x1e5c) from [<8006be10>] (SyS_finit_module+0x68/0x6c) [<8006be10>] (SyS_finit_module+0x68/0x6c) from [<8000e080>] (ret_fast_syscall+0x0/0x30) ieee80211 phy0: Atheros AR9462 Rev:2 mem=0xc0c00000, irq=155 =======================
This bug appears in all of the Freescale kernels we've looked at including the 3.10.31_1.1.0_alpha:
pci/access.c linux-2.6-imx.git - Freescale i.MX Linux Tree
pci/host/pci-imx6.c linux-2.6-imx.git - Freescale i.MX Linux Tree
It appears that the delay is needed, so it's not clear how this should be addressed.
已解决! 转到解答。
To close this out, it appears that changing the usleep_range() to udelay() addresses the issue:
imx6_pcie_link_up: scheduling while atomic · Issue #9 · boundarydevices/linux-imx6 · GitHub
Thanks Yuan (and Richard).
I'm not in a position to test, but hopefully provided the right info to Naoki:
imx6_pcie_link_up: scheduling while atomic · Issue #9 · boundarydevices/linux-imx6 · GitHub
To close this out, it appears that changing the usleep_range() to udelay() addresses the issue:
imx6_pcie_link_up: scheduling while atomic · Issue #9 · boundarydevices/linux-imx6 · GitHub