net/ice: enable CVL DCF device reset API

Message ID 20210901052605.829969-1-dapengx.yu@intel.com (mailing list archive)
State Accepted, archived
Delegated to: Qi Zhang
Headers
Series net/ice: enable CVL DCF device reset API |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/github-robot: build success github build: passed
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing fail Testing issues
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS

Commit Message

Yu, DapengX Sept. 1, 2021, 5:26 a.m. UTC
  From: Dapeng Yu <dapengx.yu@intel.com>

DCF PMD needs to support rte_eth_dev_reset, the reason is when a DCF
instance is killed, all the flow rules still exists in hardware, when
DCF gets to reconnect, it already lost the flow context, and if the
application wants to create new rules, it may fail due to firmware
reports rules already exist.

The rte_eth_dev_reset API provides a more elegant way for the
application to reset DCF when reconnect happens.

Signed-off-by: Dapeng Yu <dapengx.yu@intel.com>
---
 drivers/net/ice/ice_dcf.c        | 28 ++++++++++++++++++++++
 drivers/net/ice/ice_dcf.h        |  2 ++
 drivers/net/ice/ice_dcf_ethdev.c | 41 ++++++++++++++++++++++++++++++++
 drivers/net/ice/ice_dcf_parent.c |  5 ++++
 4 files changed, 76 insertions(+)
  

Comments

Qi Zhang Sept. 6, 2021, 1:17 a.m. UTC | #1
> -----Original Message-----
> From: Yu, DapengX <dapengx.yu@intel.com>
> Sent: Wednesday, September 1, 2021 1:26 PM
> To: Yang, Qiming <qiming.yang@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>
> Cc: dev@dpdk.org; Yu, DapengX <dapengx.yu@intel.com>
> Subject: [PATCH] net/ice: enable CVL DCF device reset API
> 
> From: Dapeng Yu <dapengx.yu@intel.com>
> 
> DCF PMD needs to support rte_eth_dev_reset, the reason is when a DCF
> instance is killed, all the flow rules still exists in hardware, when DCF gets to
> reconnect, it already lost the flow context, and if the application wants to
> create new rules, it may fail due to firmware reports rules already exist.
> 
> The rte_eth_dev_reset API provides a more elegant way for the application to
> reset DCF when reconnect happens.
> 
> Signed-off-by: Dapeng Yu <dapengx.yu@intel.com>

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

Applied to dpdk-next-net-intel.

Thanks
Qi
  

Patch

diff --git a/drivers/net/ice/ice_dcf.c b/drivers/net/ice/ice_dcf.c
index 4c2e0c7216..878fef0a68 100644
--- a/drivers/net/ice/ice_dcf.c
+++ b/drivers/net/ice/ice_dcf.c
@@ -337,6 +337,9 @@  ice_dcf_mode_disable(struct ice_dcf_hw *hw)
 {
 	int err;
 
+	if (hw->resetting)
+		return 0;
+
 	err = ice_dcf_send_cmd_req_no_irq(hw, VIRTCHNL_OP_DCF_DISABLE,
 					  NULL, 0);
 	if (err) {
@@ -721,11 +724,25 @@  ice_dcf_uninit_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
 	iavf_shutdown_adminq(&hw->avf);
 
 	rte_free(hw->arq_buf);
+	hw->arq_buf = NULL;
+
 	rte_free(hw->vf_vsi_map);
+	hw->vf_vsi_map = NULL;
+
 	rte_free(hw->vf_res);
+	hw->vf_res = NULL;
+
 	rte_free(hw->rss_lut);
+	hw->rss_lut = NULL;
+
 	rte_free(hw->rss_key);
+	hw->rss_key = NULL;
+
 	rte_free(hw->qos_bw_cfg);
+	hw->qos_bw_cfg = NULL;
+
+	rte_free(hw->ets_config);
+	hw->ets_config = NULL;
 }
 
 static int
@@ -1009,6 +1026,9 @@  ice_dcf_disable_queues(struct ice_dcf_hw *hw)
 	struct dcf_virtchnl_cmd args;
 	int err;
 
+	if (hw->resetting)
+		return 0;
+
 	memset(&queue_select, 0, sizeof(queue_select));
 	queue_select.vsi_id = hw->vsi_res->vsi_id;
 
@@ -1063,6 +1083,14 @@  ice_dcf_add_del_all_mac_addr(struct ice_dcf_hw *hw, bool add)
 	struct dcf_virtchnl_cmd args;
 	int len, err = 0;
 
+	if (hw->resetting) {
+		if (!add)
+			return 0;
+
+		PMD_DRV_LOG(ERR, "fail to add all MACs for VF resetting");
+		return -EIO;
+	}
+
 	len = sizeof(struct virtchnl_ether_addr_list);
 	addr = hw->eth_dev->data->mac_addrs;
 	len += sizeof(struct virtchnl_ether_addr);
diff --git a/drivers/net/ice/ice_dcf.h b/drivers/net/ice/ice_dcf.h
index 36c2d0965e..6ec766ebda 100644
--- a/drivers/net/ice/ice_dcf.h
+++ b/drivers/net/ice/ice_dcf.h
@@ -111,6 +111,8 @@  struct ice_dcf_hw {
 	/* Link status */
 	bool link_up;
 	uint32_t link_speed;
+
+	bool resetting;
 };
 
 int ice_dcf_execute_virtchnl_cmd(struct ice_dcf_hw *hw,
diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c
index cab7c4da87..94c6a6e61c 100644
--- a/drivers/net/ice/ice_dcf_ethdev.c
+++ b/drivers/net/ice/ice_dcf_ethdev.c
@@ -32,6 +32,12 @@  static int
 ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
 				struct rte_eth_udp_tunnel *udp_tunnel);
 
+static int
+ice_dcf_dev_init(struct rte_eth_dev *eth_dev);
+
+static int
+ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev);
+
 static uint16_t
 ice_dcf_recv_pkts(__rte_unused void *rx_queue,
 		  __rte_unused struct rte_mbuf **bufs,
@@ -511,6 +517,12 @@  ice_dcf_dev_start(struct rte_eth_dev *dev)
 	struct ice_dcf_hw *hw = &dcf_ad->real_hw;
 	int ret;
 
+	if (hw->resetting) {
+		PMD_DRV_LOG(ERR,
+			    "The DCF has been reset by PF, please reinit first");
+		return -EIO;
+	}
+
 	ad->pf.adapter_stopped = 0;
 
 	hw->num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
@@ -585,6 +597,7 @@  ice_dcf_stop_queues(struct rte_eth_dev *dev)
 		txq->tx_rel_mbufs(txq);
 		reset_tx_queue(txq);
 		dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+		dev->data->tx_queues[i] = NULL;
 	}
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
 		rxq = dev->data->rx_queues[i];
