]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
synclink: kill the big kernel lock
authorAlan Cox <alan@linux.intel.com>
Tue, 1 Jun 2010 20:52:46 +0000 (22:52 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 10 Aug 2010 20:47:40 +0000 (13:47 -0700)
We don't need it while waiting and we can lock the ioctls using the port
mutex. While at it eliminate use of the hangup mutex and switch to the port
mutex.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c

index 0658fc5482225089d07abda0d4c43f582d1e0890..2b03d4d473505a6808612598007fd6cb2ac77871 100644 (file)
@@ -81,7 +81,6 @@
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -2436,7 +2435,9 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *
        if (!user_icount) {
                memset(&info->icount, 0, sizeof(info->icount));
        } else {
+               mutex_lock(&info->port.mutex);
                COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
+               mutex_unlock(&info->port.mutex);
                if (err)
                        return -EFAULT;
        }
@@ -2461,7 +2462,9 @@ static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_p
                printk("%s(%d):mgsl_get_params(%s)\n",
                         __FILE__,__LINE__, info->device_name);
                        
+       mutex_lock(&info->port.mutex);
        COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS));
+       mutex_unlock(&info->port.mutex);
        if (err) {
                if ( debug_level >= DEBUG_LEVEL_INFO )
                        printk( "%s(%d):mgsl_get_params(%s) user buffer copy failed\n",
@@ -2501,11 +2504,13 @@ static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_pa
                return -EFAULT;
        }
        
+       mutex_lock(&info->port.mutex);
        spin_lock_irqsave(&info->irq_spinlock,flags);
        memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS));
        spin_unlock_irqrestore(&info->irq_spinlock,flags);
        
        mgsl_change_params(info);
+       mutex_unlock(&info->port.mutex);
        
        return 0;
        
@@ -2935,7 +2940,6 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file,
                    unsigned int cmd, unsigned long arg)
 {
        struct mgsl_struct * info = tty->driver_data;
-       int ret;
        
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__,
@@ -2950,10 +2954,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file,
                    return -EIO;
        }
 
-       lock_kernel();
-       ret = mgsl_ioctl_common(info, cmd, arg);
-       unlock_kernel();
-       return ret;
+       return mgsl_ioctl_common(info, cmd, arg);
 }
 
 static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg)
@@ -3109,12 +3110,14 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
 
        if (tty_port_close_start(&info->port, tty, filp) == 0)                   
                goto cleanup;
-                       
+
+       mutex_lock(&info->port.mutex);
        if (info->port.flags & ASYNC_INITIALIZED)
                mgsl_wait_until_sent(tty, info->timeout);
        mgsl_flush_buffer(tty);
        tty_ldisc_flush(tty);
        shutdown(info);
+       mutex_unlock(&info->port.mutex);
 
        tty_port_close_end(&info->port, tty);   
        info->port.tty = NULL;
@@ -3162,7 +3165,6 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
         * Note: use tight timings here to satisfy the NIST-PCTS.
         */ 
 
-       lock_kernel();
        if ( info->params.data_rate ) {
                char_time = info->timeout/(32 * 5);
                if (!char_time)
@@ -3192,7 +3194,6 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
                                break;
                }
        }
-       unlock_kernel();
       
 exit:
        if (debug_level >= DEBUG_LEVEL_INFO)
index 334cf5c8c8b6e09f56b67b70ec54921ac8f325fd..3c7ac6a3ff809e9b2a8275d82e902fa91b1c2666 100644 (file)
@@ -40,8 +40,8 @@
 #define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt
 #define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt
 #define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label))
-//#define DBGTBUF(info) dump_tbufs(info)
-//#define DBGRBUF(info) dump_rbufs(info)
+/*#define DBGTBUF(info) dump_tbufs(info)*/
+/*#define DBGRBUF(info) dump_rbufs(info)*/
 
 
 #include <linux/module.h>
@@ -62,7 +62,6 @@
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
@@ -901,8 +900,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
         * Note: use tight timings here to satisfy the NIST-PCTS.
         */
 
