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 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 index 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
Linux-HyperV Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-hyperv/0 linux-hyperv/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-hyperv linux-hyperv/ https://lore.kernel.org/linux-hyperv \ linux-hyperv@vger.kernel.org public-inbox-index linux-hyperv Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-hyperv AGPL code for this site: git clone https://public-inbox.org/public-inbox.git