Skip to content

Commit 49b0b6f

Browse files
Longpeng(Mike)kuba-moo
authored andcommitted
vsock/virtio: avoid potential deadlock when vsock device remove
There's a potential deadlock case when remove the vsock device or process the RESET event: vsock_for_each_connected_socket: spin_lock_bh(&vsock_table_lock) ----------- (1) ... virtio_vsock_reset_sock: lock_sock(sk) --------------------- (2) ... spin_unlock_bh(&vsock_table_lock) lock_sock() may do initiative schedule when the 'sk' is owned by other thread at the same time, we would receivce a warning message that "scheduling while atomic". Even worse, if the next task (selected by the scheduler) try to release a 'sk', it need to request vsock_table_lock and the deadlock occur, cause the system into softlockup state. Call trace: queued_spin_lock_slowpath vsock_remove_bound vsock_remove_sock virtio_transport_release __vsock_release vsock_release __sock_release sock_close __fput ____fput So we should not require sk_lock in this case, just like the behavior in vhost_vsock or vmci. Fixes: 0ea9e1d ("VSOCK: Introduce virtio_transport.ko") Cc: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Link: https://lore.kernel.org/r/20210812053056.1699-1-longpeng2@huawei.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent d9d5b89 commit 49b0b6f

1 file changed

Lines changed: 5 additions & 2 deletions

File tree

net/vmw_vsock/virtio_transport.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,14 @@ static void virtio_vsock_event_fill(struct virtio_vsock *vsock)
357357

358358
static void virtio_vsock_reset_sock(struct sock *sk)
359359
{
360-
lock_sock(sk);
360+
/* vmci_transport.c doesn't take sk_lock here either. At least we're
361+
* under vsock_table_lock so the sock cannot disappear while we're
362+
* executing.
363+
*/
364+
361365
sk->sk_state = TCP_CLOSE;
362366
sk->sk_err = ECONNRESET;
363367
sk_error_report(sk);
364-
release_sock(sk);
365368
}
366369

367370
static void virtio_vsock_update_guest_cid(struct virtio_vsock *vsock)

0 commit comments

Comments
 (0)