request/free_irq is not a hotpath, so we can afford to serialize it with a global lock. That allows us to shorten critical sections as the action chain of an irq descriptor becomes protected by the global lock. It's also a prerequisite for further changes which provide adaptive oneshot functionality for possibly shared interrupts. Signed-off-by: Thomas Gleixner Cc: Tom Lyon Cc: Alex Williamson Cc: "Michael S. Tsirkin" Cc: Avi Kivity Cc: Marcelo Tosatti Cc: Jan Kiszka Cc: Jan Kiszka --- kernel/irq/manage.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) Index: linux-2.6-tip/kernel/irq/manage.c =================================================================== --- linux-2.6-tip.orig/kernel/irq/manage.c +++ linux-2.6-tip/kernel/irq/manage.c @@ -14,9 +14,12 @@ #include #include #include +#include #include "internals.h" +static DEFINE_MUTEX(register_lock); + /** * synchronize_irq - wait for pending IRQ handlers (on other CPUs) * @irq: interrupt number to wait for @@ -870,8 +873,12 @@ out_thread: int setup_irq(unsigned int irq, struct irqaction *act) { struct irq_desc *desc = irq_to_desc(irq); + int ret; - return __setup_irq(irq, desc, act); + mutex_lock(®ister_lock); + ret = __setup_irq(irq, desc, act); + mutex_unlock(®ister_lock); + return ret; } EXPORT_SYMBOL_GPL(setup_irq); @@ -977,7 +984,9 @@ static struct irqaction *__free_irq(unsi */ void remove_irq(unsigned int irq, struct irqaction *act) { + mutex_lock(®ister_lock); __free_irq(irq, act->dev_id); + mutex_unlock(®ister_lock); } EXPORT_SYMBOL_GPL(remove_irq); @@ -1002,9 +1011,13 @@ void free_irq(unsigned int irq, void *de if (!desc) return; + mutex_lock(®ister_lock); + chip_bus_lock(desc); kfree(__free_irq(irq, dev_id)); chip_bus_sync_unlock(desc); + + mutex_unlock(®ister_lock); } EXPORT_SYMBOL(free_irq); @@ -1091,10 +1104,14 @@ int request_threaded_irq(unsigned int ir action->name = devname; action->dev_id = dev_id; + mutex_lock(®ister_lock); + chip_bus_lock(desc); retval = __setup_irq(irq, desc, action); chip_bus_sync_unlock(desc); + mutex_unlock(®ister_lock); + if (retval) kfree(action); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/