f_mass_storage configuration races (Was: Virtual hub, resets etc...)

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

 



Sooo...

I think I found what's going on with some of the issues triggering
things like

	usb_composite_setup_continue: Unexpected call 

Or possibly

	gadget: common->fsg is NULL in fsg_setup at 489

But I mostly tracked down the former.

Fundamentally, it boils down to the storage going through multiple
attempts at FSG_STATE_CONFIG_CHANGE too quickly. In my case:

 - The hub port gets reset, this eventually calls fsg_disable

 - In the middle of handle_exception, we get a fsg_set_alt(), after
common->state is set back to FSG_STATE_NORMAL and before we get to
call do_set_interface (or inside it).

What happens is that not only new_fsg is indeterminate and possibly
racy (maybe not a huge deal per-se), but we end up in that
interesting situation where the handle_exception caused by fsg_disable
ends up applying "new_fsg" *and* calling usb_composite_setup_continue
because it sees new_fsg being set by fsg_set_alt.

But *then*, fsg_set_alt() also queues up a new exception. So we come
back a second time around. We call do_set_interface() again, which
resets everything for no reason, re-established the fsg and ... we call
usb_composite_setup_continue() again, this time completely at the wrong
time since there's nothing to continue.

I think the right fix is to replace that racy exception crap with a
little queue so we remove those races.

In the meantime however, I think the simpler patch that I'll send as
a reply to this works around it, provided the host doesn't do multiple
set_alt too quickly. The latter could be handled by setting new_fsg
with the lock used for the state, and reading it from that same lock.
But I haven't observed that problem in practice.

With this patch, I can now unplug & replug on my host solidly, this
wasn't the case before.

Cheers,
Ben.






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

  Powered by Linux