OSDN Git Service

cxgb4: Fix race between loopback and normal Tx path
authorGanji Aravind <ganji.aravind@chelsio.com>
Tue, 18 Aug 2020 15:40:58 +0000 (21:10 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 18 Aug 2020 20:02:51 +0000 (13:02 -0700)
Even after Tx queues are marked stopped, there exists a
small window where the current packet in the normal Tx
path is still being sent out and loopback selftest ends
up corrupting the same Tx ring. So, ensure selftest takes
the Tx lock to synchronize access the Tx ring.

Fixes: 7235ffae3d2c ("cxgb4: add loopback ethtool self-test")
Signed-off-by: Ganji Aravind <ganji.aravind@chelsio.com>
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/sge.c

index 7c9fe4b..869431a 100644 (file)
@@ -2561,11 +2561,14 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
        lb->loopback = 1;
 
        q = &adap->sge.ethtxq[pi->first_qset];
+       __netif_tx_lock(q->txq, smp_processor_id());
 
        reclaim_completed_tx(adap, &q->q, -1, true);
        credits = txq_avail(&q->q) - ndesc;
-       if (unlikely(credits < 0))
+       if (unlikely(credits < 0)) {
+               __netif_tx_unlock(q->txq);
                return -ENOMEM;
+       }
 
        wr = (void *)&q->q.desc[q->q.pidx];
        memset(wr, 0, sizeof(struct tx_desc));
@@ -2598,6 +2601,7 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
        init_completion(&lb->completion);
        txq_advance(&q->q, ndesc);
        cxgb4_ring_tx_db(adap, &q->q, ndesc);
+       __netif_tx_unlock(q->txq);
 
        /* wait for the pkt to return */
        ret = wait_for_completion_timeout(&lb->completion, 10 * HZ);