| From foo@baz Thu 06 Feb 2020 06:56:59 AM GMT |
| From: Nicolin Chen <nicoleotsuka@gmail.com> |
| Date: Fri, 31 Jan 2020 18:01:24 -0800 |
| Subject: net: stmmac: Delete txtimer in suspend() |
| |
| From: Nicolin Chen <nicoleotsuka@gmail.com> |
| |
| [ Upstream commit 14b41a2959fbaa50932699d32ceefd6643abacc6 ] |
| |
| When running v5.5 with a rootfs on NFS, memory abort may happen in |
| the system resume stage: |
| Unable to handle kernel paging request at virtual address dead00000000012a |
| [dead00000000012a] address between user and kernel address ranges |
| pc : run_timer_softirq+0x334/0x3d8 |
| lr : run_timer_softirq+0x244/0x3d8 |
| x1 : ffff800011cafe80 x0 : dead000000000122 |
| Call trace: |
| run_timer_softirq+0x334/0x3d8 |
| efi_header_end+0x114/0x234 |
| irq_exit+0xd0/0xd8 |
| __handle_domain_irq+0x60/0xb0 |
| gic_handle_irq+0x58/0xa8 |
| el1_irq+0xb8/0x180 |
| arch_cpu_idle+0x10/0x18 |
| do_idle+0x1d8/0x2b0 |
| cpu_startup_entry+0x24/0x40 |
| secondary_start_kernel+0x1b4/0x208 |
| Code: f9000693 a9400660 f9000020 b4000040 (f9000401) |
| ---[ end trace bb83ceeb4c482071 ]--- |
| Kernel panic - not syncing: Fatal exception in interrupt |
| SMP: stopping secondary CPUs |
| SMP: failed to stop secondary CPUs 2-3 |
| Kernel Offset: disabled |
| CPU features: 0x00002,2300aa30 |
| Memory Limit: none |
| ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]--- |
| |
| It's found that stmmac_xmit() and stmmac_resume() sometimes might |
| run concurrently, possibly resulting in a race condition between |
| mod_timer() and setup_timer(), being called by stmmac_xmit() and |
| stmmac_resume() respectively. |
| |
| Since the resume() runs setup_timer() every time, it'd be safer to |
| have del_timer_sync() in the suspend() as the counterpart. |
| |
| Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
| +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
| @@ -4513,6 +4513,7 @@ int stmmac_suspend(struct device *dev) |
| { |
| struct net_device *ndev = dev_get_drvdata(dev); |
| struct stmmac_priv *priv = netdev_priv(ndev); |
| + u32 chan; |
| |
| if (!ndev || !netif_running(ndev)) |
| return 0; |
| @@ -4527,6 +4528,9 @@ int stmmac_suspend(struct device *dev) |
| |
| stmmac_disable_all_queues(priv); |
| |
| + for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) |
| + del_timer_sync(&priv->tx_queue[chan].txtimer); |
| + |
| /* Stop TX/RX DMA */ |
| stmmac_stop_all_dma(priv); |
| |