Re: Threaded interrupts for USB HCD instead of tasklets

2018-06-01 Thread Alan Stern
On Fri, 1 Jun 2018, Sebastian Andrzej Siewior wrote:

> On 2018-05-22 15:14:17 [-0400], Alan Stern wrote:
> > Sorry, I don't understand that sentence at all.  And I don't see how it 
> > could be relevant to the point I was trying to make.
> > 
> > Consider, for example, drivers/hid/usbhid/hid-core.c.  In that file,
> > hid_io_error() is called by hid_irq_in(), which is an URB completion
> > handler.  hid_io_error() acquires usbhid_lock.  Therefore it would be
> > necessary to audit the usbhid driver to see whether interrupts are
> > enabled or disabled any place where usbhid_lock is acquired.  And in
> > fact, hid_ctrl() (another completion handler) calls
> > spin_lock(>lock) -- this could cause problems for you.  And
> > usbhid->lock is acquired in other places, ones that are not inside
> > completion handlers.
> 
> To pick up this example. hid_io_error() is called from process context
> (usb_hid_open()) or the completion handler and disables interrupts while
> acquiring the lock. hid_ctrl() acquires the lock without disabling the
> interrupts. This is not a problem because hid_ctrl() can not be
> preempted while it is holding the  lock by anything that also wants the
> lock. So hid-core could stay as-is and we would be fine. However
> lockdep would complain if hid-core would be used on ehci
> (softirq/tasklet completion) and ohci (IRQ-handler completion) because
> then lockdep would think that hid_ctrl() invoked by ehci could be
> preempted by the ohci driver.

In any case, it's generally bad form for two routines to obtain the 
same lock in process context, if one of them uses spin_lock and the 
other uses spin_lock_irqsave.  It indicates that the programmer didn't 
have a firm grasp on how the lock would be used.

> > None of this has anything to do with IRQ usage or hrtimers.
> hid-core sets up a timer_list timer hid_retry_timeout(). This timer runs
> in softirq context which means it can't preempt the completion handler
> (hid_ctrlhid_ctrl()) which does just spin_lock() (both run in BH).
> However, if hid_retry_timeout() were a hrtimer timer then it would be
> invoked in IRQ-context. In that case it could preempt hid_ctrlhid_ctrl()
> and _irqsave() would be required in hid_ctrlhid_ctrl().
> 
> My counting reveals ~250 USB drivers. I think it is best to audit them
> first and make sure that completion handler like hid_ctrl() do

And any routines they call, obviously.

> _irqsave(). Once that is done, the local_irq_save() in
> __usb_hcd_giveback_urb() could go.

Agreed.

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


Re: Threaded interrupts for USB HCD instead of tasklets

2018-06-01 Thread Sebastian Andrzej Siewior
On 2018-05-22 15:14:17 [-0400], Alan Stern wrote:
> Sorry, I don't understand that sentence at all.  And I don't see how it 
> could be relevant to the point I was trying to make.
> 
> Consider, for example, drivers/hid/usbhid/hid-core.c.  In that file,
> hid_io_error() is called by hid_irq_in(), which is an URB completion
> handler.  hid_io_error() acquires usbhid_lock.  Therefore it would be
> necessary to audit the usbhid driver to see whether interrupts are
> enabled or disabled any place where usbhid_lock is acquired.  And in
> fact, hid_ctrl() (another completion handler) calls
> spin_lock(>lock) -- this could cause problems for you.  And
> usbhid->lock is acquired in other places, ones that are not inside
> completion handlers.

To pick up this example. hid_io_error() is called from process context
(usb_hid_open()) or the completion handler and disables interrupts while
acquiring the lock. hid_ctrl() acquires the lock without disabling the
interrupts. This is not a problem because hid_ctrl() can not be
preempted while it is holding the  lock by anything that also wants the
lock. So hid-core could stay as-is and we would be fine. However
lockdep would complain if hid-core would be used on ehci
(softirq/tasklet completion) and ohci (IRQ-handler completion) because
then lockdep would think that hid_ctrl() invoked by ehci could be
preempted by the ohci driver.

> None of this has anything to do with IRQ usage or hrtimers.
hid-core sets up a timer_list timer hid_retry_timeout(). This timer runs
in softirq context which means it can't preempt the completion handler
(hid_ctrlhid_ctrl()) which does just spin_lock() (both run in BH).
However, if hid_retry_timeout() were a hrtimer timer then it would be
invoked in IRQ-context. In that case it could preempt hid_ctrlhid_ctrl()
and _irqsave() would be required in hid_ctrlhid_ctrl().

