Skip to content

Commit

Permalink
ice: create scheduler aggregator node config and move VSIs
Browse files Browse the repository at this point in the history
Create set scheduler aggregator node and move for VSIs into respective
scheduler node. Max children per aggregator node is 64.

There are two types of aggregator node(s) created.
1. dedicated node for PF and _CTRL VSIs
2. dedicated node(s) for VFs.

As part of reset and rebuild, aggregator nodes are recreated and VSIs
are moved to respective aggregator node.

Having related VSIs in respective tree avoid starvation between PF and VF
w.r.t Tx bandwidth.

Co-developed-by: Tarun Singh <tarun.k.singh@intel.com>
Signed-off-by: Tarun Singh <tarun.k.singh@intel.com>
Co-developed-by: Victor Raj <victor.raj@intel.com>
Signed-off-by: Victor Raj <victor.raj@intel.com>
Co-developed-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Signed-off-by: Kiran Patil <kiran.patil@intel.com>
Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Kiran Patil authored and Tony Nguyen committed Feb 9, 2021
1 parent df006dd commit b126bd6
Show file tree
Hide file tree
Showing 9 changed files with 1,207 additions and 20 deletions.
20 changes: 20 additions & 0 deletions drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,11 @@ struct ice_vsi {
struct ice_ring **xdp_rings; /* XDP ring array */
u16 num_xdp_txq; /* Used XDP queues */
u8 xdp_mapping_mode; /* ICE_MAP_MODE_[CONTIG|SCATTER] */

/* setup back reference, to which aggregator node this VSI
* corresponds to
*/
struct ice_agg_node *agg_node;
} ____cacheline_internodealigned_in_smp;

/* struct that defines an interrupt vector */
Expand Down Expand Up @@ -376,6 +381,13 @@ enum ice_pf_flags {
ICE_PF_FLAGS_NBITS /* must be last */
};

struct ice_agg_node {
u32 agg_id;
#define ICE_MAX_VSIS_IN_AGG_NODE 64
u32 num_vsis;
u8 valid;
};

