net/ice/base: modify recursive way of adding nodes
Remove the recursive way of adding the nodes to the layer in order to reduce the stack usage. Instead the algorithm is modified to use a while loop. The previous code was scanning recursively the nodes horizontally. The total stack consumption will be based on number of nodes present on that layer. In some cases it can consume more stack. Signed-off-by: Victor Raj <victor.raj@intel.com> Signed-off-by: Qi Zhang <qi.z.zhang@intel.com> Acked-by: Qiming Yang <qiming.yang@intel.com>
This commit is contained in:
parent
553be3ed18
commit
254f19c8c0
@ -964,6 +964,50 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_sched_add_nodes_to_hw_layer - Add nodes to hw layer
|
||||
* @pi: port information structure
|
||||
* @tc_node: pointer to TC node
|
||||
* @parent: pointer to parent node
|
||||
* @layer: layer number to add nodes
|
||||
* @num_nodes: number of nodes to be added
|
||||
* @first_node_teid: pointer to the first node TEID
|
||||
* @num_nodes_added: pointer to number of nodes added
|
||||
*
|
||||
* Add nodes into specific hw layer.
|
||||
*/
|
||||
static enum ice_status
|
||||
ice_sched_add_nodes_to_hw_layer(struct ice_port_info *pi,
|
||||
struct ice_sched_node *tc_node,
|
||||
struct ice_sched_node *parent, u8 layer,
|
||||
u16 num_nodes, u32 *first_node_teid,
|
||||
u16 *num_nodes_added)
|
||||
{
|
||||
u16 max_child_nodes;
|
||||
|
||||
*num_nodes_added = 0;
|
||||
|
||||
if (!num_nodes)
|
||||
return ICE_SUCCESS;
|
||||
|
||||
if (!parent || layer < pi->hw->sw_entry_point_layer)
|
||||
return ICE_ERR_PARAM;
|
||||
|
||||
/* max children per node per layer */
|
||||
max_child_nodes = pi->hw->max_children[parent->tx_sched_layer];
|
||||
|
||||
/* current number of children + required nodes exceed max children */
|
||||
if ((parent->num_children + num_nodes) > max_child_nodes) {
|
||||
/* Fail if the parent is a TC node */
|
||||
if (parent == tc_node)
|
||||
return ICE_ERR_CFG;
|
||||
return ICE_ERR_MAX_LIMIT;
|
||||
}
|
||||
|
||||
return ice_sched_add_elems(pi, tc_node, parent, layer, num_nodes,
|
||||
num_nodes_added, first_node_teid);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_sched_add_nodes_to_layer - Add nodes to a given layer
|
||||
* @pi: port information structure
|
||||
@ -984,72 +1028,44 @@ ice_sched_add_nodes_to_layer(struct ice_port_info *pi,
|
||||
u16 *num_nodes_added)
|
||||
{
|
||||
u32 *first_teid_ptr = first_node_teid;
|
||||
u16 new_num_nodes, max_child_nodes;
|
||||
u16 new_num_nodes = num_nodes;
|
||||
enum ice_status status = ICE_SUCCESS;
|
||||
struct ice_hw *hw = pi->hw;
|
||||
u16 num_added = 0;
|
||||
u32 temp;
|
||||
|
||||
*num_nodes_added = 0;
|
||||
while (*num_nodes_added < num_nodes) {
|
||||
u16 max_child_nodes, num_added = 0;
|
||||
u32 temp;
|
||||
|
||||
if (!num_nodes)
|
||||
return status;
|
||||
|
||||
if (!parent || layer < hw->sw_entry_point_layer)
|
||||
return ICE_ERR_PARAM;
|
||||
|
||||
/* max children per node per layer */
|
||||
max_child_nodes = hw->max_children[parent->tx_sched_layer];
|
||||
|
||||
/* current number of children + required nodes exceed max children ? */
|
||||
if ((parent->num_children + num_nodes) > max_child_nodes) {
|
||||
/* Fail if the parent is a TC node */
|
||||
if (parent == tc_node)
|
||||
return ICE_ERR_CFG;
|
||||
|
||||
status = ice_sched_add_nodes_to_hw_layer(pi, tc_node, parent,
|
||||
layer, new_num_nodes,
|
||||
first_teid_ptr,
|
||||
&num_added);
|
||||
*num_nodes_added += num_added;
|
||||
/* break if all the nodes are added successfully */
|
||||
if (status == ICE_SUCCESS && (*num_nodes_added == num_nodes))
|
||||
break;
|
||||
/* break if the error is not max limit */
|
||||
if (status != ICE_SUCCESS && status != ICE_ERR_MAX_LIMIT)
|
||||
break;
|
||||
/* Exceeded the max children */
|
||||
max_child_nodes = pi->hw->max_children[parent->tx_sched_layer];
|
||||
/* utilize all the spaces if the parent is not full */
|
||||
if (parent->num_children < max_child_nodes) {
|
||||
new_num_nodes = max_child_nodes - parent->num_children;
|
||||
/* this recursion is intentional, and wouldn't
|
||||
* go more than 2 calls
|
||||
} else {
|
||||
/* This parent is full, try the next sibling */
|
||||
parent = parent->sibling;
|
||||
/* Don't modify the first node TEID memory if the
|
||||
* first node was added already in the above call.
|
||||
* Instead send some temp memory for all other
|
||||
* recursive calls.
|
||||
*/
|
||||
status = ice_sched_add_nodes_to_layer(pi, tc_node,
|
||||
parent, layer,
|
||||
new_num_nodes,
|
||||
first_node_teid,
|
||||
&num_added);
|
||||
if (status != ICE_SUCCESS)
|
||||
return status;
|
||||
if (num_added)
|
||||
first_teid_ptr = &temp;
|
||||
|
||||
*num_nodes_added += num_added;
|
||||
new_num_nodes = num_nodes - num_added;
|
||||
}
|
||||
/* Don't modify the first node TEID memory if the first node was
|
||||
* added already in the above call. Instead send some temp
|
||||
* memory for all other recursive calls.
|
||||
*/
|
||||
if (num_added)
|
||||
first_teid_ptr = &temp;
|
||||
|
||||
new_num_nodes = num_nodes - num_added;
|
||||
|
||||
/* This parent is full, try the next sibling */
|
||||
parent = parent->sibling;
|
||||
|
||||
/* this recursion is intentional, for 1024 queues
|
||||
* per VSI, it goes max of 16 iterations.
|
||||
* 1024 / 8 = 128 layer 8 nodes
|
||||
* 128 /8 = 16 (add 8 nodes per iteration)
|
||||
*/
|
||||
status = ice_sched_add_nodes_to_layer(pi, tc_node, parent,
|
||||
layer, new_num_nodes,
|
||||
first_teid_ptr,
|
||||
&num_added);
|
||||
*num_nodes_added += num_added;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = ice_sched_add_elems(pi, tc_node, parent, layer, num_nodes,
|
||||
num_nodes_added, first_node_teid);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user