Skip to content

Commit 168e283

Browse files
iulia-tanasescuVudentz
authored andcommitted
Bluetooth: iso: Fix circular lock in iso_listen_bis
This fixes the circular locking dependency warning below, by releasing the socket lock before enterning iso_listen_bis, to avoid any potential deadlock with hdev lock. [ 75.307983] ====================================================== [ 75.307984] WARNING: possible circular locking dependency detected [ 75.307985] 6.12.0-rc6+ #22 Not tainted [ 75.307987] ------------------------------------------------------ [ 75.307987] kworker/u81:2/2623 is trying to acquire lock: [ 75.307988] ffff8fde1769da58 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO) at: iso_connect_cfm+0x253/0x840 [bluetooth] [ 75.308021] but task is already holding lock: [ 75.308022] ffff8fdd61a10078 (&hdev->lock) at: hci_le_per_adv_report_evt+0x47/0x2f0 [bluetooth] [ 75.308053] which lock already depends on the new lock. [ 75.308054] the existing dependency chain (in reverse order) is: [ 75.308055] -> #1 (&hdev->lock){+.+.}-{3:3}: [ 75.308057] __mutex_lock+0xad/0xc50 [ 75.308061] mutex_lock_nested+0x1b/0x30 [ 75.308063] iso_sock_listen+0x143/0x5c0 [bluetooth] [ 75.308085] __sys_listen_socket+0x49/0x60 [ 75.308088] __x64_sys_listen+0x4c/0x90 [ 75.308090] x64_sys_call+0x2517/0x25f0 [ 75.308092] do_syscall_64+0x87/0x150 [ 75.308095] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 75.308098] -> #0 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}: [ 75.308100] __lock_acquire+0x155e/0x25f0 [ 75.308103] lock_acquire+0xc9/0x300 [ 75.308105] lock_sock_nested+0x32/0x90 [ 75.308107] iso_connect_cfm+0x253/0x840 [bluetooth] [ 75.308128] hci_connect_cfm+0x6c/0x190 [bluetooth] [ 75.308155] hci_le_per_adv_report_evt+0x27b/0x2f0 [bluetooth] [ 75.308180] hci_le_meta_evt+0xe7/0x200 [bluetooth] [ 75.308206] hci_event_packet+0x21f/0x5c0 [bluetooth] [ 75.308230] hci_rx_work+0x3ae/0xb10 [bluetooth] [ 75.308254] process_one_work+0x212/0x740 [ 75.308256] worker_thread+0x1bd/0x3a0 [ 75.308258] kthread+0xe4/0x120 [ 75.308259] ret_from_fork+0x44/0x70 [ 75.308261] ret_from_fork_asm+0x1a/0x30 [ 75.308263] other info that might help us debug this: [ 75.308264] Possible unsafe locking scenario: [ 75.308264] CPU0 CPU1 [ 75.308265] ---- ---- [ 75.308265] lock(&hdev->lock); [ 75.308267] lock(sk_lock- AF_BLUETOOTH-BTPROTO_ISO); [ 75.308268] lock(&hdev->lock); [ 75.308269] lock(sk_lock-AF_BLUETOOTH-BTPROTO_ISO); [ 75.308270] *** DEADLOCK *** [ 75.308271] 4 locks held by kworker/u81:2/2623: [ 75.308272] #0: ffff8fdd66e52148 ((wq_completion)hci0#2){+.+.}-{0:0}, at: process_one_work+0x443/0x740 [ 75.308276] #1: ffffafb488b7fe48 ((work_completion)(&hdev->rx_work)), at: process_one_work+0x1ce/0x740 [ 75.308280] #2: ffff8fdd61a10078 (&hdev->lock){+.+.}-{3:3} at: hci_le_per_adv_report_evt+0x47/0x2f0 [bluetooth] [ 75.308304] #3: ffffffffb6ba4900 (rcu_read_lock){....}-{1:2}, at: hci_connect_cfm+0x29/0x190 [bluetooth] Fixes: 02171da ("Bluetooth: ISO: Add hcon for listening bis sk") Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 29a6514 commit 168e283

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

net/bluetooth/iso.c

+12-2
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,7 @@ static int iso_listen_bis(struct sock *sk)
11291129
return -EHOSTUNREACH;
11301130

11311131
hci_dev_lock(hdev);
1132+
lock_sock(sk);
11321133

11331134
/* Fail if user set invalid QoS */
11341135
if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
@@ -1159,6 +1160,7 @@ static int iso_listen_bis(struct sock *sk)
11591160
}
11601161

11611162
unlock:
1163+
release_sock(sk);
11621164
hci_dev_unlock(hdev);
11631165
hci_dev_put(hdev);
11641166
return err;
@@ -1187,6 +1189,7 @@ static int iso_sock_listen(struct socket *sock, int backlog)
11871189

11881190
BT_DBG("sk %p backlog %d", sk, backlog);
11891191

1192+
sock_hold(sk);
11901193
lock_sock(sk);
11911194

11921195
if (sk->sk_state != BT_BOUND) {
@@ -1199,10 +1202,16 @@ static int iso_sock_listen(struct socket *sock, int backlog)
11991202
goto done;
12001203
}
12011204

1202-
if (!bacmp(&iso_pi(sk)->dst, BDADDR_ANY))
1205+
if (!bacmp(&iso_pi(sk)->dst, BDADDR_ANY)) {
12031206
err = iso_listen_cis(sk);
1204-
else
1207+
} else {
1208+
/* Drop sock lock to avoid potential
1209+
* deadlock with the hdev lock.
1210+
*/
1211+
release_sock(sk);
12051212
err = iso_listen_bis(sk);
1213+
lock_sock(sk);
1214+
}
12061215

12071216
if (err)
12081217
goto done;
@@ -1214,6 +1223,7 @@ static int iso_sock_listen(struct socket *sock, int backlog)
12141223

12151224
done:
12161225
release_sock(sk);
1226+
sock_put(sk);
12171227
return err;
12181228
}
12191229

0 commit comments

Comments
 (0)