struct ice_pf {
struct pci_dev *pdev;

Expand Down Expand Up @@ -455,6 +467,14 @@ struct ice_pf {
__le64 nvm_phy_type_hi; /* NVM PHY type high */
struct ice_link_default_override_tlv link_dflt_override;
struct ice_lag *lag; /* Link Aggregation information */

#define ICE_INVALID_AGG_NODE_ID 0
#define ICE_PF_AGG_NODE_ID_START 1
#define ICE_MAX_PF_AGG_NODES 32
struct ice_agg_node pf_agg_node[ICE_MAX_PF_AGG_NODES];
#define ICE_VF_AGG_NODE_ID_START 65
#define ICE_MAX_VF_AGG_NODES 32
struct ice_agg_node vf_agg_node[ICE_MAX_VF_AGG_NODES];
};

struct ice_netdev_priv {
Expand Down
13 changes: 13 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,18 @@ struct ice_aqc_sched_elem_cmd {
__le32 addr_low;
};

struct ice_aqc_txsched_move_grp_info_hdr {
__le32 src_parent_teid;
__le32 dest_parent_teid;
__le16 num_elems;
__le16 reserved;
};

struct ice_aqc_move_elem {
struct ice_aqc_txsched_move_grp_info_hdr hdr;
__le32 teid[];
};

struct ice_aqc_elem_info_bw {
__le16 bw_profile_idx;
__le16 bw_alloc;
Expand Down Expand Up @@ -1961,6 +1973,7 @@ enum ice_adminq_opc {
ice_aqc_opc_add_sched_elems = 0x0401,
ice_aqc_opc_cfg_sched_elems = 0x0403,
ice_aqc_opc_get_sched_elems = 0x0404,
ice_aqc_opc_move_sched_elems = 0x0408,
ice_aqc_opc_suspend_sched_elems = 0x0409,
ice_aqc_opc_resume_sched_elems = 0x040A,
ice_aqc_opc_query_port_ets = 0x040E,
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -4078,6 +4078,7 @@ static enum ice_status ice_replay_pre_init(struct ice_hw *hw)
for (i = 0; i < ICE_SW_LKUP_LAST; i++)
list_replace_init(&sw->recp_list[i].filt_rules,
&sw->recp_list[i].filt_replay_rules);
ice_sched_replay_agg_vsi_preinit(hw);

return 0;
}
Expand Down Expand Up @@ -4109,6 +4110,8 @@ enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle)
return status;
/* Replay per VSI all filters */
status = ice_replay_vsi_all_fltr(hw, vsi_handle);
if (!status)
status = ice_replay_vsi_agg(hw, vsi_handle);
return status;
}

Expand All @@ -4122,6 +4125,7 @@ void ice_replay_post(struct ice_hw *hw)
{
/* Delete old entries from replay filter list head */
ice_rm_all_sw_replay_rule_info(hw);
ice_sched_replay_agg(hw);
}

/**
Expand Down
125 changes: 125 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2164,6 +2164,126 @@ void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create)
vsi->vsi_num, ice_stat_str(status));
}

/**
* ice_set_agg_vsi - sets up scheduler aggregator node and move VSI into it
* @vsi: pointer to the VSI
*
* This function will allocate new scheduler aggregator now if needed and will
* move specified VSI into it.
*/
static void ice_set_agg_vsi(struct ice_vsi *vsi)
{
struct device *dev = ice_pf_to_dev(vsi->back);
struct ice_agg_node *agg_node_iter = NULL;
u32 agg_id = ICE_INVALID_AGG_NODE_ID;
struct ice_agg_node *agg_node = NULL;
int node_offset, max_agg_nodes = 0;
struct ice_port_info *port_info;
struct ice_pf *pf = vsi->back;
u32 agg_node_id_start = 0;
enum ice_status status;

/* create (as needed) scheduler aggregator node and move VSI into
* corresponding aggregator node
* - PF aggregator node to contains VSIs of type _PF and _CTRL
* - VF aggregator nodes will contain VF VSI
*/
port_info = pf->hw.port_info;
if (!port_info)
return;

switch (vsi->type) {
case ICE_VSI_CTRL:
case ICE_VSI_LB:
case ICE_VSI_PF:
max_agg_nodes = ICE_MAX_PF_AGG_NODES;
agg_node_id_start = ICE_PF_AGG_NODE_ID_START;
agg_node_iter = &pf->pf_agg_node[0];
break;
case ICE_VSI_VF:
/* user can create 'n' VFs on a given PF, but since max children
* per aggregator node can be only 64. Following code handles
* aggregator(s) for VF VSIs, either selects a agg_node which
* was already created provided num_vsis < 64, otherwise
* select next available node, which will be created
*/
max_agg_nodes = ICE_MAX_VF_AGG_NODES;
agg_node_id_start = ICE_VF_AGG_NODE_ID_START;
agg_node_iter = &pf->vf_agg_node[0];
break;
default:
/* other VSI type, handle later if needed */
dev_dbg(dev, "unexpected VSI type %s\n",
ice_vsi_type_str(vsi->type));
return;
}

/* find the appropriate aggregator node */
for (node_offset = 0; node_offset < max_agg_nodes; node_offset++) {
/* see if we can find space in previously created
* node if num_vsis < 64, otherwise skip
*/
if (agg_node_iter->num_vsis &&
agg_node_iter->num_vsis == ICE_MAX_VSIS_IN_AGG_NODE) {
agg_node_iter++;
continue;
}

if (agg_node_iter->valid &&
agg_node_iter->agg_id != ICE_INVALID_AGG_NODE_ID) {
agg_id = agg_node_iter->agg_id;
agg_node = agg_node_iter;
break;
}

/* find unclaimed agg_id */
if (agg_node_iter->agg_id == ICE_INVALID_AGG_NODE_ID) {
agg_id = node_offset + agg_node_id_start;
agg_node = agg_node_iter;
break;
}
/* move to next agg_node */
agg_node_iter++;
}

if (!agg_node)
return;

/* if selected aggregator node was not created, create it */
if (!agg_node->valid) {
status = ice_cfg_agg(port_info, agg_id, ICE_AGG_TYPE_AGG,
(u8)vsi->tc_cfg.ena_tc);
if (status) {
dev_err(dev, "unable to create aggregator node with agg_id %u\n",
agg_id);
return;
}
/* aggregator node is created, store the neeeded info */
agg_node->valid = true;
agg_node->agg_id = agg_id;
}

/* move VSI to corresponding aggregator node */
status = ice_move_vsi_to_agg(port_info, agg_id, vsi->idx,
(u8)vsi->tc_cfg.ena_tc);
if (status) {
dev_err(dev, "unable to move VSI idx %u into aggregator %u node",
vsi->idx, agg_id);
return;
}

/* keep active children count for aggregator node */
agg_node->num_vsis++;

/* cache the 'agg_id' in VSI, so that after reset - VSI will be moved
* to aggregator node
*/
vsi->agg_node = agg_node;
dev_dbg(dev, "successfully moved VSI idx %u tc_bitmap 0x%x) into aggregator node %d which has num_vsis %u\n",
vsi->idx, vsi->tc_cfg.ena_tc, vsi->agg_node->agg_id,
vsi->agg_node->num_vsis);
}

/**
* ice_vsi_setup - Set up a VSI by a given type
* @pf: board private structure
Expand Down Expand Up @@ -2334,6 +2454,8 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
ice_cfg_sw_lldp(vsi, true, true);
}

if (!vsi->agg_node)
ice_set_agg_vsi(vsi);
return vsi;

unroll_clear_rings:
Expand Down Expand Up @@ -2678,6 +2800,9 @@ int ice_vsi_release(struct ice_vsi *vsi)
vsi->netdev = NULL;
}

if (vsi->type == ICE_VSI_VF &&
vsi->agg_node && vsi->agg_node->valid)
vsi->agg_node->num_vsis--;
ice_vsi_clear_rings(vsi);

ice_vsi_put_qs(vsi);
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,11 +435,19 @@ static void ice_sync_fltr_subtask(struct ice_pf *pf)
*/
static void ice_pf_dis_all_vsi(struct ice_pf *pf, bool locked)
{
int node;
int v;

ice_for_each_vsi(pf, v)
if (pf->vsi[v])
ice_dis_vsi(pf->vsi[v], locked);

for (node = 0; node < ICE_MAX_PF_AGG_NODES; node++)
pf->pf_agg_node[node].num_vsis = 0;

for (node = 0; node < ICE_MAX_VF_AGG_NODES; node++)
pf->vf_agg_node[node].num_vsis = 0;

}

/**
Expand Down
Loading

0 comments on commit b126bd6

Please sign in to comment.