My counting reveals ~250 USB drivers. I think it is best to audit them
first and make sure that completion handler like hid_ctrl() do
_irqsave(). Once that is done, the local_irq_save() in
__usb_hcd_giveback_urb() could go.

Sebastian
--
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


Re: Threaded interrupts for USB HCD instead of tasklets

2018-05-23 Thread Sebastian Andrzej Siewior
On 2018-05-22 15:14:17 [-0400], Alan Stern wrote:
> On Tue, 22 May 2018, Sebastian Andrzej Siewior wrote:
> 
> > On 2018-05-07 11:37:29 [-0400], Alan Stern wrote:
> > > > As far as I understand it there should be no deadlock. Without the
> > > > local_irq_save() things should not deadlock because the HCD invokes USB
> > > > driver's (usb-storage for instance) ->complete callback always in the
> > > > same way. If you mix the usb-driver with two different HCDs (say ehci
> > > > and xhci) then lockdep would complain. However, the locks which were
> > > > allocated by usb-storage for the ehci driver would never be used in the
> > > > context of the xhci driver. So lockdep would report a deacklock but
> > > > there wouldn't be one (again, if I got the piece right).
> > > 
> > > That argument would be correct if the completion routines were the only
> > > places where the higher-level drivers (such as usb-storage or usbhid)  
> > > acquired their locks.  But we can't depend on this being true; you
> > > would have to audit each USB driver to make sure.
> > 
> > an entry point for IRQ usage outside of the driver would be the usage of
> > hrtimer.
> 
> Sorry, I don't understand that sentence at all.  And I don't see how it 
> could be relevant to the point I was trying to make.
> 
> Consider, for example, drivers/hid/usbhid/hid-core.c.  In that file,
> hid_io_error() is called by hid_irq_in(), which is an URB completion
> handler.  hid_io_error() acquires usbhid_lock.  Therefore it would be
> necessary to audit the usbhid driver to see whether interrupts are
> enabled or disabled any place where usbhid_lock is acquired.  And in
> fact, hid_ctrl() (another completion handler) calls
> spin_lock(>lock) -- this could cause problems for you.  And
> usbhid->lock is acquired in other places, ones that are not inside
> completion handlers.
> 
> None of this has anything to do with IRQ usage or hrtimers.

Yeah, I get what you mean.

