Skip to content
  • Grygorii Strashko's avatar
    net: ethernet: ti: cpsw: fix net watchdog timeout · 62f94c21
    Grygorii Strashko authored
    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: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
    Reviewed-by: default avatarIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    62f94c21