DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH] net/iavf: add devargs to enable vf auto-reset
@ 2023-08-01  9:48 Shiyang He
  2023-08-11  9:40 ` [PATCH v2] " Shiyang He
  0 siblings, 1 reply; 14+ messages in thread
From: Shiyang He @ 2023-08-01  9:48 UTC (permalink / raw)
  To: dev
  Cc: yidingx.zhou, Shiyang He, Simei Su, Wenjun Wu, Qiming Yang,
	Yuying Zhang, Beilei Xing, Jingjing Wu

Originally, the iavf PMD does not perform special actions when it
receives a PF-to-VF reset event, resulting in vf being offline and
unavailable.

This patch enables vf auto-reset by setting 'watchdog_period' devargs
to true. The iavf PMD will perform an automatic reset to bring the vf
back online when it receives a PF-to-VF event.

Signed-off-by: Shiyang He <shiyangx.he@intel.com>
---
 doc/guides/nics/intel_vf.rst   |   3 +
 drivers/net/iavf/iavf.h        |  28 ++++++
 drivers/net/iavf/iavf_ethdev.c | 166 +++++++++++++++++++++++++++++++++
 drivers/net/iavf/iavf_rxtx.c   |  25 +++++
 drivers/net/iavf/iavf_rxtx.h   |   1 +
 drivers/net/iavf/iavf_vchnl.c  |   8 ++
 6 files changed, 231 insertions(+)

diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index d365dbc185..c0acd2a7f5 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the following documents:
     Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog period in microseconds, or set it to 0 to disable the watchdog,
     for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a 18:01.0,watchdog_period=0``.
 
+    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a 18:01.0,enable_auto_reset=1`` when IAVF is backed
+    by an Intel® E810 device or an Intel® 700 Series Ethernet device.
+
 The PCIE host-interface of Intel Ethernet Switch FM10000 Series VF infrastructure
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 98861e4242..a150b7d5cf 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -95,6 +95,24 @@
 
 #define IAVF_L2TPV2_FLAGS_LEN	0x4000
 
+#ifndef DIV_ROUND_UP
+#define DIV_ROUND_UP(n, d) (	\
+{								\
+	const typeof(d) __d = d;	\
+	(((n) + (__d) - 1) / (__d));\
+}								\
+)
+#endif
+#ifndef DELAY
+#define DELAY(x) rte_delay_us(x)
+#endif
+#ifndef msleep
+#define msleep(x) DELAY(1000 * (x))
+#endif
+#ifndef usleep_range
+#define usleep_range(min, max) msleep(DIV_ROUND_UP(min, 1000))
+#endif
+
 struct iavf_adapter;
 struct iavf_rx_queue;
 struct iavf_tx_queue;
@@ -305,6 +323,7 @@ struct iavf_devargs {
 	uint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];
 	uint16_t quanta_size;
 	uint32_t watchdog_period;
+	uint8_t  enable_auto_reset;
 };
 
 struct iavf_security_ctx;
@@ -424,6 +443,14 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops)
 
 	return !ret;
 }
+
+static inline bool
+iavf_is_reset(struct iavf_hw *hw)
+{
+	return !(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) &
+		 IAVF_VF_ARQLEN1_ARQENABLE_MASK);
+}
+
 int iavf_check_api_version(struct iavf_adapter *adapter);
 int iavf_get_vf_resource(struct iavf_adapter *adapter);
 void iavf_dev_event_handler_fini(void);
@@ -501,4 +528,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter,
 			struct iavf_fsub_conf *filter);
 void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
 void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
+int iavf_handle_hw_reset(struct rte_eth_dev *dev);
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index f2fc5a5621..5f9fce34a5 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -37,6 +37,7 @@
 #define IAVF_PROTO_XTR_ARG         "proto_xtr"
 #define IAVF_QUANTA_SIZE_ARG       "quanta_size"
 #define IAVF_RESET_WATCHDOG_ARG    "watchdog_period"
+#define IAVF_ENABLE_AUTO_RESET_ARG "enable_auto_reset"
 
 uint64_t iavf_timestamp_dynflag;
 int iavf_timestamp_dynfield_offset = -1;
@@ -45,6 +46,7 @@ static const char * const iavf_valid_args[] = {
 	IAVF_PROTO_XTR_ARG,
 	IAVF_QUANTA_SIZE_ARG,
 	IAVF_RESET_WATCHDOG_ARG,
+	IAVF_ENABLE_AUTO_RESET_ARG,
 	NULL
 };
 
@@ -305,6 +307,8 @@ iavf_dev_watchdog(void *cb_arg)
 			adapter->vf.vf_reset = true;
 			adapter->vf.link_up = false;
 
+			iavf_handle_hw_reset(adapter->vf.eth_dev);
+
 			rte_eth_dev_callback_process(adapter->vf.eth_dev,
 				RTE_ETH_EVENT_INTR_RESET, NULL);
 		}
@@ -2210,6 +2214,26 @@ parse_u16(__rte_unused const char *key, const char *value, void *args)
 	return 0;
 }
 
+static int
+parse_bool(const char *key, const char *value, void *args)
+{
+	int *i = (int *)args;
+	char *end;
+	int num;
+
+	num = strtoul(value, &end, 10);
+
+	if (num != 0 && num != 1) {
+		PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+			"value must be 0 or 1",
+			value, key);
+		return -1;
+	}
+
+	*i = num;
+	return 0;
+}
+
 static int
 iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
 {
@@ -2278,6 +2302,11 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
 		goto bail;
 	}
 
+	ret = rte_kvargs_process(kvlist, IAVF_ENABLE_AUTO_RESET_ARG,
+				 &parse_bool, &ad->devargs.enable_auto_reset);
+	if (ret)
+		goto bail;
+
 bail:
 	rte_kvargs_free(kvlist);
 	return ret;
@@ -2879,6 +2908,143 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 	return iavf_dev_init(dev);
 }
 
+static bool
+iavf_is_reset_detected(struct iavf_adapter *adapter)
+{
+	struct iavf_hw *hw = &adapter->hw;
+	int i;
+
+	/* poll until we see the reset actually happen */
+	for (i = 0; i < IAVF_RESET_WAIT_CNT; i++) {
+		if (iavf_is_reset(hw))
+			return true;
+		usleep_range(5000, 10000);
+	}
+
+	return false;
+}
+
+static int
+iavf_uninit_hw(struct rte_eth_dev *dev, struct iavf_hw *hw)
+{
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+	struct rte_intr_handle *intr_handle = dev->intr_handle;
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	struct iavf_adapter *adapter = dev->data->dev_private;
+
+	iavf_reset_queues(dev);
+
+	/* Disable the interrupt for Rx */
+	rte_intr_efd_disable(intr_handle);
+	/* Rx interrupt vector mapping free */
+	rte_intr_vec_list_free(intr_handle);
+
+	adapter->stopped = 1;
+	dev->data->dev_started = 0;
+
+	adapter->closed = true;
+
+	/* free iAVF security device context all related resources */
+	iavf_security_ctx_destroy(adapter);
+
+	iavf_flow_flush(dev, NULL);
+	iavf_flow_uninit(adapter);
+
+	if (vf->promisc_unicast_enabled || vf->promisc_multicast_enabled)
+		iavf_config_promisc(adapter, false, false);
+
+	iavf_shutdown_adminq(hw);
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
+		/* disable uio intr before callback unregister */
+		rte_intr_disable(intr_handle);
+
+		/* unregister callback func from eal lib */
+		rte_intr_callback_unregister(intr_handle,
+					     iavf_dev_interrupt_handler, dev);
+	}
+	iavf_disable_irq0(hw);
+
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS)
+		iavf_tm_conf_uninit(dev);
+
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
+		if (vf->rss_lut) {
+			rte_free(vf->rss_lut);
+			vf->rss_lut = NULL;
+		}
+		if (vf->rss_key) {
+			rte_free(vf->rss_key);
+			vf->rss_key = NULL;
+		}
+	}
+
+	rte_free(vf->vf_res);
+	vf->vsi_res = NULL;
+	vf->vf_res = NULL;
+
+	rte_free(vf->aq_resp);
+	vf->aq_resp = NULL;
+
+	if (vf->vf_reset && !rte_pci_set_bus_master(pci_dev, true))
+		vf->vf_reset = false;
+
+	/* disable watchdog */
+	iavf_dev_watchdog_disable(adapter);
+
+	return 0;
+}
+
+static int
+iavf_reset_hw(struct rte_eth_dev *dev, struct iavf_hw *hw)
+{
+	iavf_uninit_hw(dev, hw);
+
+	return iavf_dev_init(dev);
+}
+
+/*
+ * Handle hardware reset
+ */
+int
+iavf_handle_hw_reset(struct rte_eth_dev *dev)
+{
+	struct iavf_adapter *adapter = dev->data->dev_private;
+	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	int ret;
+
+	if (!adapter->devargs.enable_auto_reset)
+		return 0;
+
+	if (!iavf_is_reset_detected(adapter))
+		return 0;
+
+	if (iavf_reset_hw(dev, hw))
+		return -1;
+
+	/*
+	 * This may return a failure due to the vf may not able to get
+	 * a response from the pf.
+	 */
+	ret = iavf_dev_configure(dev);
+	if (ret)
+		PMD_DRV_LOG(ERR, "Failed to configure dev");
+
+	iavf_dev_xstats_reset(dev);
+
+	/* start the device */
+	ret = iavf_dev_start(dev);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to start dev");
+		return ret;
+	}
+
+	dev->data->dev_started = 1;
+	vf->vf_reset = false;
+
+	return 0;
+}
+
 static int
 iavf_dcf_cap_check_handler(__rte_unused const char *key,
 			   const char *value, __rte_unused void *opaque)
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index f7df4665d1..a1f556d1ce 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -1094,6 +1094,31 @@ iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
 	rte_free(q);
 }
 
+void
+iavf_reset_queues(struct rte_eth_dev *dev)
+{
+	struct iavf_rx_queue *rxq;
+	struct iavf_tx_queue *txq;
+	int i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (!txq)
+			continue;
+		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
+		reset_tx_queue(txq);
+		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (!rxq)
+			continue;
+		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
+		reset_rx_queue(rxq);
+		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+}
+
 void
 iavf_stop_queues(struct rte_eth_dev *dev)
 {
diff --git a/drivers/net/iavf/iavf_rxtx.h b/drivers/net/iavf/iavf_rxtx.h
index 605ea3f824..237022338e 100644
--- a/drivers/net/iavf/iavf_rxtx.h
+++ b/drivers/net/iavf/iavf_rxtx.h
@@ -650,6 +650,7 @@ int iavf_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int iavf_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int iavf_dev_tx_done_cleanup(void *txq, uint32_t free_cnt);
 void iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
+void iavf_reset_queues(struct rte_eth_dev *dev);
 void iavf_stop_queues(struct rte_eth_dev *dev);
 uint16_t iavf_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		       uint16_t nb_pkts);
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index 524732f67d..19e22ae283 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -80,6 +80,14 @@ iavf_dev_event_handle(void *param __rte_unused)
 		TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) {
 			TAILQ_REMOVE(&pending, pos, next);
 			rte_eth_dev_callback_process(pos->dev, pos->event, pos->param);
+
+			switch (pos->event) {
+			case RTE_ETH_EVENT_INTR_RESET:
+				iavf_handle_hw_reset(pos->dev);
+				break;
+			default:
+				break;
+			}
 			rte_free(pos);
 		}
 	}
-- 
2.37.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2] net/iavf: add devargs to enable vf auto-reset
  2023-08-01  9:48 [PATCH] net/iavf: add devargs to enable vf auto-reset Shiyang He
@ 2023-08-11  9:40 ` Shiyang He
  2023-09-15 13:02   ` [PATCH v3] " Shiyang He
  0 siblings, 1 reply; 14+ messages in thread
From: Shiyang He @ 2023-08-11  9:40 UTC (permalink / raw)
  To: dev
  Cc: yidingx.zhou, Shiyang He, Qiming Yang, Wenjun Wu, Simei Su,
	Yuying Zhang, Beilei Xing, Jingjing Wu

Originally, the iavf PMD does not perform special actions when it
receives a PF-to-VF reset event, resulting in vf being offline and
unavailable.

This patch enables vf auto-reset by setting 'watchdog_period' devargs
to true. The iavf PMD will perform an automatic reset to bring the vf
back online when it receives a PF-to-VF event.

v2: using event handler to handle reset

Signed-off-by: Shiyang He <shiyangx.he@intel.com>
---
 doc/guides/nics/intel_vf.rst           |   3 +
 doc/guides/rel_notes/release_23_11.rst |   3 +
 drivers/net/iavf/iavf.h                |  31 +++++
 drivers/net/iavf/iavf_ethdev.c         | 177 ++++++++++++++++++++++++-
 drivers/net/iavf/iavf_rxtx.c           |  25 ++++
 drivers/net/iavf/iavf_rxtx.h           |   1 +
 drivers/net/iavf/iavf_vchnl.c          |  11 +-
 7 files changed, 248 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index d365dbc185..c0acd2a7f5 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the following documents:
     Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog period in microseconds, or set it to 0 to disable the watchdog,
     for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a 18:01.0,watchdog_period=0``.
 
+    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a 18:01.0,enable_auto_reset=1`` when IAVF is backed
+    by an Intel® E810 device or an Intel® 700 Series Ethernet device.
+
 The PCIE host-interface of Intel Ethernet Switch FM10000 Series VF infrastructure
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 4411bb32c1..80e2d7672f 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -72,6 +72,9 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated Intel iavf driver.**
+
+  Added support for iavf auto-reset.
 
 Removed Items
 -------------
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 98861e4242..e78bcda962 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -95,6 +95,24 @@
 
 #define IAVF_L2TPV2_FLAGS_LEN	0x4000
 
+#ifndef DIV_ROUND_UP
+#define DIV_ROUND_UP(n, d) (	\
+{								\
+	const typeof(d) __d = d;	\
+	(((n) + (__d) - 1) / (__d));\
+}								\
+)
+#endif
+#ifndef DELAY
+#define DELAY(x) rte_delay_us(x)
+#endif
+#ifndef msleep
+#define msleep(x) DELAY(1000 * (x))
+#endif
+#ifndef usleep_range
+#define usleep_range(min, max) msleep(DIV_ROUND_UP(min, 1000))
+#endif
+
 struct iavf_adapter;
 struct iavf_rx_queue;
 struct iavf_tx_queue;
@@ -305,6 +323,7 @@ struct iavf_devargs {
 	uint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];
 	uint16_t quanta_size;
 	uint32_t watchdog_period;
+	uint8_t  enable_auto_reset;
 };
 
 struct iavf_security_ctx;
@@ -424,8 +443,19 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops)
 
 	return !ret;
 }
+
+static inline bool
+iavf_is_reset(struct iavf_hw *hw)
+{
+	return !(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) &
+		 IAVF_VF_ARQLEN1_ARQENABLE_MASK);
+}
+
 int iavf_check_api_version(struct iavf_adapter *adapter);
 int iavf_get_vf_resource(struct iavf_adapter *adapter);
+void iavf_dev_event_post(struct rte_eth_dev *dev,
+			enum rte_eth_event_type event,
+			void *param, size_t param_alloc_size);
 void iavf_dev_event_handler_fini(void);
 int iavf_dev_event_handler_init(void);
 void iavf_handle_virtchnl_msg(struct rte_eth_dev *dev);
@@ -501,4 +531,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter,
 			struct iavf_fsub_conf *filter);
 void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
 void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
+int iavf_handle_hw_reset(struct rte_eth_dev *dev);
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index f2fc5a5621..9ac612e12b 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -37,6 +37,7 @@
 #define IAVF_PROTO_XTR_ARG         "proto_xtr"
 #define IAVF_QUANTA_SIZE_ARG       "quanta_size"
 #define IAVF_RESET_WATCHDOG_ARG    "watchdog_period"
+#define IAVF_ENABLE_AUTO_RESET_ARG "enable_auto_reset"
 
 uint64_t iavf_timestamp_dynflag;
 int iavf_timestamp_dynfield_offset = -1;
@@ -45,6 +46,7 @@ static const char * const iavf_valid_args[] = {
 	IAVF_PROTO_XTR_ARG,
 	IAVF_QUANTA_SIZE_ARG,
 	IAVF_RESET_WATCHDOG_ARG,
+	IAVF_ENABLE_AUTO_RESET_ARG,
 	NULL
 };
 
@@ -305,8 +307,8 @@ iavf_dev_watchdog(void *cb_arg)
 			adapter->vf.vf_reset = true;
 			adapter->vf.link_up = false;
 
-			rte_eth_dev_callback_process(adapter->vf.eth_dev,
-				RTE_ETH_EVENT_INTR_RESET, NULL);
+			iavf_dev_event_post(adapter->vf.eth_dev, RTE_ETH_EVENT_INTR_RESET,
+				 NULL, 0);
 		}
 	}
 
@@ -2210,6 +2212,26 @@ parse_u16(__rte_unused const char *key, const char *value, void *args)
 	return 0;
 }
 
+static int
+parse_bool(const char *key, const char *value, void *args)
+{
+	int *i = (int *)args;
+	char *end;
+	int num;
+
+	num = strtoul(value, &end, 10);
+
+	if (num != 0 && num != 1) {
+		PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+			"value must be 0 or 1",
+			value, key);
+		return -1;
+	}
+
+	*i = num;
+	return 0;
+}
+
 static int
 iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
 {
@@ -2278,6 +2300,11 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
 		goto bail;
 	}
 
+	ret = rte_kvargs_process(kvlist, IAVF_ENABLE_AUTO_RESET_ARG,
+				 &parse_bool, &ad->devargs.enable_auto_reset);
+	if (ret)
+		goto bail;
+
 bail:
 	rte_kvargs_free(kvlist);
 	return ret;
@@ -2879,6 +2906,152 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 	return iavf_dev_init(dev);
 }
 
+static bool
+iavf_is_reset_detected(struct iavf_adapter *adapter)
+{
+	struct iavf_hw *hw = &adapter->hw;
+	int i;
+
+	/* poll until we see the reset actually happen */
+	for (i = 0; i < IAVF_RESET_WAIT_CNT; i++) {
+		if (iavf_is_reset(hw))
+			return true;
+		usleep_range(5000, 10000);
+	}
+
+	return false;
+}
+
+static int
+iavf_uninit_hw(struct rte_eth_dev *dev, struct iavf_hw *hw)
+{
+	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+	struct rte_intr_handle *intr_handle = dev->intr_handle;
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	struct iavf_adapter *adapter = dev->data->dev_private;
+
+	iavf_reset_queues(dev);
+
+	/* Disable the interrupt for Rx */
+	rte_intr_efd_disable(intr_handle);
+	/* Rx interrupt vector mapping free */
+	rte_intr_vec_list_free(intr_handle);
+
+	adapter->stopped = 1;
+	dev->data->dev_started = 0;
+
+	adapter->closed = true;
+
+	/* free iAVF security device context all related resources */
+	iavf_security_ctx_destroy(adapter);
+
+	iavf_flow_flush(dev, NULL);
+	iavf_flow_uninit(adapter);
+
+	if (vf->promisc_unicast_enabled || vf->promisc_multicast_enabled)
+		iavf_config_promisc(adapter, false, false);
+
+	iavf_shutdown_adminq(hw);
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
+		/* disable uio intr before callback unregister */
+		rte_intr_disable(intr_handle);
+
+		/* unregister callback func from eal lib */
+		rte_intr_callback_unregister(intr_handle,
+					     iavf_dev_interrupt_handler, dev);
+	}
+	iavf_disable_irq0(hw);
+
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_QOS)
+		iavf_tm_conf_uninit(dev);
+
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
+		if (vf->rss_lut) {
+			rte_free(vf->rss_lut);
+			vf->rss_lut = NULL;
+		}
+		if (vf->rss_key) {
+			rte_free(vf->rss_key);
+			vf->rss_key = NULL;
+		}
+	}
+
+	rte_free(vf->vf_res);
+	vf->vsi_res = NULL;
+	vf->vf_res = NULL;
+
+	rte_free(vf->aq_resp);
+	vf->aq_resp = NULL;
+
+	if (vf->vf_reset && !rte_pci_set_bus_master(pci_dev, true))
+		vf->vf_reset = false;
+
+	/* disable watchdog */
+	iavf_dev_watchdog_disable(adapter);
+
+	return 0;
+}
+
+static int
+iavf_reset_hw(struct rte_eth_dev *dev, struct iavf_hw *hw)
+{
+	iavf_uninit_hw(dev, hw);
+
+	return iavf_dev_init(dev);
+}
+
+/*
+ * Handle hardware reset
+ */
+int
+iavf_handle_hw_reset(struct rte_eth_dev *dev)
+{
+	struct iavf_adapter *adapter = dev->data->dev_private;
+	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	int ret;
+
+	ret = iavf_is_reset_detected(adapter);
+	if (!ret) {
+		PMD_DRV_LOG(ERR, "Did not detect vf reset!\n");
+		return ret;
+	}
+
+	ret = iavf_check_vf_reset_done(hw);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Wait too long for reset done!\n");
+		return ret;
+	}
+
+	ret = iavf_reset_hw(dev, hw);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to reset vf!\n");
+		return ret;
+	}
+
+	/*
+	 * This may return a failure due to the vf may not able to get
+	 * a response from the pf.
+	 */
+	ret = iavf_dev_configure(dev);
+	if (ret)
+		PMD_DRV_LOG(ERR, "Failed to configure dev!");
+
+	iavf_dev_xstats_reset(dev);
+
+	/* start the device */
+	ret = iavf_dev_start(dev);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to start dev!");
+		return ret;
+	}
+
+	dev->data->dev_started = 1;
+	vf->vf_reset = false;
+
+	return 0;
+}
+
 static int
 iavf_dcf_cap_check_handler(__rte_unused const char *key,
 			   const char *value, __rte_unused void *opaque)
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index f7df4665d1..a1f556d1ce 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -1094,6 +1094,31 @@ iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
 	rte_free(q);
 }
 
+void
+iavf_reset_queues(struct rte_eth_dev *dev)
+{
+	struct iavf_rx_queue *rxq;
+	struct iavf_tx_queue *txq;
+	int i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (!txq)
+			continue;
+		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
+		reset_tx_queue(txq);
+		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (!rxq)
+			continue;
+		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
+		reset_rx_queue(rxq);
+		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+}
+
 void
 iavf_stop_queues(struct rte_eth_dev *dev)
 {
diff --git a/drivers/net/iavf/iavf_rxtx.h b/drivers/net/iavf/iavf_rxtx.h
index 605ea3f824..237022338e 100644
--- a/drivers/net/iavf/iavf_rxtx.h
+++ b/drivers/net/iavf/iavf_rxtx.h
@@ -650,6 +650,7 @@ int iavf_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int iavf_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int iavf_dev_tx_done_cleanup(void *txq, uint32_t free_cnt);
 void iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
+void iavf_reset_queues(struct rte_eth_dev *dev);
 void iavf_stop_queues(struct rte_eth_dev *dev);
 uint16_t iavf_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		       uint16_t nb_pkts);
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index 524732f67d..dffe91f8c9 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -79,6 +79,15 @@ iavf_dev_event_handle(void *param __rte_unused)
 		struct iavf_event_element *pos, *save_next;
 		TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) {
 			TAILQ_REMOVE(&pending, pos, next);
+
+			struct iavf_adapter *adapter = pos->dev->data->dev_private;
+			if (pos->event == RTE_ETH_EVENT_INTR_RESET &&
+			    adapter->devargs.enable_auto_reset) {
+				iavf_handle_hw_reset(pos->dev);
+				rte_free(pos);
+				continue;
+			}
+
 			rte_eth_dev_callback_process(pos->dev, pos->event, pos->param);
 			rte_free(pos);
 		}
@@ -87,7 +96,7 @@ iavf_dev_event_handle(void *param __rte_unused)
 	return 0;
 }
 
-static void
+void
 iavf_dev_event_post(struct rte_eth_dev *dev,
 		enum rte_eth_event_type event,
 		void *param, size_t param_alloc_size)
-- 
2.37.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v3] net/iavf: add devargs to enable vf auto-reset
  2023-08-11  9:40 ` [PATCH v2] " Shiyang He
