Re: [PATCH] usb: core: Solve race condition in usb_kill_anchored_urbs

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

 



On Tue, Jul 28, 2020 at 12:47:30PM +0300, Eli Billauer wrote:
> Oliver, Alan,
> 
> I understand that there's a disagreement in what is allowed or not with the
> anchor API. Effectively that means that I have to assume that driver
> programmers will go either way. I have to admit that my view was that a
> driver must proactively make sure it doesn't submit further URBs to an
> anchor as long as usb_kill_anchored_urbs() runs, through completers or
> otherwise. I formed the current patch accordingly.
> 
> To make things trickier, a driver might rely (correctly or not) on that
> usb_kill_urb() makes sure that resubmission of a URB by the completer, while
> usb_kill_urb() is killing it, will fail. Or at least so says the description
> of this function.
> 
> And once again, the resubmitted URB will remain untouched if the said race
> condition occurs. So a driver's programmer, who relied on usb_kill_urb() to
> prevent the resubmission, might get the impression that he did correctly
> when testing the driver, but then the kernel panic will happen rarely and
> far from the eye.
> 
> Writing an additional API without this problem is beyond the scope of this
> discussion. I'm focused on resolving the problem of the current one. The
> existing API must be safe to use, even if it's planned to phase out.
> 
> Given the discussion so far, I realized that the resubmission by completer
> case must be handled properly as well. So I suggest modifying the patch to
> something like
> 
> do {
>     spin_lock_irq(&anchor->lock);
>     while (!list_empty(&anchor->urb_list)) {
>         /* URB kill loop */
>     }
>     spin_unlock_irq(&anchor->lock);
> } while (unlikely(!usb_anchor_check_wakeup(anchor)));
> 
> The do-while loop will almost never make any difference. But it will loop
> like a waiting spinlock in the rare event of the said race condition, while
> the completer callback executes.
> 
> And if the completer submitted a URB, it will be removed as well this way.
> Recall that this loops only in the event of a race condition, so it will NOT
> play cat-and-mouse with the completer callback, but rather finish this up
> rather quickly.
> 
> And I've dropped the WARN(): If some people consider resubmission of a URB
> to be OK, even while usb_kill_anchored_urbs() is called, no noise should be
> made if that causes a rare but tricky situation.
> 
> And since I'm at it, I'll make the same change to
> usb_poison_anchored_urbs(), which suffers from exactly the same problem.
> 
> What do you think?

This seems like a good way to fix up the existing API, until drivers can 
be converted over to Oliver's "mooring" scheme.  Of course, Oliver might 
not agree...

Alan Stern



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

  Powered by Linux