> > You mean the "Reserved Bandwidth Transfers:" paragraph?
> 
> Paragraphs (plural).  Three paragraphs, to be precise.
> 
> > > It's possible to rewrite the HCDs not to rely on this (I did exactly
> > > that for ehci-hcd), but it is a nontrivial job.
> > 
> > are you referring to commit 9118f9eb4f1e ("USB: EHCI: improve interrupt
> > qh unlink")?
> 
> That one, plus:
> 
>   46c73d1d3ebc ("USB: EHCI: handle isochronous underruns with tasklets")
>   e4e18cbd52c8 ("USB: EHCI: code rearrangement in iso_stream_schedule()")
>   24f531371de1 ("USB: EHCI: accept very late isochronous URBs")
>   35371e4fbc3e ("USB: EHCI: improve ehci_endpoint_disable")
> 
> Not all parts of all those commits were relevant, but as far as I
> recall, they each contributed something.  And I may have omitted
> one or two commits by mistake.

Thank you, let me look at those so I can see what is needed…

> Alan Stern

Sebastian
--
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


Re: Threaded interrupts for USB HCD instead of tasklets

2018-05-22 Thread Alan Stern
On Tue, 22 May 2018, Sebastian Andrzej Siewior wrote:

> On 2018-05-07 11:37:29 [-0400], Alan Stern wrote:
> > > As far as I understand it there should be no deadlock. Without the
> > > local_irq_save() things should not deadlock because the HCD invokes USB
> > > driver's (usb-storage for instance) ->complete callback always in the
> > > same way. If you mix the usb-driver with two different HCDs (say ehci
> > > and xhci) then lockdep would complain. However, the locks which were
> > > allocated by usb-storage for the ehci driver would never be used in the
> > > context of the xhci driver. So lockdep would report a deacklock but
> > > there wouldn't be one (again, if I got the piece right).
> > 
> > That argument would be correct if the completion routines were the only
> > places where the higher-level drivers (such as usb-storage or usbhid)  
> > acquired their locks.  But we can't depend on this being true; you
> > would have to audit each USB driver to make sure.
> 
> an entry point for IRQ usage outside of the driver would be the usage of
> hrtimer.

Sorry, I don't understand that sentence at all.  And I don't see how it 
could be relevant to the point I was trying to make.

Consider, for example, drivers/hid/usbhid/hid-core.c.  In that file,
hid_io_error() is called by hid_irq_in(), which is an URB completion
handler.  hid_io_error() acquires usbhid_lock.  Therefore it would be
necessary to audit the usbhid driver to see whether interrupts are
enabled or disabled any place where usbhid_lock is acquired.  And in
fact, hid_ctrl() (another completion handler) calls
spin_lock(>lock) -- this could cause problems for you.  And
usbhid->lock is acquired in other places, ones that are not inside
completion handlers.

None of this has anything to do with IRQ usage or hrtimers.

>  We have a flag to let the hrtimer run in softirq but yes, we
> need to audit them.
> 
> > > And I was thinking about converting all drivers to one model and then we
> > > could get rid of the block I quoted above.
> > > 
> > > If nobody rejects the approach as such I would go and start hacking…
> > > 
> > > > And even for those two, the conversion will not be easy.  Simply
> > > > changing the giveback routines would violate the documented guarantees
> > > > for isochronous transfers.
> > > 
> > > The requirement was that the ISO urb is completed before the BULK urb,
> > > right?
> > 
> > No, that's not what I meant.  For one thing, isochronous URBs don't
> > need to complete before bulk URBs in general (although they do have
> > higher priority).
> > 
> > However, I was really referring to the kerneldoc for usb_submit_urb().  
> > The part that talks about scheduling of isochronous and interrupt URBs
> > lists a bunch of requirements.  In order to meet these requirements
> > some of the host controller drivers may rely on the fact that when they
> > give back an URB, the URB's completion routine will return before the
> > giveback call finishes.
> 
> You mean the "Reserved Bandwidth Transfers:" paragraph?

Paragraphs (plural).  Three paragraphs, to be precise.

> > It's possible to rewrite the HCDs not to rely on this (I did exactly
> > that for ehci-hcd), but it is a nontrivial job.
> 
> are you referring to commit 9118f9eb4f1e ("USB: EHCI: improve interrupt
> qh unlink")?

That one, plus:

46c73d1d3ebc ("USB: EHCI: handle isochronous underruns with tasklets")
e4e18cbd52c8 ("USB: EHCI: code rearrangement in iso_stream_schedule()")
24f531371de1 ("USB: EHCI: accept very late isochronous URBs")
35371e4fbc3e ("USB: EHCI: improve ehci_endpoint_disable")

Not all parts of all those commits were relevant, but as far as I
recall, they each contributed something.  And I may have omitted
one or two commits by mistake.

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


Re: Threaded interrupts for USB HCD instead of tasklets

2018-05-22 Thread Sebastian Andrzej Siewior
On 2018-05-07 11:37:29 [-0400], Alan Stern wrote:
> > As far as I understand it there should be no deadlock. Without the
> > local_irq_save() things should not deadlock because the HCD invokes USB
> > driver's (usb-storage for instance) ->complete callback always in the
> > same way. If you mix the usb-driver with two different HCDs (say ehci
> > and xhci) then lockdep would complain. However, the locks which were
> > allocated by usb-storage for the ehci driver would never be used in the
> > context of the xhci driver. So lockdep would report a deacklock but
> > there wouldn't be one (again, if I got the piece right).
> 
> That argument would be correct if the completion routines were the only
> places where the higher-level drivers (such as usb-storage or usbhid)  
> acquired their locks.  But we can't depend on this being true; you
> would have to audit each USB driver to make sure.

an entry point for IRQ usage outside of the driver would be the usage of
hrtimer. We have a flag to let the hrtimer run in softirq but yes, we
need to audit them.

> > And I was thinking about converting all drivers to one model and then we
> > could get rid of the block I quoted above.
> > 
> > If nobody rejects the approach as such I would go and start hacking…
> > 
> > > And even for those two, the conversion will not be easy.  Simply
> > > changing the giveback routines would violate the documented guarantees
> > > for isochronous transfers.
> > 
> > The requirement was that the ISO urb is completed before the BULK urb,
> > right?
> 
> No, that's not what I meant.  For one thing, isochronous URBs don't
> need to complete before bulk URBs in general (although they do have
> higher priority).
> 
> However, I was really referring to the kerneldoc for usb_submit_urb().  
> The part that talks about scheduling of isochronous and interrupt URBs
> lists a bunch of requirements.  In order to meet these requirements
> some of the host controller drivers may rely on the fact that when they
> give back an URB, the URB's completion routine will return before the
> giveback call finishes.

You mean the "Reserved Bandwidth Transfers:" paragraph?

> It's possible to rewrite the HCDs not to rely on this (I did exactly
> that for ehci-hcd), but it is a nontrivial job.

