From: Mingming Cao <mmc@linux.ibm.com>
To: netdev@vger.kernel.org
Cc: horms@kernel.org, bjking1@linux.ibm.com, haren@linux.ibm.com,
ricklind@linux.ibm.com, mmc@linux.ibm.com, kuba@kernel.org,
edumazet@google.com, pabeni@redhat.com,
linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com,
mpe@ellerman.id.au, Dave Marquardt <davemarq@linux.ibm.com>
Subject: [PATCH v1 06/18] ibmveth: Refactor RX interrupt control for MQ RX queues
Date: Tue, 30 Jun 2026 07:53:13 -0700 [thread overview]
Message-ID: <9da5ab3d6db4800d5457ba3e53eb7ab259e4266c.1782758799.git.mmc@linux.ibm.com> (raw)
In-Reply-To: <cover.1782758799.git.mmc@linux.ibm.com>
Queue 0 and subordinate RX queues use different interrupt control
interfaces in PHYP:
- queue 0: h_vio_signal() after h_register_logical_lan()
- queue N: H_VIOCTL against the queue handle/hwirq mapping
The current code is single-queue oriented and cannot safely scale to
multiple RX queues in poll completion and open/close IRQ setup.
Introduce queue-indexed interrupt helpers:
ibmveth_enable_irq(adapter, queue_index)
ibmveth_disable_irq(adapter, queue_index)
ibmveth_setup_rx_interrupts()
ibmveth_cleanup_rx_interrupts()
These helpers centralize queue0-vs-subordinate dispatch and make IRQ
lifecycle symmetric across open/close and future resize paths.
request_irq() is wired with &adapter->napi[i] as dev_id per queue, so
interrupt ownership follows the NAPI instance that services that RX
queue.
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
---
drivers/net/ethernet/ibm/ibmveth.c | 160 +++++++++++++++++++++++++++++
1 file changed, 160 insertions(+)
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c
index 95068fb20dba..b5ae979c1f82 100644
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -315,6 +315,166 @@ static void __maybe_unused ibmveth_cleanup_rx_resources(struct ibmveth_adapter *
}
}
+/**
+ * ibmveth_toggle_irq - Common helper to enable/disable queue interrupts
+ * @adapter: ibmveth adapter structure
+ * @queue_index: Index of the queue (0 for primary, 1+ for subordinate)
+ * @enable: true to enable, false to disable
+ *
+ * For queue 0 (primary), uses h_vio_signal() as it's registered via
+ * h_register_logical_lan(). For subordinate queues (1+), uses H_VIOCTL
+ * with H_ENABLE/DISABLE_VIO_INTERRUPT for per-queue interrupt control.
+ *
+ * Return: 0 on success, error code otherwise
+ */
+static int
+ibmveth_toggle_irq(struct ibmveth_adapter *adapter, int queue_index, bool enable)
+{
+ unsigned long rc;
+ unsigned long irq = adapter->queue_irq[queue_index];
+ const char *action = enable ? "enable" : "disable";
+
+ if (queue_index == 0) {
+ /* Primary queue: use h_vio_signal() */
+ rc = h_vio_signal(adapter->vdev->unit_address,
+ enable ? VIO_IRQ_ENABLE : VIO_IRQ_DISABLE);
+ } else {
+ /* Subordinate queues: use H_VIOCTL with hardware IRQ */
+ struct irq_data *irq_data = irq_get_irq_data(irq);
+ irq_hw_number_t hwirq;
+ u64 vioctl_cmd = enable ? H_ENABLE_VIO_INTERRUPT : H_DISABLE_VIO_INTERRUPT;
+
+ if (!irq_data) {
+ netdev_err(adapter->netdev,
+ "Failed to get IRQ data for queue %d (virq=%lu)\n",
+ queue_index, irq);
+ return -EINVAL;
+ }
+
+ hwirq = irqd_to_hwirq(irq_data);
+ rc = plpar_hcall_norets(H_VIOCTL,
+ adapter->vdev->unit_address,
+ vioctl_cmd,
+ hwirq, 0, 0);
+
+ if (rc == H_PARAMETER) {
+ /* H_PARAMETER is non-fatal when IRQ is already in the requested state. */
+ netdev_warn_once(adapter->netdev,
+ "H_VIOCTL %s IRQ returned H_PARAMETER for queue %d (hwirq=%lu)\n",
+ action, queue_index, hwirq);
+ return 0;
+ }
+ }
+
+ if (rc)
+ netdev_err(adapter->netdev,
+ "Failed to %s IRQ for queue %d, rc=%ld\n",
+ action, queue_index, rc);
+ return rc;
+}
+
+/**
+ * ibmveth_disable_irq - Disable interrupt for a specific queue
+ * @adapter: ibmveth adapter structure
+ * @queue_index: Index of the queue (0 for primary, 1+ for subordinate)
+ *
+ * Return: 0 on success, error code otherwise
+ */
+static int
+ibmveth_disable_irq(struct ibmveth_adapter *adapter, int queue_index)
+{
+ return ibmveth_toggle_irq(adapter, queue_index, false);
+}
+
+/**
+ * ibmveth_enable_irq - Enable interrupt for a specific queue
+ * @adapter: ibmveth adapter structure
+ * @queue_index: Index of the queue (0 for primary, 1+ for subordinate)
+ *
+ * Return: 0 on success, error code otherwise
+ */
+static int
+ibmveth_enable_irq(struct ibmveth_adapter *adapter, int queue_index)
+{
+ return ibmveth_toggle_irq(adapter, queue_index, true);
+}
+
+/**
+ * ibmveth_setup_rx_interrupts - Register IRQs and enable NAPI
+ * @adapter: ibmveth adapter structure
+ *
+ * Registers interrupt handlers for all RX queues and enables NAPI polling.
+ * On error, cleans up any successfully registered IRQs before returning.
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+static int __maybe_unused
+ibmveth_setup_rx_interrupts(struct ibmveth_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int i, rc;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ if (!adapter->queue_irq[i]) {
+ netdev_err(netdev, "queue %d has invalid IRQ (0)\n", i);
+ rc = -EINVAL;
+ goto err_free_irqs;
+ }
+
+ rc = request_irq(adapter->queue_irq[i], ibmveth_interrupt,
+ 0, netdev->name, &adapter->napi[i]);
+ if (rc) {
+ netdev_err(netdev,
+ "request_irq() failed for irq 0x%x queue %d: %d\n",
+ adapter->queue_irq[i], i, rc);
+ goto err_free_irqs;
+ }
+ }
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_enable(&adapter->napi[i]);
+
+ return 0;
+
+err_free_irqs:
+ while (--i >= 0)
+ free_irq(adapter->queue_irq[i], &adapter->napi[i]);
+ return rc;
+}
+
+/**
+ * ibmveth_cleanup_rx_interrupts - Disable NAPI and free IRQs
+ * @adapter: ibmveth adapter structure
+ *
+ * Disables NAPI polling and frees interrupt handlers for all RX queues.
+ */
+static void
+ibmveth_cleanup_rx_interrupts(struct ibmveth_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_disable(&adapter->napi[i]);
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ if (adapter->queue_irq[i])
+ free_irq(adapter->queue_irq[i], &adapter->napi[i]);
+ }
+
+ /* Dispose IRQ mappings for subordinate queues (1-15).
+ * Queue 0 uses netdev->irq from device tree, not irq_create_mapping().
+ */
+ for (i = 1; i < adapter->num_rx_queues; i++) {
+ if (adapter->queue_irq[i]) {
+ irq_dispose_mapping(adapter->queue_irq[i]);
+ adapter->queue_irq[i] = 0;
+ }
+ }
+
+ /* Clear queue 0 IRQ number */
+ adapter->queue_irq[0] = 0;
+}
+
/* 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,
--
2.39.3 (Apple Git-146)
next prev parent reply other threads:[~2026-06-30 14:54 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-30 14:53 [PATCH v1 00/18] ibmveth: Add multi-queue RX Support Mingming Cao
2026-06-30 14:53 ` [PATCH v1 01/18] ibmveth: Add MQ RX hypercall wrappers and call definitions Mingming Cao
2026-06-30 14:53 ` [PATCH v1 02/18] ibmveth: Prepare adapter data structures for MQ RX Mingming Cao
2026-06-30 14:53 ` [PATCH v1 03/18] ibmveth: Add MQ-ready RX statistics structures Mingming Cao
2026-06-30 14:53 ` [PATCH v1 04/18] ibmveth: Refactor RX resource allocation for MQ RX bring-up Mingming Cao
2026-06-30 14:53 ` [PATCH v1 05/18] ibmveth: Refactor buffer pool management for per-queue MQ RX Mingming Cao
2026-06-30 14:53 ` Mingming Cao [this message]
2026-06-30 14:53 ` [PATCH v1 07/18] ibmveth: Refactor TX resource allocation in open/close paths Mingming Cao
2026-06-30 14:53 ` [PATCH v1 08/18] ibmveth: Add RX queue register/deregister helpers for MQ Mingming Cao
2026-06-30 14:53 ` [PATCH v1 09/18] ibmveth: Refactor open/close into MQ-ready resource pipeline Mingming Cao
2026-06-30 14:53 ` [PATCH v1 10/18] ibmveth: Add queue-aware RX buffer submit helper for MQ Mingming Cao
2026-06-30 14:53 ` [PATCH v1 11/18] ibmveth: Enable multi-queue RX receive path Mingming Cao
2026-06-30 14:53 ` [PATCH v1 12/18] ibmveth: Add per-queue RX statistics collection and reporting Mingming Cao
2026-06-30 14:53 ` [PATCH v1 13/18] ibmveth: Add per-queue TX statistics reporting Mingming Cao
2026-06-30 14:53 ` [PATCH v1 14/18] ibmveth: Expose per-queue buffer pool details via sysfs Mingming Cao
2026-06-30 14:53 ` [PATCH v1 15/18] ibmveth: Add helpers for incremental MQ RX queue resize Mingming Cao
2026-06-30 14:53 ` [PATCH v1 16/18] ibmveth: Implement " Mingming Cao
2026-06-30 14:53 ` [PATCH v1 17/18] ibmveth: Wire ethtool set_channels to " Mingming Cao
2026-06-30 14:53 ` [PATCH v1 18/18] ibmveth: Fix MQ RX poll and shutdown hangs after " Mingming Cao
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=9da5ab3d6db4800d5457ba3e53eb7ab259e4266c.1782758799.git.mmc@linux.ibm.com \
--to=mmc@linux.ibm.com \
--cc=bjking1@linux.ibm.com \
--cc=davemarq@linux.ibm.com \
--cc=edumazet@google.com \
--cc=haren@linux.ibm.com \
--cc=horms@kernel.org \
--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=pabeni@redhat.com \
--cc=ricklind@linux.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox