diff mbox

[22/28] macintosh: Remove BKL from ans-lcd

Message ID 20091010153349.966159859@linutronix.de (mailing list archive)
State Not Applicable
Headers show

Commit Message

Thomas Gleixner Oct. 10, 2009, 3:37 p.m. UTC
The ans-lcd driver got the cycle_kernel_lock() in anslcd_open() from
the BKL pushdown and it still uses the locked ioctl.

The BKL serialization in this driver is more than obscure and
definitely does not cover all possible corner cases. Protect the
access to the hardware with a local mutex and get rid of BKL and
locked ioctl.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: linuxppc-dev@ozlabs.org
---
 drivers/macintosh/ans-lcd.c |   45 +++++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 17 deletions(-)

Comments

John Kacur Oct. 10, 2009, 9:14 p.m. UTC | #1
On Sat, 10 Oct 2009, Thomas Gleixner wrote:

> The ans-lcd driver got the cycle_kernel_lock() in anslcd_open() from
> the BKL pushdown and it still uses the locked ioctl.
> 
> The BKL serialization in this driver is more than obscure and
> definitely does not cover all possible corner cases. Protect the
> access to the hardware with a local mutex and get rid of BKL and
> locked ioctl.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: linuxppc-dev@ozlabs.org
> ---
>  drivers/macintosh/ans-lcd.c |   45 +++++++++++++++++++++++++++-----------------
>  1 file changed, 28 insertions(+), 17 deletions(-)
> 
> Index: linux-2.6-tip/drivers/macintosh/ans-lcd.c
> ===================================================================
> --- linux-2.6-tip.orig/drivers/macintosh/ans-lcd.c
> +++ linux-2.6-tip/drivers/macintosh/ans-lcd.c
> @@ -3,7 +3,6 @@
>   */
>  
>  #include <linux/types.h>
> -#include <linux/smp_lock.h>
>  #include <linux/errno.h>
>  #include <linux/kernel.h>
>  #include <linux/miscdevice.h>
> @@ -26,6 +25,7 @@
>  static unsigned long anslcd_short_delay = 80;
>  static unsigned long anslcd_long_delay = 3280;
>  static volatile unsigned char __iomem *anslcd_ptr;
> +static DEFINE_MUTEX(anslcd_mutex);
>  
>  #undef DEBUG
>  
> @@ -65,26 +65,31 @@ anslcd_write( struct file * file, const 
>  
>  	if (!access_ok(VERIFY_READ, buf, count))
>  		return -EFAULT;
> +
> +	mutex_lock(&anslcd_mutex);
>  	for ( i = *ppos; count > 0; ++i, ++p, --count ) 
>  	{
>  		char c;
>  		__get_user(c, p);
>  		anslcd_write_byte_data( c );
>  	}
> +	mutex_unlock(&anslcd_mutex);
>  	*ppos = i;
>  	return p - buf;
>  }
>  
> -static int
> -anslcd_ioctl( struct inode * inode, struct file * file,
> -				unsigned int cmd, unsigned long arg )
> +static long
> +anslcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  {
>  	char ch, __user *temp;
> +	long ret = 0;
>  
>  #ifdef DEBUG
>  	printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg);
>  #endif
>  
> +	mutex_lock(&anslcd_mutex);
> +
>  	switch ( cmd )
>  	{
>  	case ANSLCD_CLEAR:
> @@ -93,7 +98,7 @@ anslcd_ioctl( struct inode * inode, stru
>  		anslcd_write_byte_ctrl ( 0x06 );
>  		anslcd_write_byte_ctrl ( 0x01 );
>  		anslcd_write_byte_ctrl ( 0x02 );
> -		return 0;
> +		break;
>  	case ANSLCD_SENDCTRL:
>  		temp = (char __user *) arg;
>  		__get_user(ch, temp);
> @@ -101,33 +106,37 @@ anslcd_ioctl( struct inode * inode, stru
>  			anslcd_write_byte_ctrl ( ch );
>  			__get_user(ch, temp);
>  		}
> -		return 0;
> +		break;
>  	case ANSLCD_SETSHORTDELAY:
>  		if (!capable(CAP_SYS_ADMIN))
> -			return -EACCES;
> -		anslcd_short_delay=arg;
> -		return 0;
> +			ret =-EACCES;
> +		else
> +			anslcd_short_delay=arg;
> +		break;
>  	case ANSLCD_SETLONGDELAY:
>  		if (!capable(CAP_SYS_ADMIN))
> -			return -EACCES;
> -		anslcd_long_delay=arg;
> -		return 0;
> +			ret = -EACCES;
> +		else
> +			anslcd_long_delay=arg;
> +		break;
>  	default:
> -		return -EINVAL;
> +		ret = -EINVAL;
>  	}
> +
> +	mutex_unlock(&anslcd_mutex);
> +	return ret;
>  }
>  
>  static int
>  anslcd_open( struct inode * inode, struct file * file )
>  {
> -	cycle_kernel_lock();
>  	return 0;
>  }
>  
>  const struct file_operations anslcd_fops = {
> -	.write	= anslcd_write,
> -	.ioctl	= anslcd_ioctl,
> -	.open	= anslcd_open,
> +	.write		= anslcd_write,
> +	.unlocked_ioctl	= anslcd_ioctl,
> +	.open		= anslcd_open,
>  };
>  
>  static struct miscdevice anslcd_dev = {
> @@ -168,6 +177,7 @@ anslcd_init(void)
>  	printk(KERN_DEBUG "LCD: init\n");
>  #endif
>  
> +	mutex_lock(&anslcd_mutex);
>  	anslcd_write_byte_ctrl ( 0x38 );
>  	anslcd_write_byte_ctrl ( 0x0c );
>  	anslcd_write_byte_ctrl ( 0x06 );
> @@ -176,6 +186,7 @@ anslcd_init(void)
>  	for(a=0;a<80;a++) {
>  		anslcd_write_byte_data(anslcd_logo[a]);
>  	}
> +	mutex_unlock(&anslcd_mutex);
>  	return 0;
>  }
>  
> 
> 
> 

