net: mvpp2: fix a txq_done race condition
authorAntoine Tenart <antoine.tenart@bootlin.com>
Tue, 18 Sep 2018 14:58:47 +0000 (16:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Oct 2018 07:18:06 +0000 (09:18 +0200)
[ Upstream commit 774268f3e51b53ed432a1ec516574fd5ba469398 ]

When no Tx IRQ is available, the txq_done() routine (called from
tx_done()) shouldn't be called from the polling function, as in such
case it is already called in the Tx path thanks to an hrtimer. This
mostly occurred when using PPv2.1, as the engine then do not have Tx
IRQs.

Fixes: edc660fa09e2 ("net: mvpp2: replace TX coalescing interrupts with hrtimer")
Reported-by: Stefan Chulski <stefanc@marvell.com>
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c

index 556024c4463a80a7c77eb18775849f39467d6954..3986ef83111b686a3ee6b8cf2e3803d4d220a6a0 100644 (file)
@@ -3056,10 +3056,12 @@ static int mvpp2_poll(struct napi_struct *napi, int budget)
                                   cause_rx_tx & ~MVPP2_CAUSE_MISC_SUM_MASK);
        }
 
-       cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
-       if (cause_tx) {
-               cause_tx >>= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET;
-               mvpp2_tx_done(port, cause_tx, qv->sw_thread_id);
+       if (port->has_tx_irqs) {
+               cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
+               if (cause_tx) {
+                       cause_tx >>= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET;
+                       mvpp2_tx_done(port, cause_tx, qv->sw_thread_id);
+               }
        }
 
        /* Process RX packets */