| From f8b5a34ad90eaffba508c49dfa1530cab7ef003d Mon Sep 17 00:00:00 2001 |
| From: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> |
| Date: Thu, 19 Mar 2020 23:08:10 +0530 |
| Subject: [PATCH] cxgb4: fix Txq restart check during backpressure |
| |
| commit f1f20a8666c55cb534b8f3fc1130eebf01a06155 upstream. |
| |
| 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: d429005fdf2c ("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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c |
| index 3af6d8376a66..3a45ac8f0e01 100644 |
| --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c |
| +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c |
| @@ -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++; |
| } |
| -- |
| 2.7.4 |
| |