There were 4 checkpatch errors on this patch, all of the type
ERROR: spaces required around that '=' (ctx:WxO)
#1466: FILE: drivers/macintosh/ans-lcd.c:112:
+			ret =-EACCES;

Cheers
Alan Cox Oct. 10, 2009, 11:13 p.m. UTC | #2
> There were 4 checkpatch errors on this patch, all of the type
> ERROR: spaces required around that '=' (ctx:WxO)
> #1466: FILE: drivers/macintosh/ans-lcd.c:112:
> +			ret =-EACCES;

Here's a suggestion. If a few spaces bug you that much then instead of
complaining about it and posting checkpatch results deal with the file
itself. 

Wait until the patch goes in and send a follow up patch that fixes up the
file to fit codingstyle. There's no point whining about the bits a patch
touches when the file wasn't in that format before, but if you've got
nothing better to do then doing a pass over the whole file *is* useful.

(Plus it gets a patch to your name ;))

Checkpatch whines on files that simple don't follow style are usually
best ignored because they make the file formatting less internally
consistent.

Alan
John Kacur Oct. 10, 2009, 11:27 p.m. UTC | #3
On Sun, 11 Oct 2009, Alan Cox wrote:

> > There were 4 checkpatch errors on this patch, all of the type
> > ERROR: spaces required around that '=' (ctx:WxO)
> > #1466: FILE: drivers/macintosh/ans-lcd.c:112:
> > +			ret =-EACCES;
> 
> Here's a suggestion. If a few spaces bug you that much then instead of
> complaining about it and posting checkpatch results deal with the file
> itself. 
> 
> Wait until the patch goes in and send a follow up patch that fixes up the
> file to fit codingstyle. There's no point whining about the bits a patch
> touches when the file wasn't in that format before, but if you've got
> nothing better to do then doing a pass over the whole file *is* useful.
> 
> (Plus it gets a patch to your name ;))
> 
> Checkpatch whines on files that simple don't follow style are usually
> best ignored because they make the file formatting less internally
> consistent.
> 
Thanks Alan, I was sincerely debatting whether to send this because I know 
that checkpatch can be annoying - but on the other hand, I thought it 
prudent to run it since I was claiming to have reviewed all of those 
patches.

I like your suggestion though - next time, I won't send the mail, since 
since the folks submitting these patches are more than capable of checking 
that kind of thing themselves, and if I feel it's important enough, I'll 
follow up with a trivial style patch.

Cheers!

