diff mbox

Bluetooth: btusb: use irqsave() in URB's complete callback

Message ID 20180619215657.13745-1-bigeasy@linutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Sebastian Andrzej Siewior June 19, 2018, 9:56 p.m. UTC
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 <marcel@holtmann.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Cc: linux-bluetooth@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/bluetooth/btusb.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

Comments

Marcel Holtmann June 21, 2018, 12:43 p.m. UTC | #1
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 <marcel@holtmann.org>
> Cc: Johan Hedberg <johan.hedberg@gmail.com>
> Cc: linux-bluetooth@vger.kernel.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
> 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

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sebastian Andrzej Siewior June 21, 2018, 12:52 p.m. UTC | #2
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 <marcel@holtmann.org>
> > Cc: Johan Hedberg <johan.hedberg@gmail.com>
> > Cc: linux-bluetooth@vger.kernel.org
> > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> > ---
> > 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/Pine.LNX.4.44L0.1806011629140.1404-100000@iolanthe.rowland.org

> Regards
> 
> Marcel

Sebastian
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Stern June 21, 2018, 3:34 p.m. UTC | #3
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 <marcel@holtmann.org>
> > > Cc: Johan Hedberg <johan.hedberg@gmail.com>
> > > Cc: linux-bluetooth@vger.kernel.org
> > > Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> > > ---
> > > 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/Pine.LNX.4.44L0.1806011629140.1404-100000@iolanthe.rowland.org

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

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sebastian Andrzej Siewior July 1, 2018, 3:19 p.m. UTC | #4
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/Pine.LNX.4.44L0.1806011629140.1404-100000@iolanthe.rowland.org
> 
> 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
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Marcel Holtmann July 6, 2018, 10:46 a.m. UTC | #5
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 <marcel@holtmann.org>
> Cc: Johan Hedberg <johan.hedberg@gmail.com>
> Cc: linux-bluetooth@vger.kernel.org
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
> drivers/bluetooth/btusb.c | 20 ++++++++++++--------
> 1 file changed, 12 insertions(+), 8 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

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 count)
 {
 	struct sk_buff *skb;
+	unsigned long flags;
 	int err = 0;
 
-	spin_lock(&data->rxlock);
+	spin_lock_irqsave(&data->rxlock, flags);
 	skb = data->evt_skb;
 
 	while (count) {
@@ -556,7 +557,7 @@  static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
 	}
 
 	data->evt_skb = skb;
-	spin_unlock(&data->rxlock);
+	spin_unlock_irqrestore(&data->rxlock, flags);
 
 	return err;
 }
@@ -564,9 +565,10 @@  static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
 static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
 {
 	struct sk_buff *skb;
+	unsigned long flags;
 	int err = 0;
 
-	spin_lock(&data->rxlock);
+	spin_lock_irqsave(&data->rxlock, flags);
 	skb = data->acl_skb;
 
 	while (count) {
@@ -613,7 +615,7 @@  static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
 	}
 
 	data->acl_skb = skb;
-	spin_unlock(&data->rxlock);
+	spin_unlock_irqrestore(&data->rxlock, flags);
 
 	return err;
 }
@@ -621,9 +623,10 @@  static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
 static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
 {
 	struct sk_buff *skb;
+	unsigned long flags;
 	int err = 0;
 
-	spin_lock(&data->rxlock);
+	spin_lock_irqsave(&data->rxlock, flags);
 	skb = data->sco_skb;
 
 	while (count) {
@@ -668,7 +671,7 @@  static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
 	}
 
 	data->sco_skb = skb;
-	spin_unlock(&data->rxlock);
+	spin_unlock_irqrestore(&data->rxlock, flags);
 
 	return err;
 }
@@ -1066,6 +1069,7 @@  static void btusb_tx_complete(struct urb *urb)
 	struct sk_buff *skb = urb->context;
 	struct hci_dev *hdev = (struct hci_dev *)skb->dev;
 	struct btusb_data *data = hci_get_drvdata(hdev);
+	unsigned long flags;
 
 	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++;
 
 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);
 
 	kfree(urb->setup_packet);