Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: 27c24fda62b60 ("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>

authored by

Pauli Virtanen and committed by
Luiz Augusto von Dentz
b819db93 b89e0100

+9 -11
+9 -11
net/bluetooth/sco.c
··· 1377 1377 sk->sk_state_change(sk); 1378 1378 release_sock(sk); 1379 1379 } else { 1380 - sco_conn_lock(conn); 1381 - 1382 - if (!conn->hcon) { 1383 - sco_conn_unlock(conn); 1380 + if (!conn->hcon) 1384 1381 return; 1385 - } 1382 + 1383 + lockdep_assert_held(&conn->hcon->hdev->lock); 1386 1384 1387 1385 parent = sco_get_sock_listen(&conn->hcon->src); 1388 - if (!parent) { 1389 - sco_conn_unlock(conn); 1386 + if (!parent) 1390 1387 return; 1391 - } 1392 1388 1393 1389 lock_sock(parent); 1390 + 1391 + sco_conn_lock(conn); 1394 1392 1395 1393 sk = sco_sock_alloc(sock_net(parent), NULL, 1396 1394 BTPROTO_SCO, GFP_ATOMIC, 0); 1397 1395 if (!sk) { 1398 - release_sock(parent); 1399 1396 sco_conn_unlock(conn); 1397 + release_sock(parent); 1400 1398 return; 1401 1399 } 1402 1400 ··· 1415 1417 /* Wake up parent */ 1416 1418 parent->sk_data_ready(parent); 1417 1419 1418 - release_sock(parent); 1419 - 1420 1420 sco_conn_unlock(conn); 1421 + 1422 + release_sock(parent); 1421 1423 } 1422 1424 } 1423 1425