LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* lirc: igorplususb error handling cleanup
@ 2007-02-02  9:15 Pekka J Enberg
  2007-02-02 10:25 ` Oleg Verych
  0 siblings, 1 reply; 3+ messages in thread
From: Pekka J Enberg @ 2007-02-02  9:15 UTC (permalink / raw)
  To: lirc; +Cc: linux-kernel

From: Pekka Enberg <penberg@cs.helsinki.fi>

Use goto instead of a big ugly switch for error handling. Convert some 
kmalloc + memset pairs to kzalloc too.

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
---

 drivers/lirc_igorplugusb/lirc_igorplugusb.c |  116 +++++++++++++---------------
 1 file changed, 54 insertions(+), 62 deletions(-)

Index: lirc-0.8.1/drivers/lirc_igorplugusb/lirc_igorplugusb.c
===================================================================
--- lirc-0.8.1.orig/drivers/lirc_igorplugusb/lirc_igorplugusb.c
+++ lirc-0.8.1/drivers/lirc_igorplugusb/lirc_igorplugusb.c
@@ -405,7 +405,7 @@ static int usb_remote_probe(struct usb_i
 	int minor = 0;
 	char buf[63], name[128]="";
 	int mem_failure = 0;
-	int ret;
+	int ret, err;
 
 	dprintk(DRIVER_NAME ": usb probe called.\n");
 
@@ -430,67 +430,44 @@ static int usb_remote_probe(struct usb_i
 		devnum, bytes_in_key, maxp);
 
 
-	/* allocate kernel memory */
-	mem_failure = 0;
-	if (!(ir = kmalloc(sizeof(struct irctl), GFP_KERNEL))) {
-		mem_failure = 1;
-	} else {
-		memset(ir, 0, sizeof(struct irctl));
-
-		if (!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) {
-			mem_failure = 2;
-		} else if (!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) {
-			mem_failure = 3;
-		} else if (lirc_buffer_init(rbuf, bytes_in_key, 
-                		DEVICE_BUFLEN+ADDITIONAL_LIRC_BYTES)) {
-			mem_failure = 4;
-		} else if (!(ir->buf_in = usb_buffer_alloc(dev, 
-				DEVICE_BUFLEN+DEVICE_HEADERLEN, 
-                                GFP_ATOMIC, &ir->dma_in))) {
-			mem_failure = 5;
-		} else {
-
-			memset(plugin, 0, sizeof(struct lirc_plugin));
-
-			strcpy(plugin->name, DRIVER_NAME " ");
-			plugin->minor = -1;
-			plugin->code_length = bytes_in_key*8; /* in bits */
-			plugin->features = LIRC_CAN_REC_MODE2;
-			plugin->data = ir;
-			plugin->rbuf = rbuf;
-			plugin->set_use_inc = &set_use_inc;
-			plugin->set_use_dec = &set_use_dec;
-			plugin->sample_rate = SAMPLE_RATE;    /* per second */
-			plugin->add_to_buf = &usb_remote_poll;
-			plugin->owner = THIS_MODULE;
-
-			init_MUTEX(&ir->lock);
-			init_waitqueue_head(&ir->wait_out);
-
-			if ((minor = lirc_register_plugin(plugin)) < 0) {
-				mem_failure = 9;
-			}
-		}
-	}
-
-	/* free allocated memory in case of failure */
-	switch (mem_failure) {
-	case 9:
-		usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, 
-                	ir->buf_in, ir->dma_in);
-	case 5:
-		lirc_buffer_free(rbuf);
-	case 4:
-		kfree(rbuf);
-	case 3:
-		kfree(plugin);
-	case 2:
-		kfree(ir);
-	case 1:
-		printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n",
-			devnum, mem_failure);
-		return -ENOMEM;
-	}
+	ir = kzalloc(sizeof(struct irctl), GFP_KERNEL);
+	if (!ir)
+		goto failed_ctl_alloc;
+
+	plugin = kzalloc(sizeof(struct lirc_plugin), GFP_KERNEL);
+	if (!plugin)
+		goto failed_plugin_alloc;
+	rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
+	if (!rbuf)
+		goto failed_rbuf_alloc;
+
+	err = lirc_buffer_init(rbuf, bytes_in_key, DEVICE_BUFLEN +
+			       ADDITIONAL_LIRC_BYTES);
+	if (err)
+		goto failed_buffer_init;
+
+	ir->buf_in = usb_buffer_alloc(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, GFP_ATOMIC, &ir->dma_in);
+	if (!ir->buf_in)
+		goto failed_buf_in_alloc;
+
+	strcpy(plugin->name, DRIVER_NAME " ");
+	plugin->minor = -1;
+	plugin->code_length = bytes_in_key*8; /* in bits */
+	plugin->features = LIRC_CAN_REC_MODE2;
+	plugin->data = ir;
+	plugin->rbuf = rbuf;
+	plugin->set_use_inc = &set_use_inc;
+	plugin->set_use_dec = &set_use_dec;
+	plugin->sample_rate = SAMPLE_RATE;    /* per second */
+	plugin->add_to_buf = &usb_remote_poll;
+	plugin->owner = THIS_MODULE;
+
+	init_MUTEX(&ir->lock);
+	init_waitqueue_head(&ir->wait_out);
+
+	minor = lirc_register_plugin(plugin);
+	if (minor < 0)
+		goto failed_register;
 
 	plugin->minor = minor;
 	ir->p = plugin;
@@ -522,6 +499,21 @@ static int usb_remote_probe(struct usb_i
 
 	usb_set_intfdata(intf, ir);
 	return SUCCESS;
+
+  failed_register:
+	usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, ir->buf_in,
+			ir->dma_in);
+  failed_buf_in_alloc:
+	lirc_buffer_free(rbuf);
+  failed_buffer_init:
+	kfree(rbuf);
+  failed_rbuf_alloc:
+	kfree(plugin);
+  failed_plugin_alloc:
+	kfree(ir);
+  failed_ctl_alloc:
+	printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", devnum, mem_failure);
+	return -ENOMEM;
 }
 
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: lirc: igorplususb error handling cleanup
  2007-02-02  9:15 lirc: igorplususb error handling cleanup Pekka J Enberg
@ 2007-02-02 10:25 ` Oleg Verych
  2007-02-02 10:58   ` Oliver Neukum
  0 siblings, 1 reply; 3+ messages in thread
From: Oleg Verych @ 2007-02-02 10:25 UTC (permalink / raw)
  To: linux-kernel

> From: Pekka J Enberg
> Newsgroups: gmane.linux.kernel
> Subject: lirc: igorplususb error handling cleanup
> Date: Fri, 2 Feb 2007 11:15:15 +0200 (EET)
> Archived-At: <http://permalink.gmane.org/gmane.linux.kernel/488937>

Hallo.

> Use goto instead of a big ugly switch for error handling. Convert some 
> kmalloc + memset pairs to kzalloc too.

IMHO, goto ugly 2. But this isn't issue here. Let's try to optimize
all this a little bit:

> Index: lirc-0.8.1/drivers/lirc_igorplugusb/lirc_igorplugusb.c
>===================================================================
> --- lirc-0.8.1.orig/drivers/lirc_igorplugusb/lirc_igorplugusb.c
> +++ lirc-0.8.1/drivers/lirc_igorplugusb/lirc_igorplugusb.c
> @@ -405,7 +405,7 @@ static int usb_remote_probe(struct usb_i
>  	int minor = 0;
>  	char buf[63], name[128]="";
>  	int mem_failure = 0;
> -	int ret;
> +	int ret, err;
>  
>  	dprintk(DRIVER_NAME ": usb probe called.\n");
>  
> @@ -430,67 +430,44 @@ static int usb_remote_probe(struct usb_i
>  		devnum, bytes_in_key, maxp);
>  
>  
> -	/* allocate kernel memory */
> -	mem_failure = 0;
> -	if (!(ir = kmalloc(sizeof(struct irctl), GFP_KERNEL))) {
> -		mem_failure = 1;
> -	} else {
> -		memset(ir, 0, sizeof(struct irctl));
> -
> -		if (!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) {
> -			mem_failure = 2;
> -		} else if (!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) {
> -			mem_failure = 3;

If size of all structs, allocated here is 3-4 pages (say, 4096 bytes
one), then, i think something like, allocating all at once may be
utilized:

,-*-
|struct ir_stuff_t {
|       struct irctl *ir;
|       struct lirc_plugin *plugin;
|       struct lirc_buffer *rbuf;
|} ir_stuff;
|
|ir_stuff = kzalloc(...);
|
|if(!ir_stuff)
|       error;
`-*-       

