]> git.droids-corp.org - dpdk.git/commitdiff
net/ice: track DCF state of PF
authorDapeng Yu <dapengx.yu@intel.com>
Wed, 24 Nov 2021 08:12:20 +0000 (16:12 +0800)
committerQi Zhang <qi.z.zhang@intel.com>
Sun, 2 Jan 2022 08:31:06 +0000 (09:31 +0100)
When VF is reset, PF will change DCF state from ON to other state, if
flow creation, destroy, or redirect command is sent to DCF at this
time, it will fail.

This patch tracks DCF state and returns try-again error to caller when
DCF state is not ON.

Cc: stable@dpdk.org
Signed-off-by: Dapeng Yu <dapengx.yu@intel.com>
Acked-by: Haiyue Wang <haiyue.wang@intel.com>
drivers/net/ice/ice_dcf_ethdev.c
drivers/net/ice/ice_dcf_ethdev.h
drivers/net/ice/ice_dcf_parent.c
drivers/net/ice/ice_ethdev.h
drivers/net/ice/ice_generic_flow.c
drivers/net/ice/ice_switch_filter.c

index a1f11c01d966a9d49612db2665aa05c03b354284..59610e058f099188ec841de5d9a47cbe963f8989 100644 (file)
@@ -957,6 +957,13 @@ ice_dcf_link_update(struct rte_eth_dev *dev,
        return rte_eth_linkstatus_set(dev, &new_link);
 }
 
+bool
+ice_dcf_adminq_need_retry(struct ice_adapter *ad)
+{
+       return ad->hw.dcf_enabled &&
+              !__atomic_load_n(&ad->dcf_state_on, __ATOMIC_RELAXED);
+}
+
 /* Add UDP tunneling port */
 static int
 ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
