Skip to content

Commit f0383c2

Browse files
committed
genirq/cpuhotplug: Add support for cleaning up move in progress
In order to move x86 to the generic hotplug migration code, add support for cleaning up move in progress bits. On architectures which have this x86 specific (mis)feature not enabled, this is optimized out by the compiler. Signed-off-by: Thomas Gleixner <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Keith Busch <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Christoph Hellwig <[email protected]> Link: http://lkml.kernel.org/r/[email protected]
1 parent 91f26cb commit f0383c2

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

arch/x86/include/asm/irq.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ struct irq_desc;
2929
#include <linux/cpumask.h>
3030
extern int check_irq_vectors_for_cpu_disable(void);
3131
extern void fixup_irqs(void);
32-
extern void irq_force_complete_move(struct irq_desc *desc);
3332
#endif
3433

3534
#ifdef CONFIG_HAVE_KVM

include/linux/irq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,10 +491,12 @@ extern void irq_migrate_all_off_this_cpu(void);
491491
#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
492492
void irq_move_irq(struct irq_data *data);
493493
void irq_move_masked_irq(struct irq_data *data);
494+
void irq_force_complete_move(struct irq_desc *desc);
494495
bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear);
495496
#else
496497
static inline void irq_move_irq(struct irq_data *data) { }
497498
static inline void irq_move_masked_irq(struct irq_data *data) { }
499+
static inline void irq_force_complete_move(struct irq_desc *desc) { }
498500
static inline bool irq_fixup_move_pending(struct irq_desc *desc, bool fclear)
499501
{
500502
return false;

kernel/irq/cpuhotplug.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static bool migrate_one_irq(struct irq_desc *desc)
1818
{
1919
struct irq_data *d = irq_desc_get_irq_data(desc);
2020
struct irq_chip *chip = irq_data_get_irq_chip(d);
21-
const struct cpumask *affinity = d->common->affinity;
21+
const struct cpumask *affinity;
2222
bool brokeaff = false;
2323
int err;
2424

@@ -41,9 +41,33 @@ static bool migrate_one_irq(struct irq_desc *desc)
4141
* Note: Do not check desc->action as this might be a chained
4242
* interrupt.
4343
*/
44+
affinity = irq_data_get_affinity_mask(d);
4445
if (irqd_is_per_cpu(d) || !irqd_is_started(d) ||
45-
!cpumask_test_cpu(smp_processor_id(), affinity))
46+
!cpumask_test_cpu(smp_processor_id(), affinity)) {
47+
/*
48+
* If an irq move is pending, abort it if the dying CPU is
49+
* the sole target.
50+
*/
51+
irq_fixup_move_pending(desc, false);
4652
return false;
53+
}
54+
55+
/*
56+
* Complete an eventually pending irq move cleanup. If this
57+
* interrupt was moved in hard irq context, then the vectors need
58+
* to be cleaned up. It can't wait until this interrupt actually
59+
* happens and this CPU was involved.
60+
*/
61+
irq_force_complete_move(desc);
62+
63+
/*
64+
* If there is a setaffinity pending, then try to reuse the pending
65+
* mask, so the last change of the affinity does not get lost. If
66+
* there is no move pending or the pending mask does not contain
67+
* any online CPU, use the current affinity mask.
68+
*/
69+
if (irq_fixup_move_pending(desc, true))
70+
affinity = irq_desc_get_pending_mask(desc);
4771

4872
if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
4973
affinity = cpu_online_mask;

kernel/irq/internals.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ irq_get_pending(struct cpumask *mask, struct irq_desc *desc)
268268
{
269269
cpumask_copy(mask, desc->pending_mask);
270270
}
271+
static inline struct cpumask *irq_desc_get_pending_mask(struct irq_desc *desc)
272+
{
273+
return desc->pending_mask;
274+
}
271275
#else /* CONFIG_GENERIC_PENDING_IRQ */
272276
static inline bool irq_can_move_pcntxt(struct irq_data *data)
273277
{
@@ -285,7 +289,11 @@ static inline void
285289
irq_get_pending(struct cpumask *mask, struct irq_desc *desc)
286290
{
287291
}
288-
#endif /* CONFIG_GENERIC_PENDING_IRQ */
292+
static inline struct cpumask *irq_desc_get_pending_mask(struct irq_desc *desc)
293+
{
294+
return NULL;
295+
}
296+
#endif /* !CONFIG_GENERIC_PENDING_IRQ */
289297

290298
#ifdef CONFIG_GENERIC_IRQ_DEBUGFS
291299
void irq_add_debugfs_entry(unsigned int irq, struct irq_desc *desc);

0 commit comments

Comments
 (0)