From: David Woodhouse <dwmw2@infradead.org>
To: x86@kernel.org
Cc: iommu <iommu@lists.linux-foundation.org>,
kvm <kvm@vger.kernel.org>,
linux-hyperv@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>
Subject: [PATCH 08/13] genirq: Add irq_domain_set_affinity()
Date: Mon, 5 Oct 2020 16:28:51 +0100 [thread overview]
Message-ID: <20201005152856.974112-8-dwmw2@infradead.org> (raw)
In-Reply-To: <20201005152856.974112-1-dwmw2@infradead.org>
From: David Woodhouse <dwmw@amazon.co.uk>
This allows a maximal affinity to be set, for IRQ domains which cannot
target all CPUs in the system.
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
include/linux/irqdomain.h | 4 ++++
kernel/irq/irqdomain.c | 28 ++++++++++++++++++++++++++--
kernel/irq/manage.c | 19 +++++++++++++++----
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 6b5576da77f0..cf686f18c1fa 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -151,6 +151,7 @@ struct irq_domain_chip_generic;
* drivers using the generic chip library which uses this pointer.
* @parent: Pointer to parent irq_domain to support hierarchy irq_domains
* @debugfs_file: dentry for the domain debugfs file
+ * @max_affinity: mask of CPUs targetable by this IRQ domain
*
* Revmap data, used internally by irq_domain
* @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
@@ -177,6 +178,7 @@ struct irq_domain {
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
struct dentry *debugfs_file;
#endif
+ const struct cpumask *max_affinity;
/* reverse map data. The linear map gets appended to the irq_domain */
irq_hw_number_t hwirq_max;
@@ -453,6 +455,8 @@ extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
void *chip_data, irq_flow_handler_t handler,
void *handler_data, const char *handler_name);
extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
+extern int irq_domain_set_affinity(struct irq_domain *domain,
+ const struct cpumask *affinity);
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
extern struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
unsigned int flags, unsigned int size,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index ffd41f21afca..0b298355be1b 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -661,7 +661,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
/* Allocate a virtual interrupt number */
virq = irq_domain_alloc_descs(-1, 1, hwirq, of_node_to_nid(of_node),
- NULL, NULL);
+ NULL, domain->max_affinity);
if (virq <= 0) {
pr_debug("-> virq allocation failed\n");
return 0;
@@ -1078,6 +1078,27 @@ void irq_domain_reset_irq_data(struct irq_data *irq_data)
}
EXPORT_SYMBOL_GPL(irq_domain_reset_irq_data);
+/**
+ * irq_domain_set_affinity - Set maximum CPU affinity for domain
+ * @parent: Domain to set affinity for
+ * @affinity: Pointer to cpumask, consumed by domain
+ *
+ * Sets the maximal set of CPUs to which interrupts in this domain may
+ * be delivered. Must only be called after creation, before any interrupts
+ * have been in the domain.
+ *
+ * This function retains a pointer to the cpumask which is passed in.
+ */
+int irq_domain_set_affinity(struct irq_domain *domain,
+ const struct cpumask *affinity)
+{
+ if (cpumask_empty(affinity))
+ return -EINVAL;
+ domain->max_affinity = affinity;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_set_affinity);
+
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
/**
* irq_domain_create_hierarchy - Add a irqdomain into the hierarchy
@@ -1110,6 +1131,9 @@ struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
if (domain) {
domain->parent = parent;
domain->flags |= flags;
+ if (parent && parent->max_affinity)
+ irq_domain_set_affinity(domain,
+ parent->max_affinity);
}
return domain;
@@ -1375,7 +1399,7 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
virq = irq_base;
} else {
virq = irq_domain_alloc_descs(irq_base, nr_irqs, 0, node,
- affinity, NULL);
+ affinity, domain->max_affinity);
if (virq < 0) {
pr_debug("cannot allocate IRQ(base %d, count %d)\n",
irq_base, nr_irqs);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 5df903fccb60..e8c5f8ecd306 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -345,6 +345,10 @@ int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
struct irq_desc *desc = irq_data_to_desc(data);
int ret = 0;
+ if (data->domain && data->domain->max_affinity &&
+ !cpumask_subset(mask, data->domain->max_affinity))
+ return -EINVAL;
+
if (!chip || !chip->irq_set_affinity)
return -EINVAL;
@@ -484,13 +488,20 @@ int irq_setup_affinity(struct irq_desc *desc)
struct cpumask *set = irq_default_affinity;
int ret, node = irq_desc_get_node(desc);
static DEFINE_RAW_SPINLOCK(mask_lock);
- static struct cpumask mask;
+ static struct cpumask mask, max_mask;
/* Excludes PER_CPU and NO_BALANCE interrupts */
if (!__irq_can_set_affinity(desc))
return 0;
raw_spin_lock(&mask_lock);
+
+ if (desc->irq_data.domain && desc->irq_data.domain->max_affinity)
+ cpumask_and(&max_mask, cpu_online_mask,
+ desc->irq_data.domain->max_affinity);
+ else
+ cpumask_copy(&max_mask, cpu_online_mask);
+
/*
* Preserve the managed affinity setting and a userspace affinity
* setup, but make sure that one of the targets is online.
@@ -498,15 +509,15 @@ int irq_setup_affinity(struct irq_desc *desc)
if (irqd_affinity_is_managed(&desc->irq_data) ||
irqd_has_set(&desc->irq_data, IRQD_AFFINITY_SET)) {
if (cpumask_intersects(desc->irq_common_data.affinity,
- cpu_online_mask))
+ &max_mask))
set = desc->irq_common_data.affinity;
else
irqd_clear(&desc->irq_data, IRQD_AFFINITY_SET);
}
- cpumask_and(&mask, cpu_online_mask, set);
+ cpumask_and(&mask, &max_mask, set);
if (cpumask_empty(&mask))
- cpumask_copy(&mask, cpu_online_mask);
+ cpumask_copy(&mask, &max_mask);
if (node != NUMA_NO_NODE) {
const struct cpumask *nodemask = cpumask_of_node(node);
--
2.26.2
next prev parent reply other threads:[~2020-10-05 15:29 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-05 15:28 [PATCH 0/13] Fix per-domain IRQ affinity, allow >255 CPUs on x86 without IRQ remapping David Woodhouse
2020-10-05 15:28 ` [PATCH 01/13] x86/apic: Use x2apic in guest kernels even with unusable CPUs David Woodhouse
2020-10-05 15:28 ` [PATCH 02/13] x86/msi: Only use high bits of MSI address for DMAR unit David Woodhouse
2020-10-06 20:45 ` Thomas Gleixner
2020-10-05 15:28 ` [PATCH 03/13] x86/ioapic: Handle Extended Destination ID field in RTE David Woodhouse
2020-10-05 15:28 ` [PATCH 04/13] x86/apic: Support 15 bits of APIC ID in IOAPIC/MSI where available David Woodhouse
2020-10-05 15:28 ` [PATCH 05/13] genirq: Prepare for default affinity to be passed to __irq_alloc_descs() David Woodhouse
2020-10-06 21:01 ` Thomas Gleixner
2020-10-06 21:07 ` David Woodhouse
2020-10-05 15:28 ` [PATCH 06/13] genirq: Add default_affinity argument " David Woodhouse
2020-10-06 21:06 ` Thomas Gleixner
2020-10-05 15:28 ` [PATCH 07/13] irqdomain: Add max_affinity argument to irq_domain_alloc_descs() David Woodhouse
2020-10-06 21:26 ` Thomas Gleixner
2020-10-07 7:19 ` David Woodhouse
2020-10-07 13:37 ` Thomas Gleixner
2020-10-07 14:10 ` David Woodhouse
2020-10-07 15:57 ` Thomas Gleixner
2020-10-07 16:11 ` David Woodhouse
2020-10-07 20:53 ` Thomas Gleixner
2020-10-08 7:21 ` David Woodhouse
2020-10-08 9:34 ` Thomas Gleixner
2020-10-08 11:10 ` David Woodhouse
2020-10-08 12:40 ` Thomas Gleixner
2020-10-09 7:54 ` David Woodhouse
2020-10-05 15:28 ` David Woodhouse [this message]
2020-10-06 21:32 ` [PATCH 08/13] genirq: Add irq_domain_set_affinity() Thomas Gleixner
2020-10-07 7:22 ` David Woodhouse
2020-10-05 15:28 ` [PATCH 09/13] x86/irq: Add x86_non_ir_cpumask David Woodhouse
2020-10-06 21:42 ` Thomas Gleixner
2020-10-07 7:25 ` David Woodhouse
2020-10-05 15:28 ` [PATCH 10/13] x86/irq: Limit IOAPIC and MSI domains' affinity without IR David Woodhouse
2020-10-06 21:54 ` Thomas Gleixner
2020-10-07 7:48 ` David Woodhouse
2020-10-07 12:59 ` Thomas Gleixner
2020-10-07 13:08 ` David Woodhouse
2020-10-07 14:05 ` Thomas Gleixner
2020-10-07 14:23 ` David Woodhouse
2020-10-07 16:02 ` Thomas Gleixner
2020-10-07 16:15 ` David Woodhouse
2020-10-07 15:05 ` David Woodhouse
2020-10-07 15:25 ` Thomas Gleixner
2020-10-07 15:46 ` David Woodhouse
2020-10-07 17:23 ` Thomas Gleixner
2020-10-07 17:34 ` David Woodhouse
2020-10-05 15:28 ` [PATCH 11/13] x86/smp: Allow more than 255 CPUs even without interrupt remapping David Woodhouse
2020-10-05 15:28 ` [PATCH 12/13] iommu/irq_remapping: Kill most of hyperv-iommu.c now it's redundant David Woodhouse
2020-10-05 15:28 ` [PATCH 13/13] x86/kvm: Add KVM_FEATURE_MSI_EXT_DEST_ID David Woodhouse
2020-10-07 8:14 ` Paolo Bonzini
2020-10-07 8:59 ` David Woodhouse
2020-10-07 11:15 ` Paolo Bonzini
2020-10-07 12:04 ` David Woodhouse
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=20201005152856.974112-8-dwmw2@infradead.org \
--to=dwmw2@infradead.org \
--cc=iommu@lists.linux-foundation.org \
--cc=kvm@vger.kernel.org \
--cc=linux-hyperv@vger.kernel.org \
--cc=pbonzini@redhat.com \
--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;
as well as URLs for NNTP newsgroup(s).