@ 2023-09-15 13:02   ` Shiyang He
  2023-09-26  7:48     ` Bruce Richardson
  2023-09-26 11:31     ` [PATCH v4] " Shiyang He
  0 siblings, 2 replies; 14+ messages in thread
From: Shiyang He @ 2023-09-15 13:02 UTC (permalink / raw)
  To: dev
  Cc: yidingx.zhou, Shiyang He, Liang-Min Larry Wang, Simei Su,
	Wenjun Wu, Yuying Zhang, Beilei Xing, Qiming Yang, Jingjing Wu

Originally, the iavf PMD does not perform special actions when it
receives a PF-to-VF reset event, resulting in vf being offline and
unavailable.

This patch enables vf auto-reset by setting 'watchdog_period' devargs
to true. The iavf PMD will perform an automatic reset to bring the vf
back online when it receives a PF-to-VF event.

v2: handling reset by event handler
v3: change reset process

Signed-off-by: Shiyang He <shiyangx.he@intel.com>
Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
---
 doc/guides/nics/intel_vf.rst           |  3 +
 doc/guides/rel_notes/release_23_11.rst |  3 +
 drivers/net/iavf/iavf.h                |  7 +++
 drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
 drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
 drivers/net/iavf/iavf_vchnl.c          | 11 +++-
 6 files changed, 135 insertions(+), 27 deletions(-)

diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index d365dbc185..c0acd2a7f5 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the following documents:
     Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog period in microseconds, or set it to 0 to disable the watchdog,
     for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a 18:01.0,watchdog_period=0``.
 
+    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a 18:01.0,enable_auto_reset=1`` when IAVF is backed
+    by an Intel® E810 device or an Intel® 700 Series Ethernet device.
+
 The PCIE host-interface of Intel Ethernet Switch FM10000 Series VF infrastructure
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 333e1d95a2..aeddb0d8f6 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -78,6 +78,9 @@ New Features
 * build: Optional libraries can now be selected with the new ``enable_libs``
   build option similarly to the existing ``enable_drivers`` build option.
 
+* **Updated Intel iavf driver.**
+
+  * Added support for iavf auto-reset.
 
 Removed Items
 -------------
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 98861e4242..3641401f38 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -277,6 +277,8 @@ struct iavf_info {
 
 	struct rte_eth_dev *eth_dev;
 
+	bool in_reset_recovery;
+
 	uint32_t ptp_caps;
 	rte_spinlock_t phc_time_aq_lock;
 };
@@ -305,6 +307,7 @@ struct iavf_devargs {
 	uint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];
 	uint16_t quanta_size;
 	uint32_t watchdog_period;
+	uint8_t  enable_auto_reset;
 };
 
 struct iavf_security_ctx;
@@ -426,6 +429,9 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops)
 }
 int iavf_check_api_version(struct iavf_adapter *adapter);
 int iavf_get_vf_resource(struct iavf_adapter *adapter);
+void iavf_dev_event_post(struct rte_eth_dev *dev,
+		enum rte_eth_event_type event,
+		void *param, size_t param_alloc_size);
 void iavf_dev_event_handler_fini(void);
 int iavf_dev_event_handler_init(void);
 void iavf_handle_virtchnl_msg(struct rte_eth_dev *dev);
@@ -501,4 +507,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter,
 			struct iavf_fsub_conf *filter);
 void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
 void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
+int iavf_handle_hw_reset(struct rte_eth_dev *dev);
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index f2fc5a5621..713461f6cb 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -37,6 +37,7 @@
 #define IAVF_PROTO_XTR_ARG         "proto_xtr"
 #define IAVF_QUANTA_SIZE_ARG       "quanta_size"
 #define IAVF_RESET_WATCHDOG_ARG    "watchdog_period"
+#define IAVF_ENABLE_AUTO_RESET_ARG "enable_auto_reset"
 
 uint64_t iavf_timestamp_dynflag;
 int iavf_timestamp_dynfield_offset = -1;
@@ -45,6 +46,7 @@ static const char * const iavf_valid_args[] = {
 	IAVF_PROTO_XTR_ARG,
 	IAVF_QUANTA_SIZE_ARG,
 	IAVF_RESET_WATCHDOG_ARG,
+	IAVF_ENABLE_AUTO_RESET_ARG,
 	NULL
 };
 
@@ -305,8 +307,8 @@ iavf_dev_watchdog(void *cb_arg)
 			adapter->vf.vf_reset = true;
 			adapter->vf.link_up = false;
 
-			rte_eth_dev_callback_process(adapter->vf.eth_dev,
-				RTE_ETH_EVENT_INTR_RESET, NULL);
+			iavf_dev_event_post(adapter->vf.eth_dev, RTE_ETH_EVENT_INTR_RESET,
+				NULL, 0);
 		}
 	}
 
@@ -1092,12 +1094,15 @@ iavf_dev_stop(struct rte_eth_dev *dev)
 	/* Rx interrupt vector mapping free */
 	rte_intr_vec_list_free(intr_handle);
 
-	/* remove all mac addrs */
-	iavf_add_del_all_mac_addr(adapter, false);
+	/* adminq will be disabled when vf is resetting. */
+	if (!vf->in_reset_recovery) {
+		/* remove all mac addrs */
+		iavf_add_del_all_mac_addr(adapter, false);
 
-	/* remove all multicast addresses */
-	iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
+		/* remove all multicast addresses */
+		iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
 				  false);
+	}
 
 	iavf_stop_queues(dev);
 
@@ -2210,6 +2215,26 @@ parse_u16(__rte_unused const char *key, const char *value, void *args)
 	return 0;
 }
 
+static int
+parse_bool(const char *key, const char *value, void *args)
+{
+	int *i = (int *)args;
+	char *end;
+	int num;
+
+	num = strtoul(value, &end, 10);
+
+	if (num != 0 && num != 1) {
+		PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+			"value must be 0 or 1",
+			value, key);
+		return -1;
+	}
+
+	*i = num;
+	return 0;
+}
+
 static int
 iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
 {
@@ -2278,6 +2303,11 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
 		goto bail;
 	}
 
+	ret = rte_kvargs_process(kvlist, IAVF_ENABLE_AUTO_RESET_ARG,
+				 &parse_bool, &ad->devargs.enable_auto_reset);
+	if (ret)
+		goto bail;
+
 bail:
 	rte_kvargs_free(kvlist);
 	return ret;
@@ -2841,12 +2871,15 @@ iavf_dev_close(struct rte_eth_dev *dev)
 static int
 iavf_dev_uninit(struct rte_eth_dev *dev)
 {
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return -EPERM;
 
 	iavf_dev_close(dev);
 
-	iavf_dev_event_handler_fini();
+	if (!vf->in_reset_recovery)
+		iavf_dev_event_handler_fini();
 
 	return 0;
 }
@@ -2859,6 +2892,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 {
 	int ret;
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 
 	/*
 	 * Check whether the VF reset has been done and inform application,
@@ -2870,6 +2904,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 		PMD_DRV_LOG(ERR, "Wait too long for reset done!\n");
 		return ret;
 	}
+	vf->vf_reset = false;
 
 	PMD_DRV_LOG(DEBUG, "Start dev_reset ...\n");
 	ret = iavf_dev_uninit(dev);
@@ -2879,6 +2914,43 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 	return iavf_dev_init(dev);
 }
 
+/*
+ * Handle hardware reset
+ */
+int
+iavf_handle_hw_reset(struct rte_eth_dev *dev)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	int ret;
+
+	vf->in_reset_recovery = true;
+
+	ret = iavf_dev_reset(dev);
+	if (ret)
+		goto error;
+
+	/* VF states restore */
+	ret = iavf_dev_configure(dev);
+	if (ret)
+		goto error;
+
+	iavf_dev_xstats_reset(dev);
+
+	/* start the device */
+	ret = iavf_dev_start(dev);
+	if (ret)
+		goto error;
+	dev->data->dev_started = 1;
+
+	vf->in_reset_recovery = false;
+	return 0;
+
+error:
+	PMD_DRV_LOG(DEBUG, "RESET recover with error code=%d\n", ret);
+	vf->in_reset_recovery = false;
+	return ret;
+}
+
 static int
 iavf_dcf_cap_check_handler(__rte_unused const char *key,
 			   const char *value, __rte_unused void *opaque)
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index f7df4665d1..1bea68a3eb 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -1094,15 +1094,44 @@ iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
 	rte_free(q);
 }
 
+static void
+iavf_reset_queues(struct rte_eth_dev *dev)
+{
+	struct iavf_rx_queue *rxq;
+	struct iavf_tx_queue *txq;
+	int i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (!txq)
+			continue;
+		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
+		reset_tx_queue(txq);
+		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (!rxq)
+			continue;
+		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
+		reset_rx_queue(rxq);
+		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+}
+
 void
 iavf_stop_queues(struct rte_eth_dev *dev)
 {
 	struct iavf_adapter *adapter =
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-	struct iavf_rx_queue *rxq;
-	struct iavf_tx_queue *txq;
-	int ret, i;
+	int ret;
+
+	/* adminq will be disabled when vf is resetting. */
+	if (vf->in_reset_recovery) {
+		iavf_reset_queues(dev);
+		return;
+	}
 
 	/* Stop All queues */
 	if (!vf->lv_enabled) {
@@ -1118,22 +1147,7 @@ iavf_stop_queues(struct rte_eth_dev *dev)
 	if (ret)
 		PMD_DRV_LOG(WARNING, "Fail to stop queues");
 
-	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		txq = dev->data->tx_queues[i];
-		if (!txq)
-			continue;
-		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
-		reset_tx_queue(txq);
-		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
-	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		rxq = dev->data->rx_queues[i];
-		if (!rxq)
-			continue;
-		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
-		reset_rx_queue(rxq);
-		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
+	iavf_reset_queues(dev);
 }
 
 #define IAVF_RX_FLEX_ERR0_BITS	\
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index c31a6d5c98..0726dc87be 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -79,6 +79,15 @@ iavf_dev_event_handle(void *param __rte_unused)
 		struct iavf_event_element *pos, *save_next;
 		TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) {
 			TAILQ_REMOVE(&pending, pos, next);
+
+			struct iavf_adapter *adapter = pos->dev->data->dev_private;
+			if (pos->event == RTE_ETH_EVENT_INTR_RESET &&
+			    adapter->devargs.enable_auto_reset) {
+				iavf_handle_hw_reset(pos->dev);
+				rte_free(pos);
+				continue;
+			}
+
 			rte_eth_dev_callback_process(pos->dev, pos->event, pos->param);
 			rte_free(pos);
 		}
@@ -87,7 +96,7 @@ iavf_dev_event_handle(void *param __rte_unused)
 	return 0;
 }
 
-static void
+void
 iavf_dev_event_post(struct rte_eth_dev *dev,
 		enum rte_eth_event_type event,
 		void *param, size_t param_alloc_size)
-- 
2.37.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH v4] net/iavf: add devargs to enable vf auto-reset
  2023-09-26 11:31     ` [PATCH v4] " Shiyang He
