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");

Reply via email to