diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2020-02-07 10:46:36 +0300 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2020-02-10 14:54:33 +0300 |
commit | 1ed5f698adad450b314a36aa48ff9593bdfcd968 (patch) | |
tree | e47715d779669dcced12f21d5c4918e11edb269f /drivers/gpu/drm/virtio | |
parent | 8235eab0122a051b05e3dac128a64b66c0273dac (diff) | |
download | linux-1ed5f698adad450b314a36aa48ff9593bdfcd968.tar.xz |
drm/virtio: resource teardown tweaks
Add new virtio_gpu_cleanup_object() helper function for object cleanup.
Wire up callback function for resource unref, do cleanup from callback
when we know the host stopped using the resource.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20200207074638.26386-3-kraxel@redhat.com
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/virtio')
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_object.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_vq.c | 29 |
3 files changed, 43 insertions, 9 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index d278c8c50f39..c3a33ba32571 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -114,6 +114,7 @@ struct virtio_gpu_vbuffer { char *resp_buf; int resp_size; virtio_gpu_resp_cb resp_cb; + void *resp_cb_data; struct virtio_gpu_object_array *objs; struct list_head list; @@ -263,7 +264,7 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_array *objs, struct virtio_gpu_fence *fence); void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, - uint32_t resource_id); + struct virtio_gpu_object *bo); void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev, uint64_t offset, uint32_t width, uint32_t height, @@ -356,6 +357,7 @@ void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev, u64 last_seq); /* virtio_gpu_object */ +void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo); struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev, size_t size); int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 017a9e0fc3bb..28a161af7503 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -61,6 +61,14 @@ static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t } } +void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo) +{ + struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private; + + virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); + drm_gem_shmem_free_object(&bo->base.base); +} + static void virtio_gpu_free_object(struct drm_gem_object *obj) { struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); @@ -68,11 +76,12 @@ static void virtio_gpu_free_object(struct drm_gem_object *obj) if (bo->pages) virtio_gpu_object_detach(vgdev, bo); - if (bo->created) - virtio_gpu_cmd_unref_resource(vgdev, bo->hw_res_handle); - virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle); - - drm_gem_shmem_free_object(obj); + if (bo->created) { + virtio_gpu_cmd_unref_resource(vgdev, bo); + /* completion handler calls virtio_gpu_cleanup_object() */ + return; + } + virtio_gpu_cleanup_object(bo); } static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = { diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 350ddbf8a42d..755a3e26ef01 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -164,6 +164,16 @@ static void *virtio_gpu_alloc_cmd(struct virtio_gpu_device *vgdev, NULL); } +static void *virtio_gpu_alloc_cmd_cb(struct virtio_gpu_device *vgdev, + struct virtio_gpu_vbuffer **vbuffer_p, + int size, + virtio_gpu_resp_cb cb) +{ + return virtio_gpu_alloc_cmd_resp(vgdev, cb, vbuffer_p, size, + sizeof(struct virtio_gpu_ctrl_hdr), + NULL); +} + static void free_vbuf(struct virtio_gpu_device *vgdev, struct virtio_gpu_vbuffer *vbuf) { @@ -510,18 +520,31 @@ void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev, bo->created = true; } +static void virtio_gpu_cmd_unref_cb(struct virtio_gpu_device *vgdev, + struct virtio_gpu_vbuffer *vbuf) +{ + struct virtio_gpu_object *bo; + + bo = vbuf->resp_cb_data; + vbuf->resp_cb_data = NULL; + + virtio_gpu_cleanup_object(bo); +} + void virtio_gpu_cmd_unref_resource(struct virtio_gpu_device *vgdev, - uint32_t resource_id) + struct virtio_gpu_object *bo) { struct virtio_gpu_resource_unref *cmd_p; struct virtio_gpu_vbuffer *vbuf; - cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); + cmd_p = virtio_gpu_alloc_cmd_cb(vgdev, &vbuf, sizeof(*cmd_p), + virtio_gpu_cmd_unref_cb); memset(cmd_p, 0, sizeof(*cmd_p)); cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_UNREF); - cmd_p->resource_id = cpu_to_le32(resource_id); + cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle); + vbuf->resp_cb_data = bo; virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } |