ice: Introduce new parameters in ice_sched_node
To support new devlink-rate API ice_sched_node struct needs to store a number of additional parameters. This includes tx_max, tx_share, tx_weight, and tx_priority. Add new fields to ice_sched_node struct. Add new functions to configure the hardware with new parameters. Introduce new xarray to identify nodes uniquely. Signed-off-by: Michal Wilczynski <michal.wilczynski@intel.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
f2fc15e271
commit
16dfa49406
@ -848,9 +848,9 @@ struct ice_aqc_txsched_elem {
|
|||||||
u8 generic;
|
u8 generic;
|
||||||
#define ICE_AQC_ELEM_GENERIC_MODE_M 0x1
|
#define ICE_AQC_ELEM_GENERIC_MODE_M 0x1
|
||||||
#define ICE_AQC_ELEM_GENERIC_PRIO_S 0x1
|
#define ICE_AQC_ELEM_GENERIC_PRIO_S 0x1
|
||||||
#define ICE_AQC_ELEM_GENERIC_PRIO_M (0x7 << ICE_AQC_ELEM_GENERIC_PRIO_S)
|
#define ICE_AQC_ELEM_GENERIC_PRIO_M GENMASK(3, 1)
|
||||||
#define ICE_AQC_ELEM_GENERIC_SP_S 0x4
|
#define ICE_AQC_ELEM_GENERIC_SP_S 0x4
|
||||||
#define ICE_AQC_ELEM_GENERIC_SP_M (0x1 << ICE_AQC_ELEM_GENERIC_SP_S)
|
#define ICE_AQC_ELEM_GENERIC_SP_M GENMASK(4, 4)
|
||||||
#define ICE_AQC_ELEM_GENERIC_ADJUST_VAL_S 0x5
|
#define ICE_AQC_ELEM_GENERIC_ADJUST_VAL_S 0x5
|
||||||
#define ICE_AQC_ELEM_GENERIC_ADJUST_VAL_M \
|
#define ICE_AQC_ELEM_GENERIC_ADJUST_VAL_M \
|
||||||
(0x3 << ICE_AQC_ELEM_GENERIC_ADJUST_VAL_S)
|
(0x3 << ICE_AQC_ELEM_GENERIC_ADJUST_VAL_S)
|
||||||
|
@ -1105,6 +1105,9 @@ int ice_init_hw(struct ice_hw *hw)
|
|||||||
|
|
||||||
hw->evb_veb = true;
|
hw->evb_veb = true;
|
||||||
|
|
||||||
|
/* init xarray for identifying scheduling nodes uniquely */
|
||||||
|
xa_init_flags(&hw->port_info->sched_node_ids, XA_FLAGS_ALLOC);
|
||||||
|
|
||||||
/* Query the allocated resources for Tx scheduler */
|
/* Query the allocated resources for Tx scheduler */
|
||||||
status = ice_sched_query_res_alloc(hw);
|
status = ice_sched_query_res_alloc(hw);
|
||||||
if (status) {
|
if (status) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/* Copyright (c) 2018, Intel Corporation. */
|
/* Copyright (c) 2018, Intel Corporation. */
|
||||||
|
|
||||||
|
#include <net/devlink.h>
|
||||||
#include "ice_sched.h"
|
#include "ice_sched.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -355,6 +356,9 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
|
|||||||
/* 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);
|
||||||
|
|
||||||
|
kfree(node->name);
|
||||||
|
xa_erase(&pi->sched_node_ids, node->id);
|
||||||
devm_kfree(ice_hw_to_dev(hw), node);
|
devm_kfree(ice_hw_to_dev(hw), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,7 +879,7 @@ void ice_sched_cleanup_all(struct ice_hw *hw)
|
|||||||
*
|
*
|
||||||
* This function add nodes to HW as well as to SW DB for a given layer
|
* This function add nodes to HW as well as to SW DB for a given layer
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
|
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,
|
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)
|
||||||
@ -940,6 +944,22 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
|
|||||||
|
|
||||||
new_node->sibling = NULL;
|
new_node->sibling = NULL;
|
||||||
new_node->tc_num = tc_node->tc_num;
|
new_node->tc_num = tc_node->tc_num;
|
||||||
|
new_node->tx_weight = ICE_SCHED_DFLT_BW_WT;
|
||||||
|
new_node->tx_share = ICE_SCHED_DFLT_BW;
|
||||||
|
new_node->tx_max = ICE_SCHED_DFLT_BW;
|
||||||
|
new_node->name = kzalloc(SCHED_NODE_NAME_MAX_LEN, GFP_KERNEL);
|
||||||
|
if (!new_node->name)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
status = xa_alloc(&pi->sched_node_ids, &new_node->id, NULL, XA_LIMIT(0, UINT_MAX),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (status) {
|
||||||
|
ice_debug(hw, ICE_DBG_SCHED, "xa_alloc failed for sched node status =%d\n",
|
||||||
|
status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(new_node->name, SCHED_NODE_NAME_MAX_LEN, "node_%u", new_node->id);
|
||||||
|
|
||||||
/* 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 */
|
||||||
@ -2154,7 +2174,7 @@ ice_sched_get_free_vsi_parent(struct ice_hw *hw, struct ice_sched_node *node,
|
|||||||
* This function removes the child from the old parent and adds it to a new
|
* This function removes the child from the old parent and adds it to a new
|
||||||
* parent
|
* parent
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
ice_sched_update_parent(struct ice_sched_node *new_parent,
|
ice_sched_update_parent(struct ice_sched_node *new_parent,
|
||||||
struct ice_sched_node *node)
|
struct ice_sched_node *node)
|
||||||
{
|
{
|
||||||
@ -2188,7 +2208,7 @@ ice_sched_update_parent(struct ice_sched_node *new_parent,
|
|||||||
*
|
*
|
||||||
* This function move the child nodes to a given parent.
|
* This function move the child nodes to a given parent.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent,
|
ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent,
|
||||||
u16 num_items, u32 *list)
|
u16 num_items, u32 *list)
|
||||||
{
|
{
|
||||||
@ -3560,7 +3580,7 @@ ice_sched_set_eir_srl_excl(struct ice_port_info *pi,
|
|||||||
* node's RL profile ID of type CIR, EIR, or SRL, and removes old profile
|
* node's RL profile ID of type CIR, EIR, or SRL, and removes old profile
|
||||||
* ID from local database. The caller needs to hold scheduler lock.
|
* ID from local database. The caller needs to hold scheduler lock.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
|
ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
|
||||||
enum ice_rl_type rl_type, u32 bw, u8 layer_num)
|
enum ice_rl_type rl_type, u32 bw, u8 layer_num)
|
||||||
{
|
{
|
||||||
@ -3596,6 +3616,57 @@ ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
|
|||||||
ICE_AQC_RL_PROFILE_TYPE_M, old_id);
|
ICE_AQC_RL_PROFILE_TYPE_M, old_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_sched_set_node_priority - set node's priority
|
||||||
|
* @pi: port information structure
|
||||||
|
* @node: tree node
|
||||||
|
* @priority: number 0-7 representing priority among siblings
|
||||||
|
*
|
||||||
|
* This function sets priority of a node among it's siblings.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ice_sched_set_node_priority(struct ice_port_info *pi, struct ice_sched_node *node,
|
||||||
|
u16 priority)
|
||||||
|
{
|
||||||
|
struct ice_aqc_txsched_elem_data buf;
|
||||||
|
struct ice_aqc_txsched_elem *data;
|
||||||
|
|
||||||
|
buf = node->info;
|
||||||
|
data = &buf.data;
|
||||||
|
|
||||||
|
data->valid_sections |= ICE_AQC_ELEM_VALID_GENERIC;
|
||||||
|
data->generic |= FIELD_PREP(ICE_AQC_ELEM_GENERIC_PRIO_M, priority);
|
||||||
|
|
||||||
|
return ice_sched_update_elem(pi->hw, node, &buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_sched_set_node_weight - set node's weight
|
||||||
|
* @pi: port information structure
|
||||||
|
* @node: tree node
|
||||||
|
* @weight: number 1-200 representing weight for WFQ
|
||||||
|
*
|
||||||
|
* This function sets weight of the node for WFQ algorithm.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ice_sched_set_node_weight(struct ice_port_info *pi, struct ice_sched_node *node, u16 weight)
|
||||||
|
{
|
||||||
|
struct ice_aqc_txsched_elem_data buf;
|
||||||
|
struct ice_aqc_txsched_elem *data;
|
||||||
|
|
||||||
|
buf = node->info;
|
||||||
|
data = &buf.data;
|
||||||
|
|
||||||
|
data->valid_sections = ICE_AQC_ELEM_VALID_CIR | ICE_AQC_ELEM_VALID_EIR |
|
||||||
|
ICE_AQC_ELEM_VALID_GENERIC;
|
||||||
|
data->cir_bw.bw_alloc = cpu_to_le16(weight);
|
||||||
|
data->eir_bw.bw_alloc = cpu_to_le16(weight);
|
||||||
|
|
||||||
|
data->generic |= FIELD_PREP(ICE_AQC_ELEM_GENERIC_SP_M, 0x0);
|
||||||
|
|
||||||
|
return ice_sched_update_elem(pi->hw, node, &buf);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_sched_set_node_bw_lmt - set node's BW limit
|
* ice_sched_set_node_bw_lmt - set node's BW limit
|
||||||
* @pi: port information structure
|
* @pi: port information structure
|
||||||
@ -3606,7 +3677,7 @@ ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
|
|||||||
* It updates node's BW limit parameters like BW RL profile ID of type CIR,
|
* It updates node's BW limit parameters like BW RL profile ID of type CIR,
|
||||||
* EIR, or SRL. The caller needs to hold scheduler lock.
|
* EIR, or SRL. The caller needs to hold scheduler lock.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node,
|
ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node,
|
||||||
enum ice_rl_type rl_type, u32 bw)
|
enum ice_rl_type rl_type, u32 bw)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "ice_common.h"
|
#include "ice_common.h"
|
||||||
|
|
||||||
|
#define SCHED_NODE_NAME_MAX_LEN 32
|
||||||
|
|
||||||
#define ICE_QGRP_LAYER_OFFSET 2
|
#define ICE_QGRP_LAYER_OFFSET 2
|
||||||
#define ICE_VSI_LAYER_OFFSET 4
|
#define ICE_VSI_LAYER_OFFSET 4
|
||||||
#define ICE_AGG_LAYER_OFFSET 6
|
#define ICE_AGG_LAYER_OFFSET 6
|
||||||
@ -69,6 +71,28 @@ int
|
|||||||
ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
|
ice_aq_query_sched_elems(struct ice_hw *hw, u16 elems_req,
|
||||||
struct ice_aqc_txsched_elem_data *buf, u16 buf_size,
|
struct ice_aqc_txsched_elem_data *buf, u16 buf_size,
|
||||||
u16 *elems_ret, struct ice_sq_cd *cd);
|
u16 *elems_ret, struct ice_sq_cd *cd);
|
||||||
|
|
||||||
|
int
|
||||||
|
ice_sched_set_node_bw_lmt(struct ice_port_info *pi, struct ice_sched_node *node,
|
||||||
|
enum ice_rl_type rl_type, u32 bw);
|
||||||
|
|
||||||
|
int
|
||||||
|
ice_sched_set_node_bw(struct ice_port_info *pi, struct ice_sched_node *node,
|
||||||
|
enum ice_rl_type rl_type, u32 bw, u8 layer_num);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
int
|
||||||
|
ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent,
|
||||||
|
u16 num_items, u32 *list);
|
||||||
|
|
||||||
|
int ice_sched_set_node_priority(struct ice_port_info *pi, struct ice_sched_node *node,
|
||||||
|
u16 priority);
|
||||||
|
int ice_sched_set_node_weight(struct ice_port_info *pi, struct ice_sched_node *node, u16 weight);
|
||||||
|
|
||||||
int ice_sched_init_port(struct ice_port_info *pi);
|
int ice_sched_init_port(struct ice_port_info *pi);
|
||||||
int ice_sched_query_res_alloc(struct ice_hw *hw);
|
int ice_sched_query_res_alloc(struct ice_hw *hw);
|
||||||
void ice_sched_get_psm_clk_freq(struct ice_hw *hw);
|
void ice_sched_get_psm_clk_freq(struct ice_hw *hw);
|
||||||
@ -82,6 +106,9 @@ ice_sched_find_node_by_teid(struct ice_sched_node *start_node, u32 teid);
|
|||||||
int
|
int
|
||||||
ice_sched_add_node(struct ice_port_info *pi, u8 layer,
|
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);
|
||||||
|
void
|
||||||
|
ice_sched_update_parent(struct ice_sched_node *new_parent,
|
||||||
|
struct ice_sched_node *node);
|
||||||
void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node);
|
void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node);
|
||||||
struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc);
|
struct ice_sched_node *ice_sched_get_tc_node(struct ice_port_info *pi, u8 tc);
|
||||||
struct ice_sched_node *
|
struct ice_sched_node *
|
||||||
|
@ -524,7 +524,14 @@ struct ice_sched_node {
|
|||||||
struct ice_sched_node *sibling; /* next sibling in the same layer */
|
struct ice_sched_node *sibling; /* next sibling in the same layer */
|
||||||
struct ice_sched_node **children;
|
struct ice_sched_node **children;
|
||||||
struct ice_aqc_txsched_elem_data info;
|
struct ice_aqc_txsched_elem_data info;
|
||||||
|
char *name;
|
||||||
|
struct devlink_rate *rate_node;
|
||||||
|
u64 tx_max;
|
||||||
|
u64 tx_share;
|
||||||
u32 agg_id; /* aggregator group ID */
|
u32 agg_id; /* aggregator group ID */
|
||||||
|
u32 id;
|
||||||
|
u32 tx_priority;
|
||||||
|
u32 tx_weight;
|
||||||
u16 vsi_handle;
|
u16 vsi_handle;
|
||||||
u8 in_use; /* suspended or in use */
|
u8 in_use; /* suspended or in use */
|
||||||
u8 tx_sched_layer; /* Logical Layer (1-9) */
|
u8 tx_sched_layer; /* Logical Layer (1-9) */
|
||||||
@ -706,6 +713,7 @@ struct ice_port_info {
|
|||||||
/* List contain profile ID(s) and other params per layer */
|
/* List contain profile ID(s) and other params per layer */
|
||||||
struct list_head rl_prof_list[ICE_AQC_TOPO_MAX_LEVEL_NUM];
|
struct list_head rl_prof_list[ICE_AQC_TOPO_MAX_LEVEL_NUM];
|
||||||
struct ice_qos_cfg qos_cfg;
|
struct ice_qos_cfg qos_cfg;
|
||||||
|
struct xarray sched_node_ids;
|
||||||
u8 is_vf:1;
|
u8 is_vf:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user