From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755733Ab0LOXNL (ORCPT ); Wed, 15 Dec 2010 18:13:11 -0500 Received: from www.tglx.de ([62.245.132.106]:59028 "EHLO www.tglx.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755633Ab0LOXNJ (ORCPT ); Wed, 15 Dec 2010 18:13:09 -0500 Message-Id: <20101215230531.141459653@linutronix.de> User-Agent: quilt/0.48-1 Date: Wed, 15 Dec 2010 23:12:35 -0000 From: Thomas Gleixner To: LKML Cc: Ingo Molnar , Peter Zijlstra , Tom Lyon , Alex Williamson , "Michael S. Tsirkin" , Avi Kivity , Marcelo Tosatti , Jan Kiszka , Jan Kiszka Subject: [RFC patch 1/4] genirq: Globally serialize request/free_irq References: <20101215230352.411894017@linutronix.de> Content-Disposition: inline; filename=genirq-serialize-request-free-irq.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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);