On 2021/01/22 0:30, Oliver Neukum wrote:
Hi,
you have moved kill_urbs() below
cancel_work_sync(&desc->rxwork);
cancel_work_sync(&desc->service_outs_intr);
to close a race, as
rv = usb_submit_urb(desc->response, GFP_KERNEL);
in service_outstanding_interrupt() would submit the response URB,
right?
Right. Shouldn't remaining
kill_urbs(desc);
cancel_work_sync(&desc->rxwork);
cancel_work_sync(&desc->service_outs_intr);
sequence in wdm_suspend() and wdm_pre_reset() be updated as well?
Unfortunately we have in wdm_in_callback() the following code path
if (desc->rerr) {
/*
* Since there was an error, userspace may decide to not read
* any data after poll'ing.
* We should respond to further attempts from the device to send
* data, so that we can get unstuck.
*/
schedule_work(&desc->service_outs_intr);
It looks to me like we have a circular dependency here and this needs some
change to break. What do you think about the attached patch?
I don't know how poisoning works. But why can't we simply use test_bit() on
WDM_SUSPENDING/WDM_RESETTING/WDM_DISCONNECTING flags, for schedule_work() in
wdm_in_callback() is called with desc->iuspin (which serializes setting of
these flags) held.
By the way, since someone might interpret "broken" as "out of order / not working",
I expect not using "This needs to be broken." in the commit message. There would be
some better idiom.