@@ -593,6 +606,7 @@  ice_dcf_stop_queues(struct rte_eth_dev *dev)
 		rxq->rx_rel_mbufs(rxq);
 		reset_rx_queue(rxq);
 		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+		dev->data->rx_queues[i] = NULL;
 	}
 }
 
@@ -805,6 +819,12 @@  ice_dcf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	struct virtchnl_eth_stats pstats;
 	int ret;
 
+	if (hw->resetting) {
+		PMD_DRV_LOG(ERR,
+			    "The DCF has been reset by PF, please reinit first");
+		return -EIO;
+	}
+
 	ret = ice_dcf_query_stats(hw, &pstats);
 	if (ret == 0) {
 		ice_dcf_update_stats(&hw->eth_stats_offset, &pstats);
@@ -831,6 +851,9 @@  ice_dcf_stats_reset(struct rte_eth_dev *dev)
 	struct virtchnl_eth_stats pstats;
 	int ret;
 
+	if (hw->resetting)
+		return 0;
+
 	/* read stat values to clear hardware registers */
 	ret = ice_dcf_query_stats(hw, &pstats);
 	if (ret != 0)
@@ -874,6 +897,8 @@  ice_dcf_dev_close(struct rte_eth_dev *dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	(void)ice_dcf_dev_stop(dev);
+
 	ice_dcf_free_repr_info(adapter);
 	ice_dcf_uninit_parent_adapter(dev);
 	ice_dcf_uninit_hw(dev, &adapter->real_hw);
@@ -1006,10 +1031,25 @@  ice_dcf_tm_ops_get(struct rte_eth_dev *dev __rte_unused,
 	return 0;
 }
 
+static int
+ice_dcf_dev_reset(struct rte_eth_dev *dev)
+{
+	int ret;
+
+	ret = ice_dcf_dev_uninit(dev);
+	if (ret)
+		return ret;
+
+	ret = ice_dcf_dev_init(dev);
+
+	return ret;
+}
+
 static const struct eth_dev_ops ice_dcf_eth_dev_ops = {
 	.dev_start               = ice_dcf_dev_start,
 	.dev_stop                = ice_dcf_dev_stop,
 	.dev_close               = ice_dcf_dev_close,
+	.dev_reset               = ice_dcf_dev_reset,
 	.dev_configure           = ice_dcf_dev_configure,
 	.dev_infos_get           = ice_dcf_dev_info_get,
 	.rx_queue_setup          = ice_rx_queue_setup,
@@ -1038,6 +1078,7 @@  ice_dcf_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
 
+	adapter->real_hw.resetting = false;
 	eth_dev->dev_ops = &ice_dcf_eth_dev_ops;
 	eth_dev->rx_pkt_burst = ice_dcf_recv_pkts;
 	eth_dev->tx_pkt_burst = ice_dcf_xmit_pkts;
diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c
index f461318f96..04078345eb 100644
--- a/drivers/net/ice/ice_dcf_parent.c
+++ b/drivers/net/ice/ice_dcf_parent.c
@@ -234,6 +234,7 @@  ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 	case VIRTCHNL_EVENT_RESET_IMPENDING:
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
 		start_vsi_reset_thread(dcf_hw, false, 0);
+		dcf_hw->resetting = true;
 		break;
 	case VIRTCHNL_EVENT_LINK_CHANGE:
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
@@ -357,6 +358,7 @@  ice_dcf_init_parent_hw(struct ice_hw *hw)
 err_unroll_alloc:
 	ice_free(hw, hw->port_info);
 	hw->port_info = NULL;
+	hw->switch_info = NULL;
 
 	return status;
 }
@@ -370,6 +372,7 @@  static void ice_dcf_uninit_parent_hw(struct ice_hw *hw)
 
 	ice_free(hw, hw->port_info);
 	hw->port_info = NULL;
+	hw->switch_info = NULL;
 
 	ice_clear_all_vsi_ctx(hw);
 }
@@ -485,6 +488,8 @@  ice_dcf_uninit_parent_adapter(struct rte_eth_dev *eth_dev)
 	struct ice_hw *parent_hw = &parent_adapter->hw;
 
 	eth_dev->data->mac_addrs = NULL;
+	rte_free(parent_adapter->pf.main_vsi);
+	parent_adapter->pf.main_vsi = NULL;
 
 	ice_flow_uninit(parent_adapter);
 	ice_dcf_uninit_parent_hw(parent_hw);