]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Bluetooth: Fix l2cap_sock_teardown_cb lockdep warning
authorJohan Hedberg <johan.hedberg@intel.com>
Wed, 12 Nov 2014 07:15:50 +0000 (09:15 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 12 Nov 2014 09:05:25 +0000 (10:05 +0100)
Any code calling bt_accept_dequeue() to get a new child socket from a
server socket should use lock_sock_nested to avoid lockdep warnings due
to the parent and child sockets being locked at the same time. The
l2cap_sock_accept() function is already doing this correctly but a
second place calling bt_accept_dequeue() is the code path from
l2cap_sock_teardown_cb() that calls l2cap_sock_cleanup_listen().

This patch fixes the proper nested locking annotation and thereby avoids
the following style of lockdep warning.

[  +0.000224] [ INFO: possible recursive locking detected ]
[  +0.000222] 3.17.0+ #1153 Not tainted
[  +0.000130] ---------------------------------------------
[  +0.000227] l2cap-tester/562 is trying to acquire lock:
[  +0.000210]  (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+...}, at: [<c1393f47>] bt_accept_dequeue+0x68/0x11b
[  +0.000467]
but task is already holding lock:
[  +0.000186]  (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+...}, at: [<c13b949a>] lock_sock+0xa/0xc
[  +0.000421]
other info that might help us debug this:
[  +0.000199]  Possible unsafe locking scenario:

[  +0.000117]        CPU0
[  +0.000000]        ----
[  +0.000000]   lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP);
[  +0.000000]   lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP);
[  +0.000000]
 *** DEADLOCK ***

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/l2cap_sock.c

index 31f106e61ca20fd15420830e653f81e7b1f87a20..ad1cf82fee02906e3ac3fb69c196787ae7741a34 100644 (file)
@@ -1246,7 +1246,7 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
        struct sock *sk = chan->data;
        struct sock *parent;
 
-       lock_sock(sk);
+       lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
 
        parent = bt_sk(sk)->parent;