[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Pine.LNX.4.64.0703281809510.29565@twin.jikos.cz>
Date: Wed, 28 Mar 2007 18:12:34 +0200 (CEST)
From: Jiri Kosina <jikos@...os.cz>
To: Michal Piotrowski <michal.k.k.piotrowski@...il.com>
cc: Andi Kleen <ak@...e.de>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
Andrew Morton <akpm@...ux-foundation.org>,
Philippe Elie <phil.el@...adoo.fr>
Subject: Re: Linux 2.6.21-rc5
On Wed, 28 Mar 2007, Michal Piotrowski wrote:
> BUG: using smp_processor_id() in preemptible [00000001] code: mount/7245
> is fixed, thanks.
> but I still get this
> [ 208.523901] =================================
> [ 208.529739] [ INFO: inconsistent lock state ]
> [ 208.534087] 2.6.21-rc5-g28defbea-dirty #131
> [ 208.538260] ---------------------------------
> [ 208.542611] inconsistent {hardirq-on-W} -> {in-hardirq-W} usage.
> [ 208.548600] swapper/0 [HC1[1]:SC0[0]:HE0:SE1] takes:
Perhaps something like the one below?
From: Jiri Kosina <jkosina@...e.cz>
oprofile: fix potential deadlock on oprofilefs_lock
nmi_cpu_setup() is called from hardirq context and acquires oprofilefs_lock.
alloc_event_buffer() and oprofilefs_ulong_from_user() acquire this lock
without disabling irqs, which could deadlock.
Signed-off-by: Jiri Kosina <jkosina@...e.cz>
drivers/oprofile/event_buffer.c | 5 +++--
drivers/oprofile/oprofilefs.c | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
index 00e937e..e7fbac5 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -70,11 +70,12 @@ void wake_up_buffer_waiter(void)
int alloc_event_buffer(void)
{
int err = -ENOMEM;
+ unsigned long flags;
- spin_lock(&oprofilefs_lock);
+ spin_lock_irqsave(&oprofilefs_lock, flags);
buffer_size = fs_buffer_size;
buffer_watershed = fs_buffer_watershed;
- spin_unlock(&oprofilefs_lock);
+ spin_unlock_irqrestore(&oprofilefs_lock, flags);
if (buffer_watershed >= buffer_size)
return -EINVAL;
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index 6e67b42..8543cb2 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -65,6 +65,7 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user * buf, size_t co
int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, size_t count)
{
char tmpbuf[TMPBUFSIZE];
+ unsigned long flags;
if (!count)
return 0;
@@ -77,9 +78,9 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, siz
if (copy_from_user(tmpbuf, buf, count))
return -EFAULT;
- spin_lock(&oprofilefs_lock);
+ spin_lock_irqsave(&oprofilefs_lock, flags);
*val = simple_strtoul(tmpbuf, NULL, 0);
- spin_unlock(&oprofilefs_lock);
+ spin_unlock_irqrestore(&oprofilefs_lock, flags);
return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists