USB stack getting confused

Warner Losh imp at bsdimp.com
Sat Mar 9 18:41:45 UTC 2019


On Sat, Mar 9, 2019 at 11:25 AM Konstantin Belousov <kostikbel at gmail.com>
wrote:

> On Sat, Mar 09, 2019 at 04:42:50PM +0100, Hans Petter Selasky wrote:
> > On 3/9/19 4:26 PM, Konstantin Belousov wrote:
> > > On Sat, Mar 09, 2019 at 08:59:30PM +1030, O'Connor, Daniel wrote:
> > >>
> > >>
> > >>> On 9 Mar 2019, at 19:30, Hans Petter Selasky <hps at selasky.org>
> wrote:
> > >>> On 3/9/19 12:08 AM, O'Connor, Daniel wrote:
> > >>>> My program normally runs continually doing acquisitions of data for
> N seconds, doing some checks and restarting. After a while (~30 1 minute
> acquisitions or ~8 30 minute ones) my program can't 'see' the device (it
> uses libusb10) any more (it reconnects each acquisition for $REASONS). Also
> pretty weirdly usbconfig can't see it either(!).
> > >>>
> > >>> What is printed in dmesg? Maybe the device has a problem.
> > >>
> > >> There is nothing in dmesg - no disconnect / reconnect etc.
> > >>
> > >> If I hold the user space process in gdb 'forever' (eg over night)
> usbconfig doesn't see the device, but the moment I quit the user space
> process it can be seen again.
> > >
> > > Does it mean that the file descriptor opened for ugen has a chance to
> > > be closed ?
> >
> > The USB stack will wait for all FDs to be closed during detach also via
> > destroy_dev().
> So my guess was correct.  Do you agree that this behaviour is wrong ?
>
> In fact I saw something similar with apcupsd and either usb/com adapters
> or native usb control card for APC UPSes.  For reasons I do not understand,
> these devices are often disconnected.  For older versions of apcupsd,
> it required restart for newly reattached device to be recreated in /dev.
> Sometimes it hangs whole usb stack.
>
> Newer apcupsd seems to open /dev/ugen only for the duration of the query,
> which makes the erratic behaviour is much less likely, but could still
> cause
> breakage when device disappear while apcupsd has it opened.
>

Is there a form of destroy_dev() that does a revoke on all open instances?
Eg, this is gone, you can't use it anymore, and all further attempts to use
the device will generate an error, but in the mean time we destroy the
device and let the detach routine get on with life. waiting may make sense
when you are merely unloading the driver (and getting to the detach routine
that way), but when the device is gone, I've come around to the point of
view that we should just destroy it w/o waiting for closes and anybody that
touches it afterwards gets an error and has to cope with the error. But
even in the unload case, we maybe we shouldn't get to the detach routine
unless we're forcing and/or the detach routine just returns EBUSY since the
only one that knows what dev_t's are associated with the device_t is the
driver itself.

Warner

>
> > >
> > > I suspect that usb subsystem tried to destroy the device but some
> internal
> > > refcounting prevents it.  Proper use of destroy_dev(_cb)(9) avoids
> > > the issue.
> >
> > --HPS
> _______________________________________________
> freebsd-hackers at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
>


More information about the freebsd-hackers mailing list