are you referring to commit 9118f9eb4f1e ("USB: EHCI: improve interrupt
qh unlink")?

> Alan Stern

Sebastian
--
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


Re: Threaded interrupts for USB HCD instead of tasklets

2018-05-07 Thread Alan Stern
On Mon, 7 May 2018, Sebastian Andrzej Siewior wrote:

> On 2018-05-04 16:07:22 [-0400], Alan Stern wrote:
> > On Fri, 4 May 2018, Sebastian Andrzej Siewior wrote:
> > 
> > > Hi Alan,
> > > 
> > > I posted a RFC [0] to let the HCD complete the URB in threaded-IRQ
> > > context to avoid the softirq/tasklet. Mauro reported that this does not
> > > help him and never came back after that.
> > > You did not oppose the approach as long as there is no performance issue
> > > which I did not see. Would you mind if I revisit the approach and
> > > convert all HCDs to threaded IRQs while at it?
> > 
> > I don't mind revisiting the approach, although it certainly would be 
> > good to find out why it doesn't help Mauro's video problem.
> > 
> > However, converting _all_ the HCDs to threaded IRQs is a different
> > story.  It should be okay to convert the ones that currently use
> > tasklets, but I can't approve changes to all the others.  Only the
> > drivers that I maintain (ohci-hcd and uhci-hcd).
> 
> Sure. The plan was to convert all drivers to one model so we could get
> rid of:
> 
> |static void __usb_hcd_giveback_urb(struct urb *urb)
> |{
> |…
> | /* 
> |  * We disable local IRQs here avoid possible deadlock because
> |  * drivers may call spin_lock() to hold lock which might be
> |  * acquired in one hard interrupt handler.
> |  * 
> |  * The local_irq_save()/local_irq_restore() around complete()
> |  * will be removed if current USB drivers have been cleaned up
> |  * and no one may trigger the above deadlock situation when
> |  * running complete() in tasklet.
> |  */
> | local_irq_save(flags);
> | urb->complete(urb);
> | local_irq_restore(flags);
> |…
> |}
> 
> As far as I understand it there should be no deadlock. Without the
> local_irq_save() things should not deadlock because the HCD invokes USB
> driver's (usb-storage for instance) ->complete callback always in the
> same way. If you mix the usb-driver with two different HCDs (say ehci
> and xhci) then lockdep would complain. However, the locks which were
> allocated by usb-storage for the ehci driver would never be used in the
> context of the xhci driver. So lockdep would report a deacklock but
> there wouldn't be one (again, if I got the piece right).

That argument would be correct if the completion routines were the only
places where the higher-level drivers (such as usb-storage or usbhid)  
acquired their locks.  But we can't depend on this being true; you
would have to audit each USB driver to make sure.

> And I was thinking about converting all drivers to one model and then we
> could get rid of the block I quoted above.
> 
> If nobody rejects the approach as such I would go and start hacking…
> 
> > And even for those two, the conversion will not be easy.  Simply
> > changing the giveback routines would violate the documented guarantees
> > for isochronous transfers.
> 
> The requirement was that the ISO urb is completed before the BULK urb,
> right?

No, that's not what I meant.  For one thing, isochronous URBs don't
need to complete before bulk URBs in general (although they do have
higher priority).

However, I was really referring to the kerneldoc for usb_submit_urb().  
The part that talks about scheduling of isochronous and interrupt URBs
lists a bunch of requirements.  In order to meet these requirements
some of the host controller drivers may rely on the fact that when they
give back an URB, the URB's completion routine will return before the
giveback call finishes.

It's possible to rewrite the HCDs not to rely on this (I did exactly
that for ehci-hcd), but it is a nontrivial job.

Alan Stern

