diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-09-05 21:19:50 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-09-08 19:07:55 +0200 |
commit | f3d82d0c8ec025fc113408e3ad5775fed5a060ff (patch) | |
tree | 9b436aa3ad6613171c0a9646188bc24587299980 /include/net/bluetooth/l2cap.h | |
parent | Bluetooth: Don't take any action in smp_resume_cb if not encrypted (diff) | |
download | linux-f3d82d0c8ec025fc113408e3ad5775fed5a060ff.tar.xz linux-f3d82d0c8ec025fc113408e3ad5775fed5a060ff.zip |
Bluetooth: Move identity address update behind a workqueue
The identity address update of all channels for an l2cap_conn needs to
take the lock for each channel, i.e. it's safest to do this by a
separate workqueue callback.
Previously this was partially solved by moving the entire SMP key
distribution behind a workqueue. However, if we want SMP context locking
to be correct and safe we should always use the l2cap_chan lock when
accessing it, meaning even smp_distribute_keys needs to take that lock
which would once again create a dead lock when updating the identity
address.
The simplest way to solve this is to have l2cap_conn manage the deferred
work which is what this patch does. A subsequent patch will remove the
now unnecessary SMP key distribution work struct.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'include/net/bluetooth/l2cap.h')
-rw-r--r-- | include/net/bluetooth/l2cap.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index be25eddea615..ead99f032f7a 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -633,6 +633,8 @@ struct l2cap_conn { struct sk_buff_head pending_rx; struct work_struct pending_rx_work; + struct work_struct id_addr_update_work; + __u8 disc_reason; struct l2cap_chan *smp; @@ -937,7 +939,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan); void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); void l2cap_chan_del(struct l2cap_chan *chan, int err); -void l2cap_conn_update_id_addr(struct hci_conn *hcon); void l2cap_send_conn_req(struct l2cap_chan *chan); void l2cap_move_start(struct l2cap_chan *chan); void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, |