From nobody Tue Feb 10 15:30:41 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E42A3112D9; Wed, 15 Oct 2025 19:33:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760556806; cv=none; b=HrH6p1TVsvjZtVqD2taRHy/QqKHJM5Jfpu741L9IT4ZN/1BHKm/e9rXbndS4xlOzEd37uTBVWhdH//fA92ChbuDt1gz8aIAmKidAikYy+7X3kHYuMgt2hn2+h0QexrVZQuzazpkb7iLjI/FE7RcDCnqrFrkSX8tjSReZj8sCRq8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760556806; c=relaxed/simple; bh=VkEW/b94qsJPRgbIyueNOXpcoYsgPly1CazSFtbBMjE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uLVRSPxKgXwJc6AyqjFQIALRx7zbFAhb6D+KPb2sLnkSInTTi8B4PuaBBHqfJQABgPCMI0W4/T4OAWCD0VZETZoXyF8bDM1LjCBzGmCfO93qqE8nBnKlERaGDo8TCAKSkWVWkfwyAKfDKcizbHJKdZx8J2cKa4qPsJCI+Z977Es= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=M/lRm2wW; arc=none smtp.client-ip=192.198.163.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="M/lRm2wW" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1760556804; x=1792092804; h=from:date:subject:mime-version:content-transfer-encoding: message-id:references:in-reply-to:to:cc; bh=VkEW/b94qsJPRgbIyueNOXpcoYsgPly1CazSFtbBMjE=; b=M/lRm2wWzdJ+3mh68LCWwT1DoqrNm/cmnd+mSAq/talSmDKBxK8IPzw1 W8eR2tHHHF/lRr5ByV3B5uGS81Z5vSS6KvZPQdTl6ZdBhGwk/Jtqg6YbX S4BOPNkhPloN/ubCBliENSlSdHHvwGG++hgqSTgsZ+V1Bvq4Ij5fSW8Hq 2Iu5DHCV2alB24oXZyoCVGeitAhOawqtHRBjpGzEKMMJSfnO6V0efYfY8 nSHsmWzrmkzVGLi72v48VWmDf7tiz4XYVHxgz992hCJ5ffqjonJuH8Fq5 d9GFVn5PydmN0pyboI3g/lcFFzkYd5ev1jJxO4rfYxwG9pjMlmB2YKrsM Q==; X-CSE-ConnectionGUID: K3rqcqPSR7OVJMDFo7Zk1A== X-CSE-MsgGUID: C08YrlicTuSVKKnWWCTqJA== X-IronPort-AV: E=McAfee;i="6800,10657,11583"; a="74083503" X-IronPort-AV: E=Sophos;i="6.19,232,1754982000"; d="scan'208";a="74083503" Received: from orviesa007.jf.intel.com ([10.64.159.147]) by fmvoesa104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Oct 2025 12:33:14 -0700 X-CSE-ConnectionGUID: SDo0dXZ7RkW1kCwPTO3low== X-CSE-MsgGUID: 0wxrywheT4m7RPplXTOzWA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,232,1754982000"; d="scan'208";a="182044882" Received: from orcnseosdtjek.jf.intel.com (HELO [10.166.28.70]) ([10.166.28.70]) by orviesa007-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Oct 2025 12:33:14 -0700 From: Jacob Keller Date: Wed, 15 Oct 2025 12:32:01 -0700 Subject: [PATCH net-next 05/14] ice: improve TCAM priority handling for RSS profiles Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251015-jk-iwl-next-2025-10-15-v1-5-79c70b9ddab8@intel.com> References: <20251015-jk-iwl-next-2025-10-15-v1-0-79c70b9ddab8@intel.com> In-Reply-To: <20251015-jk-iwl-next-2025-10-15-v1-0-79c70b9ddab8@intel.com> To: Jiri Pirko , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Jonathan Corbet , Tony Nguyen , Przemek Kitszel , Andrew Lunn , Alexander Lobakin Cc: netdev@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Jacob Keller , Aleksandr Loktionov , Dan Nowlin , Rafal Romanowski X-Mailer: b4 0.15-dev-96507 X-Developer-Signature: v=1; a=openpgp-sha256; l=7192; i=jacob.e.keller@intel.com; h=from:subject:message-id; bh=smGgpvfX+gSDBMANc31Roi2reIHrxuqN9JAOIexBwC4=; b=owGbwMvMwCWWNS3WLp9f4wXjabUkhoz33755zU+zljsc33x8ta2Aaun9JU5yns/jTGxUvv42C nBd4Xiwo5SFQYyLQVZMkUXBIWTldeMJYVpvnOVg5rAygQxh4OIUgImoCzH8M1tc9WCb2C9TF1HG qFqJivcfPkb+rzvx8XP21iz1r1ziIowMFz+FiG098aBbf8Y93Q7p99l6m4zy18YcuPn3s8B3k7n J7AA= X-Developer-Key: i=jacob.e.keller@intel.com; a=openpgp; fpr=204054A9D73390562AEC431E6A965D3E6F0F28E8 From: Aleksandr Loktionov 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 Signed-off-by: Dan Nowlin Signed-off-by: Przemek Kitszel Reviewed-by: Simon Horman Signed-off-by: Aleksandr Loktionov Tested-by: Rafal Romanowski Signed-off-by: Jacob Keller --- drivers/net/ethernet/intel/ice/ice_flex_type.h | 1 + drivers/net/ethernet/intel/ice/ice_flex_pipe.c | 91 ++++++++++++++++++++++= ---- 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_flex_type.h b/drivers/net/e= thernet/intel/ice/ice_flex_type.h index 817beca591e0..80c9e7c749c2 100644 --- a/drivers/net/ethernet/intel/ice/ice_flex_type.h +++ b/drivers/net/ethernet/intel/ice/ice_flex_type.h @@ -187,6 +187,7 @@ struct ice_prof_map { }; =20 #define ICE_INVALID_TCAM 0xFFFF +#define ICE_MAX_PTG_ATTRS 1024 =20 struct ice_tcam_inf { u16 tcam_idx; diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c b/drivers/net/e= thernet/intel/ice/ice_flex_pipe.c index 363ae79a3620..fc94e189e52e 100644 --- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c +++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c @@ -3581,6 +3581,20 @@ ice_move_vsi(struct ice_hw *hw, enum ice_block blk, = u16 vsi, u16 vsig, return 0; } =20 +/** + * 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 *flag_word; + + /* flags are lowest u16 */ + flag_word =3D (u16 *)dc_mask; + *flag_word =3D ~mask; +} + /** * ice_rem_chg_tcam_ent - remove a specific TCAM entry from change list * @hw: pointer to the HW struct @@ -3651,6 +3665,9 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_blo= ck blk, bool enable, if (!p) return -ENOMEM; =20 + /* set don't care masks for TCAM flags */ + ice_set_tcam_flags(tcam->attr.mask, dc_msk); + status =3D 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); @@ -3676,6 +3693,32 @@ ice_prof_tcam_ena_dis(struct ice_hw *hw, enum ice_bl= ock blk, bool enable, return status; } =20 +/** + * 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 + */ +static bool +ice_ptg_attr_in_use(struct ice_tcam_inf *ptg_attr, unsigned long *ptgs_use= d, + 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 =3D 0; i < attr_cnt; i++) + if (attr_used[i]->ptg =3D=3D ptg_attr->ptg && + attr_used[i]->attr.flags =3D=3D ptg_attr->attr.flags && + attr_used[i]->attr.mask =3D=3D ptg_attr->attr.mask) + return true; + + return false; +} + /** * ice_adj_prof_priorities - adjust profile based on priorities * @hw: pointer to the HW struct @@ -3688,10 +3731,17 @@ 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 =3D 0; + int status =3D 0; u16 idx; =20 + attr_used =3D devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_PTG_ATTRS, + sizeof(*attr_used), GFP_KERNEL); + if (!attr_used) + return -ENOMEM; + bitmap_zero(ptgs_used, ICE_XLT1_CNT); idx =3D vsig & ICE_VSIG_IDX_M; =20 @@ -3709,11 +3759,15 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice= _block blk, u16 vsig, u16 i; =20 for (i =3D 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 =3D 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) @@ -3723,9 +3777,8 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_b= lock 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) */ @@ -3734,15 +3787,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; } =20 /* 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++] =3D &t->tcam[i]; + else + ice_debug(hw, ICE_DBG_INIT, "Warn: ICE_MAX_PTG_ATTRS exceeded\n"); } } =20 - return 0; +free_attr_used: + devm_kfree(ice_hw_to_dev(hw), attr_used); + return status; } =20 /** @@ -3825,11 +3884,15 @@ ice_add_prof_id_vsig(struct ice_hw *hw, enum ice_bl= ock blk, u16 vsig, u64 hdl, p->vsig =3D vsig; p->tcam_idx =3D t->tcam[i].tcam_idx; =20 + /* set don't care masks for TCAM flags */ + ice_set_tcam_flags(t->tcam[i].attr.mask, dc_msk); + /* write the TCAM entry */ status =3D 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; @@ -4143,9 +4206,6 @@ ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_= block blk, u16 vsi_num; int status; =20 - if (blk !=3D ICE_BLK_FD) - return -EINVAL; - vsi_num =3D ice_get_hw_vsi_num(hw, dest_vsi); status =3D ice_add_prof_id_flow(hw, blk, vsi_num, hdl); if (status) { @@ -4154,6 +4214,9 @@ ice_flow_assoc_fdir_prof(struct ice_hw *hw, enum ice_= block blk, return status; } =20 + if (blk !=3D ICE_BLK_FD) + return 0; + vsi_num =3D ice_get_hw_vsi_num(hw, fdir_vsi); status =3D ice_add_prof_id_flow(hw, blk, vsi_num, hdl); if (status) { --=20 2.51.0.rc1.197.g6d975e95c9d7