The Tx cleanup helpers check the DD bit of the descriptor at the next
RS boundary and assume software has already posted it. The burst path
guarantees this by only cleaning up when nb_tx_free drops below
tx_free_thresh, but iavf_dev_tx_drain() called the helpers on any
non-empty queue.
With fewer than tx_rs_thresh descriptors outstanding, that descriptor
still held the DESC_DONE value set by reset_tx_queue(), so the helpers
treated the block as complete and freed NULL (or already freed) mbufs,
crashing on PF reset.
Only clean up a queue once a full RS block is outstanding.
Fixes: 30e1aab01bae ("net/iavf: drain in-flight Tx before reset")
Cc: [email protected]
Signed-off-by: Ciara Loftus <[email protected]>
---
drivers/net/intel/iavf/iavf_rxtx.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/net/intel/iavf/iavf_rxtx.c
b/drivers/net/intel/iavf/iavf_rxtx.c
index 84b931e78a..8c84991b86 100644
--- a/drivers/net/intel/iavf/iavf_rxtx.c
+++ b/drivers/net/intel/iavf/iavf_rxtx.c
@@ -4098,11 +4098,9 @@ iavf_dev_tx_drain(struct rte_eth_dev *dev)
RTE_ETH_QUEUE_STATE_STARTED)
continue;
- /*
- * nb_tx_free == nb_tx_desc - 1 means the ring is
- * empty (one descriptor is always reserved).
- */
- if (txq->nb_tx_free >= txq->nb_tx_desc - 1)
+ /* Only clean up once a full RS block is outstanding. */
+ if ((uint16_t)(txq->nb_tx_desc - 1 - txq->nb_tx_free) <
+ txq->tx_rs_thresh)
continue;
any_pending = true;
--
2.43.0