Re: usbrsa: dead lock usbrsa_write/usbrsa_write_room

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 22, 2012 at 07:41:44AM +0000, tilman wrote:
> Hello
> 
> I am posting this in reference to the thread "usb-serial: tcgetattr, 
> tcsetattr". There, I described a buffering effect that I observed. I 
> investigated this further, and found a dead lock: write_room is called while 
> the write function has not completely finished yet. Consequently write_room 
> indicates that 0 bytes are available, and the tx queue stalls.

Your code is probably incorrect, but since you have not shown us any
code for your driver it's kinda hard to tell what you're doing wrong
(but read on).

But first, why are you reimplementing the write functionality -- why not
reuse the generic implementation?


> Setup:
> ======
> Two serial ports, ttyUSB0 and ttyS1 are connected end to end.
> The USBRSA is device under test and attached to ttyUSB0.
> The USBRSA is the sending device (echo "xyz" > /dev/ttyUSB0) while ttyS1 
> receives (cat /dev/ttyS1).
> 
> Remark:
> =======
> The write function of the USBRSA driver streams the characters to be sent 
> using a preallocated pool of 10 URBs (very much like the whiteheat driver)
> 
> Observation:
> ===========
> If usbrsa_write requires more urbs than available, echo blocks on the command 
> line. 
> I am sending 577 characters (in 10 URBs each containg up to 64 bytes of 
> payload). echo adds "\a\n" which would require urb #11.
> 
> The tty layer queries the number of available bytes of the send buffer 
> (usbrsa_write_room)  BEFORE any of the urbs sent downstream to the USBRSA is 
> returned to the pool. This leads to a deadlock, i.e.  echo waits because there 
> is no urb available and I need to terminiate it with CTRL-C. Nothing is dumped 
> on the receiving terminal. Only if I then issue another echo, the string 
> previously sent by is dumped. This is probably related to the "\a\n" that 
> could not directly be sent.
> 
> Log file:
> =========
> Here is how this looks in the log file: 
> usbrsa_write - port 1; bytes=577 := count=577 : nofTxBytesFree=4096
> usbrsa_write - poolsize  10, urb_index 0
> usbrsa_write - port 1;URB allocated=0; bytes in urb=64
> usbrsa_write - port 1;URB allocated=1; bytes in urb=64
> ...
> usbrsa_write - port 1;URB allocated=9; bytes in urb=1
> usbrsa_write() End - sent=577 bytes
> usbrsa_write_room() port = 1
> usbrsa_write_room(): 0
> usbrsa_write_callback(): Returned URB 0
> usbrsa_write_callback(): Returned URB 1
> usbrsa_write_callback(): Returned URB 9
> [Here I press control-C. Only then  "\a\n" is no sent in URB #0]
> usbrsa_write - port 1 START
> usbrsa_write - port 1; bytes=2 := count=2 : nofTxBytesFree=4096
> usbrsa_write - poolsize  10, urb_index 0
> usbrsa_write - port 1;URB allocated=0;; bytes in urb=2
> usbrsa_write() End - sent=2
> 
> Questions:
> ==========
> Can I trigger another write_room ? Or do I need to wait in usbrsa_write until 
> the first urb of the empty pool is returned to it ? The whiteheat driver does 
> not seem to explicitly handle an empty URB pool either -- how does it avoid 
> this dead lock?

You need to call usb_serial_port_softint from your completion handler.


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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux