]> git.baikalelectronics.ru Git - kernel.git/commit
net: ethernet: ti: cpsw: fix net watchdog timeout
authorGrygorii Strashko <grygorii.strashko@ti.com>
Wed, 7 Feb 2018 01:17:06 +0000 (19:17 -0600)
committerDavid S. Miller <davem@davemloft.net>
Thu, 8 Feb 2018 02:57:10 +0000 (21:57 -0500)
commit2ea7b68515bf1e81f3a8baa27c266ec6f46ab352
tree0fd9661af957cf921abe217fc4191b65498d8c5d
parentbadca34ebe6f3a9ca53a03dfcde4360a0a25fc12
net: ethernet: ti: cpsw: fix net watchdog timeout

It was discovered that simple program which indefinitely sends 200b UDP
packets and runs on TI AM574x SoC (SMP) under RT Kernel triggers network
watchdog timeout in TI CPSW driver (<6 hours run). The network watchdog
timeout is triggered due to race between cpsw_ndo_start_xmit() and
cpsw_tx_handler() [NAPI]

cpsw_ndo_start_xmit()
if (unlikely(!cpdma_check_free_tx_desc(txch))) {
txq = netdev_get_tx_queue(ndev, q_idx);
netif_tx_stop_queue(txq);

^^ as per [1] barier has to be used after set_bit() otherwise new value
might not be visible to other cpus
}

cpsw_tx_handler()
if (unlikely(netif_tx_queue_stopped(txq)))
netif_tx_wake_queue(txq);

and when it happens ndev TX queue became disabled forever while driver's HW
TX queue is empty.

Fix this, by adding smp_mb__after_atomic() after netif_tx_stop_queue()
calls and double check for free TX descriptors after stopping ndev TX queue
- if there are free TX descriptors wake up ndev TX queue.

[1] https://www.kernel.org/doc/html/latest/core-api/atomic_ops.html
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/ti/cpsw.c