Skip to content

Commit 7cec18a

Browse files
mpredfearnKAGA-KOKO
authored andcommitted
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 <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: Qais Yousef <[email protected]> Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Thomas Gleixner <[email protected]>
1 parent 01292ce commit 7cec18a

File tree

2 files changed

+19
-17
lines changed

2 files changed

+19
-17
lines changed

include/linux/irqdomain.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,9 +346,8 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
346346
irq_hw_number_t *out_hwirq, unsigned int *out_type);
347347

348348
/* IPI functions */
349-
unsigned int irq_reserve_ipi(struct irq_domain *domain,
350-
const struct cpumask *dest);
351-
void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
349+
int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
350+
int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
352351

353352
/* V2 interfaces to support hierarchy IRQ domains. */
354353
extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,

kernel/irq/ipi.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
*
2020
* Allocate a virq that can be used to send IPI to any CPU in dest mask.
2121
*
22-
* On success it'll return linux irq number and 0 on failure
22+
* On success it'll return linux irq number and error code on failure
2323
*/
24-
unsigned int irq_reserve_ipi(struct irq_domain *domain,
24+
int irq_reserve_ipi(struct irq_domain *domain,
2525
const struct cpumask *dest)
2626
{
2727
unsigned int nr_irqs, offset;
@@ -30,18 +30,18 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain,
3030

3131
if (!domain ||!irq_domain_is_ipi(domain)) {
3232
pr_warn("Reservation on a non IPI domain\n");
33-
return 0;
33+
return -EINVAL;
3434
}
3535

3636
if (!cpumask_subset(dest, cpu_possible_mask)) {
3737
pr_warn("Reservation is not in possible_cpu_mask\n");
38-
return 0;
38+
return -EINVAL;
3939
}
4040

4141
nr_irqs = cpumask_weight(dest);
4242
if (!nr_irqs) {
4343
pr_warn("Reservation for empty destination mask\n");
44-
return 0;
44+
return -EINVAL;
4545
}
4646

4747
if (irq_domain_is_ipi_single(domain)) {
@@ -72,14 +72,14 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain,
7272
next = cpumask_next(next, dest);
7373
if (next < nr_cpu_ids) {
7474
pr_warn("Destination mask has holes\n");
75-
return 0;
75+
return -EINVAL;
7676
}
7777
}
7878

7979
virq = irq_domain_alloc_descs(-1, nr_irqs, 0, NUMA_NO_NODE);
8080
if (virq <= 0) {
8181
pr_warn("Can't reserve IPI, failed to alloc descs\n");
82-
return 0;
82+
return -ENOMEM;
8383
}
8484

8585
virq = __irq_domain_alloc_irqs(domain, virq, nr_irqs, NUMA_NO_NODE,
@@ -100,42 +100,44 @@ unsigned int irq_reserve_ipi(struct irq_domain *domain,
100100

101101
free_descs:
102102
irq_free_descs(virq, nr_irqs);
103-
return 0;
103+
return -EBUSY;
104104
}
105105

106106
/**
107107
* irq_destroy_ipi() - unreserve an IPI that was previously allocated
108108
* @irq: linux irq number to be destroyed
109109
* @dest: cpumask of cpus which should have the IPI removed
110110
*
111-
* Return the IPIs allocated with irq_reserve_ipi() to the system destroying
112-
* all virqs associated with them.
111+
* The IPIs allocated with irq_reserve_ipi() are retuerned to the system
112+
* destroying all virqs associated with them.
113+
*
114+
* Return 0 on success or error code on failure.
113115
*/
114-
void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
116+
int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
115117
{
116118
struct irq_data *data = irq_get_irq_data(irq);
117119
struct cpumask *ipimask = data ? irq_data_get_affinity_mask(data) : NULL;
118120
struct irq_domain *domain;
119121
unsigned int nr_irqs;
120122

121123
if (!irq || !data || !ipimask)
122-
return;
124+
return -EINVAL;
123125

124126
domain = data->domain;
125127
if (WARN_ON(domain == NULL))
126128
return;
127129

128130
if (!irq_domain_is_ipi(domain)) {
129131
pr_warn("Trying to destroy a non IPI domain!\n");
130-
return;
132+
return -EINVAL;
131133
}
132134

133135
if (WARN_ON(!cpumask_subset(dest, ipimask)))
134136
/*
135137
* Must be destroying a subset of CPUs to which this IPI
136138
* was set up to target
137139
*/
138-
return;
140+
return -EINVAL;
139141

140142
if (irq_domain_is_ipi_per_cpu(domain)) {
141143
irq = irq + cpumask_first(dest) - data->common->ipi_offset;
@@ -145,6 +147,7 @@ void irq_destroy_ipi(unsigned int irq, const struct cpumask *dest)
145147
}
146148

147149
irq_domain_free_irqs(irq, nr_irqs);
150+
return 0;
148151
}
149152

150153
/**

0 commit comments

Comments
 (0)