Hi,
this driver has locking problems. Here's the first round of fixes
for the obvious cases.
- it makes clear differences between completion handlers and task context
- it fixes cases of sleeping in interrupt
The cset is against Linus' tree.
Regards
Oliver
You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.
===================================================================
[EMAIL PROTECTED], 2003-12-02 19:44:22+01:00, [EMAIL PROTECTED]
- fix sleeping in interrupt
- optimize spinlocks in completion handlers
cyberjack.c | 25 +++++++++++--------------
1 files changed, 11 insertions(+), 14 deletions(-)
diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
--- a/drivers/usb/serial/cyberjack.c Tue Dec 2 19:58:58 2003
+++ b/drivers/usb/serial/cyberjack.c Tue Dec 2 19:58:58 2003
@@ -295,7 +295,6 @@
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct cyberjack_private *priv = usb_get_serial_port_data(port);
- unsigned long flags;
struct usb_serial *serial;
unsigned char *data = urb->transfer_buffer;
int result;
@@ -323,13 +322,13 @@
/* This is a announcement of coming bulk_ins. */
unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
old_rdtodo = priv->rdtodo;
if( (old_rdtodo+size)<(old_rdtodo) ) {
dbg( "To many bulk_in urbs to do." );
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
goto resubmit;
}
@@ -338,11 +337,11 @@
dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
if( !old_rdtodo ) {
port->read_urb->dev = port->serial->dev;
- result = usb_submit_urb(port->read_urb, GFP_KERNEL);
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if( result )
err("%s - failed resubmitting read urb, error %d",
__FUNCTION__, result);
dbg("%s - usb_submit_urb(read urb)", __FUNCTION__);
@@ -351,7 +350,7 @@
resubmit:
port->interrupt_in_urb->dev = port->serial->dev;
- result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
err(" usb_submit_urb(read int) failed");
dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
@@ -361,7 +360,6 @@
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct cyberjack_private *priv = usb_get_serial_port_data(port);
- unsigned long flags;
struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
struct tty_struct *tty;
unsigned char *data = urb->transfer_buffer;
@@ -397,7 +395,7 @@
tty_flip_buffer_push(tty);
}
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
/* Reduce urbs to do by one. */
priv->rdtodo-=urb->actual_length;
@@ -405,14 +403,14 @@
if ( priv->rdtodo<0 ) priv->rdtodo = 0;
todo = priv->rdtodo;
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
dbg("%s - rdtodo: %d", __FUNCTION__, todo);
/* Continue to read if we have still urbs to do. */
if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
port->read_urb->dev = port->serial->dev;
- result = usb_submit_urb(port->read_urb, GFP_KERNEL);
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
err("%s - failed resubmitting read urb, error %d",
__FUNCTION__, result);
dbg("%s - usb_submit_urb(read urb)", __FUNCTION__);
@@ -423,7 +421,6 @@
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct cyberjack_private *priv = usb_get_serial_port_data(port);
- unsigned long flags;
struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -438,7 +435,7 @@
return;
}
- spin_lock_irqsave(&priv->lock, flags);
+ spin_lock(&priv->lock);
/* only do something if we have more data to send */
if( priv->wrfilled ) {
@@ -446,7 +443,7 @@
if (port->write_urb->status == -EINPROGRESS) {
dbg("%s - already writing", __FUNCTION__);
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
return;
}
@@ -492,7 +489,7 @@
}
exit:
- spin_unlock_irqrestore(&priv->lock, flags);
+ spin_unlock(&priv->lock);
schedule_work(&port->work);
}
===================================================================
This BitKeeper patch contains the following changesets:
1.1128
## Wrapped with gzip_uu ##
begin 664 bkpatch18738
M'XL(`/[EMAIL PROTECTED]:V^;,!3]'/\*2Y6F5EW`-N:5*56[9NNJ;6J4M9^F*>+A
M)BR`D6VZ=>+'[P)3NE5ITE8K(%W@'H[ON?<`>_A*"S4:R#R[$0KMX0]2F]$`
MSHLZ%:55BGI5%Y94"\C-I(2<O92%L/L'[$LEA+:-T(9Y""#3R"1+#!D]&E#+
M6=\QMY48#6;OSJX^G<P0&H_QZ3(J%^*+,'@\1D:JFRA/]7%DEKDL+:.B4A?"
M1%8BBV8-;[EMAIL PROTECTED]':[EMAIL PROTECTED]/M-0E-*(TY%2A@//([ZVHXWB/B7RJ&4N<2C
M(?$;-R#<01-,+;@98.+8E-F$81J..!\Q=DCHB!#\,#4^I'A(T%O\?[6<[EMAIL PROTECTED]/
M\77V$^M<B"[EMAIL PROTECTED]"J;HR7596)BNR7P)KR.<R6>D6`ZM5N3"9+#&LF>8P
M$_01NX'CA&AZUWXT?.*&$(D(.L)5.]C-(E/5=DG;M8YML%<6Y79R&POU/4I6
M5G*G/.`!#1M"B,^;-(Y]CWDQM"'T:[EMAIL PROTECTED]/R<T(9RE[+.<]N?:XWX
MPJ)0<5S$>J6M:Z!>@:A4?%THL?CV&$DD8#X#480WCN,'M'.KP^Y[E=#'>!7,
M2OD+N;76`I^]G\Y/+B\^GY_B2&,M$EFF.%*+NA"EP?(:0/%<UW&1F7FMXOV#
MARS[5(/WT[[`0_6C.\"PTQV#?\8K,&%A@&$"#O,@G/=A,&CKF[<%[K^J8,GA
M47M^\`9P,*<6UX7!'V!=;H1RVD&[L`/I]DBW)U5"USE\3^_WMI+*#(^4B-+V
M\O5?L^E87-ZQ=&$'Q_J[,[EMAIL PROTECTED]&&;A7+:">W#
M<W7R;D83WK>W#UMJXV$/"W<.C(=]=5W8`ES_#).E``O7Q=BE/&1^Q-%OUKBS
%&8<'````
`
end
-------------------------------------------------------
This SF.net email is sponsored by OSDN's Audience Survey.
Help shape OSDN's sites and tell us what you think. Take this
five minute survey and you could win a $250 Gift Certificate.
http://www.wrgsurveys.com/2003/osdntech03.php?site=8
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel