[v4] ethdev: TEST support single queue per port

Message ID 20241024145550.985298-1-mb@smartsharesystems.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series [v4] ethdev: TEST support single queue per port |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing fail Unit Testing FAIL
ci/Intel-compilation fail Compilation issues
ci/intel-Testing success Testing PASS
ci/github-robot: build fail github build: failed
ci/intel-Functional success Functional PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-marvell-Functional success Functional Testing PASS
ci/iol-intel-Functional fail Functional Testing issues
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-unit-amd64-testing fail Testing issues
ci/iol-compile-arm64-testing fail Testing issues
ci/iol-compile-amd64-testing fail Testing issues
ci/iol-sample-apps-testing success Testing PASS

Commit Message

Morten Brørup Oct. 24, 2024, 2:55 p.m. UTC
Configuring one queue per port fails compilation on my system.
Test to see how much it fails in CI.

Signed-off-by: Morten Brørup <mb@smartsharesystems.com>
---
v4:
* Workaound GCC optimizer incorrectly throwing a warning in these network
  drivers:
  * bnxt
  * e1000
  * failsafe
  * hns3
v3:
* Fix net/ixgbe driver.
v2:
* Fix net/vmxnet3 driver.
---
 config/rte_config.h                  |  4 ++--
 drivers/net/bnxt/bnxt_ethdev.c       |  3 +++
 drivers/net/e1000/igb_rxtx.c         |  3 +++
 drivers/net/failsafe/failsafe_ops.c  |  6 ++++++
 drivers/net/hns3/hns3_rxtx.c         |  3 +++
 drivers/net/ixgbe/ixgbe_ethdev.c     |  3 ++-
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 32 +++++++++++++++++-----------
 7 files changed, 39 insertions(+), 15 deletions(-)
  

Comments

Stephen Hemminger Oct. 24, 2024, 4:41 p.m. UTC | #1
On Thu, 24 Oct 2024 14:55:50 +0000
Morten Brørup <mb@smartsharesystems.com> wrote:

> diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
> index 1f7c0d77d5..f34a953ecd 100644
> --- a/drivers/net/bnxt/bnxt_ethdev.c
> +++ b/drivers/net/bnxt/bnxt_ethdev.c
> @@ -842,6 +842,8 @@ static int bnxt_alloc_prev_ring_stats(struct bnxt *bp)
>  	return -ENOMEM;
>  }
>  
> +#pragma GCC push_options
> +#pragma GCC optimize("no-peel-loops")
>  static int bnxt_start_nic(struct bnxt *bp)
>  {
>  	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev);
> @@ -1006,6 +1008,7 @@ static int bnxt_start_nic(struct bnxt *bp)
>  
>  	return rc;
>  }
> +#pragma GCC pop_options

What is the warning, I hate pragma's they are technical debt.
  
Morten Brørup Oct. 24, 2024, 6:38 p.m. UTC | #2
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Thursday, 24 October 2024 18.42
> 
> On Thu, 24 Oct 2024 14:55:50 +0000
> Morten Brørup <mb@smartsharesystems.com> wrote:
> 
> > diff --git a/drivers/net/bnxt/bnxt_ethdev.c
> b/drivers/net/bnxt/bnxt_ethdev.c
> > index 1f7c0d77d5..f34a953ecd 100644
> > --- a/drivers/net/bnxt/bnxt_ethdev.c
> > +++ b/drivers/net/bnxt/bnxt_ethdev.c
> > @@ -842,6 +842,8 @@ static int bnxt_alloc_prev_ring_stats(struct bnxt
> *bp)
> >  	return -ENOMEM;
> >  }
> >
> > +#pragma GCC push_options
> > +#pragma GCC optimize("no-peel-loops")
> >  static int bnxt_start_nic(struct bnxt *bp)
> >  {
> >  	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev);
> > @@ -1006,6 +1008,7 @@ static int bnxt_start_nic(struct bnxt *bp)
> >
> >  	return rc;
> >  }
> > +#pragma GCC pop_options
> 
> What is the warning,

The warning is about access at offset beyond the array.
It seems the optimizer loop unrolls or something similar, not realizing the array only has one entry. And then it warns when it realizes afterwards.

