]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
ice: Remove node before releasing VSI
authorAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Fri, 26 Oct 2018 17:41:02 +0000 (10:41 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Tue, 13 Nov 2018 17:09:26 +0000 (09:09 -0800)
Before releasing the VSI, remove the VSI scheduler node. If not,
the node is left in the scheduler tree and, on subsequent load, the
scheduler tree contains the node so it does not set it in vsi_ctx.
This, later, causes the node to not be found in ice_sched_get_free_qparent
which leads to a "Failed to set LAN Tx queue context, error: -1".

To remove the scheduler node, this patch introduces ice_rm_vsi_lan_cfg
and related helpers.

Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ice/ice_lib.c
drivers/net/ethernet/intel/ice/ice_sched.c
drivers/net/ethernet/intel/ice/ice_sched.h

index 11d0ab185dd247da74ae05706d79bf3dd3f07803..1efd760debc2dcd5606bf860879c3aa2573c074f 100644 (file)
@@ -2492,6 +2492,7 @@ int ice_vsi_release(struct ice_vsi *vsi)
        }
 
        ice_remove_vsi_fltr(&pf->hw, vsi->idx);
+       ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);
        ice_vsi_delete(vsi);
        ice_vsi_free_q_vectors(vsi);
        ice_vsi_clear_rings(vsi);
index 7cc8aa18a22bb5c062d74d2178ee60b9d29ee72c..7e807b0e75142bd07b197191faee8a1026088b7d 100644 (file)
@@ -1527,7 +1527,7 @@ ice_sched_update_vsi_child_nodes(struct ice_port_info *pi, u16 vsi_handle,
 }
 
 /**
- * ice_sched_cfg_vsi - configure the new/exisiting VSI
+ * ice_sched_cfg_vsi - configure the new/existing VSI
  * @pi: port information structure
  * @vsi_handle: software VSI handle
  * @tc: TC number
@@ -1605,3 +1605,109 @@ ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs,
 
        return status;
 }
+
+/**
+ * ice_sched_rm_agg_vsi_entry - remove agg related VSI info entry
+ * @pi: port information structure
+ * @vsi_handle: software VSI handle
+ *
+ * This function removes single aggregator VSI info entry from
+ * aggregator list.
+ */
+static void
+ice_sched_rm_agg_vsi_info(struct ice_port_info *pi, u16 vsi_handle)
+{
+       struct ice_sched_agg_info *agg_info;
+       struct ice_sched_agg_info *atmp;
+
+       list_for_each_entry_safe(agg_info, atmp, &pi->agg_list, list_entry) {
+               struct ice_sched_agg_vsi_info *agg_vsi_info;
+               struct ice_sched_agg_vsi_info *vtmp;
+
+               list_for_each_entry_safe(agg_vsi_info, vtmp,
+                                        &agg_info->agg_vsi_list, list_entry)
+                       if (agg_vsi_info->vsi_handle == vsi_handle) {
+                               list_del(&agg_vsi_info->list_entry);
+                               devm_kfree(ice_hw_to_dev(pi->hw),
+                                          agg_vsi_info);
+                               return;
+                       }
+       }
+}
+
+/**
+ * ice_sched_rm_vsi_cfg - remove the VSI and its children nodes
+ * @pi: port information structure
+ * @vsi_handle: software VSI handle
+ * @owner: LAN or RDMA
+ *
+ * This function removes the VSI and its LAN or RDMA children nodes from the
+ * scheduler tree.
+ */
+static enum ice_status
+ice_sched_rm_vsi_cfg(struct ice_port_info *pi, u16 vsi_handle, u8 owner)
+{
+       enum ice_status status = ICE_ERR_PARAM;
+       struct ice_vsi_ctx *vsi_ctx;
+       u8 i, j = 0;
+
+       if (!ice_is_vsi_valid(pi->hw, vsi_handle))
+               return status;
+       mutex_lock(&pi->sched_lock);
+       vsi_ctx = ice_get_vsi_ctx(pi->hw, vsi_handle);
+       if (!vsi_ctx)
+               goto exit_sched_rm_vsi_cfg;
+
+       for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
+               struct ice_sched_node *vsi_node, *tc_node;
+
+               tc_node = ice_sched_get_tc_node(pi, i);
+               if (!tc_node)
+                       continue;
+
+               vsi_node = ice_sched_get_vsi_node(pi->hw, tc_node, vsi_handle);
+               if (!vsi_node)
+                       continue;
+
+               while (j < vsi_node->num_children) {
+                       if (vsi_node->children[j]->owner == owner) {
+                               ice_free_sched_node(pi, vsi_node->children[j]);
+
+                               /* reset the counter again since the num
+                                * children will be updated after node removal
+                                */
+                               j = 0;
+                       } else {
+                               j++;
+                       }
+               }
+               /* remove the VSI if it has no children */
+               if (!vsi_node->num_children) {
+                       ice_free_sched_node(pi, vsi_node);
+                       vsi_ctx->sched.vsi_node[i] = NULL;
+
+                       /* clean up agg related vsi info if any */
+                       ice_sched_rm_agg_vsi_info(pi, vsi_handle);
+               }
+               if (owner == ICE_SCHED_NODE_OWNER_LAN)
+                       vsi_ctx->sched.max_lanq[i] = 0;
+       }
+       status = 0;
+
+exit_sched_rm_vsi_cfg:
+       mutex_unlock(&pi->sched_lock);
+       return status;
+}
+
+/**
+ * ice_rm_vsi_lan_cfg - remove VSI and its LAN children nodes
+ * @pi: port information structure
+ * @vsi_handle: software VSI handle
+ *
+ * This function clears the VSI and its LAN children nodes from scheduler tree
+ * for all TCs.
+ */
+enum ice_status ice_rm_vsi_lan_cfg(struct ice_port_info *pi, u16 vsi_handle)
+{
+       return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_LAN);
+}
index 5dc9cfa04c589734f15e2bb446fe52c1b1dc4a84..dc59fbac7ddec6f8d76e3327131023a3f7703002 100644 (file)
@@ -12,6 +12,7 @@
 struct ice_sched_agg_vsi_info {
        struct list_head list_entry;
        DECLARE_BITMAP(tc_bitmap, ICE_MAX_TRAFFIC_CLASS);
+       u16 vsi_handle;
 };
 
 struct ice_sched_agg_info {
@@ -39,4 +40,5 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
 enum ice_status
 ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs,
                  u8 owner, bool enable);
+enum ice_status ice_rm_vsi_lan_cfg(struct ice_port_info *pi, u16 vsi_handle);
 #endif /* _ICE_SCHED_H_ */