@ 2023-09-26  4:51       ` Zhang, Qi Z
  2023-09-26 12:29       ` [PATCH v5] " Shiyang He
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Zhang, Qi Z @ 2023-09-26  4:51 UTC (permalink / raw)
  To: He, ShiyangX, dev
  Cc: Zhou, YidingX, He, ShiyangX, Wang, Liang-min, Zhang, Yuying,
	Xing, Beilei, Su, Simei, Wu, Wenjun1, Yang, Qiming, Wu, Jingjing



> -----Original Message-----
> From: Shiyang He <shiyangx.he@intel.com>
> Sent: Tuesday, September 26, 2023 7:32 PM
> To: dev@dpdk.org
> Cc: Zhou, YidingX <yidingx.zhou@intel.com>; He, ShiyangX
> <shiyangx.he@intel.com>; Wang, Liang-min <liang-min.wang@intel.com>;
> Zhang, Yuying <yuying.zhang@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Su, Simei <simei.su@intel.com>; Wu, Wenjun1
> <wenjun1.wu@intel.com>; Yang, Qiming <qiming.yang@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: [PATCH v4] net/iavf: add devargs to enable vf auto-reset
> 
> Originally, the iavf PMD does not perform special actions when it receives a
> PF-to-VF reset event, resulting in vf being offline and unavailable.
> 
> This patch enables vf auto-reset by setting 'watchdog_period' devargs to true.
> The iavf PMD will perform an automatic reset to bring the vf back online
> when it receives a PF-to-VF event.
> 
> v2: handling reset by event handler
> v3: change reset process
> v3: rebase
> 
> Signed-off-by: Shiyang He <shiyangx.he@intel.com>
> Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
> ---
>  doc/guides/nics/intel_vf.rst           |  3 +
>  doc/guides/rel_notes/release_23_11.rst |  3 +
>  drivers/net/iavf/iavf.h                |  7 +++
>  drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
>  drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
>  drivers/net/iavf/iavf_vchnl.c          | 11 +++-
>  6 files changed, 135 insertions(+), 27 deletions(-)
> 
> diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst index
> d365dbc185..c0acd2a7f5 100644
> --- a/doc/guides/nics/intel_vf.rst
> +++ b/doc/guides/nics/intel_vf.rst
> @@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the
> following documents:
>      Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog
> period in microseconds, or set it to 0 to disable the watchdog,
>      for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a
> 18:01.0,watchdog_period=0``.
> 
> +    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a
> 18:01.0,enable_auto_reset=1`` when IAVF is backed

The argument enable_auto_reset=1 seems somewhat redundant; why not simply use auto_reset=1 instead?

Otherwise
Acked-by: Qi Zhang <qi.z.zhang@intel.com>




^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH v5] net/iavf: add devargs to enable vf auto-reset
  2023-09-26 12:38       ` Shiyang He
@ 2023-09-26  5:33         ` Zhang, Qi Z
  0 siblings, 0 replies; 14+ messages in thread
From: Zhang, Qi Z @ 2023-09-26  5:33 UTC (permalink / raw)
  To: He, ShiyangX, dev
  Cc: Zhou, YidingX, Wang, Liang-min, Zhang, Yuying, Xing, Beilei, Su,
	Simei, Wu, Wenjun1, Yang, Qiming, Wu,  Jingjing



> -----Original Message-----
> From: He, ShiyangX <shiyangx.he@intel.com>
> Sent: Tuesday, September 26, 2023 8:39 PM
> To: dev@dpdk.org
> Cc: Zhou, YidingX <yidingx.zhou@intel.com>; He, ShiyangX
> <shiyangx.he@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Wang, Liang-
> min <liang-min.wang@intel.com>; Zhang, Yuying <yuying.zhang@intel.com>;
> Xing, Beilei <beilei.xing@intel.com>; Su, Simei <simei.su@intel.com>; Wu,
> Wenjun1 <wenjun1.wu@intel.com>; Yang, Qiming <qiming.yang@intel.com>;
> Wu, Jingjing <jingjing.wu@intel.com>
> Subject: [PATCH v5] net/iavf: add devargs to enable vf auto-reset
> 
> Originally, the iavf PMD does not perform special actions when it receives a
> PF-to-VF reset event, resulting in vf being offline and unavailable.
> 
> This patch enables vf auto-reset by setting 'watchdog_period' devargs to true.
> The iavf PMD will perform an automatic reset to bring the vf back online
> when it receives a PF-to-VF event.

Fix typo by s/watchdog_period/auto_reset

> 
> v2: handling reset by event handler
> v3: change reset process
> v4: rebase
> v5: change enable_auto_reset to auto_reset
> 
> Acked-by: Qi Zhang <qi.z.zhang@intel.com>
> Signed-off-by: Shiyang He <shiyangx.he@intel.com>
> Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>

Applied to dpdk-next-net-intel.

