[RFC patch 1/4] genirq: Globally serialize request/free_irq

From: Thomas Gleixner
Date: Wed Dec 15 2010 - 18:13:16 EST


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 <tglx@xxxxxxxxxxxxx>
Cc: Tom Lyon <pugs@xxxxxxxxx>
Cc: Alex Williamson <alex.williamson@xxxxxxxxxx>
Cc: "Michael S. Tsirkin" <mst@xxxxxxxxxx>
Cc: Avi Kivity <avi@xxxxxxxxxx>
Cc: Marcelo Tosatti <mtosatti@xxxxxxxxxx>
Cc: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>
Cc: Jan Kiszka <jan.kiszka@xxxxxx>
---
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 <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/mutex.h>

#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(&register_lock);
+ ret = __setup_irq(irq, desc, act);
+ mutex_unlock(&register_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(&register_lock);
__free_irq(irq, act->dev_id);
+ mutex_unlock(&register_lock);
}
EXPORT_SYMBOL_GPL(remove_irq);

@@ -1002,9 +1011,13 @@ void free_irq(unsigned int irq, void *de
if (!desc)
return;

+ mutex_lock(&register_lock);
+
chip_bus_lock(desc);
kfree(__free_irq(irq, dev_id));
chip_bus_sync_unlock(desc);
+
+ mutex_unlock(&register_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(&register_lock);
+
chip_bus_lock(desc);
retval = __setup_irq(irq, desc, action);
chip_bus_sync_unlock(desc);

+ mutex_unlock(&register_lock);
+
if (retval)
kfree(action);



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/