x86: Remove BKL from apm_32

The lock/unlock kernel pair in do_open() got there with the BKL push
down and protects nothing. Remove it.

Replace the lock/unlock kernel in the ioctl code with a mutex to
protect standbys_pending and suspends_pending.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <20091010153349.365236337@linutronix.de>
This commit is contained in:
Thomas Gleixner 2009-10-09 19:02:20 +02:00
parent ac06ea2cd0
commit 05d86412ea

View File

@ -204,7 +204,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/timer.h> #include <linux/timer.h>
@ -403,6 +402,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
static struct apm_user *user_list; static struct apm_user *user_list;
static DEFINE_SPINLOCK(user_list_lock); static DEFINE_SPINLOCK(user_list_lock);
static DEFINE_MUTEX(apm_mutex);
/* /*
* Set up a segment that references the real mode segment 0x40 * Set up a segment that references the real mode segment 0x40
@ -1531,7 +1531,7 @@ static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
return -EPERM; return -EPERM;
switch (cmd) { switch (cmd) {
case APM_IOC_STANDBY: case APM_IOC_STANDBY:
lock_kernel(); mutex_lock(&apm_mutex);
if (as->standbys_read > 0) { if (as->standbys_read > 0) {
as->standbys_read--; as->standbys_read--;
as->standbys_pending--; as->standbys_pending--;
@ -1540,10 +1540,10 @@ static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
queue_event(APM_USER_STANDBY, as); queue_event(APM_USER_STANDBY, as);
if (standbys_pending <= 0) if (standbys_pending <= 0)
standby(); standby();
unlock_kernel(); mutex_unlock(&apm_mutex);
break; break;
case APM_IOC_SUSPEND: case APM_IOC_SUSPEND:
lock_kernel(); mutex_lock(&apm_mutex);
if (as->suspends_read > 0) { if (as->suspends_read > 0) {
as->suspends_read--; as->suspends_read--;
as->suspends_pending--; as->suspends_pending--;
@ -1552,13 +1552,14 @@ static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
queue_event(APM_USER_SUSPEND, as); queue_event(APM_USER_SUSPEND, as);
if (suspends_pending <= 0) { if (suspends_pending <= 0) {
ret = suspend(1); ret = suspend(1);
mutex_unlock(&apm_mutex);
} else { } else {
as->suspend_wait = 1; as->suspend_wait = 1;
mutex_unlock(&apm_mutex);
wait_event_interruptible(apm_suspend_waitqueue, wait_event_interruptible(apm_suspend_waitqueue,
as->suspend_wait == 0); as->suspend_wait == 0);
ret = as->suspend_result; ret = as->suspend_result;
} }
unlock_kernel();
return ret; return ret;
default: default:
return -ENOTTY; return -ENOTTY;
@ -1608,12 +1609,10 @@ static int do_open(struct inode *inode, struct file *filp)
{ {
struct apm_user *as; struct apm_user *as;
lock_kernel();
as = kmalloc(sizeof(*as), GFP_KERNEL); as = kmalloc(sizeof(*as), GFP_KERNEL);
if (as == NULL) { if (as == NULL) {
printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n", printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
sizeof(*as)); sizeof(*as));
unlock_kernel();
return -ENOMEM; return -ENOMEM;
} }
as->magic = APM_BIOS_MAGIC; as->magic = APM_BIOS_MAGIC;
@ -1635,7 +1634,6 @@ static int do_open(struct inode *inode, struct file *filp)
user_list = as; user_list = as;
spin_unlock(&user_list_lock); spin_unlock(&user_list_lock);
filp->private_data = as; filp->private_data = as;
unlock_kernel();
return 0; return 0;
} }