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:
Pauli Virtanen 2026-04-12 21:47:42 +03:00 committed by Luiz Augusto von Dentz
parent b89e0100a5
commit b819db93d7

View File

@ -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);
}
}