> I hate pragma's they are technical debt.

Me too.
The CI shows that clang doesn't have this problem, only GCC.
But we should to be able to build DPDK with only one queue per port, to conserve memory.
  

Patch

diff --git a/config/rte_config.h b/config/rte_config.h
index fd6f8a2f1a..924192c71c 100644
--- a/config/rte_config.h
+++ b/config/rte_config.h
@@ -65,8 +65,8 @@ 
 #define RTE_MBUF_DEFAULT_MEMPOOL_OPS "ring_mp_mc"
 
 /* ether defines */
-#define RTE_MAX_QUEUES_PER_PORT 1024
-#define RTE_ETHDEV_QUEUE_STAT_CNTRS 16 /* max 256 */
+#define RTE_MAX_QUEUES_PER_PORT 1 /* default 1024 */
+#define RTE_ETHDEV_QUEUE_STAT_CNTRS 1 /* max 256, default 16 */
 #define RTE_ETHDEV_RXTX_CALLBACKS 1
 #define RTE_MAX_MULTI_HOST_CTRLS 4
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 1f7c0d77d5..f34a953ecd 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -842,6 +842,8 @@  static int bnxt_alloc_prev_ring_stats(struct bnxt *bp)
 	return -ENOMEM;
 }
 
+#pragma GCC push_options
+#pragma GCC optimize("no-peel-loops")
 static int bnxt_start_nic(struct bnxt *bp)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(bp->eth_dev);
@@ -1006,6 +1008,7 @@  static int bnxt_start_nic(struct bnxt *bp)
 
 	return rc;
 }
+#pragma GCC pop_options
 
 static int bnxt_shutdown_nic(struct bnxt *bp)
 {
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index d61eaad2de..bcc62011cb 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1860,6 +1860,8 @@  eth_igb_tx_descriptor_status(void *tx_queue, uint16_t offset)
 	return RTE_ETH_TX_DESC_FULL;
 }
 
+#pragma GCC push_options
+#pragma GCC optimize("no-peel-loops")
 void
 igb_dev_clear_queues(struct rte_eth_dev *dev)
 {
@@ -1885,6 +1887,7 @@  igb_dev_clear_queues(struct rte_eth_dev *dev)
 		}
 	}
 }
+#pragma GCC pop_options
 
 void
 igb_dev_free_queues(struct rte_eth_dev *dev)
diff --git a/drivers/net/failsafe/failsafe_ops.c b/drivers/net/failsafe/failsafe_ops.c
index 9c013e0419..70862420b8 100644
--- a/drivers/net/failsafe/failsafe_ops.c
+++ b/drivers/net/failsafe/failsafe_ops.c
@@ -103,6 +103,8 @@  fs_dev_configure(struct rte_eth_dev *dev)
 	return 0;
 }
 
+#pragma GCC push_options
+#pragma GCC optimize("no-peel-loops")
 static void
 fs_set_queues_state_start(struct rte_eth_dev *dev)
 {
@@ -123,6 +125,7 @@  fs_set_queues_state_start(struct rte_eth_dev *dev)
 						RTE_ETH_QUEUE_STATE_STARTED;
 	}
 }
+#pragma GCC pop_options
 
 static int
 fs_dev_start(struct rte_eth_dev *dev)
@@ -171,6 +174,8 @@  fs_dev_start(struct rte_eth_dev *dev)
 	return 0;
 }
 
+#pragma GCC push_options
+#pragma GCC optimize("no-peel-loops")
 static void
 fs_set_queues_state_stop(struct rte_eth_dev *dev)
 {
@@ -185,6 +190,7 @@  fs_set_queues_state_stop(struct rte_eth_dev *dev)
 			dev->data->tx_queue_state[i] =
 						RTE_ETH_QUEUE_STATE_STOPPED;
 }
+#pragma GCC pop_options
 
 static int
 fs_dev_stop(struct rte_eth_dev *dev)
diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c
index 5941b966e0..ad03dcc108 100644
--- a/drivers/net/hns3/hns3_rxtx.c
+++ b/drivers/net/hns3/hns3_rxtx.c
@@ -1299,6 +1299,8 @@  hns3_init_queues(struct hns3_adapter *hns, bool reset_queue)
 	return ret;
 }
 