Thanks
Qi


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
  2023-09-15 13:02   ` [PATCH v3] " Shiyang He
@ 2023-09-26  7:48     ` Bruce Richardson
  2023-09-26 12:15       ` Zhang, Qi Z
  2023-09-26 11:31     ` [PATCH v4] " Shiyang He
  1 sibling, 1 reply; 14+ messages in thread
From: Bruce Richardson @ 2023-09-26  7:48 UTC (permalink / raw)
  To: Shiyang He
  Cc: dev, yidingx.zhou, Liang-Min Larry Wang, Simei Su, Wenjun Wu,
	Yuying Zhang, Beilei Xing, Qiming Yang, Jingjing Wu

On Fri, Sep 15, 2023 at 01:02:49PM +0000, Shiyang He wrote:
> Originally, the iavf PMD does not perform special actions when it
> receives a PF-to-VF reset event, resulting in vf being offline and
> unavailable.
> 
> This patch enables vf auto-reset by setting 'watchdog_period' devargs
> to true. The iavf PMD will perform an automatic reset to bring the vf
> back online when it receives a PF-to-VF event.
> 
> v2: handling reset by event handler
> v3: change reset process
> 
> Signed-off-by: Shiyang He <shiyangx.he@intel.com>
> Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
> ---
>  doc/guides/nics/intel_vf.rst           |  3 +
>  doc/guides/rel_notes/release_23_11.rst |  3 +
>  drivers/net/iavf/iavf.h                |  7 +++
>  drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
>  drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
>  drivers/net/iavf/iavf_vchnl.c          | 11 +++-
>  6 files changed, 135 insertions(+), 27 deletions(-)
> 
> diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
> index d365dbc185..c0acd2a7f5 100644
> --- a/doc/guides/nics/intel_vf.rst
> +++ b/doc/guides/nics/intel_vf.rst
> @@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the following documents:
>      Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog period in microseconds, or set it to 0 to disable the watchdog,
>      for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a 18:01.0,watchdog_period=0``.
>  
> +    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a 18:01.0,enable_auto_reset=1`` when IAVF is backed
> +    by an Intel® E810 device or an Intel® 700 Series Ethernet device.
> +

Why do we need a devargs for this? If the VF is unavailable - as you
mention in the commit log above - should this behaviour not always be the
case without the user having to ask?

/Bruce

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4] net/iavf: add devargs to enable vf auto-reset
  2023-09-15 13:02   ` [PATCH v3] " Shiyang He
  2023-09-26  7:48     ` Bruce Richardson
@ 2023-09-26 11:31     ` Shiyang He
  2023-09-26  4:51       ` Zhang, Qi Z
                         ` (3 more replies)
  1 sibling, 4 replies; 14+ messages in thread
From: Shiyang He @ 2023-09-26 11:31 UTC (permalink / raw)
  To: dev
  Cc: yidingx.zhou, Shiyang He, Liang-Min Larry Wang, Yuying Zhang,
	Beilei Xing, Simei Su, Wenjun Wu, Qiming Yang, Jingjing Wu

Originally, the iavf PMD does not perform special actions when it
receives a PF-to-VF reset event, resulting in vf being offline and
unavailable.

This patch enables vf auto-reset by setting 'watchdog_period' devargs
to true. The iavf PMD will perform an automatic reset to bring the vf
back online when it receives a PF-to-VF event.

v2: handling reset by event handler
v3: change reset process
v3: rebase

Signed-off-by: Shiyang He <shiyangx.he@intel.com>
Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
---
 doc/guides/nics/intel_vf.rst           |  3 +
 doc/guides/rel_notes/release_23_11.rst |  3 +
 drivers/net/iavf/iavf.h                |  7 +++
 drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
 drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
 drivers/net/iavf/iavf_vchnl.c          | 11 +++-
 6 files changed, 135 insertions(+), 27 deletions(-)

diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index d365dbc185..c0acd2a7f5 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the following documents:
     Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog period in microseconds, or set it to 0 to disable the watchdog,
     for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a 18:01.0,watchdog_period=0``.
 
+    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a 18:01.0,enable_auto_reset=1`` when IAVF is backed
+    by an Intel® E810 device or an Intel® 700 Series Ethernet device.
+
 The PCIE host-interface of Intel Ethernet Switch FM10000 Series VF infrastructure
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 03191b3ae0..8536ce88f4 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -86,6 +86,9 @@ New Features
 
   * Added support for port representor.
 
+* **Updated Intel iavf driver.**
+  * Added support for iavf auto-reset.
+
 Removed Items
 -------------
 
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 98861e4242..3641401f38 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -277,6 +277,8 @@ struct iavf_info {
 
 	struct rte_eth_dev *eth_dev;
 
+	bool in_reset_recovery;
+
 	uint32_t ptp_caps;
 	rte_spinlock_t phc_time_aq_lock;
 };
@@ -305,6 +307,7 @@ struct iavf_devargs {
 	uint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];
 	uint16_t quanta_size;
 	uint32_t watchdog_period;
+	uint8_t  enable_auto_reset;
 };
 
 struct iavf_security_ctx;
@@ -426,6 +429,9 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops)
 }
 int iavf_check_api_version(struct iavf_adapter *adapter);
 int iavf_get_vf_resource(struct iavf_adapter *adapter);
+void iavf_dev_event_post(struct rte_eth_dev *dev,
+		enum rte_eth_event_type event,
+		void *param, size_t param_alloc_size);
 void iavf_dev_event_handler_fini(void);
 int iavf_dev_event_handler_init(void);
 void iavf_handle_virtchnl_msg(struct rte_eth_dev *dev);
@@ -501,4 +507,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter,
 			struct iavf_fsub_conf *filter);
 void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
 void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
+int iavf_handle_hw_reset(struct rte_eth_dev *dev);
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 97390237ba..94b9881fce 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -37,6 +37,7 @@
 #define IAVF_PROTO_XTR_ARG         "proto_xtr"
 #define IAVF_QUANTA_SIZE_ARG       "quanta_size"
 #define IAVF_RESET_WATCHDOG_ARG    "watchdog_period"
+#define IAVF_ENABLE_AUTO_RESET_ARG "enable_auto_reset"
 
 uint64_t iavf_timestamp_dynflag;
 int iavf_timestamp_dynfield_offset = -1;
@@ -45,6 +46,7 @@ static const char * const iavf_valid_args[] = {
 	IAVF_PROTO_XTR_ARG,
 	IAVF_QUANTA_SIZE_ARG,
 	IAVF_RESET_WATCHDOG_ARG,
+	IAVF_ENABLE_AUTO_RESET_ARG,
 	NULL
 };
 
@@ -307,8 +309,8 @@ iavf_dev_watchdog(void *cb_arg)
 			adapter->vf.vf_reset = true;
 			adapter->vf.link_up = false;
 
-			rte_eth_dev_callback_process(adapter->vf.eth_dev,
-				RTE_ETH_EVENT_INTR_RESET, NULL);
+			iavf_dev_event_post(adapter->vf.eth_dev, RTE_ETH_EVENT_INTR_RESET,
+				NULL, 0);
 		}
 	}
 
@@ -1101,12 +1103,15 @@ iavf_dev_stop(struct rte_eth_dev *dev)
 	/* Rx interrupt vector mapping free */
 	rte_intr_vec_list_free(intr_handle);
 
-	/* remove all mac addrs */
-	iavf_add_del_all_mac_addr(adapter, false);
+	/* adminq will be disabled when vf is resetting. */
+	if (!vf->in_reset_recovery) {
+		/* remove all mac addrs */
+		iavf_add_del_all_mac_addr(adapter, false);
 
-	/* remove all multicast addresses */
-	iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
+		/* remove all multicast addresses */
+		iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
 				  false);
+	}
 
 	iavf_stop_queues(dev);
 
@@ -2239,6 +2244,26 @@ parse_u16(__rte_unused const char *key, const char *value, void *args)
 	return 0;
 }
 
+static int
+parse_bool(const char *key, const char *value, void *args)
+{
+	int *i = (int *)args;
+	char *end;
+	int num;
+
+	num = strtoul(value, &end, 10);
+
+	if (num != 0 && num != 1) {
+		PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+			"value must be 0 or 1",
+			value, key);
+		return -1;
+	}
+
+	*i = num;
+	return 0;
+}
+
 static int
 iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
 {
@@ -2307,6 +2332,11 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
 		goto bail;
 	}
 
+	ret = rte_kvargs_process(kvlist, IAVF_ENABLE_AUTO_RESET_ARG,
+				 &parse_bool, &ad->devargs.enable_auto_reset);
+	if (ret)
+		goto bail;
+
 bail:
 	rte_kvargs_free(kvlist);
 	return ret;
@@ -2887,12 +2917,15 @@ iavf_dev_close(struct rte_eth_dev *dev)
 static int
 iavf_dev_uninit(struct rte_eth_dev *dev)
 {
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return -EPERM;
 
 	iavf_dev_close(dev);
 
-	iavf_dev_event_handler_fini();
+	if (!vf->in_reset_recovery)
+		iavf_dev_event_handler_fini();
 
 	return 0;
 }
@@ -2905,6 +2938,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 {
 	int ret;
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 
 	/*
 	 * Check whether the VF reset has been done and inform application,
@@ -2916,6 +2950,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 		PMD_DRV_LOG(ERR, "Wait too long for reset done!\n");
 		return ret;
 	}
+	vf->vf_reset = false;
 
 	PMD_DRV_LOG(DEBUG, "Start dev_reset ...\n");
 	ret = iavf_dev_uninit(dev);
@@ -2925,6 +2960,43 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 	return iavf_dev_init(dev);
 }
 
+/*
+ * Handle hardware reset
+ */
+int
+iavf_handle_hw_reset(struct rte_eth_dev *dev)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	int ret;
+
+	vf->in_reset_recovery = true;
+
+	ret = iavf_dev_reset(dev);
+	if (ret)
+		goto error;
+
+	/* VF states restore */
+	ret = iavf_dev_configure(dev);
+	if (ret)
+		goto error;
+
+	iavf_dev_xstats_reset(dev);
+
+	/* start the device */
+	ret = iavf_dev_start(dev);
+	if (ret)
+		goto error;
+	dev->data->dev_started = 1;
+
+	vf->in_reset_recovery = false;
+	return 0;
+
+error:
+	PMD_DRV_LOG(DEBUG, "RESET recover with error code=%d\n", ret);
+	vf->in_reset_recovery = false;
+	return ret;
+}
+
 static int
 iavf_dcf_cap_check_handler(__rte_unused const char *key,
 			   const char *value, __rte_unused void *opaque)
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index 72e8ae8aa6..0484988d13 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -1101,15 +1101,44 @@ iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
 	rte_free(q);
 }
 
+static void
+iavf_reset_queues(struct rte_eth_dev *dev)
+{
+	struct iavf_rx_queue *rxq;
+	struct iavf_tx_queue *txq;
+	int i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (!txq)
+			continue;
+		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
+		reset_tx_queue(txq);
+		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (!rxq)
+			continue;
+		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
+		reset_rx_queue(rxq);
+		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+}
+
 void
 iavf_stop_queues(struct rte_eth_dev *dev)
 {
 	struct iavf_adapter *adapter =
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-	struct iavf_rx_queue *rxq;
-	struct iavf_tx_queue *txq;
-	int ret, i;
+	int ret;
+
+	/* adminq will be disabled when vf is resetting. */
+	if (vf->in_reset_recovery) {
+		iavf_reset_queues(dev);
+		return;
+	}
 
 	/* Stop All queues */
 	if (!vf->lv_enabled) {
@@ -1125,22 +1154,7 @@ iavf_stop_queues(struct rte_eth_dev *dev)
 	if (ret)
 		PMD_DRV_LOG(WARNING, "Fail to stop queues");
 
-	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		txq = dev->data->tx_queues[i];
-		if (!txq)
-			continue;
-		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
-		reset_tx_queue(txq);
-		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
-	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		rxq = dev->data->rx_queues[i];
-		if (!rxq)
-			continue;
-		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
-		reset_rx_queue(rxq);
-		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
+	iavf_reset_queues(dev);
 }
 
 #define IAVF_RX_FLEX_ERR0_BITS	\
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index b3e106b41f..caf7cd6d8e 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -79,6 +79,15 @@ iavf_dev_event_handle(void *param __rte_unused)
 		struct iavf_event_element *pos, *save_next;
 		TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) {
 			TAILQ_REMOVE(&pending, pos, next);
+
+			struct iavf_adapter *adapter = pos->dev->data->dev_private;
+			if (pos->event == RTE_ETH_EVENT_INTR_RESET &&
+			    adapter->devargs.enable_auto_reset) {
+				iavf_handle_hw_reset(pos->dev);
+				rte_free(pos);
+				continue;
+			}
+
 			rte_eth_dev_callback_process(pos->dev, pos->event, pos->param);
 			rte_free(pos);
 		}
@@ -87,7 +96,7 @@ iavf_dev_event_handle(void *param __rte_unused)
 	return 0;
 }
 
-static void
+void
 iavf_dev_event_post(struct rte_eth_dev *dev,
 		enum rte_eth_event_type event,
 		void *param, size_t param_alloc_size)
-- 
2.37.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
  2023-09-26  7:48     ` Bruce Richardson
@ 2023-09-26 12:15       ` Zhang, Qi Z
  2023-09-26 14:05         ` Bruce Richardson
  0 siblings, 1 reply; 14+ messages in thread