@@ -1106,6 +1113,7 @@ static int
 ice_dcf_dev_init(struct rte_eth_dev *eth_dev)
 {
        struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
+       struct ice_adapter *parent_adapter = &adapter->parent;
 
        eth_dev->dev_ops = &ice_dcf_eth_dev_ops;
        eth_dev->rx_pkt_burst = ice_dcf_recv_pkts;
@@ -1117,9 +1125,13 @@ ice_dcf_dev_init(struct rte_eth_dev *eth_dev)
        adapter->real_hw.vc_event_msg_cb = ice_dcf_handle_pf_event_msg;
        if (ice_dcf_init_hw(eth_dev, &adapter->real_hw) != 0) {
                PMD_INIT_LOG(ERR, "Failed to init DCF hardware");
+               __atomic_store_n(&parent_adapter->dcf_state_on, false,
+                                __ATOMIC_RELAXED);
                return -1;
        }
 
+       __atomic_store_n(&parent_adapter->dcf_state_on, true, __ATOMIC_RELAXED);
+
        if (ice_dcf_init_parent_adapter(eth_dev) != 0) {
                PMD_INIT_LOG(ERR, "Failed to init DCF parent adapter");
                ice_dcf_uninit_hw(eth_dev, &adapter->real_hw);
index 8510e37119ad17e0857318a8803f5befe0a3d7d8..11a1305038db97f15e6801b8d64dc17599fda1c9 100644 (file)
@@ -64,5 +64,6 @@ int ice_dcf_vf_repr_init(struct rte_eth_dev *vf_rep_eth_dev, void *init_param);
 int ice_dcf_vf_repr_uninit(struct rte_eth_dev *vf_rep_eth_dev);
 int ice_dcf_vf_repr_init_vlan(struct rte_eth_dev *vf_rep_eth_dev);
 void ice_dcf_vf_repr_stop_all(struct ice_dcf_adapter *dcf_adapter);
+bool ice_dcf_adminq_need_retry(struct ice_adapter *ad);
 
 #endif /* _ICE_DCF_ETHDEV_H_ */
index 1ff2c47172cfba1851866e9126fb38c33a20e8da..0c8c2ed6c7e6443dfb3be765ef512bdbc9f40967 100644 (file)
@@ -119,7 +119,9 @@ ice_dcf_vsi_update_service_handler(void *param)
 {
        struct ice_dcf_reset_event_param *reset_param = param;
        struct ice_dcf_hw *hw = reset_param->dcf_hw;
-       struct ice_dcf_adapter *adapter;
+       struct ice_dcf_adapter *adapter =
+               container_of(hw, struct ice_dcf_adapter, real_hw);
+       struct ice_adapter *parent_adapter = &adapter->parent;
 
        pthread_detach(pthread_self());
 
@@ -127,11 +129,12 @@ ice_dcf_vsi_update_service_handler(void *param)
 
        rte_spinlock_lock(&vsi_update_lock);
 
-       adapter = container_of(hw, struct ice_dcf_adapter, real_hw);
-
-       if (!ice_dcf_handle_vsi_update_event(hw))
+       if (!ice_dcf_handle_vsi_update_event(hw)) {
+               __atomic_store_n(&parent_adapter->dcf_state_on, true,
+                                __ATOMIC_RELAXED);
                ice_dcf_update_vf_vsi_map(&adapter->parent.hw,
                                          hw->num_vfs, hw->vf_vsi_map);
+       }
 
        if (reset_param->vfr && adapter->repr_infos) {
                struct rte_eth_dev *vf_rep_eth_dev =
@@ -224,6 +227,9 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
                            uint8_t *msg, uint16_t msglen)
 {
        struct virtchnl_pf_event *pf_msg = (struct virtchnl_pf_event *)msg;
+       struct ice_dcf_adapter *adapter =
+               container_of(dcf_hw, struct ice_dcf_adapter, real_hw);
+       struct ice_adapter *parent_adapter = &adapter->parent;
 
        if (msglen < sizeof(struct virtchnl_pf_event)) {
                PMD_DRV_LOG(DEBUG, "Invalid event message length : %u", msglen);
@@ -258,6 +264,8 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
                PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_DCF_VSI_MAP_UPDATE event : VF%u with VSI num %u",
                            pf_msg->event_data.vf_vsi_map.vf_id,
                            pf_msg->event_data.vf_vsi_map.vsi_id);
+               __atomic_store_n(&parent_adapter->dcf_state_on, false,
+                                __ATOMIC_RELAXED);
                start_vsi_reset_thread(dcf_hw, true,
                                       pf_msg->event_data.vf_vsi_map.vf_id);
                break;
index 2e3e45f3d7695a457f2ff4097f0540d124a874ec..1242177b42bdcf3735c3309b4542ff3234e3800e 100644 (file)
@@ -531,6 +531,8 @@ struct ice_adapter {
        uint64_t time_hw;
        struct ice_fdir_prof_info fdir_prof_info[ICE_MAX_PTGS];
        struct ice_rss_prof_info rss_prof_info[ICE_MAX_PTGS];
+       /* True if DCF state of the associated PF is on */
+       bool dcf_state_on;
 #ifdef RTE_ARCH_X86
        bool rx_use_avx2;
        bool rx_use_avx512;
index c673feb7a6f81093c2fe63e321fa3cb1e7bed383..406a0a953f6ecdc153745db4819bd062e47edb4a 100644 (file)
@@ -2515,7 +2515,9 @@ ice_flow_flush(struct rte_eth_dev *dev,
                ret = ice_flow_destroy(dev, p_flow, error);
                if (ret) {
                        PMD_DRV_LOG(ERR, "Failed to flush flows");
-                       return -EINVAL;
+                       if (ret != -EAGAIN)
+                               ret = -EINVAL;
+                       return ret;
                }
        }
 
index ed29c00d779710994bc2350993760e8701701305..bd805d960612f87af75d0ec519ad3b447ba5a3a4 100644 (file)
@@ -400,6 +400,14 @@ ice_switch_create(struct ice_adapter *ad,
                        "lookup list should not be NULL");
                goto error;
        }
+
+       if (ice_dcf_adminq_need_retry(ad)) {
+               rte_flow_error_set(error, EAGAIN,
+                       RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+                       "DCF is not on");
+               goto error;
+       }
+
        ret = ice_add_adv_rule(hw, list, lkups_cnt, rule_info, &rule_added);
        if (!ret) {
                filter_conf_ptr = rte_zmalloc("ice_switch_filter",
@@ -423,7 +431,12 @@ ice_switch_create(struct ice_adapter *ad,
 
                flow->rule = filter_conf_ptr;
        } else {
-               rte_flow_error_set(error, EINVAL,
+               if (ice_dcf_adminq_need_retry(ad))
+                       ret = -EAGAIN;
+               else
+                       ret = -EINVAL;
+
+               rte_flow_error_set(error, -ret,
                        RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
                        "switch filter create flow fail");
                goto error;
@@ -475,9 +488,21 @@ ice_switch_destroy(struct ice_adapter *ad,
                return -rte_errno;
        }
 
+       if (ice_dcf_adminq_need_retry(ad)) {
+               rte_flow_error_set(error, EAGAIN,
+                       RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+                       "DCF is not on");
+               return -rte_errno;
+       }
+
        ret = ice_rem_adv_rule_by_id(hw, &filter_conf_ptr->sw_query_data);
        if (ret) {
-               rte_flow_error_set(error, EINVAL,
+               if (ice_dcf_adminq_need_retry(ad))
+                       ret = -EAGAIN;
+               else
+                       ret = -EINVAL;
+
+               rte_flow_error_set(error, -ret,
                        RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
                        "fail to destroy switch filter rule");
                return -rte_errno;
@@ -2016,6 +2041,12 @@ ice_switch_redirect(struct ice_adapter *ad,
        }
 
 rmv_rule:
+       if (ice_dcf_adminq_need_retry(ad)) {
+               PMD_DRV_LOG(WARNING, "DCF is not on");
+               ret = -EAGAIN;
+               goto out;
+       }
+
        /* Remove the old rule */
        ret = ice_rem_adv_rule(hw, lkups_ref, lkups_cnt, &rinfo);
        if (ret) {
@@ -2028,6 +2059,12 @@ rmv_rule:
        }
 
 add_rule:
+       if (ice_dcf_adminq_need_retry(ad)) {
+               PMD_DRV_LOG(WARNING, "DCF is not on");
+               ret = -EAGAIN;
+               goto out;
+       }
+
        /* Update VSI context */
        hw->vsi_ctx[rd->vsi_handle]->vsi_num = rd->new_vsi_num;
 
@@ -2047,6 +2084,10 @@ add_rule:
        }
 
 out:
+       if (ret == -EINVAL)
+               if (ice_dcf_adminq_need_retry(ad))
+                       ret = -EAGAIN;
+
        ice_free(hw, lkups_dp);
        return ret;
 }