]> git.baikalelectronics.ru Git - kernel.git/commitdiff
cxgb4: fix Txq restart check during backpressure
authorRahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Thu, 19 Mar 2020 17:38:10 +0000 (23:08 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Apr 2020 09:01:30 +0000 (11:01 +0200)
[ Upstream commit ccd4b270a7ea674c553d9c998cec09b650ef5b95 ]

Driver reclaims descriptors in much smaller batches, even if hardware
indicates more to reclaim, during backpressure. So, fix the check to
restart the Txq during backpressure, by looking at how many
descriptors hardware had indicated to reclaim, and not on how many
descriptors that driver had actually reclaimed. Once the Txq is
restarted, driver will reclaim even more descriptors when Tx path
is entered again.

Fixes: bd0ef9097b8b ("cxgb4/cxgb4vf: Add support for SGE doorbell queue timer")
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/chelsio/cxgb4/sge.c

index 3af6d8376a663612bd97377cd480efcbd272404a..3a45ac8f0e01141b04fcb41611162ca8dbb96079 100644 (file)
@@ -1324,8 +1324,9 @@ static inline void t6_fill_tnl_lso(struct sk_buff *skb,
 int t4_sge_eth_txq_egress_update(struct adapter *adap, struct sge_eth_txq *eq,
                                 int maxreclaim)
 {
+       unsigned int reclaimed, hw_cidx;
        struct sge_txq *q = &eq->q;
-       unsigned int reclaimed;
+       int hw_in_use;
 
        if (!q->in_use || !__netif_tx_trylock(eq->txq))
                return 0;
@@ -1333,12 +1334,17 @@ int t4_sge_eth_txq_egress_update(struct adapter *adap, struct sge_eth_txq *eq,
        /* Reclaim pending completed TX Descriptors. */
        reclaimed = reclaim_completed_tx(adap, &eq->q, maxreclaim, true);
 
+       hw_cidx = ntohs(READ_ONCE(q->stat->cidx));
+       hw_in_use = q->pidx - hw_cidx;
+       if (hw_in_use < 0)
+               hw_in_use += q->size;
+
        /* If the TX Queue is currently stopped and there's now more than half
         * the queue available, restart it.  Otherwise bail out since the rest
         * of what we want do here is with the possibility of shipping any
         * currently buffered Coalesced TX Work Request.
         */
-       if (netif_tx_queue_stopped(eq->txq) && txq_avail(q) > (q->size / 2)) {
+       if (netif_tx_queue_stopped(eq->txq) && hw_in_use < (q->size / 2)) {
                netif_tx_wake_queue(eq->txq);
                eq->q.restarts++;
        }