Commit 5f6c871f authored by Gerd Hoffmann's avatar Gerd Hoffmann

drm/qxl: properly free qxl releases

Reorganize qxl_device_fini() a bit.
Add missing unpin() calls.

Count releases.  Add wait queue for releases.  That way
qxl_device_fini() can easily wait until everything is
ready for proper shutdown.
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Acked-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Link: http://patchwork.freedesktop.org/patch/msgid/20210204145712.1531203-9-kraxel@redhat.com
parent a7709b9b
...@@ -254,6 +254,7 @@ int qxl_garbage_collect(struct qxl_device *qdev) ...@@ -254,6 +254,7 @@ int qxl_garbage_collect(struct qxl_device *qdev)
} }
} }
wake_up_all(&qdev->release_event);
DRM_DEBUG_DRIVER("%d\n", i); DRM_DEBUG_DRIVER("%d\n", i);
return i; return i;
......
...@@ -214,6 +214,8 @@ struct qxl_device { ...@@ -214,6 +214,8 @@ struct qxl_device {
spinlock_t release_lock; spinlock_t release_lock;
struct idr release_idr; struct idr release_idr;
uint32_t release_seqno; uint32_t release_seqno;
atomic_t release_count;
wait_queue_head_t release_event;
spinlock_t release_idr_lock; spinlock_t release_idr_lock;
struct mutex async_io_mutex; struct mutex async_io_mutex;
unsigned int last_sent_io_cmd; unsigned int last_sent_io_cmd;
......
...@@ -87,6 +87,7 @@ int qxl_irq_init(struct qxl_device *qdev) ...@@ -87,6 +87,7 @@ int qxl_irq_init(struct qxl_device *qdev)
init_waitqueue_head(&qdev->display_event); init_waitqueue_head(&qdev->display_event);
init_waitqueue_head(&qdev->cursor_event); init_waitqueue_head(&qdev->cursor_event);
init_waitqueue_head(&qdev->io_cmd_event); init_waitqueue_head(&qdev->io_cmd_event);
init_waitqueue_head(&qdev->release_event);
INIT_WORK(&qdev->client_monitors_config_work, INIT_WORK(&qdev->client_monitors_config_work,
qxl_client_monitors_config_work_func); qxl_client_monitors_config_work_func);
atomic_set(&qdev->irq_received, 0); atomic_set(&qdev->irq_received, 0);
......
...@@ -286,11 +286,31 @@ int qxl_device_init(struct qxl_device *qdev, ...@@ -286,11 +286,31 @@ int qxl_device_init(struct qxl_device *qdev,
void qxl_device_fini(struct qxl_device *qdev) void qxl_device_fini(struct qxl_device *qdev)
{ {
qxl_bo_unref(&qdev->current_release_bo[0]); int cur_idx;
qxl_bo_unref(&qdev->current_release_bo[1]);
for (cur_idx = 0; cur_idx < 3; cur_idx++) {
if (!qdev->current_release_bo[cur_idx])
continue;
qxl_bo_unpin(qdev->current_release_bo[cur_idx]);
qxl_bo_unref(&qdev->current_release_bo[cur_idx]);
qdev->current_release_bo_offset[cur_idx] = 0;
qdev->current_release_bo[cur_idx] = NULL;
}
/*
* Ask host to release resources (+fill release ring),
* then wait for the release actually happening.
*/
qxl_io_notify_oom(qdev);
wait_event_timeout(qdev->release_event,
atomic_read(&qdev->release_count) == 0,
HZ);
flush_work(&qdev->gc_work);
qxl_surf_evict(qdev);
qxl_vram_evict(qdev);
qxl_gem_fini(qdev); qxl_gem_fini(qdev);
qxl_bo_fini(qdev); qxl_bo_fini(qdev);
flush_work(&qdev->gc_work);
qxl_ring_free(qdev->command_ring); qxl_ring_free(qdev->command_ring);
qxl_ring_free(qdev->cursor_ring); qxl_ring_free(qdev->cursor_ring);
qxl_ring_free(qdev->release_ring); qxl_ring_free(qdev->release_ring);
......
...@@ -196,6 +196,7 @@ qxl_release_free(struct qxl_device *qdev, ...@@ -196,6 +196,7 @@ qxl_release_free(struct qxl_device *qdev,
qxl_release_free_list(release); qxl_release_free_list(release);
kfree(release); kfree(release);
} }
atomic_dec(&qdev->release_count);
} }
static int qxl_release_bo_alloc(struct qxl_device *qdev, static int qxl_release_bo_alloc(struct qxl_device *qdev,
...@@ -344,6 +345,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size, ...@@ -344,6 +345,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
*rbo = NULL; *rbo = NULL;
return idr_ret; return idr_ret;
} }
atomic_inc(&qdev->release_count);
mutex_lock(&qdev->release_mutex); mutex_lock(&qdev->release_mutex);
if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) { if (qdev->current_release_bo_offset[cur_idx] + 1 >= releases_per_bo[cur_idx]) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment