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.
Solved! Go to Solution.
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
Comments from Richard:
The sleep should be replaced by the delay if it maybe used in the irq-context.
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
Dear Eric,
Our expert team it is reviewing your issue privatly , we will provide an answer soon.
Thanks James