On Mon, 13 Mar 2017, Charles Manning wrote:

> On Mon, Mar 13, 2017 at 2:38 PM, Alan Stern <st...@rowland.harvard.edu>
> wrote:
> 
> > On Mon, 13 Mar 2017, Charles Manning wrote:
> >
> > > Hello
> > >
> > > I have an issue where the first 512-byte high speed bulk transfer
> > > between a custom peripheral and a Linux host is sometimes lost.
> > >
> > > I have the bus attached to a Beagle 480 and I can see the transaction
> > > happening over the bus (IN, DATA, ACK) at the right time but the data
> > > does not show up into userspace buffers. ie. it would seem the data is
> > > getting lost somewhere between the host hardware and user space.
> > >
> > > I've seen on both Ubuntu with 4.4.0 x64 as well as on various Android
> > > ARM platforms (ie commercial Android phones/tablets).
> > >
> > > There are two independently written user space programs that both
> > > exhibit this behaviour:
> > > * Linux PC based application written using libusb.
> > > * Android application written in NDK using ioctls.
> > >
> > > In both cases everything works fine (eg. long term streaming for
> > > hours, orderly start/stopping) except when the process is killed
> > > (swipe app right in Android) or Control C in Ubuntu.
> > >
> > > If the application is killed then the first 512-byte transfer in the
> > > next invocation of the application **might** be lost.
> > >
> > > In our application we're stuffing approx 8 or 9 MBytes of data a
> > > second through the high speed USB link (ie. around 1/7) of the full
> > > bandwidth. The problem occurs approximately 1/7th of the time.
> > >
> > > This leads me to suspect that around 1/7th of the time the process is
> > > being killed during the middle of a transfer and this results in the
> > > host controller being left in a weird state causing the first packet
> > > to be lost.
> > >
> > > Any hints on where to look for this or how to debug further would be
> > > much appreciated.
> >
> > No doubt what happens is that the packet is received by the system, but
> > the process is killed before it can get the packet's contents from the
> > operating system.  (Or after it has gotten the packet's contents but
> > before it can do anything with them.)
> >
> >
> Thanks for the response, but that does not stack up.
> 
> The order is this:
> 
> Start a process.... all transfering nicely.

Okay.  The process submits URBs 1 - N, and processes the replies for
URBs 1 - (N-1).  The data for URB N has just arrived at the computer
and (let's say) has been sent to the process.  But before the process
can do anything with this data...

> Kill process with Ctl C.

The process is now dead.  The data for URB N has been lost.  The data 
for URBs 1 - (N-1), on the other hand, have been fully processed.

> Start another process
> The new process does set halt, clear halts etc. (as well as some config).

Why on earth would you want to do a Set-Halt?  That request hardly ever 
gets used -- and when it does, it's usually in error.

> The new process submits URBs.

It submits URBs (N+1) - M.

> The device sends out new packets.

Starting with the data for URB N+1.

> The first 512 byte transfer goes AWOL.

No, it doesn't.  What you _think_ is the first 512 bytes is actually 
the 512 bytes for URB N, which (as mentioned above) have been 
permanently lost.  The data for URB N+1 gets sent to the new process as 
it should be.

> ie. it isn't the control C that is causing the data to not get to the
> process. The Control C was on an entirely different process.

The missing data doesn't get to the new process because it was already
sent to the original process.  The ^C prevents the original process
from processing (or receiving, as the case may be) this data.

> > I can assure you that the host controller is not left in any sort of
> > weird state.
> >
> 
> Where is that state managed?

In the host controller driver.  You can probably find out what driver
that is by reading the information in /sys/kernel/debug/usb/devices, or 
if necessary, by examining the kernel log.

> > If you want to prevent this sort of thing from happening, don't just
> > kill the process willy-nilly.  Have it catch the signal and set a flag,
> > and have it check this flag at an appropriate place so that it can
> > fetch the contents of any remaining packets before exiting in an
> > orderly manner.
> >
> 
> That's not really the point. I was doing this as a stress test, not as
> inything intended in production code.

Ah, okay.

If you want to find out what the kernel thinks is happening to your
URBs during the stress test, follow the instructions in
Documentation/usb/usbmon.txt.

Alan Stern

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

Reply via email to