From: David Woodhouse <dwmw@xxxxxxxxxxxx> 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 <dwmw@xxxxxxxxxxxx> --- 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 1b7f4dfee35b..6e119594d35d 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 f6e5515ee077..079339decc23 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 4ac91b9fc618..fcc3b8a1fe01 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 76cd7ebd1178..c93e00ca11d8 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.26.2