-       lock_kernel();
-
        if (info->params.data_rate) {
                char_time = info->timeout/(32 * 5);
                if (!char_time)
@@ -920,8 +917,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
                if (timeout && time_after(jiffies, orig_jiffies + timeout))
                        break;
        }
-       unlock_kernel();
-
 exit:
        DBGINFO(("%s wait_until_sent exit\n", info->device_name));
 }
@@ -1041,8 +1036,37 @@ static int ioctl(struct tty_struct *tty, struct file *file,
                    return -EIO;
        }
 
-       lock_kernel();
-
+       switch (cmd) {
+       case MGSL_IOCWAITEVENT:
+               return wait_mgsl_event(info, argp);
+       case TIOCMIWAIT:
+               return modem_input_wait(info,(int)arg);
+       case TIOCGICOUNT:
+               spin_lock_irqsave(&info->lock,flags);
+               cnow = info->icount;
+               spin_unlock_irqrestore(&info->lock,flags);
+               p_cuser = argp;
+               if (put_user(cnow.cts, &p_cuser->cts) ||
+                   put_user(cnow.dsr, &p_cuser->dsr) ||
+                   put_user(cnow.rng, &p_cuser->rng) ||
+                   put_user(cnow.dcd, &p_cuser->dcd) ||
+                   put_user(cnow.rx, &p_cuser->rx) ||
+                   put_user(cnow.tx, &p_cuser->tx) ||
+                   put_user(cnow.frame, &p_cuser->frame) ||
+                   put_user(cnow.overrun, &p_cuser->overrun) ||
+                   put_user(cnow.parity, &p_cuser->parity) ||
+                   put_user(cnow.brk, &p_cuser->brk) ||
+                   put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
+                       return -EFAULT;
+               return 0;
+       case MGSL_IOCSGPIO:
+               return set_gpio(info, argp);
+       case MGSL_IOCGGPIO:
+               return get_gpio(info, argp);
+       case MGSL_IOCWAITGPIO:
+               return wait_gpio(info, argp);
+       }
+       mutex_lock(&info->port.mutex);
        switch (cmd) {
        case MGSL_IOCGPARAMS:
                ret = get_params(info, argp);
@@ -1068,50 +1092,16 @@ static int ioctl(struct tty_struct *tty, struct file *file,
        case MGSL_IOCGSTATS:
                ret = get_stats(info, argp);
                break;
-       case MGSL_IOCWAITEVENT:
-               ret = wait_mgsl_event(info, argp);
-               break;
-       case TIOCMIWAIT:
-               ret = modem_input_wait(info,(int)arg);
-               break;
        case MGSL_IOCGIF:
                ret = get_interface(info, argp);
                break;
        case MGSL_IOCSIF:
                ret = set_interface(info,(int)arg);
                break;
-       case MGSL_IOCSGPIO:
-               ret = set_gpio(info, argp);
-               break;
-       case MGSL_IOCGGPIO:
-               ret = get_gpio(info, argp);
-               break;
-       case MGSL_IOCWAITGPIO:
-               ret = wait_gpio(info, argp);
-               break;
-       case TIOCGICOUNT:
-               spin_lock_irqsave(&info->lock,flags);
-               cnow = info->icount;
-               spin_unlock_irqrestore(&info->lock,flags);
-               p_cuser = argp;
-               if (put_user(cnow.cts, &p_cuser->cts) ||
-                   put_user(cnow.dsr, &p_cuser->dsr) ||
-                   put_user(cnow.rng, &p_cuser->rng) ||
-                   put_user(cnow.dcd, &p_cuser->dcd) ||
-                   put_user(cnow.rx, &p_cuser->rx) ||
-                   put_user(cnow.tx, &p_cuser->tx) ||
-                   put_user(cnow.frame, &p_cuser->frame) ||
-                   put_user(cnow.overrun, &p_cuser->overrun) ||
-                   put_user(cnow.parity, &p_cuser->parity) ||
-                   put_user(cnow.brk, &p_cuser->brk) ||
-                   put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
-                       ret = -EFAULT;
-               ret = 0;
-               break;
        default:
                ret = -ENOIOCTLCMD;
        }
-       unlock_kernel();
+       mutex_unlock(&info->port.mutex);
        return ret;
 }
 
index 2b18adc4ee1930818c856b92672af4b11b68671c..8da976bd7314d3a3470329df1756a839fb9d3be3 100644 (file)
@@ -52,7 +52,6 @@
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
@@ -1062,9 +1061,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
        if (sanity_check(info, tty->name, "wait_until_sent"))
                return;
 
-       lock_kernel();
-
-       if (!(info->port.flags & ASYNC_INITIALIZED))
+       if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags))
                goto exit;
 
        orig_jiffies = jiffies;
