qxl: allow creation of pre-pinned objects and use for releases.
authorDave Airlie <airlied@redhat.com>
Tue, 23 Jul 2013 04:06:07 +0000 (14:06 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 24 Jul 2013 01:58:10 +0000 (11:58 +1000)
In order to fix an issue with reservations we need to create the releases
as pre-pinned objects, this changes the placement interface and bo creation
interface to allow creating pinned objects to save nested reservations later.

This is just a stepping stone to main fix which follows to actually fix how
qxl deals with reservations.

Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/qxl/qxl_cmd.c
drivers/gpu/drm/qxl/qxl_gem.c
drivers/gpu/drm/qxl/qxl_ioctl.c
drivers/gpu/drm/qxl/qxl_object.c
drivers/gpu/drm/qxl/qxl_object.h
drivers/gpu/drm/qxl/qxl_release.c
drivers/gpu/drm/qxl/qxl_ttm.c

index 93c2f2cceb5165c25e80c6480c60c3e2e9e7fd62..4e6a6271661873a944418d9a1424b1e869614dc9 100644 (file)
@@ -266,7 +266,7 @@ int qxl_alloc_bo_reserved(struct qxl_device *qdev, unsigned long size,
        int ret;
 
        ret = qxl_bo_create(qdev, size, false /* not kernel - device */,
-                           QXL_GEM_DOMAIN_VRAM, NULL, &bo);
+                           false, QXL_GEM_DOMAIN_VRAM, NULL, &bo);
        if (ret) {
                DRM_ERROR("failed to allocate VRAM BO\n");
                return ret;
index a235693aabba331284fca3017c519002789c1ab9..25e1777fb0a28551ac1d43d8a7a5b183812f54a7 100644 (file)
@@ -55,7 +55,7 @@ int qxl_gem_object_create(struct qxl_device *qdev, int size,
        /* At least align on page size */
        if (alignment < PAGE_SIZE)
                alignment = PAGE_SIZE;
-       r = qxl_bo_create(qdev, size, kernel, initial_domain, surf, &qbo);
+       r = qxl_bo_create(qdev, size, kernel, false, initial_domain, surf, &qbo);
        if (r) {
                if (r != -ERESTARTSYS)
                        DRM_ERROR(
index 27f45e49250d72e48efd1bce5cc86b1f7442334e..7448c5ea92e6150bce7be9b495ff571bad74425b 100644 (file)
@@ -305,7 +305,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data,
                goto out;
 
        if (!qobj->pin_count) {
-               qxl_ttm_placement_from_domain(qobj, qobj->type);
+               qxl_ttm_placement_from_domain(qobj, qobj->type, false);
                ret = ttm_bo_validate(&qobj->tbo, &qobj->placement,
                                      true, false);
                if (unlikely(ret))
index 1191fe7788c932d6c10e678815724c1dd44b8f16..50e7a61771675e5fc22abb7b7dc3da6c45480175 100644 (file)
@@ -51,20 +51,21 @@ bool qxl_ttm_bo_is_qxl_bo(struct ttm_buffer_object *bo)
        return false;
 }
 
-void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain)
+void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned)
 {
        u32 c = 0;
+       u32 pflag = pinned ? TTM_PL_FLAG_NO_EVICT : 0;
 
        qbo->placement.fpfn = 0;
        qbo->placement.lpfn = 0;
        qbo->placement.placement = qbo->placements;
        qbo->placement.busy_placement = qbo->placements;
        if (domain == QXL_GEM_DOMAIN_VRAM)
-               qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_VRAM;
+               qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_VRAM | pflag;
        if (domain == QXL_GEM_DOMAIN_SURFACE)
-               qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_PRIV0;
+               qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_PRIV0 | pflag;
        if (domain == QXL_GEM_DOMAIN_CPU)
-               qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
+               qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM | pflag;
        if (!c)
                qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
        qbo->placement.num_placement = c;
@@ -73,7 +74,7 @@ void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain)
 
 
 int qxl_bo_create(struct qxl_device *qdev,
-                 unsigned long size, bool kernel, u32 domain,
+                 unsigned long size, bool kernel, bool pinned, u32 domain,
                  struct qxl_surface *surf,
                  struct qxl_bo **bo_ptr)
 {
@@ -99,7 +100,7 @@ int qxl_bo_create(struct qxl_device *qdev,
        }
        bo->gem_base.driver_private = NULL;
        bo->type = domain;
-       bo->pin_count = 0;
+       bo->pin_count = pinned ? 1 : 0;
        bo->surface_id = 0;
        qxl_fence_init(qdev, &bo->fence);
        INIT_LIST_HEAD(&bo->list);
@@ -107,7 +108,7 @@ int qxl_bo_create(struct qxl_device *qdev,
        if (surf)
                bo->surf = *surf;
 
-       qxl_ttm_placement_from_domain(bo, domain);
+       qxl_ttm_placement_from_domain(bo, domain, pinned);
 
        r = ttm_bo_init(&qdev->mman.bdev, &bo->tbo, size, type,
                        &bo->placement, 0, !kernel, NULL, size,
@@ -228,7 +229,7 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
 int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
 {
        struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
-       int r, i;
+       int r;
 
        if (bo->pin_count) {
                bo->pin_count++;
@@ -236,9 +237,7 @@ int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
                        *gpu_addr = qxl_bo_gpu_offset(bo);
                return 0;
        }
-       qxl_ttm_placement_from_domain(bo, domain);
-       for (i = 0; i < bo->placement.num_placement; i++)
-               bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+       qxl_ttm_placement_from_domain(bo, domain, true);
        r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
        if (likely(r == 0)) {
                bo->pin_count = 1;
@@ -350,7 +349,7 @@ int qxl_bo_list_add(struct qxl_reloc_list *reloc_list, struct qxl_bo *bo)
                return ret;
 
        if (!bo->pin_count) {
-               qxl_ttm_placement_from_domain(bo, bo->type);
+               qxl_ttm_placement_from_domain(bo, bo->type, false);
                ret = ttm_bo_validate(&bo->tbo, &bo->placement,
                                      true, false);
                if (ret)
index ee7ad79ce781b163fdc31836184af2b44fb10d70..116637f09347e70535402351b1f168e5dbcb41a2 100644 (file)
@@ -88,7 +88,7 @@ static inline int qxl_bo_wait(struct qxl_bo *bo, u32 *mem_type,
 
 extern int qxl_bo_create(struct qxl_device *qdev,
                         unsigned long size,
-                        bool kernel, u32 domain,
+                        bool kernel, bool pinned, u32 domain,
                         struct qxl_surface *surf,
                         struct qxl_bo **bo_ptr);
 extern int qxl_bo_kmap(struct qxl_bo *bo, void **ptr);
@@ -99,7 +99,7 @@ extern struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo);
 extern void qxl_bo_unref(struct qxl_bo **bo);
 extern int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr);
 extern int qxl_bo_unpin(struct qxl_bo *bo);
-extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain);
+extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned);
 extern bool qxl_ttm_bo_is_qxl_bo(struct ttm_buffer_object *bo);
 
 extern int qxl_bo_list_add(struct qxl_reloc_list *reloc_list, struct qxl_bo *bo);
index b443d6751d5f2da675dda7fccec24b2637312ba7..b7f1271c6014d76060a2d804063cd1c0404c039d 100644 (file)
@@ -118,7 +118,9 @@ static int qxl_release_bo_alloc(struct qxl_device *qdev,
                                struct qxl_bo **bo)
 {
        int ret;
-       ret = qxl_bo_create(qdev, PAGE_SIZE, false, QXL_GEM_DOMAIN_VRAM, NULL,
+       /* pin releases bo's they are too messy to evict */
+       ret = qxl_bo_create(qdev, PAGE_SIZE, false, true,
+                           QXL_GEM_DOMAIN_VRAM, NULL,
                            bo);
        return ret;
 }
@@ -216,11 +218,6 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
                        mutex_unlock(&qdev->release_mutex);
                        return ret;
                }
-
-               /* pin releases bo's they are too messy to evict */
-               ret = qxl_bo_reserve(qdev->current_release_bo[cur_idx], false);
-               qxl_bo_pin(qdev->current_release_bo[cur_idx], QXL_GEM_DOMAIN_VRAM, NULL);
-               qxl_bo_unreserve(qdev->current_release_bo[cur_idx]);
        }
 
        bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]);
index 489cb8cece4da553b9f5c36c4dc9c610e617c3ea..1dfd84cda2a128e39f4e8143c43b3d0c6a99f30b 100644 (file)
@@ -206,7 +206,7 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo,
                return;
        }
        qbo = container_of(bo, struct qxl_bo, tbo);
-       qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU);
+       qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU, false);
        *placement = qbo->placement;
 }