From: Mingming Cao <mmc@linux.ibm.com>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, kuba@kernel.org, edumazet@google.com,
pabeni@redhat.com, andrew+netdev@lunn.ch, nnac123@linux.ibm.com,
maddy@linux.ibm.com, mpe@ellerman.id.au,
linuxppc-dev@lists.ozlabs.org, haren@linux.ibm.com,
ricklind@linux.ibm.com, davemarq@linux.ibm.com,
bjking1@linux.ibm.com, shaik.abdulla1@ibm.com,
Mingming Cao <mmc@linux.ibm.com>
Subject: [PATCH net-next v5 15/15] ibmveth: Wire ethtool set_channels to MQ RX queue resize
Date: Fri, 14 Aug 2026 00:36:42 -0700 [thread overview]
Message-ID: <20260814073642.24630-16-mmc@linux.ibm.com> (raw)
In-Reply-To: <20260814073642.24630-1-mmc@linux.ibm.com>
Complete set_channels() RX handling around ibmveth_resize_rx_channels():
- When down: set TX queues first, then stash the desired RX count
in adapter->num_rx_queues for the next open() (open publishes via
netif_set_real_num_rx_queues). There are no RX mappings/buffers/IRQs
to grow or shrink while down, so do not allocate immediately.
- When up: resize RX, then adjust TX LTBs with the existing
stop/alloc/set_real_num_tx/free/wake path.
- Skip TX stop/wake when the TX count is unchanged.
Make TX/RX updates fail atomically: validate both ranges up front;
apply TX before stashing RX while down; when up, roll RX back if TX
cannot reach the requested count. Initialize the TX alloc loop bound
so a scale-down path that never allocates still has defined cleanup
if set_real_num_tx_queues() fails.
Gate live RX resize on adapter->opened (not IFF_UP): RX resources
exist only after a successful open, matching the while-down stash path.
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Tested-by: Shaik Abdulla <shaik.abdulla1@ibm.com>
---
Changes in v5:
- set_channels / resize_rx_channels read via get_num_rx_queues()
- Series renumber: mailed v4 13/14 set_channels -> tip P15 (end; 14->15)
- set_channels: gate on adapter->opened (not IFF_UP) for live RX resize
vs while-down stash
- Down-path RX stash also refreshes CMO (publish + set_real_num_rx)
- When up: resize RX then TX; roll RX back if TX cannot reach goal
Changes in v4:
- On !IFF_UP, stash num_rx_queues only after TX set succeeds; do not
allocate live subordinate IRQs/buffers while down.
- Initialize i = old_tx on the TX adjust path.
- Always return rc from set_channels().
- Split from the resize-helper patch (same split as v3) while keeping
a live caller of resize_rx_channels() in the previous patch.
drivers/net/ethernet/ibm/ibmveth.c | 107 +++++++++++++++++++++++------
1 file changed, 85 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 84f4a0deb0c5..35cbd2553e86 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -800,6 +800,7 @@ ibmveth_kick_rx_queue_if_pending(struct ibmveth_adapter *adapter,
if (ibmveth_rxq_pending_buffer(adapter, queue_index))
ibmveth_schedule_rx_queue(adapter, queue_index);
}
+
/* setup the initial settings for a buffer pool */
static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool,
u32 pool_index, u32 pool_size,
@@ -3175,28 +3176,75 @@ static int ibmveth_set_channels(struct net_device *netdev,
struct ethtool_channels *channels)
{
struct ibmveth_adapter *adapter = netdev_priv(netdev);
- unsigned int old = netdev->real_num_tx_queues,
- goal = channels->tx_count;
+ unsigned int old_rx = ibmveth_get_num_rx_queues(adapter);
+ unsigned int goal_rx = channels->rx_count;
+ unsigned int old_tx = netdev->real_num_tx_queues;
+ unsigned int goal_tx = channels->tx_count;
+ unsigned int want_tx = goal_tx;
+ int rxq_entries = adapter->rx_queue[0].num_slots;
+ bool rx_changed = false;
int rc, i;
- /* Validate RX (and resize when opened) before the down-path early
- * return so MQ/range errors are not deferred to the wiring patch.
- * RX stash + CMO while down still lands with that patch.
- */
- rc = ibmveth_resize_rx_channels(adapter, channels->rx_count);
+ if (goal_tx < 1 || goal_tx > ibmveth_real_max_tx_queues()) {
+ netdev_err(netdev,
+ "Invalid TX queue count %u (must be 1-%u)\n",
+ goal_tx, ibmveth_real_max_tx_queues());
+ return -EINVAL;
+ }
+
+ /* RX range / MQ checks live in ibmveth_resize_rx_channels(). */
+ rc = ibmveth_resize_rx_channels(adapter, goal_rx);
if (rc)
return rc;
- if (!adapter->opened)
- return netif_set_real_num_tx_queues(netdev, goal);
+ /* If RX resources are not live (never opened, or close+open failed
+ * while IFF_UP stayed set), only stash desired queue counts.
+ */
+ if (!adapter->opened) {
+ /* Apply TX first so a failure leaves RX stash unchanged. */
+ rc = netif_set_real_num_tx_queues(netdev, goal_tx);
+ if (rc)
+ return rc;
+
+ /* Stash desired RX count; open() publishes it via
+ * netif_set_real_num_rx_queues() after queue registration.
+ * Refresh CMO now so open() can map the larger footprint;
+ * open itself does not call vio_cmo_set_dev_desired.
+ */
+ if (goal_rx != ibmveth_get_num_rx_queues(adapter)) {
+ ibmveth_publish_num_rx_queues(adapter, goal_rx);
+ rc = netif_set_real_num_rx_queues(netdev, goal_rx);
+ if (rc) {
+ ibmveth_publish_num_rx_queues(adapter, old_rx);
+ return rc;
+ }
+ if (firmware_has_feature(FW_FEATURE_CMO)) {
+ unsigned long dma;
+
+ dma = ibmveth_get_desired_dma(adapter->vdev);
+ vio_cmo_set_dev_desired(adapter->vdev, dma);
+ }
+ }
+ return 0;
+ }
+
+ if (goal_rx != old_rx)
+ rx_changed = true;
/* We have IBMVETH_MAX_QUEUES netdev_queue's allocated
* but we may need to alloc/free the ltb's.
*/
+ if (goal_tx == old_tx)
+ return 0;
+
netif_tx_stop_all_queues(netdev);
- /* Allocate any queue that we need */
- for (i = old; i < goal; i++) {
+ /* Allocate any new TX LTBs. i starts at old_tx for the free walk
+ * below when this loop body never runs (goal_tx == old_tx already
+ * returned; goal_tx < old_tx is scale-down).
+ */
+ i = old_tx;
+ for (; i < goal_tx; i++) {
if (adapter->tx_ltb_ptr[i])
continue;
@@ -3205,28 +3253,43 @@ static int ibmveth_set_channels(struct net_device *netdev,
continue;
/* if something goes wrong, free everything we just allocated */
- netdev_err(netdev, "Failed to allocate more tx queues, returning to %d queues\n",
- old);
- goal = old;
- old = i;
+ netdev_err(netdev, "Failed to allocate more tx queues, returning to %u queues\n",
+ old_tx);
+ goal_tx = old_tx;
+ old_tx = i;
break;
}
- rc = netif_set_real_num_tx_queues(netdev, goal);
+ rc = netif_set_real_num_tx_queues(netdev, goal_tx);
if (rc) {
- netdev_err(netdev, "Failed to set real tx queues, returning to %d queues\n",
- old);
- goal = old;
- old = i;
+ netdev_err(netdev, "Failed to set real tx queues, returning to %u queues\n",
+ old_tx);
+ goal_tx = old_tx;
+ old_tx = i;
}
/* Free any that are no longer needed */
- for (i = old; i > goal; i--) {
+ for (i = old_tx; i > goal_tx; i--) {
if (adapter->tx_ltb_ptr[i - 1])
ibmveth_free_tx_ltb(adapter, i - 1);
}
netif_tx_wake_all_queues(netdev);
- return rc;
+ if (netdev->real_num_tx_queues != want_tx) {
+ if (rx_changed) {
+ int rb;
+
+ rb = ibmveth_resize_rx_queues_incremental(adapter,
+ old_rx,
+ rxq_entries);
+ if (rb)
+ netdev_err(netdev,
+ "Failed to roll back RX queues to %u after TX failure: %d\n",
+ old_rx, rb);
+ }
+ return rc ? rc : -ENOMEM;
+ }
+
+ return 0;
}
static const struct ethtool_ops netdev_ethtool_ops = {
--
2.50.1 (Apple Git-155)
prev parent reply other threads:[~2026-08-14 7:38 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 7:36 [PATCH net-next v5 00/15] ibmveth: Add multi-queue RX support Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 01/15] ibmveth: Add MQ RX hypercall wrappers and call definitions Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 02/15] ibmveth: Prepare MQ RX adapter data structures Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 03/15] ibmveth: Refactor RX resource allocation for MQ RX bring-up Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 04/15] ibmveth: Refactor buffer pool management for per-queue MQ RX Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 05/15] ibmveth: Refactor RX interrupt control for MQ RX queues Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 06/15] ibmveth: Refactor TX resource allocation in open/close paths Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 07/15] ibmveth: Add RX queue register helpers for MQ Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 08/15] ibmveth: Add queue-aware RX buffer submit helper " Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 09/15] ibmveth: Harden RX poll path with helpers Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 10/15] ibmveth: Enable multi-queue RX receive path Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 11/15] ibmveth: Add per-queue RX and TX statistics collection Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 12/15] ibmveth: Report MQ-aware RX counts in ethtool get_channels Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 13/15] ibmveth: Expose per-queue buffer pool details via debugfs Mingming Cao
2026-08-14 7:36 ` [PATCH net-next v5 14/15] ibmveth: Implement incremental MQ RX queue resize Mingming Cao
2026-08-14 7:36 ` Mingming Cao [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260814073642.24630-16-mmc@linux.ibm.com \
--to=mmc@linux.ibm.com \
--cc=andrew+netdev@lunn.ch \
--cc=bjking1@linux.ibm.com \
--cc=davem@davemloft.net \
--cc=davemarq@linux.ibm.com \
--cc=edumazet@google.com \
--cc=haren@linux.ibm.com \
--cc=kuba@kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=mpe@ellerman.id.au \
--cc=netdev@vger.kernel.org \
--cc=nnac123@linux.ibm.com \
--cc=pabeni@redhat.com \
--cc=ricklind@linux.ibm.com \
--cc=shaik.abdulla1@ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.