Skip to content

Commit 4cde9c6

Browse files
committed
genirq: Add force argument to irq_startup()
In order to handle managed interrupts gracefully on irq_startup() so they won't lose their assigned affinity, it's necessary to allow startups which keep the interrupts in managed shutdown state, if none of the assigend CPUs is online. This allows drivers to request interrupts w/o the CPUs being online, which avoid online/offline churn in drivers. Add a force argument which can override that decision and let only request_irq() and enable_irq() allow the managed shutdown handling. enable_irq() is required, because the interrupt might be requested with IRQF_NOAUTOEN and enable_irq() invokes irq_startup() which would then wreckage the assignment again. All other callers force startup and potentially break the assigned affinity. No functional change as this only adds the function argument. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Jens Axboe <axboe@kernel.dk> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Keith Busch <keith.busch@intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Christoph Hellwig <hch@lst.de> Link: http://lkml.kernel.org/r/20170619235447.112094565@linutronix.de
1 parent 708d174 commit 4cde9c6

File tree

4 files changed

+14
-7
lines changed

4 files changed

+14
-7
lines changed

kernel/irq/autoprobe.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ unsigned long probe_irq_on(void)
5353
if (desc->irq_data.chip->irq_set_type)
5454
desc->irq_data.chip->irq_set_type(&desc->irq_data,
5555
IRQ_TYPE_PROBE);
56-
irq_startup(desc, false);
56+
irq_startup(desc, IRQ_NORESEND, IRQ_START_FORCE);
5757
}
5858
raw_spin_unlock_irq(&desc->lock);
5959
}
@@ -70,7 +70,7 @@ unsigned long probe_irq_on(void)
7070
raw_spin_lock_irq(&desc->lock);
7171
if (!desc->action && irq_settings_can_probe(desc)) {
7272
desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
73-
if (irq_startup(desc, false))
73+
if (irq_startup(desc, IRQ_NORESEND, IRQ_START_FORCE))
7474
desc->istate |= IRQS_PENDING;
7575
}
7676
raw_spin_unlock_irq(&desc->lock);

kernel/irq/chip.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ static int __irq_startup(struct irq_desc *desc)
212212
return ret;
213213
}
214214

215-
int irq_startup(struct irq_desc *desc, bool resend)
215+
int irq_startup(struct irq_desc *desc, bool resend, bool force)
216216
{
217217
int ret = 0;
218218

@@ -892,7 +892,7 @@ __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
892892
irq_settings_set_norequest(desc);
893893
irq_settings_set_nothread(desc);
894894
desc->action = &chained_action;
895-
irq_startup(desc, true);
895+
irq_startup(desc, IRQ_RESEND, IRQ_START_FORCE);
896896
}
897897
}
898898

kernel/irq/internals.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned long flags);
6666
extern void __disable_irq(struct irq_desc *desc);
6767
extern void __enable_irq(struct irq_desc *desc);
6868

69-
extern int irq_startup(struct irq_desc *desc, bool resend);
69+
#define IRQ_RESEND true
70+
#define IRQ_NORESEND false
71+
72+
#define IRQ_START_FORCE true
73+
#define IRQ_START_COND false
74+
75+
extern int irq_startup(struct irq_desc *desc, bool resend, bool force);
76+
7077
extern void irq_shutdown(struct irq_desc *desc);
7178
extern void irq_enable(struct irq_desc *desc);
7279
extern void irq_disable(struct irq_desc *desc);

kernel/irq/manage.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ void __enable_irq(struct irq_desc *desc)
509509
* time. If it was already started up, then irq_startup()
510510
* will invoke irq_enable() under the hood.
511511
*/
512-
irq_startup(desc, true);
512+
irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
513513
break;
514514
}
515515
default:
@@ -1306,7 +1306,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
13061306
}
13071307

13081308
if (irq_settings_can_autoenable(desc)) {
1309-
irq_startup(desc, true);
1309+
irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
13101310
} else {
13111311
/*
13121312
* Shared interrupts do not go well with disabling

0 commit comments

Comments
 (0)