mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 23:32:14 +00:00
[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 <jkosina@suse.cz> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
6faee84b00
commit
4dfc896e90
2 changed files with 6 additions and 4 deletions
|
@ -70,11 +70,12 @@ void wake_up_buffer_waiter(void)
|
||||||
int alloc_event_buffer(void)
|
int alloc_event_buffer(void)
|
||||||
{
|
{
|
||||||
int err = -ENOMEM;
|
int err = -ENOMEM;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock(&oprofilefs_lock);
|
spin_lock_irqsave(&oprofilefs_lock, flags);
|
||||||
buffer_size = fs_buffer_size;
|
buffer_size = fs_buffer_size;
|
||||||
buffer_watershed = fs_buffer_watershed;
|
buffer_watershed = fs_buffer_watershed;
|
||||||
spin_unlock(&oprofilefs_lock);
|
spin_unlock_irqrestore(&oprofilefs_lock, flags);
|
||||||
|
|
||||||
if (buffer_watershed >= buffer_size)
|
if (buffer_watershed >= buffer_size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -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)
|
int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, size_t count)
|
||||||
{
|
{
|
||||||
char tmpbuf[TMPBUFSIZE];
|
char tmpbuf[TMPBUFSIZE];
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (!count)
|
if (!count)
|
||||||
return 0;
|
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))
|
if (copy_from_user(tmpbuf, buf, count))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
spin_lock(&oprofilefs_lock);
|
spin_lock_irqsave(&oprofilefs_lock, flags);
|
||||||
*val = simple_strtoul(tmpbuf, NULL, 0);
|
*val = simple_strtoul(tmpbuf, NULL, 0);
|
||||||
spin_unlock(&oprofilefs_lock);
|
spin_unlock_irqrestore(&oprofilefs_lock, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue