x86: Remove BKL from apm_32
authorThomas Gleixner <tglx@linutronix.de>
Fri, 9 Oct 2009 17:02:20 +0000 (19:02 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 14 Oct 2009 15:04:48 +0000 (17:04 +0200)
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>

arch/x86/kernel/apm_32.c

index 151ace6..b5b6b23 100644 (file)
 #include <linux/module.h>
 
 #include <linux/poll.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/stddef.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 struct apm_user *user_list;
 static DEFINE_SPINLOCK(user_list_lock);
+static DEFINE_MUTEX(apm_mutex);
 
 /*
  * 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;
        switch (cmd) {
        case APM_IOC_STANDBY:
-               lock_kernel();
+               mutex_lock(&apm_mutex);
                if (as->standbys_read > 0) {
                        as->standbys_read--;
                        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);
                if (standbys_pending <= 0)
                        standby();
-               unlock_kernel();
+               mutex_unlock(&apm_mutex);
                break;
        case APM_IOC_SUSPEND:
-               lock_kernel();
+               mutex_lock(&apm_mutex);
                if (as->suspends_read > 0) {
                        as->suspends_read--;
                        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);
                if (suspends_pending <= 0) {
                        ret = suspend(1);
+                       mutex_unlock(&apm_mutex);
                } else {
                        as->suspend_wait = 1;
+                       mutex_unlock(&apm_mutex);
                        wait_event_interruptible(apm_suspend_waitqueue,
                                        as->suspend_wait == 0);
                        ret = as->suspend_result;
                }
-               unlock_kernel();
                return ret;
        default:
                return -ENOTTY;
@@ -1608,12 +1609,10 @@ static int do_open(struct inode *inode, struct file *filp)
 {
        struct apm_user *as;
 
-       lock_kernel();
        as = kmalloc(sizeof(*as), GFP_KERNEL);
        if (as == NULL) {
                printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
                       sizeof(*as));
-                      unlock_kernel();
                return -ENOMEM;
        }
        as->magic = APM_BIOS_MAGIC;
@@ -1635,7 +1634,6 @@ static int do_open(struct inode *inode, struct file *filp)
        user_list = as;
        spin_unlock(&user_list_lock);
        filp->private_data = as;
-       unlock_kernel();
        return 0;
 }