* [PATCH v2 1/2] genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy
@ 2016-04-25 7:14 Matt Redfearn
2016-04-25 7:14 ` [PATCH v2 2/2] genirq: Add error code reporting to irq_{reserve,destroy}_ipi Matt Redfearn
2016-05-02 12:33 ` [tip:irq/core] genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy tip-bot for Matt Redfearn
0 siblings, 2 replies; 4+ messages in thread
From: Matt Redfearn @ 2016-04-25 7:14 UTC (permalink / raw)
To: Thomas Gleixner
Cc: lisa.parratt, jason, ralf, linux-kernel, jiang.liu, marc.zyngier,
linux-mips, Qais Yousef, Matt Redfearn
Previously irq_destroy_ipi() would destroy IPIs to all CPUs that were
configured by irq_reserve_ipi(). This change makes it possible to
destroy just a subset of the IPIs. This may be useful to remove IPIs to
CPUs that have been hot removed so that the IRQ numbers allocated within
the IPI domain can be re-used.
The original behaviour is restored by passing the complete mask that the
IPI was created with.
There are currently no users of this function that would break from the
API change.
Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
---
Changes in v2: None
include/linux/irqdomain.h | 2 +-
kernel/irq/ipi.c | 18 ++++++++++++++----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 2aed04396210..e1b81d35e7a3 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -348,7 +348,7 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
/* IPI functions */
unsigned int irq_reserve_ipi(struct irq_domain *domain,
const struct cpumask *dest);
-void irq_destroy_ipi(unsigned int irq);
+void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
/* V2 interfaces to support hierarchy IRQ domains. */
extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c
index 14777af8e097..bedc995ae214 100644
--- a/kernel/irq/ipi.c
+++ b/kernel/irq/ipi.c
@@ -106,11 +106,12 @@ free_descs:
/**
* irq_destroy_ipi() - unreserve an IPI that was previously allocated
* @irq: linux irq number to be destroyed
+ * @dest: cpumask of cpus which should have the IPI removed
*
* Return the IPIs allocated with irq_reserve_ipi() to the system destroying
* all virqs associated with them.
*/
-void irq_destroy_ipi(unsigned int irq)
+void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
{
struct irq_data *data = irq_get_irq_data(irq);
struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL;
@@ -129,10 +130,19 @@ void irq_destroy_ipi(unsigned int irq)
return;
}
- if (irq_domain_is_ipi_per_cpu(domain))
- nr_irqs = cpumask_weight(ipimask);
- else
+ if (WARN_ON(!cpumask_subset(dest, ipimask)))
+ /*
+ * Must be destroying a subset of CPUs to which this IPI
+ * was set up to target
+ */
+ return;
+
+ if (irq_domain_is_ipi_per_cpu(domain)) {
+ irq = irq + cpumask_first(dest) - data->common->ipi_offset;
+ nr_irqs = cpumask_weight(dest);
+ } else {
nr_irqs = 1;
+ }
irq_domain_free_irqs(irq, nr_irqs);
}
--
2.5.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v2 2/2] genirq: Add error code reporting to irq_{reserve,destroy}_ipi 2016-04-25 7:14 [PATCH v2 1/2] genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy Matt Redfearn @ 2016-04-25 7:14 ` Matt Redfearn 2016-05-02 12:34 ` [tip:irq/core] " tip-bot for Matt Redfearn 2016-05-02 12:33 ` [tip:irq/core] genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy tip-bot for Matt Redfearn 1 sibling, 1 reply; 4+ messages in thread From: Matt Redfearn @ 2016-04-25 7:14 UTC (permalink / raw) To: Thomas Gleixner Cc: lisa.parratt, jason, ralf, linux-kernel, jiang.liu, marc.zyngier, linux-mips, Qais Yousef, Matt Redfearn Make these functions return appropriate error codes when something goes wrong. Previously irq_destroy_ipi returned void making it impossible to notify the caller if the request could not be fulfilled. Patch 1 in the series added another condition in which this could fail in addition to the existing ones. irq_reserve_ipi returned an unsigned int meaning it could only return 0 on failure and give the caller no indication as to why the request failed. As time goes on there are likely to be further conditions added in which these functions can fail. These APIs and the IPI IRQ domain are new in 4.6 and the number of existing call sites are low, changing the API now has little impact on the code, while making it easier for these functions to grow over time. Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> --- Changes in v2: - More descriptive commit message include/linux/irqdomain.h | 5 ++--- kernel/irq/ipi.c | 31 +++++++++++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index e1b81d35e7a3..736abd74c135 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -346,9 +346,8 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, irq_hw_number_t *out_hwirq, unsigned int *out_type); /* IPI functions */ -unsigned int irq_reserve_ipi(struct irq_domain *domain, - const struct cpumask *dest); -void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest); +int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest); +int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest); /* V2 interfaces to support hierarchy IRQ domains. */ extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index bedc995ae214..c42742208e5e 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -19,9 +19,9 @@ * * Allocate a virq that can be used to send IPI to any CPU in dest mask. * - * On success it'll return linux irq number and 0 on failure + * On success it'll return linux irq number and error code on failure */ -unsigned int irq_reserve_ipi(struct irq_domain *domain, +int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest) { unsigned int nr_irqs, offset; @@ -30,18 +30,18 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, if (!domain ||!irq_domain_is_ipi(domain)) { pr_warn("Reservation on a non IPI domain\n"); - return 0; + return -EINVAL; } if (!cpumask_subset(dest, cpu_possible_mask)) { pr_warn("Reservation is not in possible_cpu_mask\n"); - return 0; + return -EINVAL; } nr_irqs = cpumask_weight(dest); if (!nr_irqs) { pr_warn("Reservation for empty destination mask\n"); - return 0; + return -EINVAL; } if (irq_domain_is_ipi_single(domain)) { @@ -72,14 +72,14 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, next = cpumask_next(next, dest); if (next < nr_cpu_ids) { pr_warn("Destination mask has holes\n"); - return 0; + return -EINVAL; } } virq = irq_domain_alloc_descs(-1, nr_irqs, 0, NUMA_NO_NODE); if (virq <= 0) { pr_warn("Can't reserve IPI, failed to alloc descs\n"); - return 0; + return -ENOMEM; } virq = __irq_domain_alloc_irqs(domain, virq, nr_irqs, NUMA_NO_NODE, @@ -100,7 +100,7 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, free_descs: irq_free_descs(virq, nr_irqs); - return 0; + return -EBUSY; } /** @@ -108,10 +108,12 @@ free_descs: * @irq: linux irq number to be destroyed * @dest: cpumask of cpus which should have the IPI removed * - * Return the IPIs allocated with irq_reserve_ipi() to the system destroying - * all virqs associated with them. + * The IPIs allocated with irq_reserve_ipi() are retuerned to the system + * destroying all virqs associated with them. + * + * Return 0 on success or error code on failure. */ -void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) +int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) { struct irq_data *data = irq_get_irq_data(irq); struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL; @@ -119,7 +121,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) unsigned int nr_irqs; if (!irq || !data || !ipimask) - return; + return -EINVAL; domain = data->domain; if (WARN_ON(domain == NULL)) @@ -127,7 +129,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) if (!irq_domain_is_ipi(domain)) { pr_warn("Trying to destroy a non IPI domain!\n"); - return; + return -EINVAL; } if (WARN_ON(!cpumask_subset(dest, ipimask))) @@ -135,7 +137,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) * Must be destroying a subset of CPUs to which this IPI * was set up to target */ - return; + return -EINVAL; if (irq_domain_is_ipi_per_cpu(domain)) { irq = irq + cpumask_first(dest) - data->common->ipi_offset; @@ -145,6 +147,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) } irq_domain_free_irqs(irq, nr_irqs); + return 0; } /** -- 2.5.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [tip:irq/core] genirq: Add error code reporting to irq_{reserve,destroy}_ipi 2016-04-25 7:14 ` [PATCH v2 2/2] genirq: Add error code reporting to irq_{reserve,destroy}_ipi Matt Redfearn @ 2016-05-02 12:34 ` tip-bot for Matt Redfearn 0 siblings, 0 replies; 4+ messages in thread From: tip-bot for Matt Redfearn @ 2016-05-02 12:34 UTC (permalink / raw) To: linux-tip-commits; +Cc: tglx, linux-kernel, matt.redfearn, mingo, hpa, qsyousef Commit-ID: 7cec18a3906b52e855c9386650c0226bbe594a4c Gitweb: http://git.kernel.org/tip/7cec18a3906b52e855c9386650c0226bbe594a4c Author: Matt Redfearn <matt.redfearn@imgtec.com> AuthorDate: Mon, 25 Apr 2016 08:14:24 +0100 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Mon, 2 May 2016 13:42:50 +0200 genirq: Add error code reporting to irq_{reserve,destroy}_ipi Make these functions return appropriate error codes when something goes wrong. Previously irq_destroy_ipi returned void making it impossible to notify the caller if the request could not be fulfilled. Patch 1 in the series added another condition in which this could fail in addition to the existing ones. irq_reserve_ipi returned an unsigned int meaning it could only return 0 on failure and give the caller no indication as to why the request failed. As time goes on there are likely to be further conditions added in which these functions can fail. These APIs and the IPI IRQ domain are new in 4.6 and the number of existing call sites are low, changing the API now has little impact on the code, while making it easier for these functions to grow over time. Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> Cc: linux-mips@linux-mips.org Cc: jason@lakedaemon.net Cc: marc.zyngier@arm.com Cc: ralf@linux-mips.org Cc: Qais Yousef <qsyousef@gmail.com> Cc: lisa.parratt@imgtec.com Cc: jiang.liu@linux.intel.com Link: http://lkml.kernel.org/r/1461568464-31701-2-git-send-email-matt.redfearn@imgtec.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/irqdomain.h | 5 ++--- kernel/irq/ipi.c | 31 +++++++++++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index e1b81d3..736abd7 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -346,9 +346,8 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, irq_hw_number_t *out_hwirq, unsigned int *out_type); /* IPI functions */ -unsigned int irq_reserve_ipi(struct irq_domain *domain, - const struct cpumask *dest); -void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest); +int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest); +int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest); /* V2 interfaces to support hierarchy IRQ domains. */ extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index bedc995..c427422 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -19,9 +19,9 @@ * * Allocate a virq that can be used to send IPI to any CPU in dest mask. * - * On success it'll return linux irq number and 0 on failure + * On success it'll return linux irq number and error code on failure */ -unsigned int irq_reserve_ipi(struct irq_domain *domain, +int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest) { unsigned int nr_irqs, offset; @@ -30,18 +30,18 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, if (!domain ||!irq_domain_is_ipi(domain)) { pr_warn("Reservation on a non IPI domain\n"); - return 0; + return -EINVAL; } if (!cpumask_subset(dest, cpu_possible_mask)) { pr_warn("Reservation is not in possible_cpu_mask\n"); - return 0; + return -EINVAL; } nr_irqs = cpumask_weight(dest); if (!nr_irqs) { pr_warn("Reservation for empty destination mask\n"); - return 0; + return -EINVAL; } if (irq_domain_is_ipi_single(domain)) { @@ -72,14 +72,14 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, next = cpumask_next(next, dest); if (next < nr_cpu_ids) { pr_warn("Destination mask has holes\n"); - return 0; + return -EINVAL; } } virq = irq_domain_alloc_descs(-1, nr_irqs, 0, NUMA_NO_NODE); if (virq <= 0) { pr_warn("Can't reserve IPI, failed to alloc descs\n"); - return 0; + return -ENOMEM; } virq = __irq_domain_alloc_irqs(domain, virq, nr_irqs, NUMA_NO_NODE, @@ -100,7 +100,7 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain, free_descs: irq_free_descs(virq, nr_irqs); - return 0; + return -EBUSY; } /** @@ -108,10 +108,12 @@ free_descs: * @irq: linux irq number to be destroyed * @dest: cpumask of cpus which should have the IPI removed * - * Return the IPIs allocated with irq_reserve_ipi() to the system destroying - * all virqs associated with them. + * The IPIs allocated with irq_reserve_ipi() are retuerned to the system + * destroying all virqs associated with them. + * + * Return 0 on success or error code on failure. */ -void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) +int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) { struct irq_data *data = irq_get_irq_data(irq); struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL; @@ -119,7 +121,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) unsigned int nr_irqs; if (!irq || !data || !ipimask) - return; + return -EINVAL; domain = data->domain; if (WARN_ON(domain == NULL)) @@ -127,7 +129,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) if (!irq_domain_is_ipi(domain)) { pr_warn("Trying to destroy a non IPI domain!\n"); - return; + return -EINVAL; } if (WARN_ON(!cpumask_subset(dest, ipimask))) @@ -135,7 +137,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) * Must be destroying a subset of CPUs to which this IPI * was set up to target */ - return; + return -EINVAL; if (irq_domain_is_ipi_per_cpu(domain)) { irq = irq + cpumask_first(dest) - data->common->ipi_offset; @@ -145,6 +147,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) } irq_domain_free_irqs(irq, nr_irqs); + return 0; } /** ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [tip:irq/core] genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy 2016-04-25 7:14 [PATCH v2 1/2] genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy Matt Redfearn 2016-04-25 7:14 ` [PATCH v2 2/2] genirq: Add error code reporting to irq_{reserve,destroy}_ipi Matt Redfearn @ 2016-05-02 12:33 ` tip-bot for Matt Redfearn 1 sibling, 0 replies; 4+ messages in thread From: tip-bot for Matt Redfearn @ 2016-05-02 12:33 UTC (permalink / raw) To: linux-tip-commits; +Cc: tglx, qsyousef, matt.redfearn, hpa, mingo, linux-kernel Commit-ID: 01292cea0df86ed4a1eb6450d6eda375ef925716 Gitweb: http://git.kernel.org/tip/01292cea0df86ed4a1eb6450d6eda375ef925716 Author: Matt Redfearn <matt.redfearn@imgtec.com> AuthorDate: Mon, 25 Apr 2016 08:14:23 +0100 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Mon, 2 May 2016 13:42:50 +0200 genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy Previously irq_destroy_ipi() would destroy IPIs to all CPUs that were configured by irq_reserve_ipi(). This change makes it possible to destroy just a subset of the IPIs. This may be useful to remove IPIs to CPUs that have been hot removed so that the IRQ numbers allocated within the IPI domain can be re-used. The original behaviour is restored by passing the complete mask that the IPI was created with. There are currently no users of this function that would break from the API change. Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> Cc: linux-mips@linux-mips.org Cc: jason@lakedaemon.net Cc: marc.zyngier@arm.com Cc: ralf@linux-mips.org Cc: Qais Yousef <qsyousef@gmail.com> Cc: lisa.parratt@imgtec.com Cc: jiang.liu@linux.intel.com Link: http://lkml.kernel.org/r/1461568464-31701-1-git-send-email-matt.redfearn@imgtec.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/irqdomain.h | 2 +- kernel/irq/ipi.c | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 2aed043..e1b81d3 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -348,7 +348,7 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, /* IPI functions */ unsigned int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest); -void irq_destroy_ipi(unsigned int irq); +void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest); /* V2 interfaces to support hierarchy IRQ domains. */ extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain, diff --git a/kernel/irq/ipi.c b/kernel/irq/ipi.c index 14777af..bedc995 100644 --- a/kernel/irq/ipi.c +++ b/kernel/irq/ipi.c @@ -106,11 +106,12 @@ free_descs: /** * irq_destroy_ipi() - unreserve an IPI that was previously allocated * @irq: linux irq number to be destroyed + * @dest: cpumask of cpus which should have the IPI removed * * Return the IPIs allocated with irq_reserve_ipi() to the system destroying * all virqs associated with them. */ -void irq_destroy_ipi(unsigned int irq) +void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest) { struct irq_data *data = irq_get_irq_data(irq); struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL; @@ -129,10 +130,19 @@ void irq_destroy_ipi(unsigned int irq) return; } - if (irq_domain_is_ipi_per_cpu(domain)) - nr_irqs = cpumask_weight(ipimask); - else + if (WARN_ON(!cpumask_subset(dest, ipimask))) + /* + * Must be destroying a subset of CPUs to which this IPI + * was set up to target + */ + return; + + if (irq_domain_is_ipi_per_cpu(domain)) { + irq = irq + cpumask_first(dest) - data->common->ipi_offset; + nr_irqs = cpumask_weight(dest); + } else { nr_irqs = 1; + } irq_domain_free_irqs(irq, nr_irqs); } ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-05-02 12:34 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-25 7:14 [PATCH v2 1/2] genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy Matt Redfearn
2016-04-25 7:14 ` [PATCH v2 2/2] genirq: Add error code reporting to irq_{reserve,destroy}_ipi Matt Redfearn
2016-05-02 12:34 ` [tip:irq/core] " tip-bot for Matt Redfearn
2016-05-02 12:33 ` [tip:irq/core] genirq: Make irq_destroy_ipi take a cpumask of IPIs to destroy tip-bot for Matt Redfearn
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox