diff options
Diffstat (limited to 'kernel/irq/migration.c')
-rw-r--r-- | kernel/irq/migration.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c index 37ddb7bda651..6ca054a3f91d 100644 --- a/kernel/irq/migration.c +++ b/kernel/irq/migration.c | |||
@@ -4,6 +4,36 @@ | |||
4 | 4 | ||
5 | #include "internals.h" | 5 | #include "internals.h" |
6 | 6 | ||
7 | /** | ||
8 | * irq_fixup_move_pending - Cleanup irq move pending from a dying CPU | ||
9 | * @desc: Interrupt descpriptor to clean up | ||
10 | * @force_clear: If set clear the move pending bit unconditionally. | ||
11 | * If not set, clear it only when the dying CPU is the | ||
12 | * last one in the pending mask. | ||
13 | * | ||
14 | * Returns true if the pending bit was set and the pending mask contains an | ||
15 | * online CPU other than the dying CPU. | ||
16 | */ | ||
17 | bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear) | ||
18 | { | ||
19 | struct irq_data *data = irq_desc_get_irq_data(desc); | ||
20 | |||
21 | if (!irqd_is_setaffinity_pending(data)) | ||
22 | return false; | ||
23 | |||
24 | /* | ||
25 | * The outgoing CPU might be the last online target in a pending | ||
26 | * interrupt move. If that's the case clear the pending move bit. | ||
27 | */ | ||
28 | if (cpumask_any_and(desc->pending_mask, cpu_online_mask) >= nr_cpu_ids) { | ||
29 | irqd_clr_move_pending(data); | ||
30 | return false; | ||
31 | } | ||
32 | if (force_clear) | ||
33 | irqd_clr_move_pending(data); | ||
34 | return true; | ||
35 | } | ||
36 | |||
7 | void irq_move_masked_irq(struct irq_data *idata) | 37 | void irq_move_masked_irq(struct irq_data *idata) |
8 | { | 38 | { |
9 | struct irq_desc *desc = irq_data_to_desc(idata); | 39 | struct irq_desc *desc = irq_data_to_desc(idata); |