+#pragma GCC push_options
+#pragma GCC optimize("no-peel-loops")
 void
 hns3_start_tqps(struct hns3_hw *hw)
 {
@@ -1322,6 +1324,7 @@  hns3_start_tqps(struct hns3_hw *hw)
 				RTE_ETH_QUEUE_STATE_STARTED;
 	}
 }
+#pragma GCC pop_options
 
 void
 hns3_stop_tqps(struct hns3_hw *hw)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index ab37c37469..895d6e7169 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3385,7 +3385,8 @@  ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	stats->opackets = hw_stats->gptc;
 	stats->obytes = hw_stats->gotc;
 
-	for (i = 0; i < IXGBE_QUEUE_STAT_COUNTERS; i++) {
+	for (i = 0; i < RTE_MIN(IXGBE_QUEUE_STAT_COUNTERS,
+			(typeof(IXGBE_QUEUE_STAT_COUNTERS))RTE_ETHDEV_QUEUE_STAT_CNTRS); i++) {
 		stats->q_ipackets[i] = hw_stats->qprc[i];
 		stats->q_opackets[i] = hw_stats->qptc[i];
 		stats->q_ibytes[i] = hw_stats->qbrc[i];
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 78fac63ab6..8a9bb452c6 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -1470,42 +1470,52 @@  vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	struct vmxnet3_hw *hw = dev->data->dev_private;
 	struct UPT1_TxStats txStats;
 	struct UPT1_RxStats rxStats;
+	uint64_t packets, bytes;
 
 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
 
 	for (i = 0; i < hw->num_tx_queues; i++) {
 		vmxnet3_tx_stats_get(hw, i, &txStats);
 
-		stats->q_opackets[i] = txStats.ucastPktsTxOK +
+		packets = txStats.ucastPktsTxOK +
 			txStats.mcastPktsTxOK +
 			txStats.bcastPktsTxOK;
 
-		stats->q_obytes[i] = txStats.ucastBytesTxOK +
+		bytes = txStats.ucastBytesTxOK +
 			txStats.mcastBytesTxOK +
 			txStats.bcastBytesTxOK;
 
-		stats->opackets += stats->q_opackets[i];
-		stats->obytes += stats->q_obytes[i];
+		stats->opackets += packets;
+		stats->obytes += bytes;
 		stats->oerrors += txStats.pktsTxError + txStats.pktsTxDiscard;
+
+		if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+			stats->q_opackets[i] = packets;
+			stats->q_obytes[i] = bytes;
+		}
 	}
 
 	for (i = 0; i < hw->num_rx_queues; i++) {
 		vmxnet3_rx_stats_get(hw, i, &rxStats);
 
-		stats->q_ipackets[i] = rxStats.ucastPktsRxOK +
+		packets = rxStats.ucastPktsRxOK +
 			rxStats.mcastPktsRxOK +
 			rxStats.bcastPktsRxOK;
 
-		stats->q_ibytes[i] = rxStats.ucastBytesRxOK +
+		bytes = rxStats.ucastBytesRxOK +
 			rxStats.mcastBytesRxOK +
 			rxStats.bcastBytesRxOK;
 
-		stats->ipackets += stats->q_ipackets[i];
-		stats->ibytes += stats->q_ibytes[i];
-
-		stats->q_errors[i] = rxStats.pktsRxError;
+		stats->ipackets += packets;
+		stats->ibytes += bytes;
 		stats->ierrors += rxStats.pktsRxError;
 		stats->imissed += rxStats.pktsRxOutOfBuf;
+
+		if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+			stats->q_ipackets[i] = packets;
+			stats->q_ibytes[i] = bytes;
+			stats->q_errors[i] = rxStats.pktsRxError;
+		}
 	}
 
 	return 0;
@@ -1521,8 +1531,6 @@  vmxnet3_dev_stats_reset(struct rte_eth_dev *dev)
 
 	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
 
-	RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_TX_QUEUES);
-
 	for (i = 0; i < hw->num_tx_queues; i++) {
 		vmxnet3_hw_tx_stats_get(hw, i, &txStats);
 		memcpy(&hw->snapshot_tx_stats[i], &txStats,