diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-02-23 23:52:13 +0000 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-02-25 20:24:21 +0100 |
commit | b5faba21a6805c33b40e258d36f57997ee1de131 (patch) | |
tree | c84ef3357ecd6e1b1cfda623136529db0e5fab6f /include | |
parent | 1204e95689f9fbd245a4ce5c1b0cd0a9b77f8d25 (diff) |
genirq: Prepare the handling of shared oneshot interrupts
For level type interrupts we need to track how many threads are on
flight to avoid useless interrupt storms when not all thread handlers
have finished yet. Keep track of the woken threads and only unmask
when there are no more threads in flight.
Yes, I'm lazy and using a bitfield. But not only because I'm lazy, the
main reason is that it's way simpler than using a refcount. A refcount
based solution would need to keep track of various things like
crashing the irq thread, spurious interrupts coming in,
disables/enables, free_irq() and some more. The bitfield keeps the
tracking simple and makes things just work. It's also nicely confined
to the thread code pathes and does not require additional checks all
over the place.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
LKML-Reference: <20110223234956.388095876@linutronix.de>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/interrupt.h | 2 | ||||
-rw-r--r-- | include/linux/irqdesc.h | 2 |
2 files changed, 4 insertions, 0 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 8da6643e39a..e116fef274c 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -99,6 +99,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *); * @thread_fn: interupt handler function for threaded interrupts * @thread: thread pointer for threaded interrupts * @thread_flags: flags related to @thread + * @thread_mask: bitmask for keeping track of @thread activity */ struct irqaction { irq_handler_t handler; @@ -109,6 +110,7 @@ struct irqaction { irq_handler_t thread_fn; struct task_struct *thread; unsigned long thread_flags; + unsigned long thread_mask; const char *name; struct proc_dir_entry *dir; } ____cacheline_internodealigned_in_smp; diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 2f87d644130..9eb9cd31305 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -28,6 +28,7 @@ struct timer_rand_state; * @lock: locking for SMP * @affinity_notify: context for notification of affinity changes * @pending_mask: pending rebalanced interrupts + * @threads_oneshot: bitfield to handle shared oneshot threads * @threads_active: number of irqaction threads currently running * @wait_for_threads: wait queue for sync_irq to wait for threaded handlers * @dir: /proc/irq/ procfs entry @@ -86,6 +87,7 @@ struct irq_desc { cpumask_var_t pending_mask; #endif #endif + unsigned long threads_oneshot; atomic_t threads_active; wait_queue_head_t wait_for_threads; #ifdef CONFIG_PROC_FS |