Subject: [PATCH] Bluetooth: btusb: use irqsave() in URB's complete callback

The USB completion callback does not disable interrupts while acquiring
the ->lock. We want to remove the local_irq_disable() invocation from
__usb_hcd_giveback_urb() and therefore it is required for the callback
handler to disable the interrupts while acquiring the lock.
The callback may be invoked either in IRQ or BH context depending on the
USB host controller.
Use the _irqsave variant of the locking primitives.

Cc: Marcel Holtmann <[email protected]>
Cc: Johan Hedberg <[email protected]>
Cc: [email protected]
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
drivers/bluetooth/btusb.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f73a27ea28cc..f262163fecd5 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -509,9 +509,10 @@ static inline void btusb_free_frags(struct btusb_data =
*data)
static int btusb_recv_intr(struct btusb_data *data, void *buffer, int coun=
t)
{
struct sk_buff *skb;
+ unsigned long flags;
int err =3D 0;
=20
- spin_lock(&data->rxlock);
+ spin_lock_irqsave(&data->rxlock, flags);
skb =3D data->evt_skb;
=20
while (count) {
@@ -556,7 +557,7 @@ static int btusb_recv_intr(struct btusb_data *data, voi=
d *buffer, int count)
}
=20
data->evt_skb =3D skb;
- spin_unlock(&data->rxlock);
+ spin_unlock_irqrestore(&data->rxlock, flags);
=20
return err;
}
@@ -564,9 +565,10 @@ static int btusb_recv_intr(struct btusb_data *data, vo=
id *buffer, int count)
static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int coun=
t)
{
struct sk_buff *skb;
+ unsigned long flags;
int err =3D 0;
=20
- spin_lock(&data->rxlock);
+ spin_lock_irqsave(&data->rxlock, flags);
skb =3D data->acl_skb;
=20
while (count) {
@@ -613,7 +615,7 @@ static int btusb_recv_bulk(struct btusb_data *data, voi=
d *buffer, int count)
}
=20
data->acl_skb =3D skb;
- spin_unlock(&data->rxlock);
+ spin_unlock_irqrestore(&data->rxlock, flags);
=20
return err;
}
@@ -621,9 +623,10 @@ static int btusb_recv_bulk(struct btusb_data *data, vo=
id *buffer, int count)
static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int coun=
t)
{
struct sk_buff *skb;
+ unsigned long flags;
int err =3D 0;
=20
- spin_lock(&data->rxlock);
+ spin_lock_irqsave(&data->rxlock, flags);
skb =3D data->sco_skb;
=20
while (count) {
@@ -668,7 +671,7 @@ static int btusb_recv_isoc(struct btusb_data *data, voi=
d *buffer, int count)
}
=20
data->sco_skb =3D skb;
- spin_unlock(&data->rxlock);
+ spin_unlock_irqrestore(&data->rxlock, flags);
=20
return err;
}
@@ -1066,6 +1069,7 @@ static void btusb_tx_complete(struct urb *urb)
struct sk_buff *skb =3D urb->context;
struct hci_dev *hdev =3D (struct hci_dev *)skb->dev;
struct btusb_data *data =3D hci_get_drvdata(hdev);
+ unsigned long flags;
=20
BT_DBG("%s urb %p status %d count %d", hdev->name, urb, urb->status,
urb->actual_length);
@@ -1079,9 +1083,9 @@ static void btusb_tx_complete(struct urb *urb)
hdev->stat.err_tx++;
=20
done:
- spin_lock(&data->txlock);
+ spin_lock_irqsave(&data->txlock, flags);
data->tx_in_flight--;
- spin_unlock(&data->txlock);
+ spin_unlock_irqrestore(&data->txlock, flags);
=20
kfree(urb->setup_packet);
=20
--=20
2.17.1


2018-06-21 15:34:15

by Alan Stern

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: btusb: use irqsave() in URB's complete callback

On Thu, 21 Jun 2018, Sebastian Andrzej Siewior wrote:

> On 2018-06-21 14:43:41 [+0200], Marcel Holtmann wrote:
> > Hi Sebastian,
> Hi Marcel,
>
> > > The USB completion callback does not disable interrupts while acquiring
> > > the ->lock. We want to remove the local_irq_disable() invocation from
> > > __usb_hcd_giveback_urb() and therefore it is required for the callback
> > > handler to disable the interrupts while acquiring the lock.
> > > The callback may be invoked either in IRQ or BH context depending on the
> > > USB host controller.
> > > Use the _irqsave variant of the locking primitives.
> > >
> > > Cc: Marcel Holtmann <[email protected]>
> > > Cc: Johan Hedberg <[email protected]>
> > > Cc: [email protected]
> > > Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
> > > ---
> > > drivers/bluetooth/btusb.c | 20 ++++++++++++--------
> > > 1 file changed, 12 insertions(+), 8 deletions(-)
> >
> > can I get an ACK from someone ensuring that this is the direction we are going with the USB host controllers?
> +Alan.
>
> EHCI completes in BH since v3.12-rc1. In order to get rid of that
> local_irq_save() in USB core code I need to make sure that the USB
> device driver(s) use irqsave primitives. See
> https://lkml.kernel.org/r/[email protected]

