Hi Nirmoy,
> -----Original Message-----
> From: Nirmoy Das <[email protected]>
> Sent: Wednesday, November 12, 2025 4:28 AM
> To: Kim, Dongwon <[email protected]>; [email protected]
> Cc: [email protected]; [email protected]; [email protected]
> Subject: Re: [PATCH v6 1/3] drm/virtio: Freeze and restore hooks to support
> suspend and resume
>
>
> On 27.10.25 21:53, [email protected] wrote:
> > From: Dongwon Kim <[email protected]>
> >
> > virtio device needs to delete before VM suspend happens then
> > reinitialize all virtqueues again upon resume
> >
> > v2: 10ms sleep was added in virtgpu_freeze to avoid the situation
> > the driver is locked up during resumption.
> >
> > v3: Plain 10ms delay was replaced with wait calls which wait until
> > the virtio queue is empty.
> > (Dmitry Osipenko)
> >
> > Suggested-by: Dmitry Osipenko <[email protected]>
> > Tested-by: Dmitry Osipenko <[email protected]>
> > Cc: Vivek Kasireddy <[email protected]>
> > Signed-off-by: Dongwon Kim <[email protected]>
> > ---
> > drivers/gpu/drm/virtio/virtgpu_drv.c | 60 +++++++++++++++++++++++++++-
> > drivers/gpu/drm/virtio/virtgpu_drv.h | 1 +
> > drivers/gpu/drm/virtio/virtgpu_kms.c | 23 ++++++++---
> > 3 files changed, 77 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c
> > b/drivers/gpu/drm/virtio/virtgpu_drv.c
> > index 71c6ccad4b99..676893e90a9f 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_drv.c
> > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
> > @@ -163,6 +163,60 @@ static unsigned int features[] = {
> > VIRTIO_GPU_F_RESOURCE_BLOB,
> > VIRTIO_GPU_F_CONTEXT_INIT,
> > };
> > +
> > +#ifdef CONFIG_PM_SLEEP
> > +static int virtgpu_freeze(struct virtio_device *vdev) {
> > + struct drm_device *dev = vdev->priv;
> > + struct virtio_gpu_device *vgdev = dev->dev_private;
> > + int error;
> > +
> > + error = drm_mode_config_helper_suspend(dev);
> > + if (error) {
> > + DRM_ERROR("suspend error %d\n", error);
> > + return error;
> > + }
> > +
> > + flush_work(&vgdev->obj_free_work);
> > + flush_work(&vgdev->ctrlq.dequeue_work);
> > + flush_work(&vgdev->cursorq.dequeue_work);
> > + flush_work(&vgdev->config_changed_work);
> > +
> > + wait_event(vgdev->ctrlq.ack_queue,
> > + vgdev->ctrlq.vq->num_free == vgdev->ctrlq.vq->num_max);
> > +
> > + wait_event(vgdev->cursorq.ack_queue,
> > + vgdev->cursorq.vq->num_free == vgdev->cursorq.vq-
> >num_max);
>
> This can wait forever, add a timeout here with wait_event_timeout().
Yeah, makes sense. I will update it.
>
>
> Otherwise looks good to me.
>
>
> Regards,
>
> Nirmoy
>
> > +
> > + vdev->config->del_vqs(vdev);
> > +
> > + return 0;
> > +}
> > +
> > +static int virtgpu_restore(struct virtio_device *vdev) {
> > + struct drm_device *dev = vdev->priv;
> > + struct virtio_gpu_device *vgdev = dev->dev_private;
> > + int error;
> > +
> > + error = virtio_gpu_find_vqs(vgdev);
> > + if (error) {
> > + DRM_ERROR("failed to find virt queues\n");
> > + return error;
> > + }
> > +
> > + virtio_device_ready(vdev);
> > +
> > + error = drm_mode_config_helper_resume(dev);
> > + if (error) {
> > + DRM_ERROR("resume error %d\n", error);
> > + return error;
> > + }
> > +
> > + return 0;
> > +}
> > +#endif
> > +
> > static struct virtio_driver virtio_gpu_driver = {
> > .feature_table = features,
> > .feature_table_size = ARRAY_SIZE(features), @@ -171,7 +225,11 @@
> > static struct virtio_driver virtio_gpu_driver = {
> > .probe = virtio_gpu_probe,
> > .remove = virtio_gpu_remove,
> > .shutdown = virtio_gpu_shutdown,
> > - .config_changed = virtio_gpu_config_changed
> > + .config_changed = virtio_gpu_config_changed, #ifdef
> CONFIG_PM_SLEEP
> > + .freeze = virtgpu_freeze,
> > + .restore = virtgpu_restore,
> > +#endif
> > };
> >
> > static int __init virtio_gpu_driver_init(void) diff --git
> > a/drivers/gpu/drm/virtio/virtgpu_drv.h
> > b/drivers/gpu/drm/virtio/virtgpu_drv.h
> > index f17660a71a3e..1279f998c8e0 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
> > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
> > @@ -300,6 +300,7 @@ void virtio_gpu_deinit(struct drm_device *dev);
> > void virtio_gpu_release(struct drm_device *dev);
> > int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file);
> > void virtio_gpu_driver_postclose(struct drm_device *dev, struct
> > drm_file *file);
> > +int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev);
> >
> > /* virtgpu_gem.c */
> > int virtio_gpu_gem_object_open(struct drm_gem_object *obj, diff
> > --git a/drivers/gpu/drm/virtio/virtgpu_kms.c
> > b/drivers/gpu/drm/virtio/virtgpu_kms.c
> > index 1c15cbf326b7..cbebe19c3fb3 100644
> > --- a/drivers/gpu/drm/virtio/virtgpu_kms.c
> > +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
> > @@ -114,15 +114,28 @@ static void virtio_gpu_get_capsets(struct
> virtio_gpu_device *vgdev,
> > vgdev->num_capsets = num_capsets;
> > }
> >
> > -int virtio_gpu_init(struct virtio_device *vdev, struct drm_device
> > *dev)
> > +int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev)
> > {
> > struct virtqueue_info vqs_info[] = {
> > { "control", virtio_gpu_ctrl_ack },
> > { "cursor", virtio_gpu_cursor_ack },
> > };
> > - struct virtio_gpu_device *vgdev;
> > - /* this will expand later */
> > struct virtqueue *vqs[2];
> > + int ret;
> > +
> > + ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL);
> > + if (ret)
> > + return ret;
> > +
> > + vgdev->ctrlq.vq = vqs[0];
> > + vgdev->cursorq.vq = vqs[1];
> > +
> > + return 0;
> > +}
> > +
> > +int virtio_gpu_init(struct virtio_device *vdev, struct drm_device
> > +*dev) {
> > + struct virtio_gpu_device *vgdev;
> > u32 num_scanouts, num_capsets;
> > int ret = 0;
> >
> > @@ -206,13 +219,11 @@ int virtio_gpu_init(struct virtio_device *vdev,
> struct drm_device *dev)
> > DRM_INFO("features: %ccontext_init\n",
> > vgdev->has_context_init ? '+' : '-');
> >
> > - ret = virtio_find_vqs(vgdev->vdev, 2, vqs, vqs_info, NULL);
> > + ret = virtio_gpu_find_vqs(vgdev);
> > if (ret) {
> > DRM_ERROR("failed to find virt queues\n");
> > goto err_vqs;
> > }
> > - vgdev->ctrlq.vq = vqs[0];
> > - vgdev->cursorq.vq = vqs[1];
> > ret = virtio_gpu_alloc_vbufs(vgdev);
> > if (ret) {
> > DRM_ERROR("failed to alloc vbufs\n");