From: mhkelley58@gmail.com
To: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
decui@microsoft.com, tglx@linutronix.de, mingo@redhat.com,
bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org,
hpa@zytor.com, lpieralisi@kernel.org, kw@linux.com,
robh@kernel.org, bhelgaas@google.com,
James.Bottomley@HansenPartnership.com,
martin.petersen@oracle.com, arnd@arndb.de,
linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org,
linux-arch@vger.kernel.org
Cc: maz@kernel.org, den@valinux.co.jp, jgowans@amazon.com,
dawei.li@shingroup.cn
Subject: [RFC 07/12] Drivers: hv: vmbus: Set up irqdomain and irqchip for the VMBus connection
Date: Mon, 3 Jun 2024 22:09:35 -0700 [thread overview]
Message-ID: <20240604050940.859909-8-mhklinux@outlook.com> (raw)
In-Reply-To: <20240604050940.859909-1-mhklinux@outlook.com>
From: Michael Kelley <mhklinux@outlook.com>
In preparation for assigning Linux IRQs to VMBus channels, set up an
irqdomain and irqchip for the VMBus connection. The irqdomain is linear,
with the VMBus relid used as the "hwirq" value. A relid is a unique
index assigned by Hyper-V to each VMBus channel, with values ranging
from 1 to 2047. Because these hwirqs don't map to anything in the
architectural hardware, the domain is not part of the domain hierarchy.
VMBus channel interrupts provide minimal management functionality, so
provide only a minimal set of irqchip functions. The set_affinity function
is a place-holder that is populated in a subsequent patch.
Signed-off-by: Michael Kelley <mhklinux@outlook.com>
---
drivers/hv/connection.c | 24 +++++++++-----
drivers/hv/hyperv_vmbus.h | 9 +++++
drivers/hv/vmbus_drv.c | 60 +++++++++++++++++++++++++++++++++-
include/asm-generic/mshyperv.h | 6 ++++
4 files changed, 90 insertions(+), 9 deletions(-)
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index f001ae880e1d..cb01784e5c3b 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -21,21 +21,29 @@
#include <linux/export.h>
#include <linux/io.h>
#include <linux/set_memory.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/irqdomain.h>
#include <asm/mshyperv.h>
#include "hyperv_vmbus.h"
struct vmbus_connection vmbus_connection = {
- .conn_state = DISCONNECTED,
- .unload_event = COMPLETION_INITIALIZER(
- vmbus_connection.unload_event),
- .next_gpadl_handle = ATOMIC_INIT(0xE1E10),
-
- .ready_for_suspend_event = COMPLETION_INITIALIZER(
- vmbus_connection.ready_for_suspend_event),
+ .conn_state = DISCONNECTED,
+ .unload_event = COMPLETION_INITIALIZER(
+ vmbus_connection.unload_event),
+ .next_gpadl_handle = ATOMIC_INIT(0xE1E10),
+
+ .vmbus_irq_chip.name = "VMBus",
+ .vmbus_irq_chip.irq_set_affinity = vmbus_irq_set_affinity,
+ .vmbus_irq_chip.irq_mask = vmbus_irq_mask,
+ .vmbus_irq_chip.irq_unmask = vmbus_irq_unmask,
+
+ .ready_for_suspend_event = COMPLETION_INITIALIZER(
+ vmbus_connection.ready_for_suspend_event),
.ready_for_resume_event = COMPLETION_INITIALIZER(
- vmbus_connection.ready_for_resume_event),
+ vmbus_connection.ready_for_resume_event),
};
EXPORT_SYMBOL_GPL(vmbus_connection);
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 76ac5185a01a..95d4d47d34f7 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -18,7 +18,11 @@
#include <asm/hyperv-tlfs.h>
#include <linux/atomic.h>
#include <linux/hyperv.h>
+#include <linux/fwnode.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/irqdomain.h>
#include "hv_trace.h"
@@ -258,6 +262,11 @@ struct vmbus_connection {
/* Array of channels */
struct vmbus_channel **channels;
+ /* IRQ domain data */
+ struct fwnode_handle *vmbus_fwnode;
+ struct irq_domain *vmbus_irq_domain;
+ struct irq_chip vmbus_irq_chip;
+
/*
* An offer message is handled first on the work_queue, and then
* is further handled on handle_primary_chan_wq or
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 291a8358370b..cbccdfad49a2 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -36,6 +36,9 @@
#include <linux/syscore_ops.h>
#include <linux/dma-map-ops.h>
#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/hardirq.h>
#include <clocksource/hyperv_timer.h>
#include <asm/mshyperv.h>
#include "hyperv_vmbus.h"
@@ -1306,6 +1309,40 @@ static irqreturn_t vmbus_percpu_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
+int vmbus_irq_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force)
+{
+ return 0;
+}
+
+/*
+ * VMBus channel interrupts do not need to be masked or unmasked, and the
+ * Hyper-V synic doesn't provide any masking functionality anyway. But in the
+ * absence of these irqchip functions, the IRQ subsystem keeps the IRQ marked
+ * as "masked". To prevent any problems associated with staying the "masked"
+ * state, and so that IRQ status shown in debugfs doesn't indicate "masked",
+ * provide null implementations.
+ */
+void vmbus_irq_unmask(struct irq_data *data)
+{
+}
+
+void vmbus_irq_mask(struct irq_data *data)
+{
+}
+
+static int vmbus_irq_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(irq,
+ &vmbus_connection.vmbus_irq_chip, handle_simple_irq);
+ return 0;
+}
+
+static const struct irq_domain_ops vmbus_domain_ops = {
+ .map = vmbus_irq_map,
+};
+
/*
* vmbus_bus_init -Main vmbus driver initialization routine.
*
@@ -1340,6 +1377,7 @@ static int vmbus_bus_init(void)
if (vmbus_irq == -1) {
hv_setup_vmbus_handler(vmbus_isr);
} else {
+ irq_set_handler(vmbus_irq, handle_percpu_demux_irq);
vmbus_evt = alloc_percpu(long);
ret = request_percpu_irq(vmbus_irq, vmbus_percpu_isr,
"Hyper-V VMbus", vmbus_evt);
@@ -1355,6 +1393,20 @@ static int vmbus_bus_init(void)
if (ret)
goto err_alloc;
+ /* Create IRQ domain for VMBus devices */
+ vmbus_connection.vmbus_fwnode = irq_domain_alloc_named_fwnode("hv-vmbus");
+ if (!vmbus_connection.vmbus_fwnode) {
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+ vmbus_connection.vmbus_irq_domain = irq_domain_create_linear(
+ vmbus_connection.vmbus_fwnode, MAX_CHANNEL_RELIDS,
+ &vmbus_domain_ops, NULL);
+ if (!vmbus_connection.vmbus_irq_domain) {
+ ret = -ENOMEM;
+ goto err_fwnode;
+ }
+
/*
* Initialize the per-cpu interrupt state and stimer state.
* Then connect to the host.
@@ -1362,7 +1414,7 @@ static int vmbus_bus_init(void)
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hyperv/vmbus:online",
hv_synic_init, hv_synic_cleanup);
if (ret < 0)
- goto err_alloc;
+ goto err_domain;
hyperv_cpuhp_online = ret;
ret = vmbus_connect();
@@ -1382,6 +1434,10 @@ static int vmbus_bus_init(void)
err_connect:
cpuhp_remove_state(hyperv_cpuhp_online);
+err_domain:
+ irq_domain_remove(vmbus_connection.vmbus_irq_domain);
+err_fwnode:
+ irq_domain_free_fwnode(vmbus_connection.vmbus_fwnode);
err_alloc:
hv_synic_free();
if (vmbus_irq == -1) {
@@ -2690,6 +2746,8 @@ static void __exit vmbus_exit(void)
hv_debug_rm_all_dir();
vmbus_free_channels();
+ irq_domain_remove(vmbus_connection.vmbus_irq_domain);
+ irq_domain_free_fwnode(vmbus_connection.vmbus_fwnode);
kfree(vmbus_connection.channels);
/*
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 8fe7aaab2599..0488ff8b511f 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -24,6 +24,7 @@
#include <acpi/acpi_numa.h>
#include <linux/cpumask.h>
#include <linux/nmi.h>
+#include <linux/irq.h>
#include <asm/ptrace.h>
#include <asm/hyperv-tlfs.h>
@@ -187,6 +188,11 @@ void hv_remove_kexec_handler(void);
void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
void hv_remove_crash_handler(void);
+extern void vmbus_irq_mask(struct irq_data *data);
+extern void vmbus_irq_unmask(struct irq_data *data);
+extern int vmbus_irq_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force);
+
extern int vmbus_interrupt;
extern int vmbus_irq;
--
2.25.1
next prev parent reply other threads:[~2024-06-04 5:10 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-04 5:09 [RFC 00/12] Hyper-V guests use Linux IRQs for channel interrupts mhkelley58
2024-06-04 5:09 ` [RFC 01/12] Drivers: hv: vmbus: Drop unsupported VMBus devices earlier mhkelley58
2024-06-24 7:11 ` Wei Liu
2024-06-04 5:09 ` [RFC 02/12] Drivers: hv: vmbus: Fix error path that deletes non-existent sysfs group mhkelley58
2024-06-04 5:09 ` [RFC 03/12] Drivers: hv: vmbus: Add an IRQ name to VMBus channels mhkelley58
2024-06-04 5:09 ` [RFC 04/12] PCI: hv: Annotate the VMBus channel IRQ name mhkelley58
2024-09-20 23:13 ` Bjorn Helgaas
2024-06-04 5:09 ` [RFC 05/12] scsi: storvsc: " mhkelley58
2024-06-04 5:09 ` [RFC 06/12] genirq: Add per-cpu flow handler with conditional IRQ stats mhkelley58
2024-06-04 18:13 ` Thomas Gleixner
2024-06-04 23:03 ` Michael Kelley
2024-06-05 13:20 ` Thomas Gleixner
2024-06-05 13:45 ` Michael Kelley
2024-06-05 14:19 ` Thomas Gleixner
2024-06-06 3:14 ` Michael Kelley
2024-06-06 9:34 ` Thomas Gleixner
2024-06-06 14:34 ` Michael Kelley
2024-06-04 5:09 ` mhkelley58 [this message]
2024-06-04 5:09 ` [RFC 08/12] Drivers: hv: vmbus: Allocate an IRQ per channel and use for relid mapping mhkelley58
2024-06-04 5:09 ` [RFC 09/12] Drivers: hv: vmbus: Use Linux IRQs to handle VMBus channel interrupts mhkelley58
2024-06-04 5:09 ` [RFC 10/12] Drivers: hv: vmbus: Implement vmbus_irq_set_affinity mhkelley58
2024-06-04 5:09 ` [RFC 11/12] Drivers: hv: vmbus: Wait for MODIFYCHANNEL to finish when offlining CPUs mhkelley58
2024-06-24 17:55 ` Boqun Feng
2024-06-24 19:32 ` Michael Kelley
2024-06-04 5:09 ` [RFC 12/12] Drivers: hv: vmbus: Ensure IRQ affinity isn't set to a CPU going offline mhkelley58
2024-09-16 18:15 ` [RFC 00/12] Hyper-V guests use Linux IRQs for channel interrupts Michael Kelley
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=20240604050940.859909-8-mhklinux@outlook.com \
--to=mhkelley58@gmail.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=arnd@arndb.de \
--cc=bhelgaas@google.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=dawei.li@shingroup.cn \
--cc=decui@microsoft.com \
--cc=den@valinux.co.jp \
--cc=haiyangz@microsoft.com \
--cc=hpa@zytor.com \
--cc=jgowans@amazon.com \
--cc=kw@linux.com \
--cc=kys@microsoft.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=martin.petersen@oracle.com \
--cc=maz@kernel.org \
--cc=mhklinux@outlook.com \
--cc=mingo@redhat.com \
--cc=robh@kernel.org \
--cc=tglx@linutronix.de \
--cc=wei.liu@kernel.org \
--cc=x86@kernel.org \
/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