diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2019-08-30 08:01:16 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2019-09-04 06:54:12 +0200 |
commit | f0c6cef7e7174bdb11bbf972cded48bbb33bfba4 (patch) | |
tree | 67ce19d823f0b8423176425fd2a0f0342e388909 /drivers/gpu/drm/virtio/virtgpu_gem.c | |
parent | 12afce08ed51a67aafcc678f4b6e428d71b1f6fb (diff) |
drm/virtio: add worker for object release
Move object release into a separate worker. Releasing objects requires
sending commands to the host. Doing that in the dequeue worker will
cause deadlocks in case the command queue gets filled up, because the
dequeue worker is also the one which will free up slots in the command
queue.
Reported-by: Chia-I Wu <olvaffe@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Tested-by: Chia-I Wu <olvaffe@gmail.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20190830060116.10476-1-kraxel@redhat.com
Diffstat (limited to 'drivers/gpu/drm/virtio/virtgpu_gem.c')
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_gem.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index b812094ae9166..4c1f579edfb39 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -239,3 +239,30 @@ void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs) drm_gem_object_put_unlocked(objs->objs[i]); virtio_gpu_array_free(objs); } + +void virtio_gpu_array_put_free_delayed(struct virtio_gpu_device *vgdev, + struct virtio_gpu_object_array *objs) +{ + spin_lock(&vgdev->obj_free_lock); + list_add_tail(&objs->next, &vgdev->obj_free_list); + spin_unlock(&vgdev->obj_free_lock); + schedule_work(&vgdev->obj_free_work); +} + +void virtio_gpu_array_put_free_work(struct work_struct *work) +{ + struct virtio_gpu_device *vgdev = + container_of(work, struct virtio_gpu_device, obj_free_work); + struct virtio_gpu_object_array *objs; + + spin_lock(&vgdev->obj_free_lock); + while (!list_empty(&vgdev->obj_free_list)) { + objs = list_first_entry(&vgdev->obj_free_list, + struct virtio_gpu_object_array, next); + list_del(&objs->next); + spin_unlock(&vgdev->obj_free_lock); + virtio_gpu_array_put_free(objs); + spin_lock(&vgdev->obj_free_lock); + } + spin_unlock(&vgdev->obj_free_lock); +} |