From aea59b6a8bf14f9f9981f085ccd9e8aaa18d1850 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sun, 4 Oct 2020 16:51:38 +0100 Subject: [PATCH] genirq: Add default_affinity argument to __irq_alloc_descs() It already takes an array of affinities for each individual irq being allocated but that's awkward to allocate and populate in the case where they're all the same and inherited from the irqdomain, so pass the default in separately as a simple cpumask. Signed-off-by: David Woodhouse --- include/linux/irq.h | 10 ++++++---- kernel/irq/devres.c | 8 ++++++-- kernel/irq/irqdesc.c | 10 ++++++++-- kernel/irq/irqdomain.c | 6 +++--- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/linux/irq.h b/include/linux/irq.h index 1b7f4dfee35b3..6e119594d35de 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -897,15 +897,17 @@ unsigned int arch_dynirq_lower_bound(unsigned int from); int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, struct module *owner, - const struct irq_affinity_desc *affinity); + const struct irq_affinity_desc *affinity, + const struct cpumask *default_affinity); int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from, unsigned int cnt, int node, struct module *owner, - const struct irq_affinity_desc *affinity); + const struct irq_affinity_desc *affinity, + const struct cpumask *default_affinity); /* use macros to avoid needing export.h for THIS_MODULE */ #define irq_alloc_descs(irq, from, cnt, node) \ - __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE, NULL) + __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE, NULL, NULL) #define irq_alloc_desc(node) \ irq_alloc_descs(-1, 0, 1, node) @@ -920,7 +922,7 @@ int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from, irq_alloc_descs(-1, from, cnt, node) #define devm_irq_alloc_descs(dev, irq, from, cnt, node) \ - __devm_irq_alloc_descs(dev, irq, from, cnt, node, THIS_MODULE, NULL) + __devm_irq_alloc_descs(dev, irq, from, cnt, node, THIS_MODULE, NULL, NULL) #define devm_irq_alloc_desc(dev, node) \ devm_irq_alloc_descs(dev, -1, 0, 1, node) diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c index f6e5515ee0774..079339decc236 100644 --- a/kernel/irq/devres.c +++ b/kernel/irq/devres.c @@ -170,6 +170,8 @@ static void devm_irq_desc_release(struct device *dev, void *res) * @affinity: Optional pointer to an irq_affinity_desc array of size @cnt * which hints where the irq descriptors should be allocated * and which default affinities to use + * @default_affinity: Optional pointer to a cpumask indicating the default + * affinity to use where not specified by the @affinity array * * Returns the first irq number or error code. * @@ -177,7 +179,8 @@ static void devm_irq_desc_release(struct device *dev, void *res) */ int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from, unsigned int cnt, int node, struct module *owner, - const struct irq_affinity_desc *affinity) + const struct irq_affinity_desc *affinity, + const struct cpumask *default_affinity) { struct irq_desc_devres *dr; int base; @@ -186,7 +189,8 @@ int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from, if (!dr) return -ENOMEM; - base = __irq_alloc_descs(irq, from, cnt, node, owner, affinity); + base = __irq_alloc_descs(irq, from, cnt, node, owner, affinity, + default_affinity); if (base < 0) { devres_free(dr); return base; diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 4ac91b9fc618e..fcc3b8a1fe01c 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -770,15 +770,21 @@ EXPORT_SYMBOL_GPL(irq_free_descs); * @affinity: Optional pointer to an affinity mask array of size @cnt which * hints where the irq descriptors should be allocated and which * default affinities to use + * @default_affinity: Optional pointer to a cpumask indicating the default + * affinity where not specified in the @affinity array * * Returns the first irq number or error code */ int __ref __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, - struct module *owner, const struct irq_affinity_desc *affinity) + struct module *owner, const struct irq_affinity_desc *affinity, + const struct cpumask *default_affinity) { int start, ret; + if (!default_affinity) + default_affinity = irq_default_affinity; + if (!cnt) return -EINVAL; @@ -808,7 +814,7 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, if (ret) goto unlock; } - ret = alloc_descs(start, cnt, node, affinity, irq_default_affinity, owner); + ret = alloc_descs(start, cnt, node, affinity, default_affinity, owner); unlock: mutex_unlock(&sparse_irq_lock); return ret; diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 76cd7ebd1178c..c93e00ca11d86 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1017,16 +1017,16 @@ int irq_domain_alloc_descs(int virq, unsigned int cnt, irq_hw_number_t hwirq, if (virq >= 0) { virq = __irq_alloc_descs(virq, virq, cnt, node, THIS_MODULE, - affinity); + affinity, NULL); } else { hint = hwirq % nr_irqs; if (hint == 0) hint++; virq = __irq_alloc_descs(-1, hint, cnt, node, THIS_MODULE, - affinity); + affinity, NULL); if (virq <= 0 && hint > 1) { virq = __irq_alloc_descs(-1, 1, cnt, node, THIS_MODULE, - affinity); + affinity, NULL); } } -- 2.50.1