From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (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 6E2862BDC32; Mon, 23 Mar 2026 03:51:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774237920; cv=none; b=Rad2pLsIV68YcKZ8N/F5YbeIQIS8gvm5IkFmlQfDRfwTiFUgyWQIgB0kc6kh32KSMEQQZyAOMObN0XJAuw2AmS1COugy6YMKpc2aMbTzGQVgSeOoqHgs8gGvABKVaClaeVZnx/XQQyx2ONS2vQeYamzM5tRRED6A5Q17hwWphXc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774237920; c=relaxed/simple; bh=23GPt3rsLvgGZ1TK1h3/5uiA/gRvNChzvg7GYy00Tu0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZvzwHLcSMxVEeHSw8wwbNMkBeqp9Sd5QEND9PsUuJLa3ECEgonVSJ0AABk63DwfH7SjwT21j1xyRCLst5j0ApMMp1nKkQNJg3BYJQ2ZHA3H0rHdFOGiU/6sGZYzwI5w38ZlVFphfzZ+7nkpwuetNGpc1IvSnN1QQW0iEArbdFYA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=RUmS0Kqd; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="RUmS0Kqd" Received: from pps.filterd (m0431384.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 62MMgmCD942074; Sun, 22 Mar 2026 20:51:38 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pfpt0220; bh=O U7BkKVn5NBU8Yza9LLBmGfMoGWn2yewhah+XYzIVtw=; b=RUmS0KqdrZA+LoGMN r9ljQG/5JSTbPJLIajCccB54pGLqXTbnikf0fFtRaSny9VaFCUHOHgJj9qd4GLvb APmiRdM1KoRzW9DRWPcEzpXX7gaDja6EcLhqB5tDQId7F4SW0wTDwVqhDDhn9mpR 6fYbXU18VHmb1ux7OY8XPK1ecO0C2pHfwtjVZNexI2n5a61jpbeCC4/e7CAZPS3N 1kNoAN5MzFTjEyUZuMYl+kEhelKswNsOK1PcB/qsaGeFcF5R2SWwwlxerznkHHSR HQc+Di9BtIea97rGJ6hG/z1cmo9zSjGhV69/N3RGUH82gp7M6MSfFifqqJjogQMR Wh7IQ== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 4d2fk710js-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 22 Mar 2026 20:51:37 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.25; Sun, 22 Mar 2026 20:51:37 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.25 via Frontend Transport; Sun, 22 Mar 2026 20:51:36 -0700 Received: from rkannoth-OptiPlex-7090.. (unknown [10.28.36.165]) by maili.marvell.com (Postfix) with ESMTP id 939963F70A2; Sun, 22 Mar 2026 20:51:30 -0700 (PDT) From: Ratheesh Kannoth To: , CC: , , , , , , , , , , , , , , Ratheesh Kannoth Subject: [PATCH v7 net-next 3/5] octeontx2-af: npc: cn20k: add subbank search order control Date: Mon, 23 Mar 2026 09:21:08 +0530 Message-ID: <20260323035110.3908741-4-rkannoth@marvell.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260323035110.3908741-1-rkannoth@marvell.com> References: <20260323035110.3908741-1-rkannoth@marvell.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Authority-Analysis: v=2.4 cv=caPfb3DM c=1 sm=1 tr=0 ts=69c0b8ca cx=c_pps a=gIfcoYsirJbf48DBMSPrZA==:117 a=gIfcoYsirJbf48DBMSPrZA==:17 a=Yq5XynenixoA:10 a=VkNPw1HP01LnGYTKEx00:22 a=l0iWHRpgs5sLHlkKQ1IR:22 a=TtqV-g6YmW1Jfm2GSLaY:22 a=M5GUcnROAAAA:8 a=-COZLs7YStbzE7aUQ_YA:9 a=OBjm3rFKGHvpk9ecZwUJ:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzIzMDAyNSBTYWx0ZWRfXwtO1hwOC/k2M 2CivRbpAP/mK/g20NQbNviBhmC/nTrPfX/3AyH1Z92DObVy7rGbup8DiYsSaDdiQID03ZhJ/3P1 wlzuHZjje8rux6SwqzeUbqtCKRsoH2ES30TYcfOylIeMkJqr8Jr8fdlmi8wKYUHzdUh8oQ0OfMv NXSucv5BcSWGHP2W2wMzPPbQ/W3/AkRlOQ2TE0n8NWChIQCUINlLwsVlHYP/BIZIgipJbi0l/Ow 6mdU8QATcnhxmvqUnE7hGQWoyJcXo2l4+x9Y+lZoetNN5m4Ogt7qgRUllhq/mEJpeJaMxgtgRVY 0j1OxYo2qzqNmoZOs/yjS6pCsqDHcIsZFTivx1ZsE+Aq9r65rhdsj6LiThRkVAtbT7xhGIVi6IB fGNSuJHf+468+kbK2nzk6bXTJmHqK4kjVykEm8dk45IqEII1TZ1+PBqxwa2ocgfqGSmVkCkZCzx YAJmPh/KFn/XHPzJ7Mg== X-Proofpoint-GUID: npZ3lD1ZHPrY9ddZC4EiMGd1EcpMb0oL X-Proofpoint-ORIG-GUID: npZ3lD1ZHPrY9ddZC4EiMGd1EcpMb0oL X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-03-23_01,2026-03-20_02,2025-10-01_01 CN20K NPC MCAM is split into 32 subbanks that are searched in a predefined order during allocation. Lower-numbered subbanks have higher priority than higher-numbered ones. Add a runtime devlink parameter "srch_order" ( DEVLINK_PARAM_TYPE_U32_ARRAY) to control the order in which subbanks are searched during MCAM allocation. Signed-off-by: Ratheesh Kannoth --- .../ethernet/marvell/octeontx2/af/cn20k/npc.c | 91 +++++++++++++++++- .../ethernet/marvell/octeontx2/af/cn20k/npc.h | 2 + .../marvell/octeontx2/af/rvu_devlink.c | 92 +++++++++++++++++-- 3 files changed, 173 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c index e854b85ced9e..153765b3e504 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.c @@ -3317,7 +3317,7 @@ rvu_mbox_handler_npc_cn20k_get_kex_cfg(struct rvu *rvu, return 0; } -static int *subbank_srch_order; +static u32 *subbank_srch_order; static void npc_populate_restricted_idxs(int num_subbanks) { @@ -3329,7 +3329,7 @@ static int npc_create_srch_order(int cnt) { int val = 0; - subbank_srch_order = kcalloc(cnt, sizeof(int), + subbank_srch_order = kcalloc(cnt, sizeof(u32), GFP_KERNEL); if (!subbank_srch_order) return -ENOMEM; @@ -3809,6 +3809,93 @@ static void npc_unlock_all_subbank(void) mutex_unlock(&npc_priv.sb[i].lock); } +int npc_cn20k_search_order_set(struct rvu *rvu, + u64 arr[MAX_NUM_SUB_BANKS], int cnt) +{ + struct npc_mcam *mcam = &rvu->hw->mcam; + u32 fslots[MAX_NUM_SUB_BANKS][2]; + u32 uslots[MAX_NUM_SUB_BANKS][2]; + int fcnt = 0, ucnt = 0; + struct npc_subbank *sb; + int idx, val, rc = 0; + + unsigned long index; + void *v; + + if (cnt != npc_priv.num_subbanks) { + dev_err(rvu->dev, "Number of entries(%u) != %u\n", + cnt, npc_priv.num_subbanks); + return -EINVAL; + } + + mutex_lock(&mcam->lock); + npc_lock_all_subbank(); + restrict_valid = false; + + for (int i = 0; i < cnt; i++) + subbank_srch_order[i] = (u32)arr[i]; + + xa_for_each(&npc_priv.xa_sb_used, index, v) { + val = xa_to_value(v); + uslots[ucnt][0] = index; + uslots[ucnt][1] = val; + xa_erase(&npc_priv.xa_sb_used, index); + ucnt++; + } + + xa_for_each(&npc_priv.xa_sb_free, index, v) { + val = xa_to_value(v); + fslots[fcnt][0] = index; + fslots[fcnt][1] = val; + xa_erase(&npc_priv.xa_sb_free, index); + fcnt++; + } + + /* xa_store() is done under lock. If xa_store fails + * ,no rollback is planned as it might also fail. + */ + for (int i = 0; i < ucnt; i++) { + idx = uslots[i][1]; + sb = &npc_priv.sb[idx]; + sb->arr_idx = subbank_srch_order[sb->idx]; + rc = xa_err(xa_store(&npc_priv.xa_sb_used, sb->arr_idx, + xa_mk_value(sb->idx), GFP_KERNEL)); + if (rc) { + dev_err(rvu->dev, + "Error to insert index to used list %u\n", + sb->idx); + goto fail_used; + } + } + + for (int i = 0; i < fcnt; i++) { + idx = fslots[i][1]; + sb = &npc_priv.sb[idx]; + sb->arr_idx = subbank_srch_order[sb->idx]; + rc = xa_err(xa_store(&npc_priv.xa_sb_free, sb->arr_idx, + xa_mk_value(sb->idx), GFP_KERNEL)); + if (rc) { + dev_err(rvu->dev, + "Error to insert index to free list %u\n", + sb->idx); + goto fail_used; + } + } + +fail_used: + npc_unlock_all_subbank(); + mutex_unlock(&mcam->lock); + + return rc; +} + +const u32 *npc_cn20k_search_order_get(bool *restricted_order, u32 *sz) +{ + *restricted_order = restrict_valid; + *sz = npc_priv.num_subbanks; + return subbank_srch_order; +} + /* Only non-ref non-contigous mcam indexes * are picked for defrag process */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h index 004a556c7b90..6f9f796940f3 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/cn20k/npc.h @@ -343,5 +343,7 @@ int npc_cn20k_defrag(struct rvu *rvu); int npc_mcam_idx_2_subbank_idx(struct rvu *rvu, u16 mcam_idx, struct npc_subbank **sb, int *sb_off); +const u32 *npc_cn20k_search_order_get(bool *restricted_order, u32 *sz); +int npc_cn20k_search_order_set(struct rvu *rvu, u64 arr[32], int cnt); #endif /* NPC_CN20K_H */ diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c index 6494a9ee2f0d..0e8e33c836c9 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c @@ -1258,6 +1258,7 @@ enum rvu_af_dl_param_id { RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE, RVU_AF_DEVLINK_PARAM_ID_NPC_DEF_RULE_CNTR_ENABLE, RVU_AF_DEVLINK_PARAM_ID_NPC_DEFRAG, + RVU_AF_DEVLINK_PARAM_ID_NPC_SRCH_ORDER, RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF, }; @@ -1619,12 +1620,83 @@ static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, return 0; } +static int rvu_af_dl_npc_srch_order_set(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +{ + struct rvu_devlink *rvu_dl = devlink_priv(devlink); + struct rvu *rvu = rvu_dl->rvu; + + return npc_cn20k_search_order_set(rvu, + ctx->val.u64arr.val, + ctx->val.u64arr.size); +} + +static int rvu_af_dl_npc_srch_order_get(struct devlink *devlink, u32 id, + struct devlink_param_gset_ctx *ctx, + struct netlink_ext_ack *extack) +{ + bool restricted_order; + const u32 *order; + u32 sz; + + order = npc_cn20k_search_order_get(&restricted_order, &sz); + ctx->val.u64arr.size = sz; + for (int i = 0; i < sz; i++) + ctx->val.u64arr.val[i] = order[i]; + + return 0; +} + +static int rvu_af_dl_npc_srch_order_validate(struct devlink *devlink, u32 id, + union devlink_param_value val, + struct netlink_ext_ack *extack) +{ + struct rvu_devlink *rvu_dl = devlink_priv(devlink); + struct rvu *rvu = rvu_dl->rvu; + bool restricted_order; + unsigned long w = 0; + u64 *arr; + u32 sz; + + npc_cn20k_search_order_get(&restricted_order, &sz); + if (sz != val.u64arr.size) { + dev_err(rvu->dev, + "Wrong size %llu, should be %u\n", + val.u64arr.size, sz); + return -EINVAL; + } + + arr = val.u64arr.val; + for (int i = 0; i < sz; i++) { + if (arr[i] >= sz) + return -EINVAL; + + w |= BIT_ULL(arr[i]); + } + + if (bitmap_weight(&w, sz) != sz) { + dev_err(rvu->dev, + "Duplicate or out-of-range subbank index. %lu\n", + find_first_zero_bit(&w, sz)); + return -EINVAL; + } + + return 0; +} + static const struct devlink_ops rvu_devlink_ops = { .eswitch_mode_get = rvu_devlink_eswitch_mode_get, .eswitch_mode_set = rvu_devlink_eswitch_mode_set, }; -static const struct devlink_param rvu_af_dl_param_defrag[] = { +static const struct devlink_param rvu_af_dl_cn20k_params[] = { + DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_SRCH_ORDER, + "npc_srch_order", DEVLINK_PARAM_TYPE_U64_ARRAY, + BIT(DEVLINK_PARAM_CMODE_RUNTIME), + rvu_af_dl_npc_srch_order_get, + rvu_af_dl_npc_srch_order_set, + rvu_af_dl_npc_srch_order_validate), DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_DEFRAG, "npc_defrag", DEVLINK_PARAM_TYPE_STRING, BIT(DEVLINK_PARAM_CMODE_RUNTIME), @@ -1666,13 +1738,13 @@ int rvu_register_dl(struct rvu *rvu) } if (is_cn20k(rvu->pdev)) { - err = devlink_params_register(dl, rvu_af_dl_param_defrag, - ARRAY_SIZE(rvu_af_dl_param_defrag)); + err = devlink_params_register(dl, rvu_af_dl_cn20k_params, + ARRAY_SIZE(rvu_af_dl_cn20k_params)); if (err) { dev_err(rvu->dev, - "devlink defrag params register failed with error %d", + "devlink cn20k params register failed with error %d", err); - goto err_dl_defrag; + goto err_dl_cn20k_params; } } @@ -1695,10 +1767,10 @@ int rvu_register_dl(struct rvu *rvu) err_dl_exact_match: if (is_cn20k(rvu->pdev)) - devlink_params_unregister(dl, rvu_af_dl_param_defrag, - ARRAY_SIZE(rvu_af_dl_param_defrag)); + devlink_params_unregister(dl, rvu_af_dl_cn20k_params, + ARRAY_SIZE(rvu_af_dl_cn20k_params)); -err_dl_defrag: +err_dl_cn20k_params: devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params)); err_dl_health: @@ -1717,8 +1789,8 @@ void rvu_unregister_dl(struct rvu *rvu) devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params)); if (is_cn20k(rvu->pdev)) - devlink_params_unregister(dl, rvu_af_dl_param_defrag, - ARRAY_SIZE(rvu_af_dl_param_defrag)); + devlink_params_unregister(dl, rvu_af_dl_cn20k_params, + ARRAY_SIZE(rvu_af_dl_cn20k_params)); /* Unregister exact match devlink only for CN10K-B */ if (rvu_npc_exact_has_match_table(rvu)) -- 2.43.0