From: Zhang, Qi Z @ 2023-09-26 12:15 UTC (permalink / raw)
  To: Richardson, Bruce, He, ShiyangX
  Cc: dev, Zhou, YidingX, Wang, Liang-min, Su, Simei, Wu, Wenjun1,
	Zhang, Yuying, Xing, Beilei, Yang, Qiming, Wu, Jingjing



> -----Original Message-----
> From: Bruce Richardson <bruce.richardson@intel.com>
> Sent: Tuesday, September 26, 2023 3:49 PM
> To: He, ShiyangX <shiyangx.he@intel.com>
> Cc: dev@dpdk.org; Zhou, YidingX <yidingx.zhou@intel.com>; Wang, Liang-
> min <liang-min.wang@intel.com>; Su, Simei <simei.su@intel.com>; Wu,
> Wenjun1 <wenjun1.wu@intel.com>; Zhang, Yuying
> <yuying.zhang@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang,
> Qiming <qiming.yang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Subject: Re: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
> 
> On Fri, Sep 15, 2023 at 01:02:49PM +0000, Shiyang He wrote:
> > Originally, the iavf PMD does not perform special actions when it
> > receives a PF-to-VF reset event, resulting in vf being offline and
> > unavailable.
> >
> > This patch enables vf auto-reset by setting 'watchdog_period' devargs
> > to true. The iavf PMD will perform an automatic reset to bring the vf
> > back online when it receives a PF-to-VF event.
> >
> > v2: handling reset by event handler
> > v3: change reset process
> >
> > Signed-off-by: Shiyang He <shiyangx.he@intel.com>
> > Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
> > ---
> >  doc/guides/nics/intel_vf.rst           |  3 +
> >  doc/guides/rel_notes/release_23_11.rst |  3 +
> >  drivers/net/iavf/iavf.h                |  7 +++
> >  drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
> >  drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
> >  drivers/net/iavf/iavf_vchnl.c          | 11 +++-
> >  6 files changed, 135 insertions(+), 27 deletions(-)
> >
> > diff --git a/doc/guides/nics/intel_vf.rst
> > b/doc/guides/nics/intel_vf.rst index d365dbc185..c0acd2a7f5 100644
> > --- a/doc/guides/nics/intel_vf.rst
> > +++ b/doc/guides/nics/intel_vf.rst
> > @@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the
> following documents:
> >      Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog
> period in microseconds, or set it to 0 to disable the watchdog,
> >      for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a
> 18:01.0,watchdog_period=0``.
> >
> > +    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a
> 18:01.0,enable_auto_reset=1`` when IAVF is backed
> > +    by an Intel(r) E810 device or an Intel(r) 700 Series Ethernet device.
> > +
> 
> Why do we need a devargs for this? If the VF is unavailable - as you mention
> in the commit log above - should this behaviour not always be the case
> without the user having to ask?

Ideally it does not need, but with below considerations:

1. Not break existing scenario, which still assume some application will call dev_reset /dev_configure/ queue_setup / ...  after receive RTE_ETH_EVENT_INTR_RESET event to recover the VF manually, the devargs make sure application be aware of this new feature and will not call rte_eth_dev_reset which will fail now.

2. intent to ensure a smoother transition, in case some corner case issues evaded our validation, keeping this devargs provides us with the flexibility to remove it once we determine that the implementation is stable enough.  

> 
> /Bruce

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v5] net/iavf: add devargs to enable vf auto-reset
  2023-09-26 11:31     ` [PATCH v4] " Shiyang He
  2023-09-26  4:51       ` Zhang, Qi Z
@ 2023-09-26 12:29       ` Shiyang He
  2023-09-26 12:31       ` Shiyang He
  2023-09-26 12:38       ` Shiyang He
  3 siblings, 0 replies; 14+ messages in thread
From: Shiyang He @ 2023-09-26 12:29 UTC (permalink / raw)
  To: dev
  Cc: yidingx.zhou, Shiyang He, Liang-Min Larry Wang, Qiming Yang,
	Wenjun Wu, Simei Su, Yuying Zhang, Beilei Xing, Jingjing Wu

Originally, the iavf PMD does not perform special actions when it
receives a PF-to-VF reset event, resulting in vf being offline and
unavailable.

This patch enables vf auto-reset by setting 'watchdog_period' devargs
to true. The iavf PMD will perform an automatic reset to bring the vf
back online when it receives a PF-to-VF event.

v2: handling reset by event handler
v3: change reset process
v3: rebase

Signed-off-by: Shiyang He <shiyangx.he@intel.com>
Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
---
 doc/guides/nics/intel_vf.rst           |  3 +
 doc/guides/rel_notes/release_23_11.rst |  3 +
 drivers/net/iavf/iavf.h                |  7 +++
 drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
 drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
 drivers/net/iavf/iavf_vchnl.c          | 11 +++-
 6 files changed, 135 insertions(+), 27 deletions(-)

diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index d365dbc185..c0acd2a7f5 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the following documents:
     Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog period in microseconds, or set it to 0 to disable the watchdog,
     for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a 18:01.0,watchdog_period=0``.
 
+    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a 18:01.0,enable_auto_reset=1`` when IAVF is backed
+    by an Intel® E810 device or an Intel® 700 Series Ethernet device.
+
 The PCIE host-interface of Intel Ethernet Switch FM10000 Series VF infrastructure
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 03191b3ae0..8536ce88f4 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -86,6 +86,9 @@ New Features
 
   * Added support for port representor.
 
+* **Updated Intel iavf driver.**
+  * Added support for iavf auto-reset.
+
 Removed Items
 -------------
 
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 98861e4242..3641401f38 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -277,6 +277,8 @@ struct iavf_info {
 
 	struct rte_eth_dev *eth_dev;
 
+	bool in_reset_recovery;
+
 	uint32_t ptp_caps;
 	rte_spinlock_t phc_time_aq_lock;
 };
@@ -305,6 +307,7 @@ struct iavf_devargs {
 	uint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];
 	uint16_t quanta_size;
 	uint32_t watchdog_period;
+	uint8_t  enable_auto_reset;
 };
 
 struct iavf_security_ctx;
@@ -426,6 +429,9 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops)
 }
 int iavf_check_api_version(struct iavf_adapter *adapter);
 int iavf_get_vf_resource(struct iavf_adapter *adapter);
+void iavf_dev_event_post(struct rte_eth_dev *dev,
+		enum rte_eth_event_type event,
+		void *param, size_t param_alloc_size);
 void iavf_dev_event_handler_fini(void);
 int iavf_dev_event_handler_init(void);
 void iavf_handle_virtchnl_msg(struct rte_eth_dev *dev);
@@ -501,4 +507,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter,
 			struct iavf_fsub_conf *filter);
 void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
 void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
+int iavf_handle_hw_reset(struct rte_eth_dev *dev);
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 97390237ba..94b9881fce 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -37,6 +37,7 @@
 #define IAVF_PROTO_XTR_ARG         "proto_xtr"
 #define IAVF_QUANTA_SIZE_ARG       "quanta_size"
 #define IAVF_RESET_WATCHDOG_ARG    "watchdog_period"
+#define IAVF_ENABLE_AUTO_RESET_ARG "enable_auto_reset"
 
 uint64_t iavf_timestamp_dynflag;
 int iavf_timestamp_dynfield_offset = -1;
@@ -45,6 +46,7 @@ static const char * const iavf_valid_args[] = {
 	IAVF_PROTO_XTR_ARG,
 	IAVF_QUANTA_SIZE_ARG,
 	IAVF_RESET_WATCHDOG_ARG,
+	IAVF_ENABLE_AUTO_RESET_ARG,
 	NULL
 };
 
@@ -307,8 +309,8 @@ iavf_dev_watchdog(void *cb_arg)
 			adapter->vf.vf_reset = true;
 			adapter->vf.link_up = false;
 
-			rte_eth_dev_callback_process(adapter->vf.eth_dev,
-				RTE_ETH_EVENT_INTR_RESET, NULL);
+			iavf_dev_event_post(adapter->vf.eth_dev, RTE_ETH_EVENT_INTR_RESET,
+				NULL, 0);
 		}
 	}
 
@@ -1101,12 +1103,15 @@ iavf_dev_stop(struct rte_eth_dev *dev)
 	/* Rx interrupt vector mapping free */
 	rte_intr_vec_list_free(intr_handle);
 
-	/* remove all mac addrs */
-	iavf_add_del_all_mac_addr(adapter, false);
+	/* adminq will be disabled when vf is resetting. */
+	if (!vf->in_reset_recovery) {
+		/* remove all mac addrs */
+		iavf_add_del_all_mac_addr(adapter, false);
 
-	/* remove all multicast addresses */
-	iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
+		/* remove all multicast addresses */
+		iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
 				  false);
+	}
 
 	iavf_stop_queues(dev);
 
@@ -2239,6 +2244,26 @@ parse_u16(__rte_unused const char *key, const char *value, void *args)
 	return 0;
 }
 
+static int
+parse_bool(const char *key, const char *value, void *args)
+{
+	int *i = (int *)args;
+	char *end;
+	int num;
+
+	num = strtoul(value, &end, 10);
+
+	if (num != 0 && num != 1) {
+		PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+			"value must be 0 or 1",
+			value, key);
+		return -1;
+	}
+
+	*i = num;
+	return 0;
+}
+
 static int
 iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
 {
@@ -2307,6 +2332,11 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
 		goto bail;
 	}
 
+	ret = rte_kvargs_process(kvlist, IAVF_ENABLE_AUTO_RESET_ARG,
+				 &parse_bool, &ad->devargs.enable_auto_reset);
+	if (ret)
+		goto bail;
+
 bail:
 	rte_kvargs_free(kvlist);
 	return ret;
@@ -2887,12 +2917,15 @@ iavf_dev_close(struct rte_eth_dev *dev)
 static int
 iavf_dev_uninit(struct rte_eth_dev *dev)
 {
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return -EPERM;
 
 	iavf_dev_close(dev);
 
-	iavf_dev_event_handler_fini();
+	if (!vf->in_reset_recovery)
+		iavf_dev_event_handler_fini();
 
 	return 0;
 }
@@ -2905,6 +2938,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 {
 	int ret;
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 
 	/*
 	 * Check whether the VF reset has been done and inform application,
@@ -2916,6 +2950,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 		PMD_DRV_LOG(ERR, "Wait too long for reset done!\n");
 		return ret;
 	}
+	vf->vf_reset = false;
 
 	PMD_DRV_LOG(DEBUG, "Start dev_reset ...\n");
 	ret = iavf_dev_uninit(dev);
@@ -2925,6 +2960,43 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 	return iavf_dev_init(dev);
 }
 
+/*
+ * Handle hardware reset
+ */
+int
+iavf_handle_hw_reset(struct rte_eth_dev *dev)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	int ret;
+
+	vf->in_reset_recovery = true;
+
+	ret = iavf_dev_reset(dev);
+	if (ret)
+		goto error;
+
+	/* VF states restore */
+	ret = iavf_dev_configure(dev);
+	if (ret)
+		goto error;
+
+	iavf_dev_xstats_reset(dev);
+
+	/* start the device */
+	ret = iavf_dev_start(dev);
+	if (ret)
+		goto error;
+	dev->data->dev_started = 1;
+
+	vf->in_reset_recovery = false;
+	return 0;
+
+error:
+	PMD_DRV_LOG(DEBUG, "RESET recover with error code=%d\n", ret);
+	vf->in_reset_recovery = false;
+	return ret;
+}
+
 static int
 iavf_dcf_cap_check_handler(__rte_unused const char *key,
 			   const char *value, __rte_unused void *opaque)
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index 72e8ae8aa6..0484988d13 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -1101,15 +1101,44 @@ iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
 	rte_free(q);
 }
 
+static void
+iavf_reset_queues(struct rte_eth_dev *dev)
+{
+	struct iavf_rx_queue *rxq;
+	struct iavf_tx_queue *txq;
+	int i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (!txq)
+			continue;
+		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
+		reset_tx_queue(txq);
+		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (!rxq)
+			continue;
+		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
+		reset_rx_queue(rxq);
+		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+}
+
 void
 iavf_stop_queues(struct rte_eth_dev *dev)
 {
 	struct iavf_adapter *adapter =
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-	struct iavf_rx_queue *rxq;
-	struct iavf_tx_queue *txq;
-	int ret, i;
+	int ret;
+
+	/* adminq will be disabled when vf is resetting. */
+	if (vf->in_reset_recovery) {
+		iavf_reset_queues(dev);
+		return;
+	}
 
 	/* Stop All queues */
 	if (!vf->lv_enabled) {
@@ -1125,22 +1154,7 @@ iavf_stop_queues(struct rte_eth_dev *dev)
 	if (ret)
 		PMD_DRV_LOG(WARNING, "Fail to stop queues");
 
-	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		txq = dev->data->tx_queues[i];
-		if (!txq)
-			continue;
-		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
-		reset_tx_queue(txq);
-		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
-	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		rxq = dev->data->rx_queues[i];
-		if (!rxq)
-			continue;
-		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
-		reset_rx_queue(rxq);
-		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
+	iavf_reset_queues(dev);
 }
 
 #define IAVF_RX_FLEX_ERR0_BITS	\
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index b3e106b41f..caf7cd6d8e 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -79,6 +79,15 @@ iavf_dev_event_handle(void *param __rte_unused)
 		struct iavf_event_element *pos, *save_next;
 		TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) {
 			TAILQ_REMOVE(&pending, pos, next);
+
+			struct iavf_adapter *adapter = pos->dev->data->dev_private;
+			if (pos->event == RTE_ETH_EVENT_INTR_RESET &&
+			    adapter->devargs.enable_auto_reset) {
+				iavf_handle_hw_reset(pos->dev);
+				rte_free(pos);
+				continue;
+			}
+
 			rte_eth_dev_callback_process(pos->dev, pos->event, pos->param);
 			rte_free(pos);
 		}
@@ -87,7 +96,7 @@ iavf_dev_event_handle(void *param __rte_unused)
 	return 0;
 }
 
-static void
+void
 iavf_dev_event_post(struct rte_eth_dev *dev,
 		enum rte_eth_event_type event,
 		void *param, size_t param_alloc_size)
-- 
2.37.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v5] net/iavf: add devargs to enable vf auto-reset
  2023-09-26 11:31     ` [PATCH v4] " Shiyang He
  2023-09-26  4:51       ` Zhang, Qi Z
  2023-09-26 12:29       ` [PATCH v5] " Shiyang He
