aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/l2cap_sock.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-11-12 15:22:21 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-11-13 01:49:09 -0500
commitabe84903a8efc6b83fa92161429e0e3a28bde15c (patch)
tree3b1b90b1c170c41bbd6fcdae92e8726024c37ade /net/bluetooth/l2cap_sock.c
parent24ccb9f4f7a3a5a867bbc880019cdb4b41176b63 (diff)
Bluetooth: Use proper nesting annotation for l2cap_chan lock
By default lockdep considers all L2CAP channels equal. This would mean that we get warnings if a channel is locked when another one's lock is tried to be acquired in the same thread. This kind of inter-channel locking dependencies exist in the form of parent-child channels as well as any channel wishing to elevate the security by requesting procedures on the SMP channel. To eliminate the chance for these lockdep warnings we introduce a nesting level for each channel and use that when acquiring the channel lock. For now there exists the earlier mentioned three identified categories: SMP, "normal" channels and parent channels (i.e. those in BT_LISTEN state). The nesting level is defined as atomic_t since we need access to it before the lock is actually acquired. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r--net/bluetooth/l2cap_sock.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index ad1cf82fee02..f1a51564b8fd 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -285,6 +285,12 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
285 sk->sk_max_ack_backlog = backlog; 285 sk->sk_max_ack_backlog = backlog;
286 sk->sk_ack_backlog = 0; 286 sk->sk_ack_backlog = 0;
287 287
288 /* Listening channels need to use nested locking in order not to
289 * cause lockdep warnings when the created child channels end up
290 * being locked in the same thread as the parent channel.
291 */
292 atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
293
288 chan->state = BT_LISTEN; 294 chan->state = BT_LISTEN;
289 sk->sk_state = BT_LISTEN; 295 sk->sk_state = BT_LISTEN;
290 296
@@ -1497,6 +1503,9 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
1497 l2cap_chan_set_defaults(chan); 1503 l2cap_chan_set_defaults(chan);
1498 } 1504 }
1499 1505
1506 /* Set default lock nesting level */
1507 atomic_set(&chan->nesting, L2CAP_NESTING_NORMAL);
1508
1500 /* Default config options */ 1509 /* Default config options */
1501 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; 1510 chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
1502 1511