Skip to contentSkip to conversation

usbmouse: random freeze/hangup; synchronize irq completion

PATCH In review Jordi Pujol 5 participants 5 messages Feb 14, 2011 – Feb 15, 2011 2 messages not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 usbmouse: random freeze/hangup; synchronize irq completion

Hello,

usbmouse: synchonize the irq completion for each urb.

Without this patch the mouse was a bit erratic and when
using the mouse the system gets freezed/hangup randomly (one or two times a day).

Jordi Pujol

Live never ending Tale
GNU/Linux Live forever!
http://livenet.selfip.com

usbmouse: synchonize the irq completion

Signed-off-by Jordi Pujol <jordipujolp AT gmail DOT com>
include/linux/usb.h +4 -0
@@ -1214,6 +1214,7 @@ struct urb {
 	int error_count;		/* (return) number of ISO errors */
 	void *context;			/* (in) context for completion */
 	usb_complete_t complete;	/* (in) completion routine */
+	struct mutex		complete_mutex;		/* synchronize completion */
 	struct usb_iso_packet_descriptor iso_frame_desc[0];
 					/* (in) ISO ONLY */
 };
@@ -1250,6 +1251,7 @@ static inline void usb_fill_control_urb(
 	urb->transfer_buffer_length = buffer_length;
 	urb->complete = complete_fn;
 	urb->context = context;
+	mutex_init(&urb->complete_mutex);
 }
 
 /**
@@ -1279,6 +1281,7 @@ static inline void usb_fill_bulk_urb(str
 	urb->transfer_buffer_length = buffer_length;
 	urb->complete = complete_fn;
 	urb->context = context;
+	mutex_init(&urb->complete_mutex);
 }
 
 /**
@@ -1326,6 +1329,7 @@ static inline void usb_fill_int_urb(stru
 	else
 		urb->interval = interval;
 	urb->start_frame = -1;
+	mutex_init(&urb->complete_mutex);
 }
 
 extern void usb_init_urb(struct urb *urb);
drivers/hid/usbhid/usbmouse.c +6 -1
@@ -66,13 +71,15 @@ static void usb_mouse_irq(struct urb *ur
 	struct input_dev *dev = mouse->dev;
 	int status;
 
+	mutex_lock(&urb->complete_mutex);
+
 	switch (urb->status) {
 	case 0:			/* success */
 		break;
 	case -ECONNRESET:	/* unlink */
 	case -ENOENT:
 	case -ESHUTDOWN:
-		return;
+		goto out;
 	/* -EPIPE:  should clear the halt */
 	default:		/* error */
 		goto resubmit;
@@ -95,6 +102,9 @@ resubmit:
 		err ("can't resubmit intr, %s-%s/input0, status %d",
 				mouse->usbdev->bus->bus_name,
 				mouse->usbdev->devpath, status);
+
+out:
+	mutex_unlock(&urb->complete_mutex);
 }
 
 static int usb_mouse_open(struct input_dev *dev)
#1 lore raw
Quoted 7 lines · Jordi Pujol

Hello,

usbmouse: synchonize the irq completion for each urb.

Without this patch the mouse was a bit erratic and when
using the mouse the system gets freezed/hangup randomly (one or two times a day).

Your patch is no good, for quite a few reasons. I'll state only two of them:

It calls mutex_lock(), which can sleep, from within an URB completion routine, which runs with interrupts disabled.

It doesn't synchronize the completion _with_ anything else, i.e., it calls mutex_lock() in only one place.

Whatever is causing your problem, this is not the proper solution.

Alan Stern

#2 lore raw

A Dilluns 14 Febrer 2011 16:00:24, Alan Stern va escriure:

Quoted 5 lines

It calls mutex_lock(), which can sleep, from within an URB completion routine, which runs with interrupts disabled.

It doesn't synchronize the completion _with_ anything else, i.e., it calls mutex_lock() in only one place.

this routine is synchronized with himself.
I said synchronize thinking about synchronized routines that are pieces of code scheduled to be executed only in a single thread simultaneously; therefore a new call to this routine can not be executed until a previous call has been completed.

Quoted 2 lines

Whatever is causing your problem, this is not the proper solution.

Yes, that this is not a patch to be included in the kernel, it's only a testing patch, but it solves the hangup. and so this probes that there is some kind of problem related to the urb update process; I think the problem should be external to this routine.

searching the web, some people has found problems like this, example:
- [ubuntu] Ubuntu 10.04 (Lucid Lynx) Random Freeze / Hang-up

Consider this as an idea to point out the problem and, if possible, someone more expert help to look for a good solution.

Jordi Pujol

Live never ending Tale
GNU/Linux Live forever!
http://livenet.selfip.com

A message that is not in the archive (sent off-list or not yet received): 201102151130.30998.jordipujolp-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#4 lore raw
Quoted 7 lines · Jordi Pujol

A Dilluns 14 Febrer 2011 16:00:24, Alan Stern va escriure:

Quoted 5 lines

It calls mutex_lock(), which can sleep, from within an URB completion routine, which runs with interrupts disabled.

It doesn't synchronize the completion _with_ anything else, i.e., it calls mutex_lock() in only one place.

this routine is synchronized with himself.

No. The code you added does not perform _any_ additional synchronization. If it did, you'd see a big fat error message in the kernel log because the mutex_lock call would try to sleep while in interrupt context.

Quoted 4 lines

I said synchronize thinking about synchronized routines that are pieces of code scheduled to be executed only in a single thread simultaneously; therefore a new call to this routine can not be executed until a previous call has been completed.

That is true even without your patch. Go ahead and add a pair of debugging printouts to the usb_mouse_irq() routine (without your patch); print the value of urb upon entry and exit. You'll see that there are never two instances of the routine running comcurrently for the same URB. In fact, if you have only one USB mouse, you'll see that there are never two instances of the routine running concurrently at all.

Quoted 11 lines
Quoted 1 line

Whatever is causing your problem, this is not the proper solution.

Yes, that this is not a patch to be included in the kernel, it's only a testing patch, but it solves the hangup. and so this probes that there is some kind of problem related to the urb update process; I think the problem should be external to this routine.

searching the web, some people has found problems like this, example:
- [ubuntu] Ubuntu 10.04 (Lucid Lynx) Random Freeze / Hang-up

Consider this as an idea to point out the problem and, if possible, someone more expert help to look for a good solution.

More to the point, why are you using the usbmouse driver in the first place? You should be using usbhid instead. See the warnings in the Kconfig help text for USB_MOUSE.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 201102140951.00866.jordipujolp-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#6 lore raw
Quoted 21 lines · Jordi Pujol

Hello,

usbmouse: synchonize the irq completion for each urb.

Without this patch the mouse was a bit erratic and when
using the mouse the system gets freezed/hangup randomly (one or two times a day).

Jordi Pujol

Live never ending Tale
GNU/Linux Live forever!
http://livenet.selfip.com

usbmouse: synchonize the irq completion

Signed-off-by Jordi Pujol <jordipujolp AT gmail DOT com>

include/linux/usb.h struct urb { · line 1217

Quoted 4 lines
include/linux/usb.h +1 -0
@@ -1214,6 +1214,7 @@ struct urb {
 	int error_count;		/* (return) number of ISO errors */
 	void *context;			/* (in) context for completion */
 	usb_complete_t complete;	/* (in) completion routine */
+	struct mutex		complete_mutex;		/* synchronize completion */

Ick, no, this should never be needed.

Please explain why the existing procedure for this isn't working for you?

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html