linux/net/bluetooth
Johan Hedberg 76727c02c1 Bluetooth: Call drain_workqueue() before resetting state
Doing things like hci_conn_hash_flush() while holding the hdev lock is
risky since its synchronous pending work cancellation could cause the
L2CAP layer to try to reacquire the hdev lock. Right now there doesn't
seem to be any obvious places where this would for certain happen but
it's already enough to cause lockdep to start warning against the hdev
and the work struct locks being taken in the "wrong" order:

[  +0.000373] mgmt-tester/1603 is trying to acquire lock:
[  +0.000292]  ((&conn->pending_rx_work)){+.+.+.}, at: [<c104266d>] flush_work+0x0/0x181
[  +0.000270]
but task is already holding lock:
[  +0.000000]  (&hdev->lock){+.+.+.}, at: [<c13b9a80>] hci_dev_do_close+0x166/0x359
[  +0.000000]
which lock already depends on the new lock.

[  +0.000000]
the existing dependency chain (in reverse order) is:
[  +0.000000]
-> #1 (&hdev->lock){+.+.+.}:
[  +0.000000]        [<c105ea8f>] lock_acquire+0xe3/0x156
[  +0.000000]        [<c140c663>] mutex_lock_nested+0x54/0x375
[  +0.000000]        [<c13d644b>] l2cap_recv_frame+0x293/0x1a9c
[  +0.000000]        [<c13d7ca4>] process_pending_rx+0x50/0x5e
[  +0.000000]        [<c1041a3f>] process_one_work+0x21c/0x436
[  +0.000000]        [<c1041e3d>] worker_thread+0x1be/0x251
[  +0.000000]        [<c1045a22>] kthread+0x94/0x99
[  +0.000000]        [<c140f801>] ret_from_kernel_thread+0x21/0x30
[  +0.000000]
-> #0 ((&conn->pending_rx_work)){+.+.+.}:
[  +0.000000]        [<c105e158>] __lock_acquire+0xa07/0xc89
[  +0.000000]        [<c105ea8f>] lock_acquire+0xe3/0x156
[  +0.000000]        [<c1042696>] flush_work+0x29/0x181
[  +0.000000]        [<c1042864>] __cancel_work_timer+0x76/0x8f
[  +0.000000]        [<c104288c>] cancel_work_sync+0xf/0x11
[  +0.000000]        [<c13d4c18>] l2cap_conn_del+0x72/0x183
[  +0.000000]        [<c13d8953>] l2cap_disconn_cfm+0x49/0x55
[  +0.000000]        [<c13be37a>] hci_conn_hash_flush+0x7a/0xc3
[  +0.000000]        [<c13b9af6>] hci_dev_do_close+0x1dc/0x359
[  +0.012038]        [<c13bbe38>] hci_unregister_dev+0x6e/0x1a3
[  +0.000000]        [<c12d33c1>] vhci_release+0x28/0x47
[  +0.000000]        [<c10dd6a9>] __fput+0xd6/0x154
[  +0.000000]        [<c10dd757>] ____fput+0xd/0xf
[  +0.000000]        [<c1044bb2>] task_work_run+0x6b/0x8d
[  +0.000000]        [<c1001bd2>] do_notify_resume+0x3c/0x3f
[  +0.000000]        [<c140fa70>] work_notifysig+0x29/0x31
[  +0.000000]
other info that might help us debug this:

[  +0.000000]  Possible unsafe locking scenario:

[  +0.000000]        CPU0                    CPU1
[  +0.000000]        ----                    ----
[  +0.000000]   lock(&hdev->lock);
[  +0.000000]                                lock((&conn->pending_rx_work));
[  +0.000000]                                lock(&hdev->lock);
[  +0.000000]   lock((&conn->pending_rx_work));
[  +0.000000]
 *** DEADLOCK ***

Fully fixing this would require some quite heavy refactoring to change
how the hdev lock and hci_conn instances are handled together. A simpler
solution for now which this patch takes is to try ensure that the hdev
workqueue is empty before proceeding with the various cleanup calls,
including hci_conn_hash_flush().

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
2014-11-18 08:32:08 +01:00
..
bnep Bluetooth: Introduce BT_BREDR and BT_LE config options 2014-11-02 10:01:53 +02:00
cmtp Bluetooth: Introduce BT_BREDR and BT_LE config options 2014-11-02 10:01:53 +02:00
hidp Bluetooth: hidp: replace kzalloc/copy_from_user by memdup_user 2014-11-15 01:30:16 +01:00
rfcomm Bluetooth: Fix sparse warnings in RFCOMM 2014-11-04 08:01:46 +01:00
6lowpan.c Bluetooth: Fix correct nesting for 6lowpan server channel 2014-11-13 09:11:37 +01:00
a2mp.c Bluetooth: Provide L2CAP ops callback for memcpy_fromiovec 2014-07-03 17:42:43 +02:00
a2mp.h Bluetooth: Move a2mp.h header file into net/bluetooth/ 2013-10-11 00:10:05 +02:00
af_bluetooth.c Bluetooth: Add BUILD_BUG_ON check for SKB control buffer size 2014-09-15 07:15:41 +03:00
amp.c Bluetooth: Fix sparse warning in amp.c 2014-11-11 00:07:29 +01:00
amp.h Bluetooth: Move amp.h header file into net/bluetooth/ 2013-10-11 00:10:03 +02:00
hci_conn.c Bluetooth: Fix check for direct advertising 2014-10-28 22:48:56 +01:00
hci_core.c Bluetooth: Call drain_workqueue() before resetting state 2014-11-18 08:32:08 +01:00
hci_event.c Bluetooth: Use shorter "rand" name for "randomizer" 2014-11-18 01:53:15 +01:00
hci_sock.c Bluetooth: spelling fixes 2014-10-28 17:23:58 +01:00
hci_sysfs.c Bluetooth: Convert to use ATTRIBUTE_GROUPS macro 2014-02-13 09:51:34 +02:00
Kconfig Bluetooth: Introduce BT_BREDR and BT_LE config options 2014-11-02 10:01:53 +02:00
l2cap_core.c Bluetooth: Add debug logs to help track locking issues 2014-11-15 01:53:27 +01:00
l2cap_sock.c Bluetooth: Add debug logs to help track locking issues 2014-11-15 01:53:27 +01:00
lib.c Bluetooth: Convert bt_<level> logging functions to return void 2014-09-24 09:40:08 +02:00
Makefile Bluetooth: 6LoWPAN: Create a kernel module 2014-07-03 17:42:44 +02:00
mgmt.c Bluetooth: Use shorter "rand" name for "randomizer" 2014-11-18 01:53:15 +01:00
sco.c Bluetooth: never linger on process exit 2014-07-17 12:13:06 +02:00
smp.c Bluetooth: Remove unnecessary hdev locking in smp.c 2014-11-15 01:53:27 +01:00
smp.h Bluetooth: Add key preference parameter to smp_sufficient_security 2014-11-15 01:46:49 +01:00