@ 2023-09-26 12:31       ` Shiyang He
  2023-09-26 12:38       ` Shiyang He
  3 siblings, 0 replies; 14+ messages in thread
From: Shiyang He @ 2023-09-26 12:31 UTC (permalink / raw)
  To: dev
  Cc: yidingx.zhou, Shiyang He, Qi Zhang, Liang-Min Larry Wang,
	Qiming Yang, Wenjun Wu, Simei Su, Yuying Zhang, Beilei Xing,
	Jingjing Wu

Originally, the iavf PMD does not perform special actions when it
receives a PF-to-VF reset event, resulting in vf being offline and
unavailable.

This patch enables vf auto-reset by setting 'watchdog_period' devargs
to true. The iavf PMD will perform an automatic reset to bring the vf
back online when it receives a PF-to-VF event.

v2: handling reset by event handler
v3: change reset process
v4: rebase
v5: change enable_auto_reset to enable_reset

Acked-by: Qi Zhang <qi.z.zhang@intel.com>
Signed-off-by: Shiyang He <shiyangx.he@intel.com>
Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
---
 doc/guides/nics/intel_vf.rst           |  3 +
 doc/guides/rel_notes/release_23_11.rst |  3 +
 drivers/net/iavf/iavf.h                |  7 +++
 drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
 drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
 drivers/net/iavf/iavf_vchnl.c          | 11 +++-
 6 files changed, 135 insertions(+), 27 deletions(-)

diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index d365dbc185..f771948242 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the following documents:
     Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog period in microseconds, or set it to 0 to disable the watchdog,
     for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a 18:01.0,watchdog_period=0``.
 
+    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a 18:01.0,enable_reset=1`` when IAVF is backed
+    by an Intel® E810 device or an Intel® 700 Series Ethernet device.
+
 The PCIE host-interface of Intel Ethernet Switch FM10000 Series VF infrastructure
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 03191b3ae0..8536ce88f4 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -86,6 +86,9 @@ New Features
 
   * Added support for port representor.
 
+* **Updated Intel iavf driver.**
+  * Added support for iavf auto-reset.
+
 Removed Items
 -------------
 
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 98861e4242..be6b9920e6 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -277,6 +277,8 @@ struct iavf_info {
 
 	struct rte_eth_dev *eth_dev;
 
+	bool in_reset_recovery;
+
 	uint32_t ptp_caps;
 	rte_spinlock_t phc_time_aq_lock;
 };
@@ -305,6 +307,7 @@ struct iavf_devargs {
 	uint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];
 	uint16_t quanta_size;
 	uint32_t watchdog_period;
+	uint8_t  enable_reset;
 };
 
 struct iavf_security_ctx;
@@ -426,6 +429,9 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops)
 }
 int iavf_check_api_version(struct iavf_adapter *adapter);
 int iavf_get_vf_resource(struct iavf_adapter *adapter);
+void iavf_dev_event_post(struct rte_eth_dev *dev,
+		enum rte_eth_event_type event,
+		void *param, size_t param_alloc_size);
 void iavf_dev_event_handler_fini(void);
 int iavf_dev_event_handler_init(void);
 void iavf_handle_virtchnl_msg(struct rte_eth_dev *dev);
@@ -501,4 +507,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter,
 			struct iavf_fsub_conf *filter);
 void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
 void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
+int iavf_handle_hw_reset(struct rte_eth_dev *dev);
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 97390237ba..191870c06b 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -37,6 +37,7 @@
 #define IAVF_PROTO_XTR_ARG         "proto_xtr"
 #define IAVF_QUANTA_SIZE_ARG       "quanta_size"
 #define IAVF_RESET_WATCHDOG_ARG    "watchdog_period"
+#define IAVF_ENABLE_AUTO_RESET_ARG "enable_reset"
 
 uint64_t iavf_timestamp_dynflag;
 int iavf_timestamp_dynfield_offset = -1;
@@ -45,6 +46,7 @@ static const char * const iavf_valid_args[] = {
 	IAVF_PROTO_XTR_ARG,
 	IAVF_QUANTA_SIZE_ARG,
 	IAVF_RESET_WATCHDOG_ARG,
+	IAVF_ENABLE_AUTO_RESET_ARG,
 	NULL
 };
 
@@ -307,8 +309,8 @@ iavf_dev_watchdog(void *cb_arg)
 			adapter->vf.vf_reset = true;
 			adapter->vf.link_up = false;
 
-			rte_eth_dev_callback_process(adapter->vf.eth_dev,
-				RTE_ETH_EVENT_INTR_RESET, NULL);
+			iavf_dev_event_post(adapter->vf.eth_dev, RTE_ETH_EVENT_INTR_RESET,
+				NULL, 0);
 		}
 	}
 
@@ -1101,12 +1103,15 @@ iavf_dev_stop(struct rte_eth_dev *dev)
 	/* Rx interrupt vector mapping free */
 	rte_intr_vec_list_free(intr_handle);
 
-	/* remove all mac addrs */
-	iavf_add_del_all_mac_addr(adapter, false);
+	/* adminq will be disabled when vf is resetting. */
+	if (!vf->in_reset_recovery) {
+		/* remove all mac addrs */
+		iavf_add_del_all_mac_addr(adapter, false);
 
-	/* remove all multicast addresses */
-	iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
+		/* remove all multicast addresses */
+		iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
 				  false);
+	}
 
 	iavf_stop_queues(dev);
 
@@ -2239,6 +2244,26 @@ parse_u16(__rte_unused const char *key, const char *value, void *args)
 	return 0;
 }
 
+static int
+parse_bool(const char *key, const char *value, void *args)
+{
+	int *i = (int *)args;
+	char *end;
+	int num;
+
+	num = strtoul(value, &end, 10);
+
+	if (num != 0 && num != 1) {
+		PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+			"value must be 0 or 1",
+			value, key);
+		return -1;
+	}
+
+	*i = num;
+	return 0;
+}
+
 static int
 iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
 {
@@ -2307,6 +2332,11 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
 		goto bail;
 	}
 
+	ret = rte_kvargs_process(kvlist, IAVF_ENABLE_AUTO_RESET_ARG,
+				 &parse_bool, &ad->devargs.enable_reset);
+	if (ret)
+		goto bail;
+
 bail:
 	rte_kvargs_free(kvlist);
 	return ret;
@@ -2887,12 +2917,15 @@ iavf_dev_close(struct rte_eth_dev *dev)
 static int
 iavf_dev_uninit(struct rte_eth_dev *dev)
 {
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return -EPERM;
 
 	iavf_dev_close(dev);
 
-	iavf_dev_event_handler_fini();
+	if (!vf->in_reset_recovery)
+		iavf_dev_event_handler_fini();
 
 	return 0;
 }
@@ -2905,6 +2938,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 {
 	int ret;
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 
 	/*
 	 * Check whether the VF reset has been done and inform application,
@@ -2916,6 +2950,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 		PMD_DRV_LOG(ERR, "Wait too long for reset done!\n");
 		return ret;
 	}
+	vf->vf_reset = false;
 
 	PMD_DRV_LOG(DEBUG, "Start dev_reset ...\n");
 	ret = iavf_dev_uninit(dev);
@@ -2925,6 +2960,43 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 	return iavf_dev_init(dev);
 }
 
+/*
+ * Handle hardware reset
+ */
+int
+iavf_handle_hw_reset(struct rte_eth_dev *dev)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	int ret;
+
+	vf->in_reset_recovery = true;
+
+	ret = iavf_dev_reset(dev);
+	if (ret)
+		goto error;
+
+	/* VF states restore */
+	ret = iavf_dev_configure(dev);
+	if (ret)
+		goto error;
+
+	iavf_dev_xstats_reset(dev);
+
+	/* start the device */
+	ret = iavf_dev_start(dev);
+	if (ret)
+		goto error;
+	dev->data->dev_started = 1;
+
+	vf->in_reset_recovery = false;
+	return 0;
+
+error:
+	PMD_DRV_LOG(DEBUG, "RESET recover with error code=%d\n", ret);
+	vf->in_reset_recovery = false;
+	return ret;
+}
+
 static int
 iavf_dcf_cap_check_handler(__rte_unused const char *key,
 			   const char *value, __rte_unused void *opaque)
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index 72e8ae8aa6..0484988d13 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -1101,15 +1101,44 @@ iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
 	rte_free(q);
 }
 
+static void
+iavf_reset_queues(struct rte_eth_dev *dev)
+{
+	struct iavf_rx_queue *rxq;
+	struct iavf_tx_queue *txq;
+	int i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (!txq)
+			continue;
+		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
+		reset_tx_queue(txq);
+		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (!rxq)
+			continue;
+		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
+		reset_rx_queue(rxq);
+		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+}
+
 void
 iavf_stop_queues(struct rte_eth_dev *dev)
 {
 	struct iavf_adapter *adapter =
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-	struct iavf_rx_queue *rxq;
-	struct iavf_tx_queue *txq;
-	int ret, i;
+	int ret;
+
+	/* adminq will be disabled when vf is resetting. */
+	if (vf->in_reset_recovery) {
+		iavf_reset_queues(dev);
+		return;
+	}
 
 	/* Stop All queues */
 	if (!vf->lv_enabled) {
@@ -1125,22 +1154,7 @@ iavf_stop_queues(struct rte_eth_dev *dev)
 	if (ret)
 		PMD_DRV_LOG(WARNING, "Fail to stop queues");
 
-	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		txq = dev->data->tx_queues[i];
-		if (!txq)
-			continue;
-		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
-		reset_tx_queue(txq);
-		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
-	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		rxq = dev->data->rx_queues[i];
-		if (!rxq)
-			continue;
-		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
-		reset_rx_queue(rxq);
-		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
+	iavf_reset_queues(dev);
 }
 
 #define IAVF_RX_FLEX_ERR0_BITS	\
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index b3e106b41f..9cefa26854 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -79,6 +79,15 @@ iavf_dev_event_handle(void *param __rte_unused)
 		struct iavf_event_element *pos, *save_next;
 		TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) {
 			TAILQ_REMOVE(&pending, pos, next);
+
+			struct iavf_adapter *adapter = pos->dev->data->dev_private;
+			if (pos->event == RTE_ETH_EVENT_INTR_RESET &&
+			    adapter->devargs.enable_reset) {
+				iavf_handle_hw_reset(pos->dev);
+				rte_free(pos);
+				continue;
+			}
+
 			rte_eth_dev_callback_process(pos->dev, pos->event, pos->param);
 			rte_free(pos);
 		}
@@ -87,7 +96,7 @@ iavf_dev_event_handle(void *param __rte_unused)
 	return 0;
 }
 
-static void
+void
 iavf_dev_event_post(struct rte_eth_dev *dev,
 		enum rte_eth_event_type event,
 		void *param, size_t param_alloc_size)
