The scheduler code saves information about the aggregator nodes in a linked list in the hw->agg_list structure. This choice of data structure is not ideal. Indeed, several places in the code iterate the list searching to see if a given ID is present.
Convert the linked list into an xarray. Where possible, simplify aggregator info lookup to use xa_load instead of iterating over all the entries. Switching to xarray data structure better matches the existing usage pattern. In addition, it prepares the code to allow removal of the ice_agg_node wrapping structure used by ice_vsi, which will be completed in following changes. Signed-off-by: Jacob Keller <[email protected]> Reviewed-by: Aleksandr Loktionov <[email protected]> --- drivers/net/ethernet/intel/ice/ice_sched.h | 1 - drivers/net/ethernet/intel/ice/ice_type.h | 2 +- drivers/net/ethernet/intel/ice/ice_common.c | 4 +- drivers/net/ethernet/intel/ice/ice_sched.c | 58 ++++++++++++----------------- 4 files changed, 27 insertions(+), 38 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_sched.h b/drivers/net/ethernet/intel/ice/ice_sched.h index 7b668083be07..f2a619fcab8b 100644 --- a/drivers/net/ethernet/intel/ice/ice_sched.h +++ b/drivers/net/ethernet/intel/ice/ice_sched.h @@ -67,7 +67,6 @@ struct ice_sched_agg_vsi_info { struct ice_sched_agg_info { struct list_head agg_vsi_list; - struct list_head list_entry; DECLARE_BITMAP(tc_bitmap, ICE_MAX_TRAFFIC_CLASS); u32 agg_id; enum ice_agg_type agg_type; diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h index b39be74b1d55..ab297b66ee16 100644 --- a/drivers/net/ethernet/intel/ice/ice_type.h +++ b/drivers/net/ethernet/intel/ice/ice_type.h @@ -948,7 +948,7 @@ struct ice_hw { u8 max_cgds; u8 sw_entry_point_layer; u16 max_children[ICE_AQC_TOPO_MAX_LEVEL_NUM]; - struct list_head agg_list; /* lists all aggregator */ + struct xarray agg_list; /* array of aggregator nodes */ struct ice_vsi_ctx *vsi_ctx[ICE_MAX_VSI]; u8 evb_veb; /* true for VEB, false for VEPA */ diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 3c36f8a28a64..f6fa0a50e08f 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -1052,6 +1052,7 @@ int ice_init_hw(struct ice_hw *hw) hw->evb_veb = true; xa_init_flags(&hw->port_info->sched_node_ids, XA_FLAGS_ALLOC); + xa_init_flags(&hw->agg_list, XA_FLAGS_ALLOC); /* Query the allocated resources for Tx scheduler */ status = ice_sched_query_res_alloc(hw); @@ -1091,7 +1092,6 @@ int ice_init_hw(struct ice_hw *hw) status = -EIO; goto err_unroll_sched; } - INIT_LIST_HEAD(&hw->agg_list); /* Initialize max burst size */ if (!hw->max_burst_size) ice_cfg_rl_burst_size(hw, ICE_SCHED_DFLT_BURST_SIZE); @@ -1147,6 +1147,7 @@ int ice_init_hw(struct ice_hw *hw) ice_sched_cleanup_all(hw); err_unroll_xarray: xa_destroy(&hw->port_info->sched_node_ids); + xa_destroy(&hw->agg_list); err_unroll_alloc: devm_kfree(ice_hw_to_dev(hw), hw->port_info); err_unroll_cqinit: @@ -1189,6 +1190,7 @@ void ice_deinit_hw(struct ice_hw *hw) ice_clear_all_vsi_ctx(hw); xa_destroy(&hw->port_info->sched_node_ids); + xa_destroy(&hw->agg_list); } /** diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c index 8b005e4603eb..a74f840cba23 100644 --- a/drivers/net/ethernet/intel/ice/ice_sched.c +++ b/drivers/net/ethernet/intel/ice/ice_sched.c @@ -813,9 +813,9 @@ static void ice_sched_clear_rl_prof(struct ice_port_info *pi) void ice_sched_clear_agg(struct ice_hw *hw) { struct ice_sched_agg_info *agg_info; - struct ice_sched_agg_info *atmp; + unsigned long index; - list_for_each_entry_safe(agg_info, atmp, &hw->agg_list, list_entry) { + xa_for_each(&hw->agg_list, index, agg_info) { struct ice_sched_agg_vsi_info *agg_vsi_info; struct ice_sched_agg_vsi_info *vtmp; @@ -824,7 +824,7 @@ void ice_sched_clear_agg(struct ice_hw *hw) list_del(&agg_vsi_info->list_entry); devm_kfree(ice_hw_to_dev(hw), agg_vsi_info); } - list_del(&agg_info->list_entry); + xa_erase(&hw->agg_list, index); devm_kfree(ice_hw_to_dev(hw), agg_info); } } @@ -2060,10 +2060,9 @@ ice_sched_cfg_vsi(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 maxqs, static void ice_sched_rm_agg_vsi_info(struct ice_port_info *pi, u16 vsi_handle) { struct ice_sched_agg_info *agg_info; - struct ice_sched_agg_info *atmp; + unsigned long index; - list_for_each_entry_safe(agg_info, atmp, &pi->hw->agg_list, - list_entry) { + xa_for_each(&pi->hw->agg_list, index, agg_info) { struct ice_sched_agg_vsi_info *agg_vsi_info; struct ice_sched_agg_vsi_info *vtmp; @@ -2226,26 +2225,6 @@ int ice_rm_vsi_rdma_cfg(struct ice_port_info *pi, u16 vsi_handle) return ice_sched_rm_vsi_cfg(pi, vsi_handle, ICE_SCHED_NODE_OWNER_RDMA); } -/** - * ice_get_agg_info - get the aggregator ID - * @hw: pointer to the hardware structure - * @agg_id: aggregator ID - * - * This function validates aggregator ID. The function returns info if - * aggregator ID is present in list otherwise it returns null. - */ -static struct ice_sched_agg_info * -ice_get_agg_info(struct ice_hw *hw, u32 agg_id) -{ - struct ice_sched_agg_info *agg_info; - - list_for_each_entry(agg_info, &hw->agg_list, list_entry) - if (agg_info->agg_id == agg_id) - return agg_info; - - return NULL; -} - /** * ice_sched_get_free_vsi_parent - Find a free parent node in aggregator subtree * @hw: pointer to the HW struct @@ -2619,7 +2598,7 @@ ice_save_agg_tc_bitmap(struct ice_port_info *pi, u32 agg_id, { struct ice_sched_agg_info *agg_info; - agg_info = ice_get_agg_info(pi->hw, agg_id); + agg_info = xa_load(&pi->hw->agg_list, agg_id); if (!agg_info) return -EINVAL; bitmap_copy(agg_info->replay_tc_bitmap, tc_bitmap, @@ -2735,7 +2714,7 @@ ice_sched_cfg_agg(struct ice_port_info *pi, u32 agg_id, int status = 0; u8 tc; - agg_info = ice_get_agg_info(hw, agg_id); + agg_info = xa_load(&hw->agg_list, agg_id); if (!agg_info) { /* Create new entry for new aggregator ID */ agg_info = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*agg_info), @@ -2750,8 +2729,13 @@ ice_sched_cfg_agg(struct ice_port_info *pi, u32 agg_id, /* Initialize the aggregator VSI list head */ INIT_LIST_HEAD(&agg_info->agg_vsi_list); - /* Add new entry in aggregator list */ - list_add(&agg_info->list_entry, &hw->agg_list); + /* Add new entry in aggregator array */ + status = xa_insert(&hw->agg_list, agg_id, agg_info, + GFP_KERNEL); + if (status) { + devm_kfree(ice_hw_to_dev(hw), agg_info); + return status; + } } /* Create aggregator node(s) for requested TC(s) */ ice_for_each_traffic_class(tc) { @@ -2836,8 +2820,9 @@ static struct ice_sched_agg_info * ice_get_vsi_agg_info(struct ice_hw *hw, u16 vsi_handle) { struct ice_sched_agg_info *agg_info; + unsigned long index; - list_for_each_entry(agg_info, &hw->agg_list, list_entry) { + xa_for_each(&hw->agg_list, index, agg_info) { struct ice_sched_agg_vsi_info *agg_vsi_info; agg_vsi_info = ice_get_agg_vsi_info(agg_info, vsi_handle); @@ -2864,7 +2849,7 @@ ice_save_agg_vsi_tc_bitmap(struct ice_port_info *pi, u32 agg_id, u16 vsi_handle, struct ice_sched_agg_vsi_info *agg_vsi_info; struct ice_sched_agg_info *agg_info; - agg_info = ice_get_agg_info(pi->hw, agg_id); + agg_info = xa_load(&pi->hw->agg_list, agg_id); if (!agg_info) return -EINVAL; /* check if entry already exist */ @@ -2899,7 +2884,7 @@ ice_sched_assoc_vsi_to_agg(struct ice_port_info *pi, u32 agg_id, if (!ice_is_vsi_valid(pi->hw, vsi_handle)) return -EINVAL; - agg_info = ice_get_agg_info(hw, agg_id); + agg_info = xa_load(&hw->agg_list, agg_id); if (!agg_info) return -EINVAL; /* If the VSI is already part of another aggregator then update @@ -4313,9 +4298,10 @@ void ice_sched_replay_agg(struct ice_hw *hw) { struct ice_port_info *pi = hw->port_info; struct ice_sched_agg_info *agg_info; + unsigned long index; mutex_lock(&pi->sched_lock); - list_for_each_entry(agg_info, &hw->agg_list, list_entry) + xa_for_each(&hw->agg_list, index, agg_info) { /* replay aggregator (re-create aggregator node) */ if (!bitmap_equal(agg_info->tc_bitmap, agg_info->replay_tc_bitmap, ICE_MAX_TRAFFIC_CLASS)) { @@ -4338,6 +4324,7 @@ void ice_sched_replay_agg(struct ice_hw *hw) continue; } } + } mutex_unlock(&pi->sched_lock); } @@ -4352,9 +4339,10 @@ void ice_sched_replay_agg_vsi_preinit(struct ice_hw *hw) { struct ice_port_info *pi = hw->port_info; struct ice_sched_agg_info *agg_info; + unsigned long index; mutex_lock(&pi->sched_lock); - list_for_each_entry(agg_info, &hw->agg_list, list_entry) { + xa_for_each(&hw->agg_list, index, agg_info) { struct ice_sched_agg_vsi_info *agg_vsi_info; agg_info->tc_bitmap[0] = 0; -- 2.54.0.1064.gd145956f57df
