ice: Add an option to pre-allocate memory for ice_sched_node
authorMichal Wilczynski <michal.wilczynski@intel.com>
Tue, 15 Nov 2022 10:48:21 +0000 (11:48 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 18 Nov 2022 05:41:28 +0000 (21:41 -0800)
devlink-rate API requires a priv object to be allocated when node still
doesn't have a parent. This is problematic, because ice_sched_node can't
be currently created without a parent.

Add an option to pre-allocate memory for ice_sched_node struct. Add
new arguments to ice_sched_add() and ice_sched_add_elems() that allow
for pre-allocation of memory for ice_sched_node struct.

Signed-off-by: Michal Wilczynski <michal.wilczynski@intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/intel/ice/ice_common.c
drivers/net/ethernet/intel/ice/ice_dcb.c
drivers/net/ethernet/intel/ice/ice_sched.c
drivers/net/ethernet/intel/ice/ice_sched.h

index e2e661010176c3360890f735355894056423a213..216370ec60d411483633394457d0d4d0d8cae98f 100644 (file)
@@ -4603,7 +4603,7 @@ ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 q_handle,
        q_ctx->q_teid = le32_to_cpu(node.node_teid);
 
        /* add a leaf node into scheduler tree queue layer */
-       status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1, &node);
+       status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1, &node, NULL);
        if (!status)
                status = ice_sched_replay_q_bw(pi, q_ctx);
 
@@ -4838,7 +4838,7 @@ ice_ena_vsi_rdma_qset(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
        for (i = 0; i < num_qsets; i++) {
                node.node_teid = buf->rdma_qsets[i].qset_teid;
                ret = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1,
-                                        &node);
+                                        &node, NULL);
                if (ret)
                        break;
                qset_teid[i] = le32_to_cpu(node.node_teid);
index 0b146a0d42058a0941821b1102d7de5b3f133aa9..6be02f9b0b8c25b777e6c2ee0ca91f110bff8d33 100644 (file)
@@ -1580,7 +1580,7 @@ ice_update_port_tc_tree_cfg(struct ice_port_info *pi,
                /* new TC */
                status = ice_sched_query_elem(pi->hw, teid2, &elem);
                if (!status)
-                       status = ice_sched_add_node(pi, 1, &elem);
+                       status = ice_sched_add_node(pi, 1, &elem, NULL);
                if (status)
                        break;
                /* update the TC number */
index 980543074ddb19acf6e47b301b78b8eedd09a74e..6d08b397df2ad9252ecf5c0f098010c295ba5197 100644 (file)
@@ -143,12 +143,14 @@ ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
  * @pi: port information structure
  * @layer: Scheduler layer of the node
  * @info: Scheduler element information from firmware
+ * @prealloc_node: preallocated ice_sched_node struct for SW DB
  *
  * This function inserts a scheduler node to the SW DB.
  */
 int
 ice_sched_add_node(struct ice_port_info *pi, u8 layer,
-                  struct ice_aqc_txsched_elem_data *info)
+                  struct ice_aqc_txsched_elem_data *info,
+                  struct ice_sched_node *prealloc_node)
 {
        struct ice_aqc_txsched_elem_data elem;
        struct ice_sched_node *parent;
@@ -177,7 +179,10 @@ ice_sched_add_node(struct ice_port_info *pi, u8 layer,
        if (status)
                return status;
 
-       node = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL);
+       if (prealloc_node)
+               node = prealloc_node;
+       else
+               node = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*node), GFP_KERNEL);
        if (!node)
                return -ENOMEM;
        if (hw->max_children[layer]) {
@@ -876,13 +881,15 @@ void ice_sched_cleanup_all(struct ice_hw *hw)
  * @num_nodes: number of nodes
  * @num_nodes_added: pointer to num nodes added
  * @first_node_teid: if new nodes are added then return the TEID of first node
+ * @prealloc_nodes: preallocated nodes struct for software DB
  *
  * This function add nodes to HW as well as to SW DB for a given layer
  */
 int
 ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
                    struct ice_sched_node *parent, u8 layer, u16 num_nodes,
-                   u16 *num_nodes_added, u32 *first_node_teid)
+                   u16 *num_nodes_added, u32 *first_node_teid,
+                   struct ice_sched_node **prealloc_nodes)
 {
        struct ice_sched_node *prev, *new_node;
        struct ice_aqc_add_elem *buf;
@@ -928,7 +935,11 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
        *num_nodes_added = num_nodes;
        /* add nodes to the SW DB */
        for (i = 0; i < num_nodes; i++) {
-               status = ice_sched_add_node(pi, layer, &buf->generic[i]);
+               if (prealloc_nodes)
+                       status = ice_sched_add_node(pi, layer, &buf->generic[i], prealloc_nodes[i]);
+               else
+                       status = ice_sched_add_node(pi, layer, &buf->generic[i], NULL);
+
                if (status) {
                        ice_debug(hw, ICE_DBG_SCHED, "add nodes in SW DB failed status =%d\n",
                                  status);
@@ -1023,7 +1034,7 @@ ice_sched_add_nodes_to_hw_layer(struct ice_port_info *pi,
        }
 
        return ice_sched_add_elems(pi, tc_node, parent, layer, num_nodes,
-                                  num_nodes_added, first_node_teid);
+                                  num_nodes_added, first_node_teid, NULL);
 }
 
 /**
@@ -1288,7 +1299,7 @@ int ice_sched_init_port(struct ice_port_info *pi)
                            ICE_AQC_ELEM_TYPE_ENTRY_POINT)
                                hw->sw_entry_point_layer = j;
 
-                       status = ice_sched_add_node(pi, j, &buf[i].generic[j]);
+                       status = ice_sched_add_node(pi, j, &buf[i].generic[j], NULL);
                        if (status)
                                goto err_init_port;
                }
index 920db43ed4fa60fcf8e466eaa117d0a92198e5f4..9c100747445aae7cc0f97d7bcbba861af20a45b6 100644 (file)
@@ -83,7 +83,8 @@ ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
 int
 ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
                    struct ice_sched_node *parent, u8 layer, u16 num_nodes,
-                   u16 *num_nodes_added, u32 *first_node_teid);
+                   u16 *num_nodes_added, u32 *first_node_teid,
+                   struct ice_sched_node **prealloc_node);
 
 int
 ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent,
@@ -105,7 +106,8 @@ struct ice_sched_node *
 ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid);
 int
 ice_sched_add_node(struct ice_port_info *pi, u8 layer,
-                  struct ice_aqc_txsched_elem_data *info);
+                  struct ice_aqc_txsched_elem_data *info,
+                  struct ice_sched_node *prealloc_node);
 void
 ice_sched_update_parent(struct ice_sched_node *new_parent,
                        struct ice_sched_node *node);