-- 
2.37.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v5] net/iavf: add devargs to enable vf auto-reset
  2023-09-26 11:31     ` [PATCH v4] " Shiyang He
                         ` (2 preceding siblings ...)
  2023-09-26 12:31       ` Shiyang He
@ 2023-09-26 12:38       ` Shiyang He
  2023-09-26  5:33         ` Zhang, Qi Z
  3 siblings, 1 reply; 14+ messages in thread
From: Shiyang He @ 2023-09-26 12:38 UTC (permalink / raw)
  To: dev
  Cc: yidingx.zhou, Shiyang He, Qi Zhang, Liang-Min Larry Wang,
	Yuying Zhang, Beilei Xing, Simei Su, Wenjun Wu, Qiming Yang,
	Jingjing Wu

Originally, the iavf PMD does not perform special actions when it
receives a PF-to-VF reset event, resulting in vf being offline and
unavailable.

This patch enables vf auto-reset by setting 'watchdog_period' devargs
to true. The iavf PMD will perform an automatic reset to bring the vf
back online when it receives a PF-to-VF event.

v2: handling reset by event handler
v3: change reset process
v4: rebase
v5: change enable_auto_reset to auto_reset

Acked-by: Qi Zhang <qi.z.zhang@intel.com>
Signed-off-by: Shiyang He <shiyangx.he@intel.com>
Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
---
 doc/guides/nics/intel_vf.rst           |  3 +
 doc/guides/rel_notes/release_23_11.rst |  3 +
 drivers/net/iavf/iavf.h                |  7 +++
 drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
 drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
 drivers/net/iavf/iavf_vchnl.c          | 11 +++-
 6 files changed, 135 insertions(+), 27 deletions(-)

diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index d365dbc185..7613e1c5e5 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the following documents:
     Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog period in microseconds, or set it to 0 to disable the watchdog,
     for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a 18:01.0,watchdog_period=0``.
 
+    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a 18:01.0,auto_reset=1`` when IAVF is backed
+    by an Intel® E810 device or an Intel® 700 Series Ethernet device.
+
 The PCIE host-interface of Intel Ethernet Switch FM10000 Series VF infrastructure
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 03191b3ae0..8536ce88f4 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -86,6 +86,9 @@ New Features
 
   * Added support for port representor.
 
+* **Updated Intel iavf driver.**
+  * Added support for iavf auto-reset.
+
 Removed Items
 -------------
 
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 98861e4242..04774ce124 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -277,6 +277,8 @@ struct iavf_info {
 
 	struct rte_eth_dev *eth_dev;
 
+	bool in_reset_recovery;
+
 	uint32_t ptp_caps;
 	rte_spinlock_t phc_time_aq_lock;
 };
@@ -305,6 +307,7 @@ struct iavf_devargs {
 	uint8_t proto_xtr[IAVF_MAX_QUEUE_NUM];
 	uint16_t quanta_size;
 	uint32_t watchdog_period;
+	uint8_t  auto_reset;
 };
 
 struct iavf_security_ctx;
@@ -426,6 +429,9 @@ _atomic_set_async_response_cmd(struct iavf_info *vf, enum virtchnl_ops ops)
 }
 int iavf_check_api_version(struct iavf_adapter *adapter);
 int iavf_get_vf_resource(struct iavf_adapter *adapter);
+void iavf_dev_event_post(struct rte_eth_dev *dev,
+		enum rte_eth_event_type event,
+		void *param, size_t param_alloc_size);
 void iavf_dev_event_handler_fini(void);
 int iavf_dev_event_handler_init(void);
 void iavf_handle_virtchnl_msg(struct rte_eth_dev *dev);
@@ -501,4 +507,5 @@ int iavf_flow_sub_check(struct iavf_adapter *adapter,
 			struct iavf_fsub_conf *filter);
 void iavf_dev_watchdog_enable(struct iavf_adapter *adapter);
 void iavf_dev_watchdog_disable(struct iavf_adapter *adapter);
+int iavf_handle_hw_reset(struct rte_eth_dev *dev);
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 97390237ba..5b2634a4e3 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -37,6 +37,7 @@
 #define IAVF_PROTO_XTR_ARG         "proto_xtr"
 #define IAVF_QUANTA_SIZE_ARG       "quanta_size"
 #define IAVF_RESET_WATCHDOG_ARG    "watchdog_period"
+#define IAVF_ENABLE_AUTO_RESET_ARG "auto_reset"
 
 uint64_t iavf_timestamp_dynflag;
 int iavf_timestamp_dynfield_offset = -1;
@@ -45,6 +46,7 @@ static const char * const iavf_valid_args[] = {
 	IAVF_PROTO_XTR_ARG,
 	IAVF_QUANTA_SIZE_ARG,
 	IAVF_RESET_WATCHDOG_ARG,
+	IAVF_ENABLE_AUTO_RESET_ARG,
 	NULL
 };
 
@@ -307,8 +309,8 @@ iavf_dev_watchdog(void *cb_arg)
 			adapter->vf.vf_reset = true;
 			adapter->vf.link_up = false;
 
-			rte_eth_dev_callback_process(adapter->vf.eth_dev,
-				RTE_ETH_EVENT_INTR_RESET, NULL);
+			iavf_dev_event_post(adapter->vf.eth_dev, RTE_ETH_EVENT_INTR_RESET,
+				NULL, 0);
 		}
 	}
 
@@ -1101,12 +1103,15 @@ iavf_dev_stop(struct rte_eth_dev *dev)
 	/* Rx interrupt vector mapping free */
 	rte_intr_vec_list_free(intr_handle);
 
-	/* remove all mac addrs */
-	iavf_add_del_all_mac_addr(adapter, false);
+	/* adminq will be disabled when vf is resetting. */
+	if (!vf->in_reset_recovery) {
+		/* remove all mac addrs */
+		iavf_add_del_all_mac_addr(adapter, false);
 
-	/* remove all multicast addresses */
-	iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
+		/* remove all multicast addresses */
+		iavf_add_del_mc_addr_list(adapter, vf->mc_addrs, vf->mc_addrs_num,
 				  false);
+	}
 
 	iavf_stop_queues(dev);
 
@@ -2239,6 +2244,26 @@ parse_u16(__rte_unused const char *key, const char *value, void *args)
 	return 0;
 }
 
+static int
+parse_bool(const char *key, const char *value, void *args)
+{
+	int *i = (int *)args;
+	char *end;
+	int num;
+
+	num = strtoul(value, &end, 10);
+
+	if (num != 0 && num != 1) {
+		PMD_DRV_LOG(WARNING, "invalid value:\"%s\" for key:\"%s\", "
+			"value must be 0 or 1",
+			value, key);
+		return -1;
+	}
+
+	*i = num;
+	return 0;
+}
+
 static int
 iavf_parse_watchdog_period(__rte_unused const char *key, const char *value, void *args)
 {
@@ -2307,6 +2332,11 @@ static int iavf_parse_devargs(struct rte_eth_dev *dev)
 		goto bail;
 	}
 
+	ret = rte_kvargs_process(kvlist, IAVF_ENABLE_AUTO_RESET_ARG,
+				 &parse_bool, &ad->devargs.auto_reset);
+	if (ret)
+		goto bail;
+
 bail:
 	rte_kvargs_free(kvlist);
 	return ret;
@@ -2887,12 +2917,15 @@ iavf_dev_close(struct rte_eth_dev *dev)
 static int
 iavf_dev_uninit(struct rte_eth_dev *dev)
 {
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return -EPERM;
 
 	iavf_dev_close(dev);
 
-	iavf_dev_event_handler_fini();
+	if (!vf->in_reset_recovery)
+		iavf_dev_event_handler_fini();
 
 	return 0;
 }
@@ -2905,6 +2938,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 {
 	int ret;
 	struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 
 	/*
 	 * Check whether the VF reset has been done and inform application,
@@ -2916,6 +2950,7 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 		PMD_DRV_LOG(ERR, "Wait too long for reset done!\n");
 		return ret;
 	}
+	vf->vf_reset = false;
 
 	PMD_DRV_LOG(DEBUG, "Start dev_reset ...\n");
 	ret = iavf_dev_uninit(dev);
@@ -2925,6 +2960,43 @@ iavf_dev_reset(struct rte_eth_dev *dev)
 	return iavf_dev_init(dev);
 }
 
+/*
+ * Handle hardware reset
+ */
+int
+iavf_handle_hw_reset(struct rte_eth_dev *dev)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	int ret;
+
+	vf->in_reset_recovery = true;
+
+	ret = iavf_dev_reset(dev);
+	if (ret)
+		goto error;
+
+	/* VF states restore */
+	ret = iavf_dev_configure(dev);
+	if (ret)
+		goto error;
+
+	iavf_dev_xstats_reset(dev);
+
+	/* start the device */
+	ret = iavf_dev_start(dev);
+	if (ret)
+		goto error;
+	dev->data->dev_started = 1;
+
+	vf->in_reset_recovery = false;
+	return 0;
+
+error:
+	PMD_DRV_LOG(DEBUG, "RESET recover with error code=%d\n", ret);
+	vf->in_reset_recovery = false;
+	return ret;
+}
+
 static int
 iavf_dcf_cap_check_handler(__rte_unused const char *key,
 			   const char *value, __rte_unused void *opaque)
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index 72e8ae8aa6..0484988d13 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -1101,15 +1101,44 @@ iavf_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
 	rte_free(q);
 }
 
+static void
+iavf_reset_queues(struct rte_eth_dev *dev)
+{
+	struct iavf_rx_queue *rxq;
+	struct iavf_tx_queue *txq;
+	int i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		txq = dev->data->tx_queues[i];
+		if (!txq)
+			continue;
+		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
+		reset_tx_queue(txq);
+		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		rxq = dev->data->rx_queues[i];
+		if (!rxq)
+			continue;
+		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
+		reset_rx_queue(rxq);
+		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+	}
+}
+
 void
 iavf_stop_queues(struct rte_eth_dev *dev)
 {
 	struct iavf_adapter *adapter =
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-	struct iavf_rx_queue *rxq;
-	struct iavf_tx_queue *txq;
-	int ret, i;
+	int ret;
+
+	/* adminq will be disabled when vf is resetting. */
+	if (vf->in_reset_recovery) {
+		iavf_reset_queues(dev);
+		return;
+	}
 
 	/* Stop All queues */
 	if (!vf->lv_enabled) {
@@ -1125,22 +1154,7 @@ iavf_stop_queues(struct rte_eth_dev *dev)
 	if (ret)
 		PMD_DRV_LOG(WARNING, "Fail to stop queues");
 
-	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		txq = dev->data->tx_queues[i];
-		if (!txq)
-			continue;
-		iavf_txq_release_mbufs_ops[txq->rel_mbufs_type].release_mbufs(txq);
-		reset_tx_queue(txq);
-		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
-	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		rxq = dev->data->rx_queues[i];
-		if (!rxq)
-			continue;
-		iavf_rxq_release_mbufs_ops[rxq->rel_mbufs_type].release_mbufs(rxq);
-		reset_rx_queue(rxq);
-		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
-	}
+	iavf_reset_queues(dev);
 }
 
 #define IAVF_RX_FLEX_ERR0_BITS	\
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index b3e106b41f..7f49eb2c1e 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -79,6 +79,15 @@ iavf_dev_event_handle(void *param __rte_unused)
 		struct iavf_event_element *pos, *save_next;
 		TAILQ_FOREACH_SAFE(pos, &pending, next, save_next) {
 			TAILQ_REMOVE(&pending, pos, next);
+
+			struct iavf_adapter *adapter = pos->dev->data->dev_private;
+			if (pos->event == RTE_ETH_EVENT_INTR_RESET &&
+			    adapter->devargs.auto_reset) {
+				iavf_handle_hw_reset(pos->dev);
+				rte_free(pos);
+				continue;
+			}
+
 			rte_eth_dev_callback_process(pos->dev, pos->event, pos->param);
 			rte_free(pos);
 		}
@@ -87,7 +96,7 @@ iavf_dev_event_handle(void *param __rte_unused)
 	return 0;
 }
 
-static void
+void
 iavf_dev_event_post(struct rte_eth_dev *dev,
 		enum rte_eth_event_type event,
 		void *param, size_t param_alloc_size)
-- 
2.37.2


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
  2023-09-26 12:15       ` Zhang, Qi Z
@ 2023-09-26 14:05         ` Bruce Richardson
  2023-09-26 23:41           ` Zhang, Qi Z
  2023-09-27  6:39           ` David Marchand
  0 siblings, 2 replies; 14+ messages in thread
From: Bruce Richardson @ 2023-09-26 14:05 UTC (permalink / raw)
  To: Zhang, Qi Z
  Cc: He, ShiyangX, dev, Zhou, YidingX, Wang, Liang-min, Su, Simei, Wu,
	Wenjun1, Zhang, Yuying, Xing, Beilei, Yang, Qiming, Wu,
	 Jingjing

On Tue, Sep 26, 2023 at 01:15:28PM +0100, Zhang, Qi Z wrote:
> 
> 
> > -----Original Message-----
> > From: Bruce Richardson <bruce.richardson@intel.com>
> > Sent: Tuesday, September 26, 2023 3:49 PM
> > To: He, ShiyangX <shiyangx.he@intel.com>
> > Cc: dev@dpdk.org; Zhou, YidingX <yidingx.zhou@intel.com>; Wang, Liang-
> > min <liang-min.wang@intel.com>; Su, Simei <simei.su@intel.com>; Wu,
> > Wenjun1 <wenjun1.wu@intel.com>; Zhang, Yuying
> > <yuying.zhang@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang,
> > Qiming <qiming.yang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> > Subject: Re: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
> > 
> > On Fri, Sep 15, 2023 at 01:02:49PM +0000, Shiyang He wrote:
> > > Originally, the iavf PMD does not perform special actions when it
> > > receives a PF-to-VF reset event, resulting in vf being offline and
> > > unavailable.
> > >
> > > This patch enables vf auto-reset by setting 'watchdog_period' devargs
> > > to true. The iavf PMD will perform an automatic reset to bring the vf
> > > back online when it receives a PF-to-VF event.
> > >
> > > v2: handling reset by event handler
> > > v3: change reset process
> > >
> > > Signed-off-by: Shiyang He <shiyangx.he@intel.com>
> > > Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
> > > ---
> > >  doc/guides/nics/intel_vf.rst           |  3 +
> > >  doc/guides/rel_notes/release_23_11.rst |  3 +
> > >  drivers/net/iavf/iavf.h                |  7 +++
> > >  drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
> > >  drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
> > >  drivers/net/iavf/iavf_vchnl.c          | 11 +++-
> > >  6 files changed, 135 insertions(+), 27 deletions(-)
> > >
> > > diff --git a/doc/guides/nics/intel_vf.rst
> > > b/doc/guides/nics/intel_vf.rst index d365dbc185..c0acd2a7f5 100644
> > > --- a/doc/guides/nics/intel_vf.rst
> > > +++ b/doc/guides/nics/intel_vf.rst
> > > @@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the
> > following documents:
> > >      Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog
> > period in microseconds, or set it to 0 to disable the watchdog,
> > >      for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a
> > 18:01.0,watchdog_period=0``.
> > >
> > > +    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a
> > 18:01.0,enable_auto_reset=1`` when IAVF is backed
> > > +    by an Intel(r) E810 device or an Intel(r) 700 Series Ethernet device.
> > > +
> > 
> > Why do we need a devargs for this? If the VF is unavailable - as you mention
> > in the commit log above - should this behaviour not always be the case
> > without the user having to ask?
> 
> Ideally it does not need, but with below considerations:
> 
> 1. Not break existing scenario, which still assume some application will call dev_reset /dev_configure/ queue_setup / ...  after receive RTE_ETH_EVENT_INTR_RESET event to recover the VF manually, the devargs make sure application be aware of this new feature and will not call rte_eth_dev_reset which will fail now.
> 
> 2. intent to ensure a smoother transition, in case some corner case issues evaded our validation, keeping this devargs provides us with the flexibility to remove it once we determine that the implementation is stable enough.  
> 
Thanks for the clear explanation.

One small suggestion: in the commit log, at the end of the first paragraph
change "resulting in the VF being offline and unavailable" to "... offline
and unavailable until the application resets the device on receipt of the
RTE_ETH_EVENT_INTR_RESET event". Similarly at the end of the second
paragraph you could add "This change removes the need for the application
to handle the reset event, as it is transparently handled inside the
driver".

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 14+ messages in thread

* RE: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
  2023-09-26 14:05         ` Bruce Richardson