then join buffer init, usb init together and final register, after
it. Thus to have second erroneous path.

So, lucky path may be faster, erroneous, with more *free() stuff slower,
but who cares?

Finally i would put first stage in do { ...if (error) break; ...} while(0),
second in if (error) ... break.

What about that? (ENOPATCH, but i have no lirc ATM ;)

> -		} else if (lirc_buffer_init(rbuf, bytes_in_key, 
> -                		DEVICE_BUFLEN+ADDITIONAL_LIRC_BYTES)) {
> -			mem_failure = 4;
> -		} else if (!(ir->buf_in = usb_buffer_alloc(dev, 
> -				DEVICE_BUFLEN+DEVICE_HEADERLEN, 
> -                                GFP_ATOMIC, &ir->dma_in))) {
> -			mem_failure = 5;
> -		} else {
> -
> -			memset(plugin, 0, sizeof(struct lirc_plugin));
> -
> -			strcpy(plugin->name, DRIVER_NAME " ");
> -			plugin->minor = -1;
> -			plugin->code_length = bytes_in_key*8; /* in bits */
> -			plugin->features = LIRC_CAN_REC_MODE2;
> -			plugin->data = ir;
> -			plugin->rbuf = rbuf;
> -			plugin->set_use_inc = &set_use_inc;
> -			plugin->set_use_dec = &set_use_dec;
> -			plugin->sample_rate = SAMPLE_RATE;    /* per second */
> -			plugin->add_to_buf = &usb_remote_poll;
> -			plugin->owner = THIS_MODULE;
> -
> -			init_MUTEX(&ir->lock);
> -			init_waitqueue_head(&ir->wait_out);
> -
> -			if ((minor = lirc_register_plugin(plugin)) < 0) {
> -				mem_failure = 9;
> -			}
> -		}
> -	}
> -
> -	/* free allocated memory in case of failure */
> -	switch (mem_failure) {
> -	case 9:
> -		usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, 
> -                	ir->buf_in, ir->dma_in);
> -	case 5:
> -		lirc_buffer_free(rbuf);
> -	case 4:
> -		kfree(rbuf);
> -	case 3:
> -		kfree(plugin);
> -	case 2:
> -		kfree(ir);
> -	case 1:
> -		printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n",
> -			devnum, mem_failure);
> -		return -ENOMEM;
> -	}
> +	ir = kzalloc(sizeof(struct irctl), GFP_KERNEL);
> +	if (!ir)
> +		goto failed_ctl_alloc;
> +
> +	plugin = kzalloc(sizeof(struct lirc_plugin), GFP_KERNEL);
> +	if (!plugin)
> +		goto failed_plugin_alloc;
> +	rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
> +	if (!rbuf)
> +		goto failed_rbuf_alloc;
> +
> +	err = lirc_buffer_init(rbuf, bytes_in_key, DEVICE_BUFLEN +
> +			       ADDITIONAL_LIRC_BYTES);
> +	if (err)
> +		goto failed_buffer_init;
> +
> +	ir->buf_in = usb_buffer_alloc(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, GFP_ATOMIC, &ir->dma_in);
> +	if (!ir->buf_in)
> +		goto failed_buf_in_alloc;
> +
> +	strcpy(plugin->name, DRIVER_NAME " ");
> +	plugin->minor = -1;
> +	plugin->code_length = bytes_in_key*8; /* in bits */
> +	plugin->features = LIRC_CAN_REC_MODE2;
> +	plugin->data = ir;
> +	plugin->rbuf = rbuf;
> +	plugin->set_use_inc = &set_use_inc;
> +	plugin->set_use_dec = &set_use_dec;
> +	plugin->sample_rate = SAMPLE_RATE;    /* per second */
> +	plugin->add_to_buf = &usb_remote_poll;
> +	plugin->owner = THIS_MODULE;
> +
> +	init_MUTEX(&ir->lock);
> +	init_waitqueue_head(&ir->wait_out);
> +
> +	minor = lirc_register_plugin(plugin);
> +	if (minor < 0)
> +		goto failed_register;
>  
>  	plugin->minor = minor;
>  	ir->p = plugin;
> @@ -522,6 +499,21 @@ static int usb_remote_probe(struct usb_i
>  
>  	usb_set_intfdata(intf, ir);
>  	return SUCCESS;
> +
> +  failed_register:
> +	usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, ir->buf_in,
> +			ir->dma_in);
> +  failed_buf_in_alloc:
> +	lirc_buffer_free(rbuf);
> +  failed_buffer_init:
> +	kfree(rbuf);
> +  failed_rbuf_alloc:
> +	kfree(plugin);
> +  failed_plugin_alloc:
> +	kfree(ir);
> +  failed_ctl_alloc:
> +	printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", devnum, mem_failure);
> +	return -ENOMEM;
>  }
>  
>  

