[PATCH v2 2/2] net/iavf: restore promiscuous mode only after VF reset

Ciara Loftus <[email protected]>
Newsgroups org.dpdk.dev
Message-ID <[email protected]>
The promiscuous and all-multicast settings persist in hardware across
a port stop/start and are only cleared by a VF reset. Despite this,
the ethdev start path re-applied them on every `dev_start` through the
config restore logic. Together with the driver's own restore after a
reset, a reset followed by a start reprogrammed them twice and issued
redundant requests to the PF.

Implement the `get_restore_flags` callback to clear
`RTE_ETH_RESTORE_PROMISC` and `RTE_ETH_RESTORE_ALLMULTI` so ethdev
skips them on start; the driver restores them only after a VF reset.
A queue reconfiguration in `iavf_dev_configure` also triggers a reset,
so the states are re-applied there too, except during reset recovery
where the reset handler already restores them once.

Signed-off-by: Ciara Loftus <[email protected]>
---
 drivers/net/intel/iavf/iavf_ethdev.c | 34 ++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/net/intel/iavf/iavf_ethdev.c b/drivers/net/intel/iavf/iavf_ethdev.c
index 829573983a..183d986831 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -163,6 +163,9 @@ static int iavf_set_mc_addr_list(struct rte_eth_dev *dev,
 			struct rte_ether_addr *mc_addrs,
 			uint32_t mc_addrs_num);
 static int iavf_tm_ops_get(struct rte_eth_dev *dev __rte_unused, void *arg);
+static uint64_t iavf_get_restore_flags(struct rte_eth_dev *dev,
+				       enum rte_eth_dev_operation op);
+static int iavf_post_reset_reconfig(struct rte_eth_dev *dev);
 
 static const struct rte_pci_id pci_id_iavf_map[] = {
 	{ RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_ADAPTIVE_VF) },
@@ -262,6 +265,7 @@ static const struct eth_dev_ops iavf_eth_dev_ops = {
 	.tx_done_cleanup	    = iavf_dev_tx_done_cleanup,
 	.get_monitor_addr           = iavf_get_monitor_addr,
 	.tm_ops_get                 = iavf_tm_ops_get,
+	.get_restore_flags          = iavf_get_restore_flags,
 };
 
 static int
@@ -282,6 +286,19 @@ iavf_tm_ops_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static uint64_t
+iavf_get_restore_flags(__rte_unused struct rte_eth_dev *dev,
+		       __rte_unused enum rte_eth_dev_operation op)
+{
+	/*
+	 * The unicast and multicast promiscuous settings persist across a
+	 * stop/start; they are only cleared by a VF reset, which the driver
+	 * restores itself. So ethdev does not need to restore them on start.
+	 */
+	return RTE_ETH_RESTORE_ALL & ~(RTE_ETH_RESTORE_PROMISC |
+				       RTE_ETH_RESTORE_ALLMULTI);
+}
+
 __rte_unused
 static int
 iavf_vfr_inprogress(struct iavf_hw *hw)
@@ -673,6 +690,7 @@ iavf_dev_configure(struct rte_eth_dev *dev)
 	struct iavf_info *vf =  IAVF_DEV_PRIVATE_TO_VF(ad);
 	uint16_t num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
 		dev->data->nb_tx_queues);
+	bool reset_done = false;
 	int ret;
 
 	if (ad->closed)
@@ -702,6 +720,7 @@ iavf_dev_configure(struct rte_eth_dev *dev)
 		ret = iavf_queues_req_reset(dev, num_queue_pairs);
 		if (ret)
 			return ret;
+		reset_done = true;
 
 		ret = iavf_get_max_rss_queue_region(ad);
 		if (ret) {
@@ -720,6 +739,7 @@ iavf_dev_configure(struct rte_eth_dev *dev)
 			ret = iavf_queues_req_reset(dev, num_queue_pairs);
 			if (ret)
 				return ret;
+			reset_done = true;
 
 			vf->lv_enabled = false;
 		}
@@ -735,6 +755,20 @@ iavf_dev_configure(struct rte_eth_dev *dev)
 			return -1;
 		}
 	}
+
+	/*
+	 * A queue reconfiguration above triggers a VF reset, which clears the
+	 * promiscuous and all-multicast settings in hardware. Re-apply the
+	 * pre-reset states here, unless this configure is itself part of reset
+	 * recovery, in which case the reset handler restores them once at the
+	 * end (avoiding a double restore).
+	 */
+	if (reset_done && !vf->in_reset_recovery) {
+		ret = iavf_post_reset_reconfig(dev);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.