From 26b9625d95db0e16e4c6bbe3d8a53c23f4b83a1c Mon Sep 17 00:00:00 2001 From: Vilas R K Date: Wed, 23 Mar 2022 21:15:07 +0530 Subject: [PATCH] [VIRTIO] Freeze and Restore Implementation. Whenever VM goes for suspend if there are any active VSOCK connections used to communicate with host, respective vsock connections were unable to resume as freeze and restore functionality was not implemented in virtio driver. This change will fix VSOCK reconnect in case of Suspend and Resume In freeze case: Change will reset all connected sockets when the device disappears and flush all device writes and interrupts and also delete virtqueues and flush outstanding callbacks if any. In Restore case: Change will initialize all the necessary parameter to make the virtio device ready Tracked-On: OAM-100107 Signed-off-by: Stefano Garzarella Signed-off-by: Vilas R K Signed-off-by: Bharat Panda --- ...IO-Freeze-and-Restore-Implementation.patch | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 bsp_diff/common/kernel/lts2019-chromium/27_0027-VIRTIO-Freeze-and-Restore-Implementation.patch diff --git a/bsp_diff/common/kernel/lts2019-chromium/27_0027-VIRTIO-Freeze-and-Restore-Implementation.patch b/bsp_diff/common/kernel/lts2019-chromium/27_0027-VIRTIO-Freeze-and-Restore-Implementation.patch new file mode 100644 index 0000000000..cd79ece9c8 --- /dev/null +++ b/bsp_diff/common/kernel/lts2019-chromium/27_0027-VIRTIO-Freeze-and-Restore-Implementation.patch @@ -0,0 +1,152 @@ +From ac91eeb67b4f235fee19c000aff27b8e1991ad53 Mon Sep 17 00:00:00 2001 +From: Vilas R K +Date: Wed, 23 Mar 2022 21:05:33 +0530 +Subject: [PATCH] Freeze and Restore Implementation. + +Whenever VM goes for suspend if there are any +active VSOCK connections used to communicate with host +respective vsock connections were unable to resume as +freeze and restore functionality was not implemented i +virtio driver. +This change will fix VSOCK reconnect in case +of Suspend and Resume + +In freeze case: +Change will reset all connected sockets when the devic +disappears and flush all device writes and interrupts +and also delete virtqueues and flush outstanding +callbacks if any. + +In Restore case: +Change will initialize all the necessary parameter to +make the virtio device ready + +Tracked-On: OAM-100107 +Signed-off-by: Stefano Garzarella +Signed-off-by: Bharat Panda +--- + net/vmw_vsock/virtio_transport.c | 100 +++++++++++++++++++++++++++++++ + 1 file changed, 100 insertions(+) + +diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c +index 9d012817cefc..f505f476973d 100644 +--- a/net/vmw_vsock/virtio_transport.c ++++ b/net/vmw_vsock/virtio_transport.c +@@ -696,6 +696,104 @@ static void virtio_vsock_remove(struct virtio_device *vdev) + kfree(vsock); + } + ++static int virtio_vsock_freeze(struct virtio_device *vdev) ++{ ++ struct virtio_vsock *vsock = vdev->priv; ++ struct virtio_vsock_pkt *pkt; ++ mutex_lock(&the_virtio_vsock_mutex); ++ rcu_assign_pointer(the_virtio_vsock, NULL); ++ synchronize_rcu(); ++ /* Reset all connected sockets when the device disappear */ ++ // vsock_for_each_connected_socket(&virtio_transport.transport,virtio_vsock_reset_sock); //Original ++ vsock_for_each_connected_socket(virtio_vsock_reset_sock); ++ /* Stop all work handlers to make sure no one is accessing the device, ++ * so we can safely call virtio_reset_device(). ++ */ ++ mutex_lock(&vsock->rx_lock); ++ vsock->rx_run = false; ++ mutex_unlock(&vsock->rx_lock); ++ mutex_lock(&vsock->tx_lock); ++ vsock->tx_run = false; ++ mutex_unlock(&vsock->tx_lock); ++ mutex_lock(&vsock->event_lock); ++ vsock->event_run = false; ++ mutex_unlock(&vsock->event_lock); ++ ++ mutex_lock(&vsock->rx_lock); ++ while ((pkt = virtqueue_detach_unused_buf(vsock->vqs[VSOCK_VQ_RX]))) ++ virtio_transport_free_pkt(pkt); ++ mutex_unlock(&vsock->rx_lock); ++ mutex_lock(&vsock->tx_lock); ++ while ((pkt = virtqueue_detach_unused_buf(vsock->vqs[VSOCK_VQ_TX]))) ++ virtio_transport_free_pkt(pkt); ++ mutex_unlock(&vsock->tx_lock); ++ spin_lock_bh(&vsock->send_pkt_list_lock); ++ while (!list_empty(&vsock->send_pkt_list)) { ++ pkt = list_first_entry(&vsock->send_pkt_list, ++ struct virtio_vsock_pkt, list); ++ list_del(&pkt->list); ++ virtio_transport_free_pkt(pkt); ++ } ++ spin_unlock_bh(&vsock->send_pkt_list_lock); ++ /* Delete virtqueues and flush outstanding callbacks if any */ ++ vdev->config->del_vqs(vdev); ++ ++ /* Other works can be queued before 'config->del_vqs()', so we flush ++ * all works before to free the vsock object to avoid use after free. ++ */ ++ flush_work(&vsock->rx_work); ++ flush_work(&vsock->tx_work); ++ flush_work(&vsock->event_work); ++ flush_work(&vsock->send_pkt_work); ++ ++ mutex_unlock(&the_virtio_vsock_mutex); ++ ++ printk("virtio_vsock_freeze: ok\n"); ++ ++ return 0; ++} ++ ++static int virtio_vsock_restore(struct virtio_device *vdev) ++{ ++ vq_callback_t *callbacks[] = { ++ virtio_vsock_rx_done, ++ virtio_vsock_tx_done, ++ virtio_vsock_event_done, ++ }; ++ static const char * const names[] = { ++ "rx", ++ "tx", ++ "event", ++ }; ++ struct virtio_vsock *vsock = vdev->priv; ++ int ret; ++ mutex_lock(&the_virtio_vsock_mutex); ++ ret = virtio_find_vqs(vsock->vdev, VSOCK_VQ_MAX, ++ vsock->vqs, callbacks, names, ++ NULL); ++ if (ret < 0) ++ goto out; ++ virtio_device_ready(vdev); ++ virtio_vsock_update_guest_cid(vsock); ++ vsock_for_each_connected_socket(virtio_vsock_reset_sock); ++ mutex_lock(&vsock->tx_lock); ++ vsock->tx_run = true; ++ mutex_unlock(&vsock->tx_lock); ++ mutex_lock(&vsock->rx_lock); ++ virtio_vsock_rx_fill(vsock); ++ vsock->rx_run = true; ++ mutex_unlock(&vsock->rx_lock); ++ mutex_lock(&vsock->event_lock); ++ virtio_vsock_event_fill(vsock); ++ vsock->event_run = true; ++ mutex_unlock(&vsock->event_lock); ++ rcu_assign_pointer(the_virtio_vsock, vsock); ++ printk("virtio_vsock_restore: ok\n"); ++ ret = 0; ++out: ++ mutex_unlock(&the_virtio_vsock_mutex); ++ return ret; ++} + static struct virtio_device_id id_table[] = { + { VIRTIO_ID_VSOCK, VIRTIO_DEV_ANY_ID }, + { 0 }, +@@ -712,6 +810,8 @@ static struct virtio_driver virtio_vsock_driver = { + .id_table = id_table, + .probe = virtio_vsock_probe, + .remove = virtio_vsock_remove, ++ .freeze = virtio_vsock_freeze, ++ .restore = virtio_vsock_restore, + }; + + static int __init virtio_vsock_init(void) +-- +2.17.1 +