summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/qxl/qxl_ttm.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-04-02 12:40:05 +0200
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-09-02 16:41:50 +0200
commit2f453ed4038526172292fb3250b638b3782c7f2b (patch)
treece8ec40176f467cab73b9764b566a6e80c389953 /drivers/gpu/drm/qxl/qxl_ttm.c
parent29ba89b2371d466ca68973525816cf10debc2655 (diff)
downloadlinux-2f453ed4038526172292fb3250b638b3782c7f2b.tar.bz2
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 <maarten.lankhorst@canonical.com>
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_ttm.c')
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c97
1 files changed, 54 insertions, 43 deletions
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;