Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4dfc896e90359df04c80da5ab08ec31e87846c43
Commit:     4dfc896e90359df04c80da5ab08ec31e87846c43
Parent:     6faee84b006af55bab9908741dd76916c8450be2
Author:     Jiri Kosina <[EMAIL PROTECTED]>
AuthorDate: Wed Mar 28 18:12:34 2007 +0200
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Mar 28 13:58:02 2007 -0700

    [PATCH] 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 <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 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 git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to