From nobody Thu Apr 9 17:57:45 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 AB1C828314E; Tue, 3 Mar 2026 18:15:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561750; cv=none; b=ine3I1oixqZTIlO1G7n1VCIgOE7BNyQgND/nAFTf32AqKkOPJRSy0WxKxY8smehfG8TeUhwRXeZChVScRgt4/uA2W93BS7J/uaUPHfDScHZ2Iq5ZDJBaa4fSUH2uS3BOdSw55BYA6x/9iJNi5hBuCAVPO/rKSdtg7lY3bNIu6lM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561750; c=relaxed/simple; bh=8vdI1F6+AEYct1WtP6LjxtoTORydqwvmamGsdLjOBLA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lWJs02j8DHiDdbahb0t6vzg3ULPYKa7gW8da4RqsWgcVNOLQqfM3w3PybO1sl9EzwbB1sFHzpade9SOZuDx1Puns202DfgelWM1qnQxK4PJVmOkSdhhJsImIvWJF419he2mfgT9XXWdhNp/dNQP7RhDY5B6VLFDg1Tly+2JGV9A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q+pB0rAR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="q+pB0rAR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 794FDC19425; Tue, 3 Mar 2026 18:15:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772561750; bh=8vdI1F6+AEYct1WtP6LjxtoTORydqwvmamGsdLjOBLA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q+pB0rARCe+SA7fiV4K2qPDSPoMFq56w3iZ0WsumUWcrntw0m6WUoGeHSkEw6TWAp cilZKRqC8fjMZBM7SqHRETKmMwvLONWBn8RsqiDZWmCVmAgEmEw2jdSHZcjCU58uGI 6EMuBMMF6ljsRst0rAuKuhhxaFVkmzmDRtP6UUzKXKKl7vmVF8XyxXOFVmRSh9fhce TRd+ks0E0lJUgfTj9V9dgg8aN926FShFnjz4kn1FvYfkarbkKTINvdDZrPx72zr/Xt /1hHATTYvdyk9n6yX9bc3uZqJ9syoc9QCjk70seK1jubdPYhIHdIWJPtDYt14ACfht pGHAz76hcPtvQ== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Michael Chan , Pavan Chebbi , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Willem de Bruijn Subject: [PATCH net-next 1/5] ethtool: Add RSS indirection table resize helpers Date: Tue, 3 Mar 2026 19:15:29 +0100 Message-ID: <20260303181535.2671734-2-bjorn@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260303181535.2671734-1-bjorn@kernel.org> References: <20260303181535.2671734-1-bjorn@kernel.org> 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 The core locks ctx->indir_size when an RSS context is created. Some NICs (e.g. bnxt) change their indirection table size based on the channel count, because the hardware table is a shared resource. This forces drivers to reject channel changes when RSS contexts exist. Add helpers to resize indirection tables: ethtool_rxfh_indir_can_resize() checks whether a table can be resized without modifying it. ethtool_rxfh_indir_resize() resizes a raw u32 table in place. Folding (shrink) requires the table to be periodic at the new size; non-periodic tables are rejected. Unfolding (grow) replicates the existing pattern. Sizes must be multiples of each other. ethtool_rxfh_contexts_resize_all() resizes all non-default RSS contexts. Validates every context before modifying any, so either all succeed or none are changed. Sends ETHTOOL_MSG_RSS_NTF per resized context after releasing rss_lock. No reallocation is needed because ethtool_rxfh_ctx_alloc() reserves space for rxfh_indir_space entries, and key_off is based on that maximum. Signed-off-by: Bj=C3=B6rn T=C3=B6pel --- include/linux/ethtool.h | 3 + net/ethtool/common.c | 126 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 798abec67a1b..add7d16ca398 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -214,6 +214,9 @@ static inline u8 *ethtool_rxfh_context_key(struct ethto= ol_rxfh_context *ctx) } =20 void ethtool_rxfh_context_lost(struct net_device *dev, u32 context_id); +int ethtool_rxfh_indir_can_resize(const u32 *tbl, u32 old_size, u32 new_si= ze); +int ethtool_rxfh_indir_resize(u32 *tbl, u32 old_size, u32 new_size); +int ethtool_rxfh_contexts_resize_all(struct net_device *dev, u32 new_indir= _size); =20 struct link_mode_info { int speed; diff --git a/net/ethtool/common.c b/net/ethtool/common.c index e252cf20c22f..8df84ff9efa4 100644 --- a/net/ethtool/common.c +++ b/net/ethtool/common.c @@ -1204,6 +1204,132 @@ void ethtool_rxfh_context_lost(struct net_device *d= ev, u32 context_id) } EXPORT_SYMBOL(ethtool_rxfh_context_lost); =20 +static bool ethtool_rxfh_indir_is_periodic(const u32 *tbl, u32 old_size, u= 32 new_size) +{ + u32 i; + + for (i =3D new_size; i < old_size; i++) + if (tbl[i] !=3D tbl[i % new_size]) + return false; + return true; +} + +/** + * ethtool_rxfh_indir_can_resize - Check if an indirection table can be re= sized + * @tbl: indirection table + * @old_size: current number of entries in the table + * @new_size: desired number of entries + * + * Validate that @tbl can be resized from @old_size to @new_size without + * data loss. Read-only; does not modify the table. + * + * Return: 0 if resize is possible, -%EINVAL otherwise. + */ +int ethtool_rxfh_indir_can_resize(const u32 *tbl, u32 old_size, u32 new_si= ze) +{ + if (old_size =3D=3D 0 || new_size =3D=3D 0) + return -EINVAL; + if (new_size =3D=3D old_size) + return 0; + + if (new_size < old_size) { + if (old_size % new_size !=3D 0) + return -EINVAL; + if (!ethtool_rxfh_indir_is_periodic(tbl, old_size, new_size)) + return -EINVAL; + return 0; + } + + if (new_size % old_size !=3D 0) + return -EINVAL; + return 0; +} +EXPORT_SYMBOL(ethtool_rxfh_indir_can_resize); + +/* Resize without validation; caller must have called can_resize first */ +static void __ethtool_rxfh_indir_resize(u32 *tbl, u32 old_size, u32 new_si= ze) +{ + u32 i; + + /* Unfold (grow): replicate existing pattern; fold is a no-op on the data= */ + for (i =3D old_size; i < new_size; i++) + tbl[i] =3D tbl[i % old_size]; +} + +/** + * ethtool_rxfh_indir_resize - Fold or unfold an indirection table + * @tbl: indirection table (must have room for max(old_size, new_size) ent= ries) + * @old_size: current number of entries in the table + * @new_size: desired number of entries + * + * Resize an RSS indirection table in place. When folding (shrinking), + * the table must be periodic with period @new_size; otherwise the + * operation is rejected. When unfolding (growing), the existing + * pattern is replicated. Both directions require the sizes to be + * multiples of each other. + * + * Return: 0 on success, -%EINVAL on failure (no mutation on failure). + */ +int ethtool_rxfh_indir_resize(u32 *tbl, u32 old_size, u32 new_size) +{ + int ret; + + ret =3D ethtool_rxfh_indir_can_resize(tbl, old_size, new_size); + if (ret) + return ret; + + __ethtool_rxfh_indir_resize(tbl, old_size, new_size); + return 0; +} +EXPORT_SYMBOL(ethtool_rxfh_indir_resize); + +/** + * ethtool_rxfh_contexts_resize_all - Resize all RSS context indirection t= ables + * @dev: network device + * @new_indir_size: new indirection table size + * + * Resize the indirection table of every non-default RSS context to + * @new_indir_size. Intended to be called from drivers when the + * device's indirection table size changes (e.g. on channel count + * change). An %ETHTOOL_MSG_RSS_NTF is sent for each resized context. + * + * All contexts are validated before any are modified, so either all + * contexts are resized or none are. + * + * Return: 0 on success, negative errno on failure. + */ +int ethtool_rxfh_contexts_resize_all(struct net_device *dev, u32 new_indir= _size) +{ + struct ethtool_rxfh_context *ctx; + unsigned long context; + int ret; + + if (dev->ethtool_ops->rxfh_indir_space =3D=3D 0 || + new_indir_size > dev->ethtool_ops->rxfh_indir_space) + return -EINVAL; + + scoped_guard(mutex, &dev->ethtool->rss_lock) { + xa_for_each(&dev->ethtool->rss_ctx, context, ctx) { + ret =3D ethtool_rxfh_indir_can_resize(ethtool_rxfh_context_indir(ctx), + ctx->indir_size, new_indir_size); + if (ret) + return ret; + } + + xa_for_each(&dev->ethtool->rss_ctx, context, ctx) { + __ethtool_rxfh_indir_resize(ethtool_rxfh_context_indir(ctx), + ctx->indir_size, new_indir_size); + ctx->indir_size =3D new_indir_size; + } + } + + xa_for_each(&dev->ethtool->rss_ctx, context, ctx) + ethtool_rss_notify(dev, ETHTOOL_MSG_RSS_NTF, context); + + return 0; +} +EXPORT_SYMBOL(ethtool_rxfh_contexts_resize_all); + enum ethtool_link_medium ethtool_str_to_medium(const char *str) { int i; --=20 2.53.0 From nobody Thu Apr 9 17:57:45 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 BD3143563E8; Tue, 3 Mar 2026 18:15:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561753; cv=none; b=ZhT8sapFL0H1gtdOxz7lHS/PvVl7zYGWZSX3ypFw3J4nIAsLnj08fdg+FYJSvqvu71Yvt90zrYyaxJyubQVGtjlqgrhfj9fs7OJtXImqEPGfSP+HiH6uwNoomOEACmWBRguY/z52RSt1L73JDdd9YwgRCOpYiWvF7QCJIdb4qlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561753; c=relaxed/simple; bh=ZJrrcvwUAYxLUxim4bsp6pe5fYg435y8GXGkO1lIokk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=FFzL2UVQ5fzPf67fkwEdgj0aVHVu6BFLeFzha9BOablnhy4vcmO7Z4l7LKCd7wKInmGvF6CSDAwVamEwEdIx1kuByTvjHU2Jl4bUZEuH3bZiolUHYnnof4ATPt4N1KWpjwxbJ+J/3H2TiLeRnRyK8q+8+dKG8zAfu9j3z0ExsUE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cJbeg+Vz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cJbeg+Vz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C85FAC2BC87; Tue, 3 Mar 2026 18:15:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772561753; bh=ZJrrcvwUAYxLUxim4bsp6pe5fYg435y8GXGkO1lIokk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cJbeg+VzcvZ8zhXh59pzMOHPFHBBB6PBmqZRfvi9yiht58lGvqhH0Ab4yR5NEfE3N TlUHDnPh7kuEaKBesNUoQ3J+Rf+/4SDdjyBwzD5NHzqVQmFZlfJqrr7kEU8u5g7k4M 0GDpMlEsS0/XZe86xP2Us6EZgjg4A3gr162A0mOmN3DKLOa1GHhjQuL/wamUoSYMhG Y4+fhsPDRldBxVXrbpPrzPKCCvrpEeJi3OipOaY/mvTrsrnDbXY2nERrbMEBe4469b CmAQaeInod/R/5yH8TBQRO3Vk49P1fF5CxHGxGGVjV3V3NWS4+oRMQw/uD0Jjq6+4F zyLgen89ERztQ== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Michael Chan , Pavan Chebbi , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Willem de Bruijn Subject: [PATCH net-next 2/5] bnxt_en: Resize RSS contexts on channel count change Date: Tue, 3 Mar 2026 19:15:30 +0100 Message-ID: <20260303181535.2671734-3-bjorn@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260303181535.2671734-1-bjorn@kernel.org> References: <20260303181535.2671734-1-bjorn@kernel.org> 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 bnxt_set_channels() rejects channel changes that alter the RSS table size when IFF_RXFH_CONFIGURED is set, because non-default context sizes were locked at creation. Replace the rejection with the new resize helpers. All validation runs before any mutation: 1. ethtool_rxfh_indir_can_resize() checks context 0. 2. ethtool_rxfh_contexts_resize_all() validates and resizes all non-default contexts (all-or-none). 3. ethtool_rxfh_indir_resize() applies context 0 changes. When context 0 uses defaults (!IFF_RXFH_CONFIGURED), steps 1 and 3 are skipped; the driver regenerates the table via bnxt_set_dflt_rss_indir_tbl(). Signed-off-by: Bj=C3=B6rn T=C3=B6pel --- .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/ne= t/ethernet/broadcom/bnxt/bnxt_ethtool.c index 26fcd52c8a61..7608e5d95630 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -977,11 +977,24 @@ static int bnxt_set_channels(struct net_device *dev, tx_xdp =3D req_rx_rings; } =20 - if (bnxt_get_nr_rss_ctxs(bp, req_rx_rings) !=3D - bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) && - netif_is_rxfh_configured(dev)) { - netdev_warn(dev, "RSS table size change required, RSS table entries must= be default to proceed\n"); - return -EINVAL; + if (bnxt_get_nr_rss_ctxs(bp, req_rx_rings) !=3D bnxt_get_nr_rss_ctxs(bp, = bp->rx_nr_rings)) { + u32 new_size =3D bnxt_get_nr_rss_ctxs(bp, req_rx_rings) * BNXT_RSS_TABLE= _ENTRIES_P5; + u32 old_size =3D bnxt_get_rxfh_indir_size(dev); + + /* Validate context 0 can be resized before mutating anything */ + if (netif_is_rxfh_configured(dev) && + ethtool_rxfh_indir_can_resize(bp->rss_indir_tbl, old_size, new_size)= ) { + netdev_warn(dev, "RSS table size change not supported with current indi= rection table\n"); + return -EINVAL; + } + + rc =3D ethtool_rxfh_contexts_resize_all(dev, new_size); + if (rc) + return rc; + + /* All validated; apply context 0 resize */ + if (netif_is_rxfh_configured(dev)) + ethtool_rxfh_indir_resize(bp->rss_indir_tbl, old_size, new_size); } =20 rc =3D bnxt_check_rings(bp, req_tx_rings, req_rx_rings, sh, tcs, tx_xdp); --=20 2.53.0 From nobody Thu Apr 9 17:57:45 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 49A4B30EF7E; Tue, 3 Mar 2026 18:15:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561757; cv=none; b=dQhxmZbrVOq02bKCk/Ss84PDLBQBkWzoc9x/dHZt3Zf05Fo/2/aqQW5jLpTbETlSjDJuUujLFCGQDZ+ZGCO8tmzlZaz1qsTgpVCbOEWRR3K1XrQG+cqGtMySbFCOIGbAZ08kTuBE7xhum2l3NQd+PJhBX1GVpQdqKwH1ENXBhDQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561757; c=relaxed/simple; bh=Jys+IUcjMRxDjzFvUBqJUe/6q09oMB+Hcs2zg/3Pm6k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=j3RUFrWsMg4oh7VzE0H5SddeKZhxvOta5IYv8tduK2MLN+8pfiPWWQlMN+wBCG1v7VxYA6OgD3Usi4WNv/n8K6FSRUXbNVKhBEIJomrGSaAGz5YABX5CCipXLNRH8uVWEs2V0jC98lYpx9y3JYumzuzemFvIJpcBYjckEro6Wcs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=g8lTT7CM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="g8lTT7CM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 21F56C19425; Tue, 3 Mar 2026 18:15:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772561757; bh=Jys+IUcjMRxDjzFvUBqJUe/6q09oMB+Hcs2zg/3Pm6k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g8lTT7CM+D7fqMiV7/NhTZKoblAb1sGupcOJhzbk+0XPz3hMt62aTIciYYBgsI7zF ar+UAzg/kUZK/XPvmpTnozFtubHSHPwIAc87zdfkCciCqAoVpm162S3dCmBMI2NyNb g0G/Nv4c2nueJb58gxqApLOq25uLBpASOhJAD+UpcAw+a3p4zHMqXtzYacphZqyQGM dqBu+ItwE3cSqAnJ8fnkcR2f6z3TV9iIpiC+VtPUn9UBuaVBNF4kSV3hY9xhweWBFN gzE3ioNmJGm9+I9BhaPqj0sOrt8kbeb6Imt+J7VAWgDgiSN4zCbhPfj9yZ1kRLwxfu cTnvVo7xhOlPw== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Michael Chan , Pavan Chebbi , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Willem de Bruijn Subject: [PATCH net-next 3/5] netdevsim: Add RSS context support with dynamic table sizing Date: Tue, 3 Mar 2026 19:15:31 +0100 Message-ID: <20260303181535.2671734-4-bjorn@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260303181535.2671734-1-bjorn@kernel.org> References: <20260303181535.2671734-1-bjorn@kernel.org> 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 Add RSS indirection table, hash key, and non-default RSS context support to netdevsim. The create/modify/remove context callbacks are no-ops; the core manages context state in its xarray. The table size is dynamic: roundup_pow_of_two(channels) * 16, capped at NSIM_RSS_INDIR_MAX (128). This mimics drivers like bnxt where the table size changes with the queue count. nsim_set_channels() uses the core resize helpers to fold/unfold tables on channel count changes, exercising the full resize path. Signed-off-by: Bj=C3=B6rn T=C3=B6pel --- drivers/net/netdevsim/ethtool.c | 119 +++++++++++++++++++++++++++++- drivers/net/netdevsim/netdevsim.h | 4 + 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtoo= l.c index 36a201533aae..c6d60b467054 100644 --- a/drivers/net/netdevsim/ethtool.c +++ b/drivers/net/netdevsim/ethtool.c @@ -2,6 +2,7 @@ // Copyright (c) 2020 Facebook =20 #include +#include #include #include =20 @@ -117,19 +118,121 @@ nsim_wake_queues(struct net_device *dev) rcu_read_unlock(); } =20 +static u32 nsim_get_rx_ring_count(struct net_device *dev) +{ + struct netdevsim *ns =3D netdev_priv(dev); + + return ns->ethtool.channels; +} + +static u32 nsim_rss_indir_size(u32 channels) +{ + return min_t(u32, roundup_pow_of_two(channels) * 16, NSIM_RSS_INDIR_MAX); +} + +static u32 nsim_get_rxfh_indir_size(struct net_device *dev) +{ + struct netdevsim *ns =3D netdev_priv(dev); + + return nsim_rss_indir_size(ns->ethtool.channels); +} + +static u32 nsim_get_rxfh_key_size(struct net_device *dev) +{ + return NSIM_RSS_HKEY_SIZE; +} + +static int nsim_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param= *rxfh) +{ + u32 indir_size =3D nsim_get_rxfh_indir_size(dev); + struct netdevsim *ns =3D netdev_priv(dev); + + rxfh->hfunc =3D ETH_RSS_HASH_TOP; + + if (rxfh->indir) + memcpy(rxfh->indir, ns->ethtool.rss_indir_tbl, indir_size * sizeof(u32)); + if (rxfh->key) + memcpy(rxfh->key, ns->ethtool.rss_hkey, NSIM_RSS_HKEY_SIZE); + + return 0; +} + +static int nsim_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param= *rxfh, + struct netlink_ext_ack *extack) +{ + u32 indir_size =3D nsim_get_rxfh_indir_size(dev); + struct netdevsim *ns =3D netdev_priv(dev); + + if (rxfh->indir) + memcpy(ns->ethtool.rss_indir_tbl, rxfh->indir, indir_size * sizeof(u32)); + if (rxfh->key) + memcpy(ns->ethtool.rss_hkey, rxfh->key, NSIM_RSS_HKEY_SIZE); + + return 0; +} + +static int nsim_create_rxfh_context(struct net_device *dev, struct ethtool= _rxfh_context *ctx, + const struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static int nsim_modify_rxfh_context(struct net_device *dev, struct ethtool= _rxfh_context *ctx, + const struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + return 0; +} + +static int nsim_remove_rxfh_context(struct net_device *dev, struct ethtool= _rxfh_context *ctx, + u32 rss_context, struct netlink_ext_ack *extack) +{ + return 0; +} + +static void nsim_rss_init(struct netdevsim *ns) +{ + u32 i, indir_size =3D nsim_rss_indir_size(ns->ethtool.channels); + + for (i =3D 0; i < indir_size; i++) + ns->ethtool.rss_indir_tbl[i] =3D ethtool_rxfh_indir_default(i, ns->ethto= ol.channels); +} + static int nsim_set_channels(struct net_device *dev, struct ethtool_channels *ch) { struct netdevsim *ns =3D netdev_priv(dev); + u32 old_indir_size, new_indir_size; int err; =20 - err =3D netif_set_real_num_queues(dev, ch->combined_count, - ch->combined_count); + old_indir_size =3D nsim_get_rxfh_indir_size(dev); + new_indir_size =3D nsim_rss_indir_size(ch->combined_count); + + if (old_indir_size !=3D new_indir_size) { + if (netif_is_rxfh_configured(dev) && + ethtool_rxfh_indir_can_resize(ns->ethtool.rss_indir_tbl, + old_indir_size, new_indir_size)) + return -EINVAL; + + err =3D ethtool_rxfh_contexts_resize_all(dev, new_indir_size); + if (err) + return err; + + if (netif_is_rxfh_configured(dev)) + ethtool_rxfh_indir_resize(ns->ethtool.rss_indir_tbl, + old_indir_size, new_indir_size); + } + + err =3D netif_set_real_num_queues(dev, ch->combined_count, ch->combined_c= ount); if (err) return err; =20 ns->ethtool.channels =3D ch->combined_count; =20 + if (old_indir_size !=3D new_indir_size && !netif_is_rxfh_configured(dev)) + nsim_rss_init(ns); + /* Only wake up queues if devices are linked */ if (rcu_access_pointer(ns->peer)) nsim_wake_queues(dev); @@ -209,6 +312,7 @@ static const struct ethtool_ops nsim_ethtool_ops =3D { .supported_coalesce_params =3D ETHTOOL_COALESCE_ALL_PARAMS, .supported_ring_params =3D ETHTOOL_RING_USE_TCP_DATA_SPLIT | ETHTOOL_RING_USE_HDS_THRS, + .rxfh_indir_space =3D NSIM_RSS_INDIR_MAX, .get_pause_stats =3D nsim_get_pause_stats, .get_pauseparam =3D nsim_get_pauseparam, .set_pauseparam =3D nsim_set_pauseparam, @@ -218,10 +322,18 @@ static const struct ethtool_ops nsim_ethtool_ops =3D { .set_ringparam =3D nsim_set_ringparam, .get_channels =3D nsim_get_channels, .set_channels =3D nsim_set_channels, + .get_rx_ring_count =3D nsim_get_rx_ring_count, .get_fecparam =3D nsim_get_fecparam, .set_fecparam =3D nsim_set_fecparam, .get_fec_stats =3D nsim_get_fec_stats, .get_ts_info =3D nsim_get_ts_info, + .get_rxfh_indir_size =3D nsim_get_rxfh_indir_size, + .get_rxfh_key_size =3D nsim_get_rxfh_key_size, + .get_rxfh =3D nsim_get_rxfh, + .set_rxfh =3D nsim_set_rxfh, + .create_rxfh_context =3D nsim_create_rxfh_context, + .modify_rxfh_context =3D nsim_modify_rxfh_context, + .remove_rxfh_context =3D nsim_remove_rxfh_context, }; =20 static void nsim_ethtool_ring_init(struct netdevsim *ns) @@ -250,6 +362,9 @@ void nsim_ethtool_init(struct netdevsim *ns) =20 ns->ethtool.channels =3D ns->nsim_bus_dev->num_queues; =20 + nsim_rss_init(ns); + get_random_bytes(ns->ethtool.rss_hkey, NSIM_RSS_HKEY_SIZE); + ethtool =3D debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir); =20 debugfs_create_u32("get_err", 0600, ethtool, &ns->ethtool.get_err); diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netd= evsim.h index f767fc8a7505..3c6dd9a98deb 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -82,6 +82,8 @@ struct nsim_ethtool_pauseparam { bool report_stats_tx; }; =20 +#define NSIM_RSS_INDIR_MAX 128 +#define NSIM_RSS_HKEY_SIZE 40 struct nsim_ethtool { u32 get_err; u32 set_err; @@ -90,6 +92,8 @@ struct nsim_ethtool { struct ethtool_coalesce coalesce; struct ethtool_ringparam ring; struct ethtool_fecparam fec; + u32 rss_indir_tbl[NSIM_RSS_INDIR_MAX]; + u8 rss_hkey[NSIM_RSS_HKEY_SIZE]; }; =20 struct nsim_rq { --=20 2.53.0 From nobody Thu Apr 9 17:57:45 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 84001347535; Tue, 3 Mar 2026 18:16:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561760; cv=none; b=RpGuv4Hv5oXRom0KX0dW6pDKU2rDazXIuYTRDc1Mfr7R/QfeWhLX7pxDbKR1XRHS/OXpXgOSSGbo3yvuUbblsQt6RurUE6c/kEUvqgpuEggtdbjCBmhTOvYO9H/ETXaGGujoq1Qs+96s9lLAkm52cOrVd3mUMtOWiRPWQMleAMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561760; c=relaxed/simple; bh=uUhxZ0J1Eu9/Ziu2SM/gMWoasgQd3w0iAby7RKC+bP0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qIKva7c9az4qeWSdLRrk7ULnBgnh1v1xp4sw3T+gYtbGM+7HD3MGqnud9Bnq5bhkk23J/QV9i37A6GNxZb/3bZFFjU8bzW4sStYJpbJMzOgYWBjbPCdEgWgJ9R4FZtidVII8dTVn6DHFwkwsBxolME1U7efwzPA7woZVzVYRTZ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YdHeLzqt; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YdHeLzqt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71047C116C6; Tue, 3 Mar 2026 18:15:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772561760; bh=uUhxZ0J1Eu9/Ziu2SM/gMWoasgQd3w0iAby7RKC+bP0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YdHeLzqt2qcHm0AGZKHwfMzbYrzJfoO60OJwBhZHQX7GH5dlcYiTjczruaE6GRDTf JMKJsZzuD24lBq51n66vv5E2hT9DI1Eu2Rp63+TZkckCYPx26ZX80p/JtngZWOusPm eEtZF3E/4TFlJ1+i5p+RfjmmQsj+xQT1mzvVBSuUlQqgEwexFiqWEICJDDTRIoazvX FLiYHVfaQvgEdyihPQN5O7/0WxZF9C8bWN+CAxLfuAtdZQdqE5EH4VAhutXykr8i6n 5/j/TfDA659CUyDUpeilUfiPtub61izZGEO0QbDm89qBpLJ1JMFcM/pz+W/V5rj/D3 s23h3kT/bErdQ== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Michael Chan , Pavan Chebbi , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Willem de Bruijn Subject: [PATCH net-next 4/5] selftests: netdevsim: Add RSS indirection table resize test Date: Tue, 3 Mar 2026 19:15:32 +0100 Message-ID: <20260303181535.2671734-5-bjorn@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260303181535.2671734-1-bjorn@kernel.org> References: <20260303181535.2671734-1-bjorn@kernel.org> 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 Test fold/unfold of RSS indirection tables on channel changes using netdevsim: - default table regenerates on channel change - periodic table folds on shrink and unfolds on grow - non-periodic table blocks channel reduction - non-default RSS context resizes on channel change - non-periodic non-default context blocks fold - table and channel count unchanged after failed reduction Signed-off-by: Bj=C3=B6rn T=C3=B6pel --- .../selftests/drivers/net/netdevsim/Makefile | 1 + .../drivers/net/netdevsim/ethtool-rss.sh | 123 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100755 tools/testing/selftests/drivers/net/netdevsim/ethtool-r= ss.sh diff --git a/tools/testing/selftests/drivers/net/netdevsim/Makefile b/tools= /testing/selftests/drivers/net/netdevsim/Makefile index 1a228c5430f5..d764d08dff1a 100644 --- a/tools/testing/selftests/drivers/net/netdevsim/Makefile +++ b/tools/testing/selftests/drivers/net/netdevsim/Makefile @@ -8,6 +8,7 @@ TEST_PROGS :=3D \ ethtool-features.sh \ ethtool-fec.sh \ ethtool-pause.sh \ + ethtool-rss.sh \ fib.sh \ fib_notifications.sh \ hw_stats_l3.sh \ diff --git a/tools/testing/selftests/drivers/net/netdevsim/ethtool-rss.sh b= /tools/testing/selftests/drivers/net/netdevsim/ethtool-rss.sh new file mode 100755 index 000000000000..1c1876f888ba --- /dev/null +++ b/tools/testing/selftests/drivers/net/netdevsim/ethtool-rss.sh @@ -0,0 +1,123 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only +# +# Test RSS indirection table resize on channel count changes. +# Exercises ethtool_rxfh_indir_resize() and +# ethtool_rxfh_contexts_resize_all() via netdevsim. + +source ethtool-common.sh + +# Create device with 8 queues +NSIM_NETDEV=3D$(make_netdev 1 8) + +set -o pipefail + +# --- Test 1: Default table regenerates on channel change --- +s=3D$(ethtool --json -x $NSIM_NETDEV | jq '.[0]["rss-indirection-table"] |= length') +check $? "$s" "128" # roundup_pow_of_two(8) * 16 =3D 128 + +ethtool -L $NSIM_NETDEV combined 2 +s=3D$(ethtool --json -x $NSIM_NETDEV | jq '.[0]["rss-indirection-table"] |= length') +check $? "$s" "32" # roundup_pow_of_two(2) * 16 =3D 32 + +ethtool -L $NSIM_NETDEV combined 8 + +# --- Test 2: Periodic context 0 table folds on channel reduction --- +ethtool -X $NSIM_NETDEV equal 2 +s=3D$(ethtool --json -x $NSIM_NETDEV | jq '[.[0]["rss-indirection-table"][= ]] | max') +check $? "$s" "1" + +ethtool -L $NSIM_NETDEV combined 2 +s=3D$(ethtool --json -x $NSIM_NETDEV | jq '.[0]["rss-indirection-table"] |= length') +check $? "$s" "32" +s=3D$(ethtool --json -x $NSIM_NETDEV | jq '[.[0]["rss-indirection-table"][= ]] | max') +check $? "$s" "1" + +# Grow back =E2=80=94 should unfold +ethtool -L $NSIM_NETDEV combined 8 +s=3D$(ethtool --json -x $NSIM_NETDEV | jq '.[0]["rss-indirection-table"] |= length') +check $? "$s" "128" +s=3D$(ethtool --json -x $NSIM_NETDEV | jq '[.[0]["rss-indirection-table"][= ]] | max') +check $? "$s" "1" + +ethtool -X $NSIM_NETDEV default + +# --- Test 3: Non-periodic context 0 table blocks fold --- +ethtool -X $NSIM_NETDEV equal 8 + +ethtool -L $NSIM_NETDEV combined 2 2>/dev/null +if [ $? -ne 0 ]; then + ((num_passes++)) +else + echo "Expected channel reduction to fail with non-periodic table" + ((num_errors++)) +fi + +ethtool -X $NSIM_NETDEV default + +# --- Test 4: Non-default context resizes on channel change --- +ctx_id=3D$(ethtool -X $NSIM_NETDEV context new equal 2 2>/dev/null | awk '= {print $NF}') +if [ -z "$ctx_id" ]; then + echo "SKIP: context creation failed" +else + s=3D$(ethtool --json -x $NSIM_NETDEV context $ctx_id | jq '.[0]["rss-i= ndirection-table"] | length') + check $? "$s" "128" + + ethtool -L $NSIM_NETDEV combined 2 + s=3D$(ethtool --json -x $NSIM_NETDEV context $ctx_id | jq '.[0]["rss-i= ndirection-table"] | length') + check $? "$s" "32" + s=3D$(ethtool --json -x $NSIM_NETDEV context $ctx_id | jq '[.[0]["rss-= indirection-table"][]] | max') + check $? "$s" "1" + + # Grow back + ethtool -L $NSIM_NETDEV combined 8 + s=3D$(ethtool --json -x $NSIM_NETDEV context $ctx_id | jq '.[0]["rss-i= ndirection-table"] | length') + check $? "$s" "128" + s=3D$(ethtool --json -x $NSIM_NETDEV context $ctx_id | jq '[.[0]["rss-= indirection-table"][]] | max') + check $? "$s" "1" + + ethtool -X $NSIM_NETDEV context $ctx_id delete +fi + +# --- Test 5: Non-periodic non-default context blocks fold --- +ctx_id=3D$(ethtool -X $NSIM_NETDEV context new equal 8 2>/dev/null | awk '= {print $NF}') +if [ -z "$ctx_id" ]; then + echo "SKIP: context creation failed" +else + ethtool -L $NSIM_NETDEV combined 2 2>/dev/null + if [ $? -ne 0 ]; then + ((num_passes++)) + else + echo "Expected channel reduction to fail with non-periodic context" + ((num_errors++)) + fi + + ethtool -X $NSIM_NETDEV context $ctx_id delete +fi + +# --- Test 6: Table unchanged after failed channel reduction --- +ethtool -X $NSIM_NETDEV equal 8 +s_before=3D$(ethtool --json -x $NSIM_NETDEV | jq '.[0]["rss-indirection-ta= ble"]') + +ethtool -L $NSIM_NETDEV combined 2 2>/dev/null +s_after=3D$(ethtool --json -x $NSIM_NETDEV | jq '.[0]["rss-indirection-tab= le"]') +check $? "$s_after" "$s_before" + +ethtool -X $NSIM_NETDEV default + +# --- Test 7: Channel count unchanged after failed reduction --- +ethtool -X $NSIM_NETDEV equal 8 +ethtool -L $NSIM_NETDEV combined 2 2>/dev/null +s=3D$(ethtool --json -l $NSIM_NETDEV | jq '.[0]["combined-count"]') +check $? "$s" "8" + +ethtool -X $NSIM_NETDEV default + +# --- Results --- +if [ $num_errors -eq 0 ]; then + echo "PASSED all $((num_passes)) checks" + exit 0 +else + echo "FAILED $num_errors/$((num_errors+num_passes)) checks" + exit 1 +fi --=20 2.53.0 From nobody Thu Apr 9 17:57:45 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 F2F48358371; Tue, 3 Mar 2026 18:16:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561764; cv=none; b=McA41AJpHsMKQvKkYZBw+8r3VzAQgOJRSb7i47ecaMNEVhlPnnLivYFRurzUfOS/qmUKy/CoZABu+NtNHTAbmGj1WnFo/UzZCG+cwr1ERSQoIpCP2sCegr4VDHMgcgoIhd0gaQ8UXmtVvKMjIg9izAruiOvjBLydn6o6bUTvvvc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772561764; c=relaxed/simple; bh=vaae6bB7vBAa0A22NTCzZ3Js4GLopWv7MnqhKAcM0n8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pYzjBUH0PAE1cZWNGHo6t7DbJk+IepIlDMY+PE9n/0oBYNNZnHO1VizFaeNkugMHi5LdZ3uafGRnAYCWhCcwJ27n8YzXwJ33qUKZ6y/BFT4HD3Sfyn/YUl5/yJca8ik7GSctgz1/u9YFIN5O0OrR0s+sp/x+11Sx+t4SvvMmsro= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=p+pdF+Ex; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="p+pdF+Ex" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C08ECC116C6; Tue, 3 Mar 2026 18:16:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772561763; bh=vaae6bB7vBAa0A22NTCzZ3Js4GLopWv7MnqhKAcM0n8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p+pdF+ExNF5nXkWcz/tZ1LYXHOxDfwWNf4JWdnwtlBPwAK3n9IVHCQyNnLKK+iTRm KYWBGjusJD62F/FFK8bHK+MbSLTkD6pg9ZJq2wdEJAKqqKy5yEwhOP4yKj2Cq50H/1 WFBNL72IgGoaUKAJa7xJLblpvuUY4VtzBoGUvhMs4Furk6+J5QkU/NGPvX2wHzt275 wtw5ADeTrGPKR8l0MuzfTJCzumbpV4i9AcYc86njhlwzs0QPy+MN8mOEF6RKRmjZ3I LER53gh7nSl4hxiYKHgo+ar3RzyRmD5elWFDho6wSS3I5gnWF4FKQEh3sfJM9fYCem aDJ8cx2ff2t1w== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Michael Chan , Pavan Chebbi , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= , Willem de Bruijn Subject: [PATCH net-next 5/5] selftests: rss_drv: Add RSS indirection table resize tests Date: Tue, 3 Mar 2026 19:15:33 +0100 Message-ID: <20260303181535.2671734-6-bjorn@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260303181535.2671734-1-bjorn@kernel.org> References: <20260303181535.2671734-1-bjorn@kernel.org> 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 Add resize tests to rss_drv.py. Devices without dynamic table sizing are skipped via _require_dynamic_indir_size(). resize_periodic: set a periodic table (equal 2), shrink channels to fold, grow back to unfold. Check the pattern is preserved. Has main and non-default context variants. resize_nonperiodic_reject: set a non-periodic table (equal N), verify that channel reduction is rejected. Pass queue_count=3D8 to NetDrvEnv so netdevsim is created with enough queues for the resize tests. Signed-off-by: Bj=C3=B6rn T=C3=B6pel --- .../selftests/drivers/net/hw/rss_drv.py | 101 +++++++++++++++++- 1 file changed, 96 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/drivers/net/hw/rss_drv.py b/tools/test= ing/selftests/drivers/net/hw/rss_drv.py index 2d1a33189076..8725500f2955 100755 --- a/tools/testing/selftests/drivers/net/hw/rss_drv.py +++ b/tools/testing/selftests/drivers/net/hw/rss_drv.py @@ -5,9 +5,9 @@ Driver-related behavior tests for RSS. """ =20 -from lib.py import ksft_run, ksft_exit, ksft_ge -from lib.py import ksft_variants, KsftNamedVariant, KsftSkipEx -from lib.py import defer, ethtool +from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_ge +from lib.py import ksft_variants, KsftNamedVariant, KsftSkipEx, KsftFailEx +from lib.py import defer, ethtool, CmdExitFailure from lib.py import EthtoolFamily, NlError from lib.py import NetDrvEnv =20 @@ -45,6 +45,18 @@ def _maybe_create_context(cfg, create_context): return ctx_id =20 =20 +def _require_dynamic_indir_size(cfg, ch_max): + """Skip if the device does not dynamically size its indirection table.= """ + ethtool(f"-X {cfg.ifname} default") + ethtool(f"-L {cfg.ifname} combined 2") + small =3D len(_get_rss(cfg)['rss-indirection-table']) + ethtool(f"-L {cfg.ifname} combined {ch_max}") + large =3D len(_get_rss(cfg)['rss-indirection-table']) + + if small =3D=3D large: + raise KsftSkipEx("Device does not dynamically size indirection tab= le") + + @ksft_variants([ KsftNamedVariant("main", False), KsftNamedVariant("ctx", True), @@ -76,11 +88,90 @@ def indir_size_4x(cfg, create_context): _test_rss_indir_size(cfg, test_max, context=3Dctx_id) =20 =20 +@ksft_variants([ + KsftNamedVariant("main", False), + KsftNamedVariant("ctx", True), +]) +def resize_periodic(cfg, create_context): + """Test that a periodic indirection table survives channel changes. + + Set a periodic table (equal 2), reduce channels to trigger a + fold, then increase to trigger an unfold. Verify the table pattern + is preserved and the size tracks the channel count. + """ + channels =3D cfg.ethnl.channels_get({'header': {'dev-index': cfg.ifind= ex}}) + ch_max =3D channels.get('combined-max', 0) + qcnt =3D channels['combined-count'] + + if ch_max < 4: + raise KsftSkipEx(f"Not enough queues for the test: max=3D{ch_max}") + + defer(ethtool, f"-L {cfg.ifname} combined {qcnt}") + ethtool(f"-L {cfg.ifname} combined {ch_max}") + + _require_dynamic_indir_size(cfg, ch_max) + + ctx_id =3D _maybe_create_context(cfg, create_context) + ctx_ref =3D f"context {ctx_id}" if ctx_id else "" + + ethtool(f"-X {cfg.ifname} {ctx_ref} equal 2") + if not create_context: + defer(ethtool, f"-X {cfg.ifname} default") + + orig_size =3D len(_get_rss(cfg, context=3Dctx_id)['rss-indirection-tab= le']) + + # Shrink =E2=80=94 should fold + ethtool(f"-L {cfg.ifname} combined 2") + rss =3D _get_rss(cfg, context=3Dctx_id) + indir =3D rss['rss-indirection-table'] + + ksft_ge(orig_size, len(indir), "Table did not shrink") + ksft_eq(set(indir), {0, 1}, "Folded table has wrong queues") + + # Grow back =E2=80=94 should unfold + ethtool(f"-L {cfg.ifname} combined {ch_max}") + rss =3D _get_rss(cfg, context=3Dctx_id) + indir =3D rss['rss-indirection-table'] + + ksft_eq(len(indir), orig_size, "Table size not restored") + ksft_eq(set(indir), {0, 1}, "Unfolded table has wrong queues") + + +def resize_nonperiodic_reject(cfg): + """Test that a non-periodic table blocks channel reduction. + + Set equal weight across all queues so the table is not periodic + at any smaller size, then verify channel reduction is rejected. + """ + channels =3D cfg.ethnl.channels_get({'header': {'dev-index': cfg.ifind= ex}}) + ch_max =3D channels.get('combined-max', 0) + qcnt =3D channels['combined-count'] + + if ch_max < 4: + raise KsftSkipEx(f"Not enough queues for the test: max=3D{ch_max}") + + defer(ethtool, f"-L {cfg.ifname} combined {qcnt}") + ethtool(f"-L {cfg.ifname} combined {ch_max}") + + _require_dynamic_indir_size(cfg, ch_max) + + ethtool(f"-X {cfg.ifname} equal {ch_max}") + defer(ethtool, f"-X {cfg.ifname} default") + + try: + ethtool(f"-L {cfg.ifname} combined 2") + except CmdExitFailure: + pass + else: + raise KsftFailEx("Channel reduction should fail with non-periodic = table") + + def main() -> None: """ Ksft boiler plate main """ - with NetDrvEnv(__file__) as cfg: + with NetDrvEnv(__file__, queue_count=3D8) as cfg: cfg.ethnl =3D EthtoolFamily() - ksft_run([indir_size_4x], args=3D(cfg, )) + ksft_run([indir_size_4x, resize_periodic, + resize_nonperiodic_reject], args=3D(cfg, )) ksft_exit() =20 =20 --=20 2.53.0