Return-Path: From: Jukka Rissanen To: linux-bluetooth@vger.kernel.org Subject: [PATCH] Bluetooth: Incorrect locking when sending data in softirq Date: Wed, 15 Oct 2014 15:43:05 +0300 Message-Id: <1413376985-25812-1-git-send-email-jukka.rissanen@linux.intel.com> Sender: linux-bluetooth-owner@vger.kernel.org List-ID: Use spin_lock_irqsave() when sending data to hci channel. Otherwise the lockdep gives inconsistent lock state warning when sending data to 6lowpan channel. [ INFO: inconsistent lock state ] 3.17.0-rc1-bt6lowpan #1 Not tainted --------------------------------- inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. kworker/u3:0/321 [HC0[0]:SC0[0]:HE1:SE1] takes: (&(&list->lock)->rlock#6){+.?...}, at: [] hci_send_acl+0xac/0x290 [bluetooth] {IN-SOFTIRQ-W} state was registered at: [] __lock_acquire+0x6d3/0x1d20 [] lock_acquire+0x9d/0x140 [] _raw_spin_lock+0x45/0x80 [] hci_send_acl+0xac/0x290 [bluetooth] [] l2cap_do_send+0x60/0x100 [bluetooth] [] l2cap_chan_send+0x7f0/0x10e0 [bluetooth] [] send_pkt+0x4e/0xa0 [bluetooth_6lowpan] [] bt_xmit+0x3b0/0x770 [bluetooth_6lowpan] [] dev_hard_start_xmit+0x344/0x670 [] __dev_queue_xmit+0x38d/0x680 [] dev_queue_xmit+0xf/0x20 [] neigh_connected_output+0x130/0x1a0 [] ip6_finish_output2+0x173/0x8c0 [] ip6_finish_output+0x7b/0x1b0 [] ip6_output+0x97/0x2a0 [] mld_sendpack+0x5eb/0x650 [] mld_ifc_timer_expire+0x191/0x2f0 [] call_timer_fn+0x85/0x1c0 [] run_timer_softirq+0x192/0x280 [] __do_softirq+0xd4/0x300 [] do_softirq_own_stack+0x2c/0x40 [] irq_exit+0x86/0xb0 [] smp_apic_timer_interrupt+0x38/0x50 [] apic_timer_interrupt+0x32/0x38 Signed-off-by: Jukka Rissanen --- Hi, this patch fixes the locking issue when sending larger amount of data via 6lowpan link. After this patch the lockdep no longer warns about softirq issues. Cheers, Jukka net/bluetooth/hci_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8aea4be..3e295ff 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -4642,6 +4642,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, struct hci_conn *conn = chan->conn; struct hci_dev *hdev = conn->hdev; struct sk_buff *list; + unsigned long irq_flags; skb->len = skb_headlen(skb); skb->data_len = 0; @@ -4673,7 +4674,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, skb_shinfo(skb)->frag_list = NULL; /* Queue all fragments atomically */ - spin_lock(&queue->lock); + spin_lock_irqsave(&queue->lock, irq_flags); __skb_queue_tail(queue, skb); @@ -4690,7 +4691,7 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue, __skb_queue_tail(queue, skb); } while (list); - spin_unlock(&queue->lock); + spin_unlock_irqrestore(&queue->lock, irq_flags); } } -- 1.8.3.1