@@ -1094,8 +1091,10 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
                                break;
                }
        } else {
-               //TODO: determine if there is something similar to USC16C32
-               //      TXSTATUS_ALL_SENT status
+               /*
+                * TODO: determine if there is something similar to USC16C32
+                *       TXSTATUS_ALL_SENT status
+                */
                while ( info->tx_active && info->tx_enabled) {
                        msleep_interruptible(jiffies_to_msecs(char_time));
                        if (signal_pending(current))
@@ -1106,7 +1105,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
        }
 
 exit:
-       unlock_kernel();
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):%s wait_until_sent() exit\n",
                         __FILE__,__LINE__, info->device_name );
@@ -1122,7 +1120,6 @@ static int write_room(struct tty_struct *tty)
        if (sanity_check(info, tty->name, "write_room"))
                return 0;
 
-       lock_kernel();
        if (info->params.mode == MGSL_MODE_HDLC) {
                ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE;
        } else {
@@ -1130,7 +1127,6 @@ static int write_room(struct tty_struct *tty)
                if (ret < 0)
                        ret = 0;
        }
-       unlock_kernel();
 
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):%s write_room()=%d\n",
@@ -1251,7 +1247,7 @@ static void tx_release(struct tty_struct *tty)
  *
  * Return Value:       0 if success, otherwise error code
  */
-static int do_ioctl(struct tty_struct *tty, struct file *file,
+static int ioctl(struct tty_struct *tty, struct file *file,
                 unsigned int cmd, unsigned long arg)
 {
        SLMP_INFO *info = tty->driver_data;
@@ -1341,16 +1337,6 @@ static int do_ioctl(struct tty_struct *tty, struct file *file,
        return 0;
 }
 
-static int ioctl(struct tty_struct *tty, struct file *file,
-                unsigned int cmd, unsigned long arg)
-{
-       int ret;
-       lock_kernel();
-       ret = do_ioctl(tty, file, cmd, arg);
-       unlock_kernel();
-       return ret;
-}
-
 /*
  * /proc fs routines....
  */
@@ -2883,7 +2869,9 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
        if (!user_icount) {
                memset(&info->icount, 0, sizeof(info->icount));
        } else {
+               mutex_lock(&info->port.mutex);
                COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
+               mutex_unlock(&info->port.mutex);
                if (err)
                        return -EFAULT;
        }
@@ -2898,7 +2886,9 @@ static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params)
                printk("%s(%d):%s get_params()\n",
                         __FILE__,__LINE__, info->device_name);
 
+       mutex_lock(&info->port.mutex);
        COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS));
+       mutex_unlock(&info->port.mutex);
        if (err) {
                if ( debug_level >= DEBUG_LEVEL_INFO )
                        printk( "%s(%d):%s get_params() user buffer copy failed\n",
@@ -2926,11 +2916,13 @@ static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params)
                return -EFAULT;
        }
 
+       mutex_lock(&info->port.mutex);
        spin_lock_irqsave(&info->lock,flags);
        memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS));
        spin_unlock_irqrestore(&info->lock,flags);
 
        change_params(info);
+       mutex_unlock(&info->port.mutex);
 
        return 0;
 }