Skip to content

Commit 90ec99e

Browse files
stefano-garzarellasmb49
authored andcommitted
vsock/virtio: factor our the code to initialize and delete VQs
BugLink: https://bugs.launchpad.net/bugs/2049417 [ Upstream commit a103209 ] Add virtio_vsock_vqs_init() and virtio_vsock_vqs_del() with the code that was in virtio_vsock_probe() and virtio_vsock_remove to initialize and delete VQs. These new functions will be used in the next commit to support device suspend/resume Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of: 53b08c4 ("vsock/virtio: initialize the_virtio_vsock before using VQs") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Roxana Nicolescu <roxana.nicolescu@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent ae13468 commit 90ec99e

File tree

1 file changed

+84
-66
lines changed

1 file changed

+84
-66
lines changed

net/vmw_vsock/virtio_transport.c

Lines changed: 84 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -566,67 +566,28 @@ static void virtio_transport_rx_work(struct work_struct *work)
566566
mutex_unlock(&vsock->rx_lock);
567567
}
568568

569-
static int virtio_vsock_probe(struct virtio_device *vdev)
569+
static int virtio_vsock_vqs_init(struct virtio_vsock *vsock)
570570
{
571-
vq_callback_t *callbacks[] = {
572-
virtio_vsock_rx_done,
573-
virtio_vsock_tx_done,
574-
virtio_vsock_event_done,
575-
};
571+
struct virtio_device *vdev = vsock->vdev;
576572
static const char * const names[] = {
577573
"rx",
578574
"tx",
579575
"event",
580576
};
581-
struct virtio_vsock *vsock = NULL;
577+
vq_callback_t *callbacks[] = {
578+
virtio_vsock_rx_done,
579+
virtio_vsock_tx_done,
580+
virtio_vsock_event_done,
581+
};
582582
int ret;
583583

584-
ret = mutex_lock_interruptible(&the_virtio_vsock_mutex);
585-
if (ret)
586-
return ret;
587-
588-
/* Only one virtio-vsock device per guest is supported */
589-
if (rcu_dereference_protected(the_virtio_vsock,
590-
lockdep_is_held(&the_virtio_vsock_mutex))) {
591-
ret = -EBUSY;
592-
goto out;
593-
}
594-
595-
vsock = kzalloc(sizeof(*vsock), GFP_KERNEL);
596-
if (!vsock) {
597-
ret = -ENOMEM;
598-
goto out;
599-
}
600-
601-
vsock->vdev = vdev;
602-
603-
ret = virtio_find_vqs(vsock->vdev, VSOCK_VQ_MAX,
604-
vsock->vqs, callbacks, names,
584+
ret = virtio_find_vqs(vdev, VSOCK_VQ_MAX, vsock->vqs, callbacks, names,
605585
NULL);
606586
if (ret < 0)
607-
goto out;
587+
return ret;
608588

609589
virtio_vsock_update_guest_cid(vsock);
610590

611-
vsock->rx_buf_nr = 0;
612-
vsock->rx_buf_max_nr = 0;
613-
atomic_set(&vsock->queued_replies, 0);
614-
615-
mutex_init(&vsock->tx_lock);
616-
mutex_init(&vsock->rx_lock);
617-
mutex_init(&vsock->event_lock);
618-
spin_lock_init(&vsock->send_pkt_list_lock);
619-
INIT_LIST_HEAD(&vsock->send_pkt_list);
620-
INIT_WORK(&vsock->rx_work, virtio_transport_rx_work);
621-
INIT_WORK(&vsock->tx_work, virtio_transport_tx_work);
622-
INIT_WORK(&vsock->event_work, virtio_transport_event_work);
623-
INIT_WORK(&vsock->send_pkt_work, virtio_transport_send_pkt_work);
624-
625-
if (virtio_has_feature(vdev, VIRTIO_VSOCK_F_SEQPACKET))
626-
vsock->seqpacket_allow = true;
627-
628-
vdev->priv = vsock;
629-
630591
virtio_device_ready(vdev);
631592

632593
mutex_lock(&vsock->tx_lock);
@@ -643,30 +604,15 @@ static int virtio_vsock_probe(struct virtio_device *vdev)
643604
vsock->event_run = true;
644605
mutex_unlock(&vsock->event_lock);
645606

646-
rcu_assign_pointer(the_virtio_vsock, vsock);
647-
648-
mutex_unlock(&the_virtio_vsock_mutex);
649-
650607
return 0;
651-
652-
out:
653-
kfree(vsock);
654-
mutex_unlock(&the_virtio_vsock_mutex);
655-
return ret;
656608
}
657609

658-
static void virtio_vsock_remove(struct virtio_device *vdev)
610+
static void virtio_vsock_vqs_del(struct virtio_vsock *vsock)
659611
{
660-
struct virtio_vsock *vsock = vdev->priv;
612+
struct virtio_device *vdev = vsock->vdev;
661613
struct virtio_vsock_pkt *pkt;
662614

663-
mutex_lock(&the_virtio_vsock_mutex);
664-
665-
vdev->priv = NULL;
666-
rcu_assign_pointer(the_virtio_vsock, NULL);
667-
synchronize_rcu();
668-
669-
/* Reset all connected sockets when the device disappear */
615+
/* Reset all connected sockets when the VQs disappear */
670616
vsock_for_each_connected_socket(&virtio_transport.transport,
671617
virtio_vsock_reset_sock);
672618

@@ -711,6 +657,78 @@ static void virtio_vsock_remove(struct virtio_device *vdev)
711657

712658
/* Delete virtqueues and flush outstanding callbacks if any */
713659
vdev->config->del_vqs(vdev);
660+
}
661+
662+
static int virtio_vsock_probe(struct virtio_device *vdev)
663+
{
664+
struct virtio_vsock *vsock = NULL;
665+
int ret;
666+
667+
ret = mutex_lock_interruptible(&the_virtio_vsock_mutex);
668+
if (ret)
669+
return ret;
670+
671+
/* Only one virtio-vsock device per guest is supported */
672+
if (rcu_dereference_protected(the_virtio_vsock,
673+
lockdep_is_held(&the_virtio_vsock_mutex))) {
674+
ret = -EBUSY;
675+
goto out;
676+
}
677+
678+
vsock = kzalloc(sizeof(*vsock), GFP_KERNEL);
679+
if (!vsock) {
680+
ret = -ENOMEM;
681+
goto out;
682+
}
683+
684+
vsock->vdev = vdev;
685+
686+
vsock->rx_buf_nr = 0;
687+
vsock->rx_buf_max_nr = 0;
688+
atomic_set(&vsock->queued_replies, 0);
689+
690+
mutex_init(&vsock->tx_lock);
691+
mutex_init(&vsock->rx_lock);
692+
mutex_init(&vsock->event_lock);
693+
spin_lock_init(&vsock->send_pkt_list_lock);
694+
INIT_LIST_HEAD(&vsock->send_pkt_list);
695+
INIT_WORK(&vsock->rx_work, virtio_transport_rx_work);
696+
INIT_WORK(&vsock->tx_work, virtio_transport_tx_work);
697+
INIT_WORK(&vsock->event_work, virtio_transport_event_work);
698+
INIT_WORK(&vsock->send_pkt_work, virtio_transport_send_pkt_work);
699+
700+
if (virtio_has_feature(vdev, VIRTIO_VSOCK_F_SEQPACKET))
701+
vsock->seqpacket_allow = true;
702+
703+
vdev->priv = vsock;
704+
705+
ret = virtio_vsock_vqs_init(vsock);
706+
if (ret < 0)
707+
goto out;
708+
709+
rcu_assign_pointer(the_virtio_vsock, vsock);
710+
711+
mutex_unlock(&the_virtio_vsock_mutex);
712+
713+
return 0;
714+
715+
out:
716+
kfree(vsock);
717+
mutex_unlock(&the_virtio_vsock_mutex);
718+
return ret;
719+
}
720+
721+
static void virtio_vsock_remove(struct virtio_device *vdev)
722+
{
723+
struct virtio_vsock *vsock = vdev->priv;
724+
725+
mutex_lock(&the_virtio_vsock_mutex);
726+
727+
vdev->priv = NULL;
728+
rcu_assign_pointer(the_virtio_vsock, NULL);
729+
synchronize_rcu();
730+
731+
virtio_vsock_vqs_del(vsock);
714732

715733
/* Other works can be queued before 'config->del_vqs()', so we flush
716734
* all works before to free the vsock object to avoid use after free.

0 commit comments

Comments
 (0)