aboutsummaryrefslogtreecommitdiffstats
path: root/net
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
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')
-rw-r--r--net/bluetooth/l2cap_sock.c9
-rw-r--r--net/bluetooth/smp.c10
2 files changed, 19 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
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 3d38553eb526..3b63c7f09dd5 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -1658,6 +1658,13 @@ static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
1658 chan->omtu = pchan->omtu; 1658 chan->omtu = pchan->omtu;
1659 chan->mode = pchan->mode; 1659 chan->mode = pchan->mode;
1660 1660
1661 /* Other L2CAP channels may request SMP routines in order to
1662 * change the security level. This means that the SMP channel
1663 * lock must be considered in its own category to avoid lockdep
1664 * warnings.
1665 */
1666 atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
1667
1661 BT_DBG("created chan %p", chan); 1668 BT_DBG("created chan %p", chan);
1662 1669
1663 return chan; 1670 return chan;
@@ -1715,6 +1722,9 @@ int smp_register(struct hci_dev *hdev)
1715 chan->imtu = L2CAP_DEFAULT_MTU; 1722 chan->imtu = L2CAP_DEFAULT_MTU;
1716 chan->ops = &smp_root_chan_ops; 1723 chan->ops = &smp_root_chan_ops;
1717 1724
1725 /* Set correct nesting level for a parent/listening channel */
1726 atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
1727
1718 hdev->smp_data = chan; 1728 hdev->smp_data = chan;
1719 1729
1720 return 0; 1730 return 0;