Hi, Marcel!

Yes, Sebastian is right. We are aiming to make it possible for the USB
core to invoke URB completion handlers with interrupts enabled, in
order to reduce latency (since USB interrupt processing can take a
fairly long time). And of course, this means completion handlers have
to work correctly regardless of whether interrupts are enabled or
disabled.

Currently ehci-hcd supports this possibility. Other host controller
drivers may follow along; I'd like to see xhci-hcd do this too.

Alan Stern

Subject: Re: [PATCH] Bluetooth: btusb: use irqsave() in URB's complete callback

On 2018-06-21 14:43:41 [+0200], Marcel Holtmann wrote:
> Hi Sebastian,
Hi Marcel,

> > The USB completion callback does not disable interrupts while acquiring
> > the ->lock. We want to remove the local_irq_disable() invocation from
> > __usb_hcd_giveback_urb() and therefore it is required for the callback
> > handler to disable the interrupts while acquiring the lock.
> > The callback may be invoked either in IRQ or BH context depending on the
> > USB host controller.
> > Use the _irqsave variant of the locking primitives.
> >
> > Cc: Marcel Holtmann <[email protected]>
> > Cc: Johan Hedberg <[email protected]>
> > Cc: [email protected]
> > Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
> > ---
> > drivers/bluetooth/btusb.c | 20 ++++++++++++--------
> > 1 file changed, 12 insertions(+), 8 deletions(-)
>
> can I get an ACK from someone ensuring that this is the direction we are going with the USB host controllers?
+Alan.

EHCI completes in BH since v3.12-rc1. In order to get rid of that
local_irq_save() in USB core code I need to make sure that the USB
device driver(s) use irqsave primitives. See
https://lkml.kernel.org/r/[email protected]

> Regards
>
> Marcel

Sebastian

2018-06-21 12:43:41

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: btusb: use irqsave() in URB's complete callback

Hi Sebastian,

> The USB completion callback does not disable interrupts while acquiring
> the ->lock. We want to remove the local_irq_disable() invocation from
> __usb_hcd_giveback_urb() and therefore it is required for the callback
> handler to disable the interrupts while acquiring the lock.
> The callback may be invoked either in IRQ or BH context depending on the
> USB host controller.
> Use the _irqsave variant of the locking primitives.
>
> Cc: Marcel Holtmann <[email protected]>
> Cc: Johan Hedberg <[email protected]>
> Cc: [email protected]
> Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
> ---
> drivers/bluetooth/btusb.c | 20 ++++++++++++--------
> 1 file changed, 12 insertions(+), 8 deletions(-)

can I get an ACK from someone ensuring that this is the direction we are going with the USB host controllers?

Regards

Marcel


2018-07-06 10:46:22

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: btusb: use irqsave() in URB's complete callback

Hi Sebastian,

> The USB completion callback does not disable interrupts while acquiring
> the ->lock. We want to remove the local_irq_disable() invocation from
> __usb_hcd_giveback_urb() and therefore it is required for the callback
> handler to disable the interrupts while acquiring the lock.
> The callback may be invoked either in IRQ or BH context depending on the
> USB host controller.
> Use the _irqsave variant of the locking primitives.
>
> Cc: Marcel Holtmann <[email protected]>
> Cc: Johan Hedberg <[email protected]>
> Cc: [email protected]
> Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
> ---
> drivers/bluetooth/btusb.c | 20 ++++++++++++--------
> 1 file changed, 12 insertions(+), 8 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel


Subject: Re: [PATCH] Bluetooth: btusb: use irqsave() in URB's complete callback

On 2018-06-21 11:34:15 [-0400], Alan Stern wrote:
> On Thu, 21 Jun 2018, Sebastian Andrzej Siewior wrote:
>
> > On 2018-06-21 14:43:41 [+0200], Marcel Holtmann wrote:
> > > can I get an ACK from someone ensuring that this is the direction we are going with the USB host controllers?
> > +Alan.
> >
> > EHCI completes in BH since v3.12-rc1. In order to get rid of that
> > local_irq_save() in USB core code I need to make sure that the USB
> > device driver(s) use irqsave primitives. See
> > https://lkml.kernel.org/r/[email protected]
>
> Hi, Marcel!
Hi Marcel,

> Yes, Sebastian is right. We are aiming to make it possible for the USB
> core to invoke URB completion handlers with interrupts enabled, in
> order to reduce latency (since USB interrupt processing can take a
> fairly long time). And of course, this means completion handlers have
> to work correctly regardless of whether interrupts are enabled or
> disabled.

I don't see this patch in linux-next. Do you still need some kind of
confirmation or has this been resolved?

> Currently ehci-hcd supports this possibility. Other host controller
> drivers may follow along; I'd like to see xhci-hcd do this too.
>
> Alan Stern

Sebastian