From nobody Mon Feb 9 16:57:50 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.16]) (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 994BC3115B8; Fri, 17 Oct 2025 06:10:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.16 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760681459; cv=none; b=StXLo8D+X+cTqmmvOq3y5NUW5R8SWAhJLzE4/RCOQBZxahRWfqQ+XxhxgnV7hmkRdoBbYfaZ3USe6EnzNrBdOQDmjknyNqXFPYV0szfZ/Yt0MhO5YBKVK6uvvQtDZMCPYg5keR1bdbJlk1uhmZdcgAbyiyBr/PZcKdosdjPJnKw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760681459; c=relaxed/simple; bh=Vb26T4wuCx0RJ+b8eWNBVw7n18jw2O+S0FURsNBBnOg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IOCDMm5nL4aqrCC9NT411Q9eBCXhtFzQH7Ed+7Vdlp4pwXCAGWoycO7XzunS1dqFB7zKXC8+kU9BPihnDp8iCPdzb+eebIGd6V3XXg6hWpk/o8R8PcpM7axwbGaEzdOm0DDqDygRHoi/RdyOozuPwvSsnP/06uiQ3sNCeRRoLwg= 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=i6ZMgfVQ; arc=none smtp.client-ip=192.198.163.16 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="i6ZMgfVQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1760681456; x=1792217456; h=from:date:subject:mime-version:content-transfer-encoding: message-id:references:in-reply-to:to:cc; bh=Vb26T4wuCx0RJ+b8eWNBVw7n18jw2O+S0FURsNBBnOg=; b=i6ZMgfVQHbTRt//7hVCneXjNxmQVOF2D6pGS1TV7UCBFVdjXHvfDt5j4 x5cHvYjqwMGiUs5DeS8QFof6PpV1GGE4JibeqFa4Hhya8oVepmOIn3W0+ DXRSAO2mZXKUQ8N8pkHmfZEAm2CqOviiWoMJhJPrQH0ZgMNjnYhBWnm7k hcY0L2nubpK8E9bZgJW3Hob2xODNyIx2Ucs9t/XiCwOw9Ze2R9ey17X01 GmwqVTfktK+4PaFwhqwfPu6cukn5YfFfAHi/8okQYG2iPVy6WwRoAMc+b S8EG73QXl2mYauebbxhKrzkfepDzKKoNv1LT3O2HSODZZvfdLE5WKGk7d w==; X-CSE-ConnectionGUID: eOm9CrcZQ0i8qEe5Z5hFhQ== X-CSE-MsgGUID: eZ3mDEZwRKGwIhuR5IURmg== X-IronPort-AV: E=McAfee;i="6800,10657,11584"; a="50453953" X-IronPort-AV: E=Sophos;i="6.19,234,1754982000"; d="scan'208";a="50453953" Received: from fmviesa008.fm.intel.com ([10.60.135.148]) by fmvoesa110.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Oct 2025 23:10:53 -0700 X-CSE-ConnectionGUID: F7Q/GiWqSSy4dxdoGTtr5g== X-CSE-MsgGUID: JwOoqSwJRcyZllMWW4bd9w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.19,234,1754982000"; d="scan'208";a="183059487" Received: from orcnseosdtjek.jf.intel.com (HELO [10.166.28.70]) ([10.166.28.70]) by fmviesa008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Oct 2025 23:10:52 -0700 From: Jacob Keller Date: Thu, 16 Oct 2025 23:08:34 -0700 Subject: [PATCH net-next v2 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: <20251016-jk-iwl-next-2025-10-15-v2-5-ff3a390d9fc6@intel.com> References: <20251016-jk-iwl-next-2025-10-15-v2-0-ff3a390d9fc6@intel.com> In-Reply-To: <20251016-jk-iwl-next-2025-10-15-v2-0-ff3a390d9fc6@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-f4b34 X-Developer-Signature: v=1; a=openpgp-sha256; l=7264; i=jacob.e.keller@intel.com; h=from:subject:message-id; bh=kaRQti9fcXHcdZTxDIahk0M7iew4tDgcVjF/jRss1o8=; b=owGbwMvMwCWWNS3WLp9f4wXjabUkhoyPd5+zvV3j3vbQJH/7kXpftW8MlbycN91lXrC47fif6 aOv3GrVUcrCIMbFICumyKLgELLyuvGEMK03znIwc1iZQIYwcHEKwEQ6pBj+x7z9Lz1f4OrSC3tb On5t+SbPYmWqdHfRw0UVYT5rtsXHyjH8lc+P3Hyt5brB5fRZJ3LYBd7FBX/1cc5hfKr28WdXyHR 7ZgA= 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 | 93 ++++++++++++++++++++++= ---- 2 files changed, 80 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..f21b9f86a049 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,34 @@ 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 + * + * Return: True if PTG and attribute is in use, false otherwise. + */ +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 +3733,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 +3761,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 +3779,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 +3789,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 +3886,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 +4208,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 +4216,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