John
Benjamin Herrenschmidt Oct. 11, 2009, 9:02 a.m. UTC | #4
On Sat, 2009-10-10 at 15:37 +0000, Thomas Gleixner wrote:
> plain text document attachment (drivers-mac-ans-lcd-remove-bkl.patch)
> The ans-lcd driver got the cycle_kernel_lock() in anslcd_open() from
> the BKL pushdown and it still uses the locked ioctl.
> 
> The BKL serialization in this driver is more than obscure and
> definitely does not cover all possible corner cases. Protect the
> access to the hardware with a local mutex and get rid of BKL and
> locked ioctl.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: linuxppc-dev@ozlabs.org
> ---

While I -do- have an ANS ... it's rusting in the back of my garage and I
really don't have time nor space to set it up and get it back to booting
shape :-) (It's a pretty huge thing)

Patch looks good, so if it builds...

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Cheers,
Ben.
diff mbox

Patch

Index: linux-2.6-tip/drivers/macintosh/ans-lcd.c
===================================================================
--- linux-2.6-tip.orig/drivers/macintosh/ans-lcd.c
+++ linux-2.6-tip/drivers/macintosh/ans-lcd.c
@@ -3,7 +3,6 @@ 
  */
 
 #include <linux/types.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
@@ -26,6 +25,7 @@ 
 static unsigned long anslcd_short_delay = 80;
 static unsigned long anslcd_long_delay = 3280;
 static volatile unsigned char __iomem *anslcd_ptr;
+static DEFINE_MUTEX(anslcd_mutex);
 
 #undef DEBUG
 
@@ -65,26 +65,31 @@  anslcd_write( struct file * file, const 
 
 	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
+
+	mutex_lock(&anslcd_mutex);
 	for ( i = *ppos; count > 0; ++i, ++p, --count ) 
 	{
 		char c;
 		__get_user(c, p);
 		anslcd_write_byte_data( c );
 	}
+	mutex_unlock(&anslcd_mutex);
 	*ppos = i;
 	return p - buf;
 }
 
-static int
-anslcd_ioctl( struct inode * inode, struct file * file,
-				unsigned int cmd, unsigned long arg )
+static long
+anslcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	char ch, __user *temp;
+	long ret = 0;
 
 #ifdef DEBUG
 	printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg);
 #endif
 
+	mutex_lock(&anslcd_mutex);
+
 	switch ( cmd )
 	{
 	case ANSLCD_CLEAR:
@@ -93,7 +98,7 @@  anslcd_ioctl( struct inode * inode, stru
 		anslcd_write_byte_ctrl ( 0x06 );
 		anslcd_write_byte_ctrl ( 0x01 );
 		anslcd_write_byte_ctrl ( 0x02 );
-		return 0;
+		break;
 	case ANSLCD_SENDCTRL:
 		temp = (char __user *) arg;
 		__get_user(ch, temp);
@@ -101,33 +106,37 @@  anslcd_ioctl( struct inode * inode, stru
 			anslcd_write_byte_ctrl ( ch );
 			__get_user(ch, temp);
 		}
-		return 0;
+		break;
 	case ANSLCD_SETSHORTDELAY:
 		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		anslcd_short_delay=arg;
-		return 0;
+			ret =-EACCES;
+		else
+			anslcd_short_delay=arg;
+		break;
 	case ANSLCD_SETLONGDELAY:
 		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		anslcd_long_delay=arg;
-		return 0;
+			ret = -EACCES;
+		else
+			anslcd_long_delay=arg;
+		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+
+	mutex_unlock(&anslcd_mutex);
+	return ret;
 }
 
 static int
 anslcd_open( struct inode * inode, struct file * file )
 {
-	cycle_kernel_lock();
 	return 0;
 }
 
 const struct file_operations anslcd_fops = {
-	.write	= anslcd_write,
-	.ioctl	= anslcd_ioctl,
-	.open	= anslcd_open,
+	.write		= anslcd_write,
+	.unlocked_ioctl	= anslcd_ioctl,
+	.open		= anslcd_open,
 };
 
 static struct miscdevice anslcd_dev = {
@@ -168,6 +177,7 @@  anslcd_init(void)
 	printk(KERN_DEBUG "LCD: init\n");
 #endif
 
+	mutex_lock(&anslcd_mutex);
 	anslcd_write_byte_ctrl ( 0x38 );
 	anslcd_write_byte_ctrl ( 0x0c );
 	anslcd_write_byte_ctrl ( 0x06 );
@@ -176,6 +186,7 @@  anslcd_init(void)
 	for(a=0;a<80;a++) {
 		anslcd_write_byte_data(anslcd_logo[a]);
 	}
+	mutex_unlock(&anslcd_mutex);
 	return 0;
 }