summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/irq/migration.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 86ae0eb80b53..8b8cecd18cce 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -38,17 +38,18 @@ bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear)
38void irq_move_masked_irq(struct irq_data *idata) 38void irq_move_masked_irq(struct irq_data *idata)
39{ 39{
40 struct irq_desc *desc = irq_data_to_desc(idata); 40 struct irq_desc *desc = irq_data_to_desc(idata);
41 struct irq_chip *chip = desc->irq_data.chip; 41 struct irq_data *data = &desc->irq_data;
42 struct irq_chip *chip = data->chip;
42 43
43 if (likely(!irqd_is_setaffinity_pending(&desc->irq_data))) 44 if (likely(!irqd_is_setaffinity_pending(data)))
44 return; 45 return;
45 46
46 irqd_clr_move_pending(&desc->irq_data); 47 irqd_clr_move_pending(data);
47 48
48 /* 49 /*
49 * Paranoia: cpu-local interrupts shouldn't be calling in here anyway. 50 * Paranoia: cpu-local interrupts shouldn't be calling in here anyway.
50 */ 51 */
51 if (irqd_is_per_cpu(&desc->irq_data)) { 52 if (irqd_is_per_cpu(data)) {
52 WARN_ON(1); 53 WARN_ON(1);
53 return; 54 return;
54 } 55 }
@@ -73,9 +74,20 @@ void irq_move_masked_irq(struct irq_data *idata)
73 * For correct operation this depends on the caller 74 * For correct operation this depends on the caller
74 * masking the irqs. 75 * masking the irqs.
75 */ 76 */
76 if (cpumask_any_and(desc->pending_mask, cpu_online_mask) < nr_cpu_ids) 77 if (cpumask_any_and(desc->pending_mask, cpu_online_mask) < nr_cpu_ids) {
77 irq_do_set_affinity(&desc->irq_data, desc->pending_mask, false); 78 int ret;
78 79
80 ret = irq_do_set_affinity(data, desc->pending_mask, false);
81 /*
82 * If the there is a cleanup pending in the underlying
83 * vector management, reschedule the move for the next
84 * interrupt. Leave desc->pending_mask intact.
85 */
86 if (ret == -EBUSY) {
87 irqd_set_move_pending(data);
88 return;
89 }
90 }
79 cpumask_clear(desc->pending_mask); 91 cpumask_clear(desc->pending_mask);
80} 92}
81 93