|SUCCESS| [RFC,7/7] ethdev: remove support for queue stats mapping
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Sat May 30 19:16:36 CEST 2026
Test-Label: ai-code-review
Test-Status: SUCCESS
https://dpdk.org/patch/164676
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-05-30
# DPDK Patch Review
**Commit:** Unknown SHA
**Author:** Stephen Hemminger <stephen at networkplumber.org>
**Subject:** [RFC 1/7] net/virtio: remove unused queue stats mapping
This is a review of a 7-patch series removing the deprecated queue stats
mapping feature from multiple DPDK drivers and the ethdev core. The
feature was deprecated in DPDK 25.11.
## Overall Comments
The patch series appropriately removes deprecated functionality following
the deprecation notice. However, several patches contain issues that need
to be addressed.
---
## Patch 1/7: net/virtio
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index 9fd746b80f..0b2574bd02 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -90,12 +90,6 @@ static int virtio_intr_disable(struct rte_eth_dev *dev);
> static int virtio_get_monitor_addr(void *rx_queue,
> struct rte_power_monitor_cond *pmc);
>
> -static int virtio_dev_queue_stats_mapping_set(
> - struct rte_eth_dev *eth_dev,
> - uint16_t queue_id,
> - uint8_t stat_idx,
> - uint8_t is_rx);
> -
> static void virtio_notify_peers(struct rte_eth_dev *dev);
> static void virtio_ack_link_announce(struct rte_eth_dev *dev);
This patch is straightforward and correct.
---
## Patch 2/7: net/enic
This patch is straightforward and correct - it removes explicit NULL
initializations that are unnecessary.
---
## Patch 3/7: net/cnxk
> diff --git a/drivers/net/cnxk/cnxk_stats.c b/drivers/net/cnxk/cnxk_stats.c
> index d57659ef51..e5d29a78b3 100644
> --- a/drivers/net/cnxk/cnxk_stats.c
> +++ b/drivers/net/cnxk/cnxk_stats.c
> @@ -14,7 +14,8 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
> struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
> struct roc_nix *nix = &dev->nix;
> struct roc_nix_stats nix_stats;
> - int rc = 0, i;
> + unsigned int i;
> + int rc = 0;
Does the variable order change here comply with reverse Christmas tree
ordering? The rc variable should come before the i variable in the
declaration if following that convention.
> @@ -33,31 +34,35 @@ cnxk_nix_stats_get(struct rte_eth_dev *eth_dev, struct rte_eth_stats *stats,
> stats->ibytes = nix_stats.rx_octs;
> stats->ierrors = nix_stats.rx_err;
>
> - if (qstats != NULL) {
> - for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
> [ ... ]
> + if (qstats == NULL)
> + goto exit;
The coding style guide indicates that NULL comparisons should be made
explicit. Does this follow the guideline, or should it be
`if (qstats == NULL)` instead? Actually, this is correct as written.
> +
> + for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
> + struct roc_nix_stats_queue qstats_data;
> +
> + if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
> + break;
Can this loop overflow RTE_ETHDEV_QUEUE_STAT_CNTRS in qstats array
accesses before the break check executes?
> + rc = roc_nix_stats_queue_get(nix, i, 0, &qstats_data);
> + if (rc)
> + goto exit;
> + qstats->q_opackets[i] = qstats_data.tx_pkts;
> + qstats->q_obytes[i] = qstats_data.tx_octs;
> + qstats->q_errors[i] = qstats_data.tx_drop_pkts;
> + }
---
## Patch 4/7: net/e1000
> diff --git a/drivers/net/intel/e1000/igc_ethdev.c b/drivers/net/intel/e1000/igc_ethdev.c
> index 727ea36c2b..891c810132 100644
> --- a/drivers/net/intel/e1000/igc_ethdev.c
> +++ b/drivers/net/intel/e1000/igc_ethdev.c
> @@ -1362,7 +1359,7 @@ eth_igc_dev_init(struct rte_eth_dev *dev)
> struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
> struct igc_adapter *igc = IGC_DEV_PRIVATE(dev);
> struct e1000_hw *hw = IGC_DEV_PRIVATE_HW(dev);
> - int i, error = 0;
> + int error = 0;
Good cleanup of unused variable.
> @@ -2070,19 +2060,11 @@ eth_igc_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats,
> /* Get per-queue statuses */
> if (qstats) {
> for (i = 0; i < IGC_QUEUE_PAIRS_NUM; i++) {
> - /* GET TX queue statuses */
> - int map_id = igc->txq_stats_map[i];
> - if (map_id >= 0) {
> - qstats->q_opackets[map_id] += queue_stats->pqgptc[i];
> - qstats->q_obytes[map_id] += queue_stats->pqgotc[i];
> - }
> - /* Get RX queue statuses */
> - map_id = igc->rxq_stats_map[i];
> - if (map_id >= 0) {
> - qstats->q_ipackets[map_id] += queue_stats->pqgprc[i];
> - qstats->q_ibytes[map_id] += queue_stats->pqgorc[i];
> - qstats->q_errors[map_id] += queue_stats->rqdpc[i];
> - }
> + qstats->q_opackets[i] += queue_stats->pqgptc[i];
> + qstats->q_obytes[i] += queue_stats->pqgotc[i];
> + qstats->q_ipackets[i] += queue_stats->pqgprc[i];
> + qstats->q_ibytes[i] += queue_stats->pqgorc[i];
> + qstats->q_errors[i] += queue_stats->rqdpc[i];
Can this code write beyond RTE_ETHDEV_QUEUE_STAT_CNTRS when
IGC_QUEUE_PAIRS_NUM exceeds RTE_ETHDEV_QUEUE_STAT_CNTRS? A bounds check
similar to the one in Patch 3 is needed here.
---
## Patch 5/7: net/ixgbe
> diff --git a/drivers/net/intel/ixgbe/ixgbe_ethdev.c b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
> index 9dc015dfff..a7d995a768 100644
> --- a/drivers/net/intel/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/intel/ixgbe/ixgbe_ethdev.c
> @@ -886,96 +881,6 @@ ixgbe_reset_qstat_mappings(struct ixgbe_hw *hw)
> }
> }
>
> -
> -static int
> -ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
> [ ... ]
This patch correctly removes the queue stats mapping implementation and
its restore function. The removal of ixgbe_restore_statistics_mapping()
from the dev_start path is correct.
---
## Patch 6/7: net/txgbe
> diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
> index 5d360f8305..3886a2cbf4 100644
> --- a/drivers/net/txgbe/txgbe_ethdev.c
> +++ b/drivers/net/txgbe/txgbe_ethdev.c
> @@ -2457,10 +2403,8 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
> {
> struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
> struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
> - struct txgbe_stat_mappings *stat_mappings =
> - TXGBE_DEV_STAT_MAPPINGS(dev);
> struct txgbe_tx_queue *txq;
> - uint32_t i, j;
> + unsigned int i;
Good cleanup. The variable type change from uint32_t to unsigned int is
appropriate for loop counters.
> @@ -2474,29 +2418,13 @@ txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
> stats->obytes = hw_stats->tx_bytes;
>
> if (qstats != NULL) {
> - memset(&qstats->q_ipackets, 0, sizeof(qstats->q_ipackets));
> [ ... all the memsets snipped ... ]
> for (i = 0; i < TXGBE_MAX_QP; i++) {
> - uint32_t n = i / NB_QMAP_FIELDS_PER_QSM_REG;
> [ ... ]
> + if (i >= RTE_ETHDEV_QUEUE_STAT_CNTRS)
> + break;
> + qstats->q_ipackets[i] += hw_stats->qp[i].rx_qp_packets;
> + qstats->q_ibytes[i] += hw_stats->qp[i].rx_qp_bytes;
> + qstats->q_opackets[i] += hw_stats->qp[i].tx_qp_packets;
> + qstats->q_obytes[i] += hw_stats->qp[i].tx_qp_bytes;
Does removing the memset operations cause uninitialized data to be
returned if TXGBE_MAX_QP < RTE_ETHDEV_QUEUE_STAT_CNTRS? The caller may be
expecting all fields to be initialized.
---
## Patch 7/7: ethdev core
> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index d0273e3f7b..e9bd5ba473 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -160,11 +160,6 @@ static const struct {
> {RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP, "FLOW_SHARED_OBJECT_KEEP"},
> };
>
> -enum {
> - STAT_QMAP_TX = 0,
> - STAT_QMAP_RX
> -};
This patch correctly removes the API functions, trace points, and
documentation. The removal is complete and appropriate.
---
## Summary
The patch series correctly removes deprecated functionality, but has
potential issues in patches 3, 4, and 6 regarding array bounds checking and
initialization.
More information about the test-report
mailing list