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>
This commit is contained in:
Johan Hedberg
2014-11-12 22:22:21 +02:00
committed by Marcel Holtmann
parent 24ccb9f4f7
commit abe84903a8
3 changed files with 33 additions and 1 deletions

View File

@@ -1658,6 +1658,13 @@ static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan)
chan->omtu = pchan->omtu;
chan->mode = pchan->mode;
/* Other L2CAP channels may request SMP routines in order to
* change the security level. This means that the SMP channel
* lock must be considered in its own category to avoid lockdep
* warnings.
*/
atomic_set(&chan->nesting, L2CAP_NESTING_SMP);
BT_DBG("created chan %p", chan);
return chan;
@@ -1715,6 +1722,9 @@ int smp_register(struct hci_dev *hdev)
chan->imtu = L2CAP_DEFAULT_MTU;
chan->ops = &smp_root_chan_ops;
/* Set correct nesting level for a parent/listening channel */
atomic_set(&chan->nesting, L2CAP_NESTING_PARENT);
hdev->smp_data = chan;
return 0;