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
This commit is contained in:
Gerd Hoffmann
2019-08-30 08:01:16 +02:00
parent 12afce08ed
commit f0c6cef7e7
4 changed files with 42 additions and 1 deletions

View File

@@ -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);
}