Commit 54fdf6a0 authored by Thomas Gleixner's avatar Thomas Gleixner

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: default avatarThomas 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
parent c7d6c9dd
...@@ -207,6 +207,8 @@ struct irq_data { ...@@ -207,6 +207,8 @@ struct irq_data {
* IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU * IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU
* IRQD_AFFINITY_MANAGED - Affinity is auto-managed by the kernel * IRQD_AFFINITY_MANAGED - Affinity is auto-managed by the kernel
* IRQD_IRQ_STARTED - Startup state of the interrupt * IRQD_IRQ_STARTED - Startup state of the interrupt
* IRQD_MANAGED_SHUTDOWN - Interrupt was shutdown due to empty affinity
* mask. Applies only to affinity managed irqs.
*/ */
enum { enum {
IRQD_TRIGGER_MASK = 0xf, IRQD_TRIGGER_MASK = 0xf,
...@@ -225,6 +227,7 @@ enum { ...@@ -225,6 +227,7 @@ enum {
IRQD_FORWARDED_TO_VCPU = (1 << 20), IRQD_FORWARDED_TO_VCPU = (1 << 20),
IRQD_AFFINITY_MANAGED = (1 << 21), IRQD_AFFINITY_MANAGED = (1 << 21),
IRQD_IRQ_STARTED = (1 << 22), IRQD_IRQ_STARTED = (1 << 22),
IRQD_MANAGED_SHUTDOWN = (1 << 23),
}; };
#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors) #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,6 +346,11 @@ static inline bool irqd_is_started(struct irq_data *d)
return __irqd_to_state(d) & IRQD_IRQ_STARTED; return __irqd_to_state(d) & IRQD_IRQ_STARTED;
} }
static inline bool irqd_is_managed_shutdown(struct irq_data *d)
{
return __irqd_to_state(d) & IRQD_MANAGED_SHUTDOWN;
}
#undef __irqd_to_state #undef __irqd_to_state
static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
......
...@@ -193,6 +193,16 @@ static inline void irqd_clr_move_pending(struct irq_data *d) ...@@ -193,6 +193,16 @@ static inline void irqd_clr_move_pending(struct irq_data *d)
__irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING; __irqd_to_state(d) &= ~IRQD_SETAFFINITY_PENDING;
} }
static inline void irqd_set_managed_shutdown(struct irq_data *d)
{
__irqd_to_state(d) |= IRQD_MANAGED_SHUTDOWN;
}
static inline void irqd_clr_managed_shutdown(struct irq_data *d)
{
__irqd_to_state(d) &= ~IRQD_MANAGED_SHUTDOWN;
}
static inline void irqd_clear(struct irq_data *d, unsigned int mask) static inline void irqd_clear(struct irq_data *d, unsigned int mask)
{ {
__irqd_to_state(d) &= ~mask; __irqd_to_state(d) &= ~mask;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment