summaryrefslogtreecommitdiffstats
path: root/kernel/irq/migration.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/migration.c')
-rw-r--r--kernel/irq/migration.c30
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 */
17bool 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
7void irq_move_masked_irq(struct irq_data *idata) 37void 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);