On 9/24/25 22:47, [email protected] wrote:
> From: Dongwon Kim <[email protected]>
> 
> Register a PM notifier in virtio-gpu to handle suspend/hibernate
> events. On PM_POST_HIBERNATION, it resubmits all GPU objects
> so that resources can properly recovered in QEMU after resume.
> 
> Suggested-by: Dmitry Osipenko <[email protected]>
> Cc: Vivek Kasireddy <[email protected]>
> Signed-off-by: Dongwon Kim <[email protected]>
> ---
>  drivers/gpu/drm/virtio/virtgpu_drv.h |  2 ++
>  drivers/gpu/drm/virtio/virtgpu_kms.c | 25 +++++++++++++++++++++++++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h 
> b/drivers/gpu/drm/virtio/virtgpu_drv.h
> index 55f836378237..88a94e974088 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drv.h
> +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
> @@ -278,6 +278,8 @@ struct virtio_gpu_device {
>       uint64_t capset_id_mask;
>       struct list_head cap_cache;
>  
> +     struct notifier_block pm_nb;
> +
>       /* protects uuid state when exporting */
>       spinlock_t resource_export_lock;
>       /* protects map state and host_visible_mm */
> diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c 
> b/drivers/gpu/drm/virtio/virtgpu_kms.c
> index 08f8e71a7072..e1b2cee30fa3 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_kms.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
> @@ -26,9 +26,12 @@
>  #include <linux/virtio.h>
>  #include <linux/virtio_config.h>
>  #include <linux/virtio_ring.h>
> +#include <linux/suspend.h>
> +#include <linux/pm_runtime.h>
>  
>  #include <drm/drm_file.h>
>  #include <drm/drm_managed.h>
> +#include <drm/drm_atomic_helper.h>
>  
>  #include "virtgpu_drv.h"
>  
> @@ -133,6 +136,21 @@ int virtio_gpu_find_vqs(struct virtio_gpu_device *vgdev)
>       return 0;
>  }
>  
> +static int virtio_gpu_pm_notifier(struct notifier_block *nb, unsigned long 
> mode,
> +                               void *data)
> +{
> +     struct virtio_gpu_device *vgdev = container_of(nb, struct 
> virtio_gpu_device, pm_nb);
> +     int ret;
> +
> +     if (mode == PM_POST_HIBERNATION) {
> +             ret = virtio_gpu_object_restore_all(vgdev);
> +             if (ret)
> +                     DRM_ERROR("Failed to resubmit virtio-gpu objects\n");
> +     }
> +
> +     return NOTIFY_DONE;
> +}
> +
>  int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
>  {
>       struct virtio_gpu_device *vgdev;
> @@ -268,6 +286,12 @@ int virtio_gpu_init(struct virtio_device *vdev, struct 
> drm_device *dev)
>               wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending,
>                                  5 * HZ);
>       }
> +
> +     vgdev->pm_nb.notifier_call = virtio_gpu_pm_notifier;
> +     ret = register_pm_notifier(&vgdev->pm_nb);
> +     if (ret)
> +             goto err_scanouts;
> +
>       return 0;
>  
>  err_scanouts:
> @@ -299,6 +323,7 @@ void virtio_gpu_deinit(struct drm_device *dev)
>       flush_work(&vgdev->config_changed_work);
>       virtio_reset_device(vgdev->vdev);
>       vgdev->vdev->config->del_vqs(vgdev->vdev);
> +     unregister_pm_notifier(&vgdev->pm_nb);
>  }
>  
>  void virtio_gpu_release(struct drm_device *dev)

Tested-by: Dmitry Osipenko <[email protected]>

-- 
Best regards,
Dmitry

Reply via email to