Commit 29358248 authored by Victor Raj's avatar Victor Raj Committed by Jeff Kirsher

ice: added sibling head to parse nodes

There was a bug in the previous code which never traverses all the
children to get the first node of the requested layer. Add a sibling
head pointer to point the first node of each layer per TC. This helps
traverse easier and quicker and also removes the recursion.
Signed-off-by: default avatarVictor Raj <victor.raj@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 9e7a5d17
...@@ -260,33 +260,17 @@ ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent, ...@@ -260,33 +260,17 @@ ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent,
/** /**
* ice_sched_get_first_node - get the first node of the given layer * ice_sched_get_first_node - get the first node of the given layer
* @hw: pointer to the HW struct * @pi: port information structure
* @parent: pointer the base node of the subtree * @parent: pointer the base node of the subtree
* @layer: layer number * @layer: layer number
* *
* This function retrieves the first node of the given layer from the subtree * This function retrieves the first node of the given layer from the subtree
*/ */
static struct ice_sched_node * static struct ice_sched_node *
ice_sched_get_first_node(struct ice_hw *hw, struct ice_sched_node *parent, ice_sched_get_first_node(struct ice_port_info *pi,
u8 layer) struct ice_sched_node *parent, u8 layer)
{ {
u8 i; return pi->sib_head[parent->tc_num][layer];
if (layer < hw->sw_entry_point_layer)
return NULL;
for (i = 0; i < parent->num_children; i++) {
struct ice_sched_node *node = parent->children[i];
if (node) {
if (node->tx_sched_layer == layer)
return node;
/* this recursion is intentional, and wouldn't
* go more than 9 calls
*/
return ice_sched_get_first_node(hw, node, layer);
}
}
return NULL;
} }
/** /**
...@@ -342,7 +326,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node) ...@@ -342,7 +326,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
parent = node->parent; parent = node->parent;
/* root has no parent */ /* root has no parent */
if (parent) { if (parent) {
struct ice_sched_node *p, *tc_node; struct ice_sched_node *p;
/* update the parent */ /* update the parent */
for (i = 0; i < parent->num_children; i++) for (i = 0; i < parent->num_children; i++)
...@@ -354,16 +338,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node) ...@@ -354,16 +338,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
break; break;
} }
/* search for previous sibling that points to this node and p = ice_sched_get_first_node(pi, node, node->tx_sched_layer);
* remove the reference
*/
tc_node = ice_sched_get_tc_node(pi, node->tc_num);
if (!tc_node) {
ice_debug(hw, ICE_DBG_SCHED,
"Invalid TC number %d\n", node->tc_num);
goto err_exit;
}
p = ice_sched_get_first_node(hw, tc_node, node->tx_sched_layer);
while (p) { while (p) {
if (p->sibling == node) { if (p->sibling == node) {
p->sibling = node->sibling; p->sibling = node->sibling;
...@@ -371,8 +346,13 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node) ...@@ -371,8 +346,13 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
} }
p = p->sibling; p = p->sibling;
} }
/* update the sibling head if head is getting removed */
if (pi->sib_head[node->tc_num][node->tx_sched_layer] == node)
pi->sib_head[node->tc_num][node->tx_sched_layer] =
node->sibling;
} }
err_exit:
/* leaf nodes have no children */ /* leaf nodes have no children */
if (node->children) if (node->children)
devm_kfree(ice_hw_to_dev(hw), node->children); devm_kfree(ice_hw_to_dev(hw), node->children);
...@@ -743,13 +723,17 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node, ...@@ -743,13 +723,17 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
/* add it to previous node sibling pointer */ /* add it to previous node sibling pointer */
/* Note: siblings are not linked across branches */ /* Note: siblings are not linked across branches */
prev = ice_sched_get_first_node(hw, tc_node, layer); prev = ice_sched_get_first_node(pi, tc_node, layer);
if (prev && prev != new_node) { if (prev && prev != new_node) {
while (prev->sibling) while (prev->sibling)
prev = prev->sibling; prev = prev->sibling;
prev->sibling = new_node; prev->sibling = new_node;
} }
/* initialize the sibling head */
if (!pi->sib_head[tc_node->tc_num][layer])
pi->sib_head[tc_node->tc_num][layer] = new_node;
if (i == 0) if (i == 0)
*first_node_teid = teid; *first_node_teid = teid;
} }
...@@ -1160,7 +1144,7 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc, ...@@ -1160,7 +1144,7 @@ ice_sched_get_free_qparent(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
goto lan_q_exit; goto lan_q_exit;
/* get the first queue group node from VSI sub-tree */ /* get the first queue group node from VSI sub-tree */
qgrp_node = ice_sched_get_first_node(pi->hw, vsi_node, qgrp_layer); qgrp_node = ice_sched_get_first_node(pi, vsi_node, qgrp_layer);
while (qgrp_node) { while (qgrp_node) {
/* make sure the qgroup node is part of the VSI subtree */ /* make sure the qgroup node is part of the VSI subtree */
if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node)) if (ice_sched_find_node_in_subtree(pi->hw, vsi_node, qgrp_node))
...@@ -1191,7 +1175,7 @@ ice_sched_get_vsi_node(struct ice_hw *hw, struct ice_sched_node *tc_node, ...@@ -1191,7 +1175,7 @@ ice_sched_get_vsi_node(struct ice_hw *hw, struct ice_sched_node *tc_node,
u8 vsi_layer; u8 vsi_layer;
vsi_layer = ice_sched_get_vsi_layer(hw); vsi_layer = ice_sched_get_vsi_layer(hw);
node = ice_sched_get_first_node(hw, tc_node, vsi_layer); node = ice_sched_get_first_node(hw->port_info, tc_node, vsi_layer);
/* Check whether it already exists */ /* Check whether it already exists */
while (node) { while (node) {
...@@ -1316,7 +1300,8 @@ ice_sched_calc_vsi_support_nodes(struct ice_hw *hw, ...@@ -1316,7 +1300,8 @@ ice_sched_calc_vsi_support_nodes(struct ice_hw *hw,
/* If intermediate nodes are reached max children /* If intermediate nodes are reached max children
* then add a new one. * then add a new one.
*/ */
node = ice_sched_get_first_node(hw, tc_node, (u8)i); node = ice_sched_get_first_node(hw->port_info, tc_node,
(u8)i);
/* scan all the siblings */ /* scan all the siblings */
while (node) { while (node) {
if (node->num_children < hw->max_children[i]) if (node->num_children < hw->max_children[i])
......
...@@ -347,6 +347,8 @@ struct ice_port_info { ...@@ -347,6 +347,8 @@ struct ice_port_info {
struct ice_mac_info mac; struct ice_mac_info mac;
struct ice_phy_info phy; struct ice_phy_info phy;
struct mutex sched_lock; /* protect access to TXSched tree */ struct mutex sched_lock; /* protect access to TXSched tree */
struct ice_sched_node *
sib_head[ICE_MAX_TRAFFIC_CLASS][ICE_AQC_TOPO_MAX_LEVEL_NUM];
struct ice_dcbx_cfg local_dcbx_cfg; /* Oper/Local Cfg */ struct ice_dcbx_cfg local_dcbx_cfg; /* Oper/Local Cfg */
/* DCBX info */ /* DCBX info */
struct ice_dcbx_cfg remote_dcbx_cfg; /* Peer Cfg */ struct ice_dcbx_cfg remote_dcbx_cfg; /* Peer Cfg */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment