From 2f453ed4038526172292fb3250b638b3782c7f2b Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 2 Apr 2014 12:40:05 +0200 Subject: drm/qxl: rework to new fence interface Final driver! \o/ This is not a proper dma_fence because the hardware may never signal anything, so don't use dma-buf with qxl, ever. Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/qxl/qxl_ttm.c | 97 ++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 43 deletions(-) (limited to 'drivers/gpu/drm/qxl/qxl_ttm.c') diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index f66c59b222f1..29e0a758ee68 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -357,67 +357,67 @@ static int qxl_bo_move(struct ttm_buffer_object *bo, return ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem); } +static bool qxl_sync_obj_signaled(void *sync_obj); static int qxl_sync_obj_wait(void *sync_obj, bool lazy, bool interruptible) { - struct qxl_fence *qfence = (struct qxl_fence *)sync_obj; - int count = 0, sc = 0; - struct qxl_bo *bo = container_of(qfence, struct qxl_bo, fence); - - if (qfence->num_active_releases == 0) - return 0; + struct qxl_bo *bo = (struct qxl_bo *)sync_obj; + struct qxl_device *qdev = bo->gem_base.dev->dev_private; + struct reservation_object_list *fobj; + int count = 0, sc = 0, num_release = 0; + bool have_drawable_releases; retry: if (sc == 0) { if (bo->type == QXL_GEM_DOMAIN_SURFACE) - qxl_update_surface(qfence->qdev, bo); + qxl_update_surface(qdev, bo); } else if (sc >= 1) { - qxl_io_notify_oom(qfence->qdev); + qxl_io_notify_oom(qdev); } sc++; for (count = 0; count < 10; count++) { - bool ret; - ret = qxl_queue_garbage_collect(qfence->qdev, true); - if (ret == false) - break; - - if (qfence->num_active_releases == 0) + if (qxl_sync_obj_signaled(sync_obj)) return 0; + + if (!qxl_queue_garbage_collect(qdev, true)) + break; } - if (qfence->num_active_releases) { - bool have_drawable_releases = false; - void **slot; - struct radix_tree_iter iter; - int release_id; + have_drawable_releases = false; + num_release = 0; - radix_tree_for_each_slot(slot, &qfence->tree, &iter, 0) { - struct qxl_release *release; + spin_lock(&qdev->release_lock); + fobj = bo->tbo.resv->fence; + for (count = 0; fobj && count < fobj->shared_count; count++) { + struct qxl_release *release; - release_id = iter.index; - release = qxl_release_from_id_locked(qfence->qdev, release_id); - if (release == NULL) - continue; + release = container_of(fobj->shared[count], + struct qxl_release, base); - if (release->type == QXL_RELEASE_DRAWABLE) - have_drawable_releases = true; - } + if (fence_is_signaled(&release->base)) + continue; + + num_release++; + + if (release->type == QXL_RELEASE_DRAWABLE) + have_drawable_releases = true; + } + spin_unlock(&qdev->release_lock); + + qxl_queue_garbage_collect(qdev, true); - qxl_queue_garbage_collect(qfence->qdev, true); - - if (have_drawable_releases || sc < 4) { - if (sc > 2) - /* back off */ - usleep_range(500, 1000); - if (have_drawable_releases && sc > 300) { - WARN(1, "sync obj %d still has outstanding releases %d %d %d %ld %d\n", sc, bo->surface_id, bo->is_primary, bo->pin_count, (unsigned long)bo->gem_base.size, qfence->num_active_releases); - return -EBUSY; - } - goto retry; + if (have_drawable_releases || sc < 4) { + if (sc > 2) + /* back off */ + usleep_range(500, 1000); + if (have_drawable_releases && sc > 300) { + WARN(1, "sync obj %d still has outstanding releases %d %d %d %ld %d\n", sc, bo->surface_id, bo->is_primary, bo->pin_count, (unsigned long)bo->gem_base.size, num_release); + return -EBUSY; } + goto retry; } return 0; } @@ -439,8 +439,21 @@ static void *qxl_sync_obj_ref(void *sync_obj) static bool qxl_sync_obj_signaled(void *sync_obj) { - struct qxl_fence *qfence = (struct qxl_fence *)sync_obj; - return (qfence->num_active_releases == 0); + struct qxl_bo *qbo = (struct qxl_bo *)sync_obj; + struct qxl_device *qdev = qbo->gem_base.dev->dev_private; + struct reservation_object_list *fobj; + bool ret = true; + unsigned i; + + spin_lock(&qdev->release_lock); + fobj = qbo->tbo.resv->fence; + for (i = 0; fobj && i < fobj->shared_count; ++i) { + ret = fence_is_signaled(fobj->shared[i]); + if (!ret) + break; + } + spin_unlock(&qdev->release_lock); + return ret; } static void qxl_bo_move_notify(struct ttm_buffer_object *bo, @@ -477,8 +490,6 @@ static struct ttm_bo_driver qxl_bo_driver = { .move_notify = &qxl_bo_move_notify, }; - - int qxl_ttm_init(struct qxl_device *qdev) { int r; -- cgit v1.2.3