aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2017-06-19 19:37:47 -0400
committerThomas Gleixner <tglx@linutronix.de>2017-06-22 12:21:23 -0400
commit54fdf6a0875ca380647ac1cc9b5b8f2dbbbfa131 (patch)
treeff92b259f8fbacc29e7299d1e7e290b0b5d604ed
parentc7d6c9dd871f42c4e0ce5563d2f684e78ea673cf (diff)
genirq: Introduce IRQD_MANAGED_SHUTDOWN
Affinity managed interrupts should keep their assigned affinity accross CPU hotplug. To avoid magic hackery in device drivers, the core code shall manage them transparently. This will set these interrupts into a managed shutdown state when the last CPU of the assigned affinity mask goes offline. The interrupt will be restarted when one of the CPUs in the assigned affinity mask comes back online. Introduce the necessary state flag and the accessor functions. 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/20170619235446.954523476@linutronix.de
-rw-r--r--include/linux/irq.h8
-rw-r--r--kernel/irq/internals.h10
2 files changed, 18 insertions, 0 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 4087ef268ba9..0e37276c5315 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -207,6 +207,8 @@ struct irq_data {
207 * IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU 207 * IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU
208 * IRQD_AFFINITY_MANAGED - Affinity is auto-managed by the kernel 208 * IRQD_AFFINITY_MANAGED - Affinity is auto-managed by the kernel
209 * IRQD_IRQ_STARTED - Startup state of the interrupt 209 * IRQD_IRQ_STARTED - Startup state of the interrupt
210 * IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity
211 * mask. Applies only to affinity managed irqs.
210 */ 212 */
211enum { 213enum {
212 IRQD_TRIGGER_MASK = 0xf, 214 IRQD_TRIGGER_MASK = 0xf,
@@ -225,6 +227,7 @@ enum {
225 IRQD_FORWARDED_TO_VCPU = (1 << 20), 227 IRQD_FORWARDED_TO_VCPU = (1 << 20),
226 IRQD_AFFINITY_MANAGED = (1 << 21), 228 IRQD_AFFINITY_MANAGED = (1 << 21),
227 IRQD_IRQ_STARTED = (1 << 22), 229 IRQD_IRQ_STARTED = (1 << 22),
230 IRQD_MANAGED_SHUTDOWN = (1 << 23),
228}; 231};
229 232
230#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors) 233#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
@@ -343,6 +346,11 @@ static inline bool irqd_is_started(struct irq_data *d)
343 return __irqd_to_state(d) & IRQD_IRQ_STARTED; 346 return __irqd_to_state(d) & IRQD_IRQ_STARTED;
344} 347}
345 348
349static inline bool irqd_is_managed_shutdown(struct irq_data *d)
350{
351 return __irqd_to_state(d) & IRQD_MANAGED_SHUTDOWN;
352}
353
346#undef __irqd_to_state 354#undef __irqd_to_state
347 355
348static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) 356static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 040806f1124c..ca4666b4cd39 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -193,6 +193,16 @@ static inline void irqd_clr_move_pending(struct irq_data *d)
193 __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING; 193 __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
194} 194}
195 195
196static inline void irqd_set_managed_shutdown(struct irq_data *d)
197{
198 __irqd_to_state(d) |= IRQD_MANAGED_SHUTDOWN;
199}
200
201static inline void irqd_clr_managed_shutdown(struct irq_data *d)
202{
203 __irqd_to_state(d) &= ~IRQD_MANAGED_SHUTDOWN;
204}
205
196static inline void irqd_clear(struct irq_data *d, unsigned int mask) 206static inline void irqd_clear(struct irq_data *d, unsigned int mask)
197{ 207{
198 __irqd_to_state(d) &= ~mask; 208 __irqd_to_state(d) &= ~mask;