> If so, the last patch would enqueue the ISO urb and wait until the BULK
> urb was completed before it completed the ISO urb.
> 
> > Alan Stern
> 
> Sebastian

--
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


Re: Threaded interrupts for USB HCD instead of tasklets

2018-05-07 Thread Sebastian Andrzej Siewior
On 2018-05-04 16:07:22 [-0400], Alan Stern wrote:
> On Fri, 4 May 2018, Sebastian Andrzej Siewior wrote:
> 
> > Hi Alan,
> > 
> > I posted a RFC [0] to let the HCD complete the URB in threaded-IRQ
> > context to avoid the softirq/tasklet. Mauro reported that this does not
> > help him and never came back after that.
> > You did not oppose the approach as long as there is no performance issue
> > which I did not see. Would you mind if I revisit the approach and
> > convert all HCDs to threaded IRQs while at it?
> 
> I don't mind revisiting the approach, although it certainly would be 
> good to find out why it doesn't help Mauro's video problem.
> 
> However, converting _all_ the HCDs to threaded IRQs is a different
> story.  It should be okay to convert the ones that currently use
> tasklets, but I can't approve changes to all the others.  Only the
> drivers that I maintain (ohci-hcd and uhci-hcd).

Sure. The plan was to convert all drivers to one model so we could get
rid of:

|static void __usb_hcd_giveback_urb(struct urb *urb)
|{
|…
| /* 
|  * We disable local IRQs here avoid possible deadlock because
|  * drivers may call spin_lock() to hold lock which might be
|  * acquired in one hard interrupt handler.
|  * 
|  * The local_irq_save()/local_irq_restore() around complete()
|  * will be removed if current USB drivers have been cleaned up
|  * and no one may trigger the above deadlock situation when
|  * running complete() in tasklet.
|  */
| local_irq_save(flags);
| urb->complete(urb);
| local_irq_restore(flags);
|…
|}

As far as I understand it there should be no deadlock. Without the
local_irq_save() things should not deadlock because the HCD invokes USB
driver's (usb-storage for instance) ->complete callback always in the
same way. If you mix the usb-driver with two different HCDs (say ehci
and xhci) then lockdep would complain. However, the locks which were
allocated by usb-storage for the ehci driver would never be used in the
context of the xhci driver. So lockdep would report a deacklock but
there wouldn't be one (again, if I got the piece right).

And I was thinking about converting all drivers to one model and then we
could get rid of the block I quoted above.

If nobody rejects the approach as such I would go and start hacking…

> And even for those two, the conversion will not be easy.  Simply
> changing the giveback routines would violate the documented guarantees
> for isochronous transfers.

The requirement was that the ISO urb is completed before the BULK urb,
right?
If so, the last patch would enqueue the ISO urb and wait until the BULK
urb was completed before it completed the ISO urb.

> Alan Stern

Sebastian
--
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


Re: Threaded interrupts for USB HCD instead of tasklets

2018-05-04 Thread Alan Stern
On Fri, 4 May 2018, Sebastian Andrzej Siewior wrote:

> Hi Alan,
> 
> I posted a RFC [0] to let the HCD complete the URB in threaded-IRQ
> context to avoid the softirq/tasklet. Mauro reported that this does not
> help him and never came back after that.
> You did not oppose the approach as long as there is no performance issue
> which I did not see. Would you mind if I revisit the approach and
> convert all HCDs to threaded IRQs while at it?

I don't mind revisiting the approach, although it certainly would be 
good to find out why it doesn't help Mauro's video problem.

However, converting _all_ the HCDs to threaded IRQs is a different
story.  It should be okay to convert the ones that currently use
tasklets, but I can't approve changes to all the others.  Only the
drivers that I maintain (ohci-hcd and uhci-hcd).

And even for those two, the conversion will not be easy.  Simply
changing the giveback routines would violate the documented guarantees
for isochronous transfers.

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


Threaded interrupts for USB HCD instead of tasklets

2018-05-04 Thread Sebastian Andrzej Siewior
Hi Alan,

I posted a RFC [0] to let the HCD complete the URB in threaded-IRQ
context to avoid the softirq/tasklet. Mauro reported that this does not
help him and never came back after that.
You did not oppose the approach as long as there is no performance issue
which I did not see. Would you mind if I revisit the approach and
convert all HCDs to threaded IRQs while at it?

[0] https://lkml.kernel.org/r/20180216170450.yl5owfphuvlts...@breakpoint.cc

Sebastian
--
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