From: Mohammad Shuab Siddique <[email protected]>

Hardware already reports an invalid/bad DMA address on a Tx BD via
the TX_CMPL_ERRORS_DMA_ERROR bit in the Tx completion record, but the
driver never inspected it, so a bad mbuf->buf_iova on Tx completed
silently with no visibility.

Check the bit in bnxt_handle_tx_cp() and in the AVX2/SSE vector
Tx-completion handlers, and count occurrences in a new per-queue
tx_dma_err counter. The counter is folded into the standard oerrors
stat and also exposed as a named xstat (tx_dma_err_pkts) for
finer-grained visibility.

Signed-off-by: Mohammad Shuab Siddique <[email protected]>
---
v2:
* Added a release notes entry documenting the new tx_dma_err_pkts
  xstat, per reviewer request.
* Left the bnxt_stats_reset_op() reset of tx_dma_err as a direct
  assignment rather than an atomic store, matching the existing
  tx_mbuf_drop reset immediately above it (same file, same pattern);
  changing only the new field would be inconsistent, and the reset
  path isn't concurrent with the fast-path increments.
* NOTE: apply this patch before "net/bnxt: add support for queue size
  of 16384" (v2) -- both add a bullet under the same "Updated bnxt
  driver" release-notes heading, and the latter's context assumes
  this one's bullet is already present. Send/apply order below
  reflects this.

 doc/guides/rel_notes/release_26_11.rst |  6 ++++++
 drivers/net/bnxt/bnxt_rxtx_vec_avx2.c  |  6 ++++++
 drivers/net/bnxt/bnxt_rxtx_vec_sse.c   |  6 ++++++
 drivers/net/bnxt/bnxt_stats.c          | 20 ++++++++++++++++++++
 drivers/net/bnxt/bnxt_stats.h          |  3 +++
 drivers/net/bnxt/bnxt_txq.h            |  1 +
 drivers/net/bnxt/bnxt_txr.c            |  6 ++++++
 7 files changed, 48 insertions(+)

diff --git a/doc/guides/rel_notes/release_26_11.rst 
b/doc/guides/rel_notes/release_26_11.rst
index 87c7e81bdeb..abda472f379 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -55,6 +55,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================

+* **Updated bnxt driver.**
+
+  * Added a per-queue ``tx_dma_err_pkts`` xstat to report Tx completions
+    that the device flagged with a DMA error. These are also folded into
+    the standard ``oerrors`` counter.
+

 Removed Items
 -------------
diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c 
b/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
index 50b3602839..7f07b0a3e1 100644
--- a/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
+++ b/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
@@ -743,6 +743,12 @@ bnxt_handle_tx_cp_vec(struct bnxt_tx_queue *txq)
                if (!bnxt_cpr_cmp_valid(txcmp, raw_cons, ring_mask + 1))
                        break;
 
+               uint16_t errors_v = rte_le_to_cpu_16(txcmp->errors_v);
+
+               if (unlikely(errors_v & TX_CMPL_ERRORS_DMA_ERROR))
+                       rte_atomic_fetch_add_explicit(&txq->tx_dma_err, 1,
+                                                     rte_memory_order_relaxed);
+
                nb_tx_pkts += txcmp->opaque;
                raw_cons = NEXT_RAW_CMP(raw_cons);
        } while (nb_tx_pkts < ring_mask);
diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_sse.c 
b/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
index 7d455b6f56..a97ff6f5fe 100644
--- a/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
+++ b/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
@@ -577,6 +577,12 @@ bnxt_handle_tx_cp_vec(struct bnxt_tx_queue *txq)
                if (!bnxt_cpr_cmp_valid(txcmp, raw_cons, ring_mask + 1))
                        break;
 
+               uint16_t errors_v = rte_le_to_cpu_16(txcmp->errors_v);
+
+               if (unlikely(errors_v & TX_CMPL_ERRORS_DMA_ERROR))
+                       rte_atomic_fetch_add_explicit(&txq->tx_dma_err, 1,
+                                                     rte_memory_order_relaxed);
+
                if (likely(CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2))
                        nb_tx_pkts += txcmp->opaque;
                else
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index ba858710a5..52d2456b66 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -697,6 +697,8 @@ static int bnxt_stats_get_ext(struct rte_eth_dev *eth_dev,
 
                bnxt_stats->oerrors += 
rte_atomic_load_explicit(&txq->tx_mbuf_drop,
                                                             
rte_memory_order_relaxed);
+               bnxt_stats->oerrors += 
rte_atomic_load_explicit(&txq->tx_dma_err,
+                                                            
rte_memory_order_relaxed);
 
                if (!txq->tx_started)
                        continue;
@@ -774,6 +776,9 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
                bnxt_stats->oerrors +=
                                rte_atomic_load_explicit(&txq->tx_mbuf_drop,
                                                         
rte_memory_order_relaxed);
+               bnxt_stats->oerrors +=
+                               rte_atomic_load_explicit(&txq->tx_dma_err,
+                                                        
rte_memory_order_relaxed);
        }
 
        return rc;