p.s. Please honor information in the 'Mail-Followup-To' header. Thanks.
____


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: lirc: igorplususb error handling cleanup
  2007-02-02 10:25 ` Oleg Verych
@ 2007-02-02 10:58   ` Oliver Neukum
  0 siblings, 0 replies; 3+ messages in thread
From: Oliver Neukum @ 2007-02-02 10:58 UTC (permalink / raw)
  To: Oleg Verych, Pekka J Enberg, lirc; +Cc: linux-kernel


> > -	/* allocate kernel memory */
> > -	mem_failure = 0;
> > -	if (!(ir = kmalloc(sizeof(struct irctl), GFP_KERNEL))) {
> > -		mem_failure = 1;
> > -	} else {
> > -		memset(ir, 0, sizeof(struct irctl));
> > -
> > -		if (!(plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL))) {
> > -			mem_failure = 2;
> > -		} else if (!(rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL))) {
> > -			mem_failure = 3;
> 
> If size of all structs, allocated here is 3-4 pages (say, 4096 bytes
> one), then, i think something like, allocating all at once may be
> utilized:
> 
> ,-*-
> |struct ir_stuff_t {
> |       struct irctl *ir;
> |       struct lirc_plugin *plugin;
> |       struct lirc_buffer *rbuf;

I guess you mean 
struct lirc_buffer rbuf;
without the "*"

> |} ir_stuff;
> |
> |ir_stuff = kzalloc(...);
> |
> |if(!ir_stuff)
> |       error;
> `-*-       
> 
> then join buffer init, usb init together and final register, after
> it. Thus to have second erroneous path.

If I understand this code correctly the allocated buffers end up as
buffers used in URBs. If that is the case you must allocate each of
them separately with kmalloc() or usb_alloc_buffer() or you violate
DMA constraints on non-coherent architectures (eg. ppc)

	Regards
		Oliver

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-02-02 10:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-02  9:15 lirc: igorplususb error handling cleanup Pekka J Enberg
2007-02-02 10:25 ` Oleg Verych
2007-02-02 10:58   ` Oliver Neukum

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).