diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index d19c6493db24..c57fe7ddcf73 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -26,6 +26,9 @@ /* Threshold for detecting small packets to copy */ #define GOOD_COPY_LEN 128 +static void virtio_transport_cancel_close_work(struct vsock_sock *vsk, + bool cancel_timeout); + static const struct virtio_transport * virtio_transport_get_ops(struct vsock_sock *vsk) { @@ -922,6 +925,8 @@ void virtio_transport_destruct(struct vsock_sock *vsk) { struct virtio_vsock_sock *vvs = vsk->trans; + virtio_transport_cancel_close_work(vsk, true); + kfree(vvs); vsk->trans = NULL; } @@ -1004,6 +1009,22 @@ static void virtio_transport_wait_close(struct sock *sk, long timeout) } } +static void virtio_transport_cancel_close_work(struct vsock_sock *vsk, + bool cancel_timeout) +{ + struct sock *sk = sk_vsock(vsk); + + if (vsk->close_work_scheduled && + (!cancel_timeout || cancel_delayed_work(&vsk->close_work))) { + vsk->close_work_scheduled = false; + + virtio_transport_remove_sock(vsk); + + /* Release refcnt obtained when we scheduled the timeout */ + sock_put(sk); + } +} + static void virtio_transport_do_close(struct vsock_sock *vsk, bool cancel_timeout) { @@ -1015,15 +1036,7 @@ static void virtio_transport_do_close(struct vsock_sock *vsk, sk->sk_state = TCP_CLOSING; sk->sk_state_change(sk); - if (vsk->close_work_scheduled && - (!cancel_timeout || cancel_delayed_work(&vsk->close_work))) { - vsk->close_work_scheduled = false; - - virtio_transport_remove_sock(vsk); - - /* Release refcnt obtained when we scheduled the timeout */ - sock_put(sk); - } + virtio_transport_cancel_close_work(vsk, cancel_timeout); } static void virtio_transport_close_timeout(struct work_struct *work)