@ 2023-09-26 23:41           ` Zhang, Qi Z
  2023-09-27  6:39           ` David Marchand
  1 sibling, 0 replies; 14+ messages in thread
From: Zhang, Qi Z @ 2023-09-26 23:41 UTC (permalink / raw)
  To: Richardson, Bruce
  Cc: He, ShiyangX, dev, Zhou, YidingX, Wang, Liang-min, Su, Simei, Wu,
	Wenjun1, Zhang, Yuying, Xing, Beilei, Yang, Qiming, Wu,
	 Jingjing



> -----Original Message-----
> From: Richardson, Bruce <bruce.richardson@intel.com>
> Sent: Tuesday, September 26, 2023 10:06 PM
> To: Zhang, Qi Z <qi.z.zhang@intel.com>
> Cc: He, ShiyangX <shiyangx.he@intel.com>; dev@dpdk.org; Zhou, YidingX
> <yidingx.zhou@intel.com>; Wang, Liang-min <liang-min.wang@intel.com>;
> Su, Simei <simei.su@intel.com>; Wu, Wenjun1 <wenjun1.wu@intel.com>;
> Zhang, Yuying <yuying.zhang@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Yang, Qiming <qiming.yang@intel.com>; Wu,
> Jingjing <jingjing.wu@intel.com>
> Subject: Re: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
> 
> On Tue, Sep 26, 2023 at 01:15:28PM +0100, Zhang, Qi Z wrote:
> >
> >
> > > -----Original Message-----
> > > From: Bruce Richardson <bruce.richardson@intel.com>
> > > Sent: Tuesday, September 26, 2023 3:49 PM
> > > To: He, ShiyangX <shiyangx.he@intel.com>
> > > Cc: dev@dpdk.org; Zhou, YidingX <yidingx.zhou@intel.com>; Wang,
> > > Liang- min <liang-min.wang@intel.com>; Su, Simei
> > > <simei.su@intel.com>; Wu,
> > > Wenjun1 <wenjun1.wu@intel.com>; Zhang, Yuying
> > > <yuying.zhang@intel.com>; Xing, Beilei <beilei.xing@intel.com>;
> > > Yang, Qiming <qiming.yang@intel.com>; Wu, Jingjing
> > > <jingjing.wu@intel.com>
> > > Subject: Re: [PATCH v3] net/iavf: add devargs to enable vf
> > > auto-reset
> > >
> > > On Fri, Sep 15, 2023 at 01:02:49PM +0000, Shiyang He wrote:
> > > > Originally, the iavf PMD does not perform special actions when it
> > > > receives a PF-to-VF reset event, resulting in vf being offline and
> > > > unavailable.
> > > >
> > > > This patch enables vf auto-reset by setting 'watchdog_period'
> > > > devargs to true. The iavf PMD will perform an automatic reset to
> > > > bring the vf back online when it receives a PF-to-VF event.
> > > >
> > > > v2: handling reset by event handler
> > > > v3: change reset process
> > > >
> > > > Signed-off-by: Shiyang He <shiyangx.he@intel.com>
> > > > Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
> > > > ---
> > > >  doc/guides/nics/intel_vf.rst           |  3 +
> > > >  doc/guides/rel_notes/release_23_11.rst |  3 +
> > > >  drivers/net/iavf/iavf.h                |  7 +++
> > > >  drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
> > > >  drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
> > > >  drivers/net/iavf/iavf_vchnl.c          | 11 +++-
> > > >  6 files changed, 135 insertions(+), 27 deletions(-)
> > > >
> > > > diff --git a/doc/guides/nics/intel_vf.rst
> > > > b/doc/guides/nics/intel_vf.rst index d365dbc185..c0acd2a7f5 100644
> > > > --- a/doc/guides/nics/intel_vf.rst
> > > > +++ b/doc/guides/nics/intel_vf.rst
> > > > @@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the
> > > following documents:
> > > >      Set ``devargs`` parameter ``watchdog_period`` to adjust the
> > > > watchdog
> > > period in microseconds, or set it to 0 to disable the watchdog,
> > > >      for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a
> > > 18:01.0,watchdog_period=0``.
> > > >
> > > > +    Enable vf auto-reset by setting the ``devargs`` parameter
> > > > + like ``-a
> > > 18:01.0,enable_auto_reset=1`` when IAVF is backed
> > > > +    by an Intel(r) E810 device or an Intel(r) 700 Series Ethernet device.
> > > > +
> > >
> > > Why do we need a devargs for this? If the VF is unavailable - as you
> > > mention in the commit log above - should this behaviour not always
> > > be the case without the user having to ask?
> >
> > Ideally it does not need, but with below considerations:
> >
> > 1. Not break existing scenario, which still assume some application will call
> dev_reset /dev_configure/ queue_setup / ...  after receive
> RTE_ETH_EVENT_INTR_RESET event to recover the VF manually, the devargs
> make sure application be aware of this new feature and will not call
> rte_eth_dev_reset which will fail now.
> >
> > 2. intent to ensure a smoother transition, in case some corner case issues
> evaded our validation, keeping this devargs provides us with the flexibility to
> remove it once we determine that the implementation is stable enough.
> >
> Thanks for the clear explanation.
> 
> One small suggestion: in the commit log, at the end of the first paragraph
> change "resulting in the VF being offline and unavailable" to "... offline and
> unavailable until the application resets the device on receipt of the
> RTE_ETH_EVENT_INTR_RESET event". Similarly at the end of the second
> paragraph you could add "This change removes the need for the application
> to handle the reset event, as it is transparently handled inside the driver".

Thank you for the suggestion. The commit log has been refined in the dpdk-next-net-intel repo.

Qi

> 
> Regards,
> /Bruce

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
  2023-09-26 14:05         ` Bruce Richardson
  2023-09-26 23:41           ` Zhang, Qi Z
@ 2023-09-27  6:39           ` David Marchand
  1 sibling, 0 replies; 14+ messages in thread
From: David Marchand @ 2023-09-27  6:39 UTC (permalink / raw)
  To: Bruce Richardson, Zhang, Qi Z
  Cc: He, ShiyangX, dev, Zhou, YidingX, Wang, Liang-min, Su, Simei, Wu,
	Wenjun1, Zhang, Yuying, Xing, Beilei, Yang, Qiming, Wu, Jingjing,
	Thomas Monjalon, Ferruh Yigit

On Tue, Sep 26, 2023 at 4:06 PM Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> On Tue, Sep 26, 2023 at 01:15:28PM +0100, Zhang, Qi Z wrote:
> >
> >
> > > -----Original Message-----
> > > From: Bruce Richardson <bruce.richardson@intel.com>
> > > Sent: Tuesday, September 26, 2023 3:49 PM
> > > To: He, ShiyangX <shiyangx.he@intel.com>
> > > Cc: dev@dpdk.org; Zhou, YidingX <yidingx.zhou@intel.com>; Wang, Liang-
> > > min <liang-min.wang@intel.com>; Su, Simei <simei.su@intel.com>; Wu,
> > > Wenjun1 <wenjun1.wu@intel.com>; Zhang, Yuying
> > > <yuying.zhang@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Yang,
> > > Qiming <qiming.yang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> > > Subject: Re: [PATCH v3] net/iavf: add devargs to enable vf auto-reset
> > >
> > > On Fri, Sep 15, 2023 at 01:02:49PM +0000, Shiyang He wrote:
> > > > Originally, the iavf PMD does not perform special actions when it
> > > > receives a PF-to-VF reset event, resulting in vf being offline and
> > > > unavailable.
> > > >
> > > > This patch enables vf auto-reset by setting 'watchdog_period' devargs
> > > > to true. The iavf PMD will perform an automatic reset to bring the vf
> > > > back online when it receives a PF-to-VF event.
> > > >
> > > > v2: handling reset by event handler
> > > > v3: change reset process
> > > >
> > > > Signed-off-by: Shiyang He <shiyangx.he@intel.com>
> > > > Signed-off-by: Liang-Min Larry Wang <liang-min.wang@intel.com>
> > > > ---
> > > >  doc/guides/nics/intel_vf.rst           |  3 +
> > > >  doc/guides/rel_notes/release_23_11.rst |  3 +
> > > >  drivers/net/iavf/iavf.h                |  7 +++
> > > >  drivers/net/iavf/iavf_ethdev.c         | 86 +++++++++++++++++++++++---
> > > >  drivers/net/iavf/iavf_rxtx.c           | 52 ++++++++++------
> > > >  drivers/net/iavf/iavf_vchnl.c          | 11 +++-
> > > >  6 files changed, 135 insertions(+), 27 deletions(-)
> > > >
> > > > diff --git a/doc/guides/nics/intel_vf.rst
> > > > b/doc/guides/nics/intel_vf.rst index d365dbc185..c0acd2a7f5 100644
> > > > --- a/doc/guides/nics/intel_vf.rst
> > > > +++ b/doc/guides/nics/intel_vf.rst
> > > > @@ -101,6 +101,9 @@ For more detail on SR-IOV, please refer to the
> > > following documents:
> > > >      Set ``devargs`` parameter ``watchdog_period`` to adjust the watchdog
> > > period in microseconds, or set it to 0 to disable the watchdog,
> > > >      for example, ``-a 18:01.0,watchdog_period=5000`` or ``-a
> > > 18:01.0,watchdog_period=0``.
> > > >
> > > > +    Enable vf auto-reset by setting the ``devargs`` parameter like ``-a
> > > 18:01.0,enable_auto_reset=1`` when IAVF is backed
> > > > +    by an Intel(r) E810 device or an Intel(r) 700 Series Ethernet device.
> > > > +
> > >
> > > Why do we need a devargs for this? If the VF is unavailable - as you mention
> > > in the commit log above - should this behaviour not always be the case
> > > without the user having to ask?
> >
> > Ideally it does not need, but with below considerations:
> >
> > 1. Not break existing scenario, which still assume some application will call dev_reset /dev_configure/ queue_setup / ...  after receive RTE_ETH_EVENT_INTR_RESET event to recover the VF manually, the devargs make sure application be aware of this new feature and will not call rte_eth_dev_reset which will fail now.
> >
> > 2. intent to ensure a smoother transition, in case some corner case issues evaded our validation, keeping this devargs provides us with the flexibility to remove it once we determine that the implementation is stable enough.
> >
> Thanks for the clear explanation.
>
> One small suggestion: in the commit log, at the end of the first paragraph
> change "resulting in the VF being offline and unavailable" to "... offline
> and unavailable until the application resets the device on receipt of the
> RTE_ETH_EVENT_INTR_RESET event". Similarly at the end of the second
> paragraph you could add "This change removes the need for the application
> to handle the reset event, as it is transparently handled inside the
> driver".

I did not read the patch.

You mention that rte_eth_dev_reset will fail now when this (horrific)
devargs is passed.
Yet, will the driver send a RTE_ETH_EVENT_INTR_RESET event?

Additionnally, how does the driver make sure that no
application/datapath thread is polling/reconfiguring this hw?



-- 
David Marchand


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-09-27  6:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-01  9:48 [PATCH] net/iavf: add devargs to enable vf auto-reset Shiyang He
2023-08-11  9:40 ` [PATCH v2] " Shiyang He
2023-09-15 13:02   ` [PATCH v3] " Shiyang He
2023-09-26  7:48     ` Bruce Richardson
2023-09-26 12:15       ` Zhang, Qi Z
2023-09-26 14:05         ` Bruce Richardson
2023-09-26 23:41           ` Zhang, Qi Z
2023-09-27  6:39           ` David Marchand
2023-09-26 11:31     ` [PATCH v4] " Shiyang He
2023-09-26  4:51       ` Zhang, Qi Z
2023-09-26 12:29       ` [PATCH v5] " Shiyang He
2023-09-26 12:31       ` Shiyang He
2023-09-26 12:38       ` Shiyang He
2023-09-26  5:33         ` Zhang, Qi Z

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).