mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
ice: improve TCAM priority handling for RSS profiles
Enhance TCAM priority logic to avoid conflicts between RSS profiles with overlapping PTGs and attributes. Track used PTG and attribute combinations. Ensure higher-priority profiles override lower ones. Add helper for setting TCAM flags and masks. Ensure RSS rule consistency and prevent unintended matches. Co-developed-by: Dan Nowlin <dan.nowlin@intel.com> Signed-off-by: Dan Nowlin <dan.nowlin@intel.com> Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
3a6d87e2ea
commit
f89e4e1512
|
|
@ -3577,6 +3577,19 @@ ice_move_vsi(struct ice_hw *hw, enum ice_block blk, u16 vsi, u16 vsig,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_set_tcam_flags - set TCAM flag don't care mask
|
||||
* @mask: mask for flags
|
||||
* @dc_mask: pointer to the don't care mask
|
||||
*/
|
||||
static void ice_set_tcam_flags(u16 mask, u8 dc_mask[ICE_TCAM_KEY_VAL_SZ])
|
||||
{
|
||||
u16 inverted_mask = ~mask;
|
||||
|
||||
/* flags are lowest u16 */
|
||||
put_unaligned_le16(inverted_mask, dc_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_rem_chg_tcam_ent - remove a specific TCAM entry from change list
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
@ -3647,6 +3660,9 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
|
|||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
/* set don't care masks for TCAM flags */
|
||||
ice_set_tcam_flags(tcam->attr.mask, dc_msk);
|
||||
|
||||
status = ice_tcam_write_entry(hw, blk, tcam->tcam_idx, tcam->prof_id,
|
||||
tcam->ptg, vsig, 0, tcam->attr.flags,
|
||||
vl_msk, dc_msk, nm_msk);
|
||||
|
|
@ -3672,6 +3688,34 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_block blk, bool enable,
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_ptg_attr_in_use - determine if PTG and attribute pair is in use
|
||||
* @ptg_attr: pointer to the PTG and attribute pair to check
|
||||
* @ptgs_used: bitmap that denotes which PTGs are in use
|
||||
* @attr_used: array of PTG and attributes pairs already used
|
||||
* @attr_cnt: count of entries in the attr_used array
|
||||
*
|
||||
* Return: true if the PTG and attribute pair is in use, false otherwise.
|
||||
*/
|
||||
static bool
|
||||
ice_ptg_attr_in_use(struct ice_tcam_inf *ptg_attr, unsigned long *ptgs_used,
|
||||
struct ice_tcam_inf *attr_used[], u16 attr_cnt)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
if (!test_bit(ptg_attr->ptg, ptgs_used))
|
||||
return false;
|
||||
|
||||
/* the PTG is used, so now look for correct attributes */
|
||||
for (i = 0; i < attr_cnt; i++)
|
||||
if (attr_used[i]->ptg == ptg_attr->ptg &&
|
||||
attr_used[i]->attr.flags == ptg_attr->attr.flags &&
|
||||
attr_used[i]->attr.mask == ptg_attr->attr.mask)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_adj_prof_priorities - adjust profile based on priorities
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
@ -3684,10 +3728,16 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
|
|||
struct list_head *chg)
|
||||
{
|
||||
DECLARE_BITMAP(ptgs_used, ICE_XLT1_CNT);
|
||||
struct ice_tcam_inf **attr_used;
|
||||
struct ice_vsig_prof *t;
|
||||
int status;
|
||||
u16 attr_used_cnt = 0;
|
||||
int status = 0;
|
||||
u16 idx;
|
||||
|
||||
attr_used = kcalloc(ICE_MAX_PTG_ATTRS, sizeof(*attr_used), GFP_KERNEL);
|
||||
if (!attr_used)
|
||||
return -ENOMEM;
|
||||
|
||||
bitmap_zero(ptgs_used, ICE_XLT1_CNT);
|
||||
idx = vsig & ICE_VSIG_IDX_M;
|
||||
|
||||
|
|
@ -3705,11 +3755,15 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
|
|||
u16 i;
|
||||
|
||||
for (i = 0; i < t->tcam_count; i++) {
|
||||
bool used;
|
||||
|
||||
/* Scan the priorities from newest to oldest.
|
||||
* Make sure that the newest profiles take priority.
|
||||
*/
|
||||
if (test_bit(t->tcam[i].ptg, ptgs_used) &&
|
||||
t->tcam[i].in_use) {
|
||||
used = ice_ptg_attr_in_use(&t->tcam[i], ptgs_used,
|
||||
attr_used, attr_used_cnt);
|
||||
|
||||
if (used && t->tcam[i].in_use) {
|
||||
/* need to mark this PTG as never match, as it
|
||||
* was already in use and therefore duplicate
|
||||
* (and lower priority)
|
||||
|
|
@ -3719,9 +3773,8 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
|
|||
&t->tcam[i],
|
||||
chg);
|
||||
if (status)
|
||||
return status;
|
||||
} else if (!test_bit(t->tcam[i].ptg, ptgs_used) &&
|
||||
!t->tcam[i].in_use) {
|
||||
goto free_attr_used;
|
||||
} else if (!used && !t->tcam[i].in_use) {
|
||||
/* need to enable this PTG, as it in not in use
|
||||
* and not enabled (highest priority)
|
||||
*/
|
||||
|
|
@ -3730,15 +3783,21 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig,
|
|||
&t->tcam[i],
|
||||
chg);
|
||||
if (status)
|
||||
return status;
|
||||
goto free_attr_used;
|
||||
}
|
||||
|
||||
/* keep track of used ptgs */
|
||||
__set_bit(t->tcam[i].ptg, ptgs_used);
|
||||
set_bit(t->tcam[i].ptg, ptgs_used);
|
||||
if (attr_used_cnt < ICE_MAX_PTG_ATTRS)
|
||||
attr_used[attr_used_cnt++] = &t->tcam[i];
|
||||
else
|
||||
ice_debug(hw, ICE_DBG_INIT, "Warn: ICE_MAX_PTG_ATTRS exceeded\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
free_attr_used:
|
||||
kfree(attr_used);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3821,11 +3880,15 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_block blk, u16 vsig, u64 hdl,
|
|||
p->vsig = vsig;
|
||||
p->tcam_idx = t->tcam[i].tcam_idx;
|
||||
|
||||
/* set don't care masks for TCAM flags */
|
||||
ice_set_tcam_flags(t->tcam[i].attr.mask, dc_msk);
|
||||
|
||||
/* write the TCAM entry */
|
||||
status = ice_tcam_write_entry(hw, blk, t->tcam[i].tcam_idx,
|
||||
t->tcam[i].prof_id,
|
||||
t->tcam[i].ptg, vsig, 0, 0,
|
||||
vl_msk, dc_msk, nm_msk);
|
||||
t->tcam[i].ptg, vsig, 0,
|
||||
t->tcam[i].attr.flags, vl_msk,
|
||||
dc_msk, nm_msk);
|
||||
if (status) {
|
||||
devm_kfree(ice_hw_to_dev(hw), p);
|
||||
goto err_ice_add_prof_id_vsig;
|
||||
|
|
@ -4139,9 +4202,6 @@ ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_block blk,
|
|||
u16 vsi_num;
|
||||
int status;
|
||||
|
||||
if (blk != ICE_BLK_FD)
|
||||
return -EINVAL;
|
||||
|
||||
vsi_num = ice_get_hw_vsi_num(hw, dest_vsi);
|
||||
status = ice_add_prof_id_flow(hw, blk, vsi_num, hdl);
|
||||
if (status) {
|
||||
|
|
@ -4150,6 +4210,9 @@ ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_block blk,
|
|||
return status;
|
||||
}
|
||||
|
||||
if (blk != ICE_BLK_FD)
|
||||
return 0;
|
||||
|
||||
vsi_num = ice_get_hw_vsi_num(hw, fdir_vsi);
|
||||
status = ice_add_prof_id_flow(hw, blk, vsi_num, hdl);
|
||||
if (status) {
|
||||
|
|
|
|||
|
|
@ -187,6 +187,7 @@ struct ice_prof_map {
|
|||
};
|
||||
|
||||
#define ICE_INVALID_TCAM 0xFFFF
|
||||
#define ICE_MAX_PTG_ATTRS 1024
|
||||
|
||||
struct ice_tcam_inf {
|
||||
u16 tcam_idx;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user