mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
Bluetooth: SCO: fix sleeping under spinlock in sco_conn_ready
sco_conn_ready calls sleeping functions under conn->lock spinlock.
The critical section can be reduced: conn->hcon is modified only with
hdev->lock held. It is guaranteed to be held in sco_conn_ready, so
conn->lock is not needed to guard it.
Move taking conn->lock after lock_sock(parent). This also follows the
lock ordering lock_sock() > conn->lock elsewhere in the file.
Fixes: 27c24fda62 ("Bluetooth: switch to lock_sock in SCO")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
b89e0100a5
commit
b819db93d7
|
|
@ -1377,26 +1377,24 @@ static void sco_conn_ready(struct sco_conn *conn)
|
|||
sk->sk_state_change(sk);
|
||||
release_sock(sk);
|
||||
} else {
|
||||
sco_conn_lock(conn);
|
||||
|
||||
if (!conn->hcon) {
|
||||
sco_conn_unlock(conn);
|
||||
if (!conn->hcon)
|
||||
return;
|
||||
}
|
||||
|
||||
lockdep_assert_held(&conn->hcon->hdev->lock);
|
||||
|
||||
parent = sco_get_sock_listen(&conn->hcon->src);
|
||||
if (!parent) {
|
||||
sco_conn_unlock(conn);
|
||||
if (!parent)
|
||||
return;
|
||||
}
|
||||
|
||||
lock_sock(parent);
|
||||
|
||||
sco_conn_lock(conn);
|
||||
|
||||
sk = sco_sock_alloc(sock_net(parent), NULL,
|
||||
BTPROTO_SCO, GFP_ATOMIC, 0);
|
||||
if (!sk) {
|
||||
release_sock(parent);
|
||||
sco_conn_unlock(conn);
|
||||
release_sock(parent);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1417,9 +1415,9 @@ static void sco_conn_ready(struct sco_conn *conn)
|
|||
/* Wake up parent */
|
||||
parent->sk_data_ready(parent);
|
||||
|
||||
release_sock(parent);
|
||||
|
||||
sco_conn_unlock(conn);
|
||||
|
||||
release_sock(parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user