@@ -824,6 +829,7 @@ int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
                struct bnxt_tx_queue *txq = bp->tx_queues[i];
 
                txq->tx_mbuf_drop = 0;
+               txq->tx_dma_err = 0;
        }
 
        bnxt_clear_prev_stat(bp);
@@ -927,6 +933,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
                RTE_DIM(bnxt_tx_stats_strings) + sz +
                RTE_DIM(bnxt_rx_ext_stats_strings) +
                RTE_DIM(bnxt_tx_ext_stats_strings) +
+               BNXT_NUM_SW_XSTATS +
                bnxt_flow_stats_cnt(bp);
 
        if (n < stat_count || xstats == NULL)
@@ -1049,6 +1056,14 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
                count++;
        }
 
+       xstats[count].id = count;
+       xstats[count].value = 0;
+       for (i = 0; i < bp->tx_cp_nr_rings; i++)
+               xstats[count].value +=
+                       rte_atomic_load_explicit(&bp->tx_queues[i]->tx_dma_err,
+                                                rte_memory_order_relaxed);
+       count++;
+
        if (bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS &&
            bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT &&
            BNXT_FLOW_XSTATS_EN(bp)) {
@@ -1128,6 +1143,7 @@ int bnxt_dev_xstats_get_names_op(struct rte_eth_dev 
*eth_dev,
                                sz +
                                RTE_DIM(bnxt_rx_ext_stats_strings) +
                                RTE_DIM(bnxt_tx_ext_stats_strings) +
+                               BNXT_NUM_SW_XSTATS +
                                bnxt_flow_stats_cnt(bp);
 
        if (xstats_names == NULL || size < stat_cnt)
@@ -1181,6 +1197,10 @@ int bnxt_dev_xstats_get_names_op(struct rte_eth_dev 
*eth_dev,
                count++;
        }
 
+       strlcpy(xstats_names[count].name, "tx_dma_err_pkts",
+               sizeof(xstats_names[count].name));
+       count++;
+
        if (bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_COUNTERS &&
            bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT &&
            BNXT_FLOW_XSTATS_EN(bp)) {
diff --git a/drivers/net/bnxt/bnxt_stats.h b/drivers/net/bnxt/bnxt_stats.h
index c0508e773a..534b9af5e8 100644
--- a/drivers/net/bnxt/bnxt_stats.h
+++ b/drivers/net/bnxt/bnxt_stats.h
@@ -8,6 +8,9 @@
 
 #include <ethdev_driver.h>
 
+/* Number of software (non-HWRM) xstats appended after the FW-reported ones. */
+#define BNXT_NUM_SW_XSTATS             1
+
 void bnxt_free_stats(struct bnxt *bp);
 int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
                           struct rte_eth_stats *bnxt_stats, struct 
eth_queue_stats *qstats);
diff --git a/drivers/net/bnxt/bnxt_txq.h b/drivers/net/bnxt/bnxt_txq.h
index ac8af91c57..525f841789 100644
--- a/drivers/net/bnxt/bnxt_txq.h
+++ b/drivers/net/bnxt/bnxt_txq.h
@@ -36,6 +36,7 @@ struct bnxt_tx_queue {
        struct rte_mbuf **free;
        uint64_t offloads;
        RTE_ATOMIC(uint64_t)    tx_mbuf_drop;
+       RTE_ATOMIC(uint64_t)    tx_dma_err;
 };
 
 void bnxt_free_txq_stats(struct bnxt_tx_queue *txq);
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 3fae0824d1..edd99dc84a 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -782,6 +782,12 @@ static int bnxt_handle_tx_cp(struct bnxt_tx_queue *txq)
                if (!bnxt_cpr_cmp_valid(txcmp, raw_cons, ring_mask + 1))
                        break;
 
+               uint16_t errors_v = rte_le_to_cpu_16(txcmp->errors_v);
+
+               if (unlikely(errors_v & TX_CMPL_ERRORS_DMA_ERROR))
+                       rte_atomic_fetch_add_explicit(&txq->tx_dma_err, 1,
+                                                     rte_memory_order_relaxed);
+
                if (CMP_TYPE(txcmp) == CMPL_BASE_TYPE_TX_L2_COAL) {
                        struct tx_cmpl_coal *txcmp_c = (struct tx_cmpl_coal 
*)txcmp;
 
-- 
2.47.3

Reply via email to