drm/radeon: fence PT updates manually v2
authorChristian König <christian.koenig@amd.com>
Wed, 19 Nov 2014 13:01:23 +0000 (14:01 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 20 Nov 2014 18:00:16 +0000 (13:00 -0500)
This allows us to add the real execution fence as shared.

v2: fix typo

Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/radeon_object.c
drivers/gpu/drm/radeon/radeon_object.h
drivers/gpu/drm/radeon/radeon_vm.c

index 33e6c7a89c3201848c99c32ff4e9ebd489afb8fb..686e450199c5250ce75a14b53217fa20070d01dd 100644 (file)
@@ -818,3 +818,22 @@ int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, bool no_wait)
        ttm_bo_unreserve(&bo->tbo);
        return r;
 }
+
+/**
+ * radeon_bo_fence - add fence to buffer object
+ *
+ * @bo: buffer object in question
+ * @fence: fence to add
+ * @shared: true if fence should be added shared
+ *
+ */
+void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence,
+                     bool shared)
+{
+       struct reservation_object *resv = bo->tbo.resv;
+
+       if (shared)
+               reservation_object_add_shared_fence(resv, &fence->base);
+       else
+               reservation_object_add_excl_fence(resv, &fence->base);
+}
index 1b8ec7917154809e10336fb346c6aacbafa72939..3b0b377f76cb08c2aa6124896818c6567ff52db4 100644 (file)
@@ -155,6 +155,8 @@ extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,
                                  struct ttm_mem_reg *new_mem);
 extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
 extern int radeon_bo_get_surface_reg(struct radeon_bo *bo);
+extern void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence,
+                           bool shared);
 
 /*
  * sub allocation
index 20ef8263d9704d05ba3b9d1609714c6221f93b5f..4ca2779ed8282fa742e7e2a6c3d208a7b5b50519 100644 (file)
@@ -143,7 +143,7 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev,
        list[0].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
        list[0].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
        list[0].tv.bo = &vm->page_directory->tbo;
-       list[0].tv.shared = false;
+       list[0].tv.shared = true;
        list[0].tiling_flags = 0;
        list[0].handle = 0;
        list_add(&list[0].tv.head, head);
@@ -157,7 +157,7 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev,
                list[idx].prefered_domains = RADEON_GEM_DOMAIN_VRAM;
                list[idx].allowed_domains = RADEON_GEM_DOMAIN_VRAM;
                list[idx].tv.bo = &list[idx].robj->tbo;
-               list[idx].tv.shared = false;
+               list[idx].tv.shared = true;
                list[idx].tiling_flags = 0;
                list[idx].handle = 0;
                list_add(&list[idx++].tv.head, head);
@@ -388,35 +388,25 @@ static void radeon_vm_set_pages(struct radeon_device *rdev,
 static int radeon_vm_clear_bo(struct radeon_device *rdev,
                              struct radeon_bo *bo)
 {
-        struct ttm_validate_buffer tv;
-        struct ww_acquire_ctx ticket;
-        struct list_head head;
        struct radeon_ib ib;
        unsigned entries;
        uint64_t addr;
        int r;
 
-        memset(&tv, 0, sizeof(tv));
-        tv.bo = &bo->tbo;
-       tv.shared = false;
-
-        INIT_LIST_HEAD(&head);
-        list_add(&tv.head, &head);
-
-        r = ttm_eu_reserve_buffers(&ticket, &head, true);
-        if (r)
+       r = radeon_bo_reserve(bo, false);
+       if (r)
                return r;
 
-        r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
-        if (r)
-                goto error;
+       r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
+       if (r)
+               goto error_unreserve;
 
        addr = radeon_bo_gpu_offset(bo);
        entries = radeon_bo_size(bo) / 8;
 
        r = radeon_ib_get(rdev, R600_RING_TYPE_DMA_INDEX, &ib, NULL, 256);
        if (r)
-                goto error;
+               goto error_unreserve;
 
        ib.length_dw = 0;
 
@@ -426,15 +416,15 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev,
 
        r = radeon_ib_schedule(rdev, &ib, NULL, false);
        if (r)
-                goto error;
+               goto error_free;
 
-       ttm_eu_fence_buffer_objects(&ticket, &head, &ib.fence->base);
-       radeon_ib_free(rdev, &ib);
+       radeon_bo_fence(bo, ib.fence, false);
 
-       return 0;
+error_free:
+       radeon_ib_free(rdev, &ib);
 
-error:
-       ttm_eu_backoff_reservation(&ticket, &head);
+error_unreserve:
+       radeon_bo_unreserve(bo);
        return r;
 }
 
@@ -707,6 +697,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev,
                        radeon_ib_free(rdev, &ib);
                        return r;
                }
+               radeon_bo_fence(pd, ib.fence, false);
                radeon_fence_unref(&vm->fence);
                vm->fence = radeon_fence_ref(ib.fence);
                radeon_fence_unref(&vm->last_flush);
@@ -862,6 +853,31 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
        }
 }
 
+/**
+ * radeon_vm_fence_pts - fence page tables after an update
+ *
+ * @vm: requested vm
+ * @start: start of GPU address range
+ * @end: end of GPU address range
+ * @fence: fence to use
+ *
+ * Fence the page tables in the range @start - @end (cayman+).
+ *
+ * Global and local mutex must be locked!
+ */
+static void radeon_vm_fence_pts(struct radeon_vm *vm,
+                               uint64_t start, uint64_t end,
+                               struct radeon_fence *fence)
+{
+       unsigned i;
+
+       start >>= radeon_vm_block_size;
+       end >>= radeon_vm_block_size;
+
+       for (i = start; i <= end; ++i)
+               radeon_bo_fence(vm->page_tables[i].bo, fence, false);
+}
+
 /**
  * radeon_vm_bo_update - map a bo into the vm page table
  *
@@ -973,6 +989,7 @@ int radeon_vm_bo_update(struct radeon_device *rdev,
                radeon_ib_free(rdev, &ib);
                return r;
        }
+       radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence);
        radeon_fence_unref(&vm->fence);
        vm->fence = radeon_fence_ref(ib.fence);
        radeon_ib_free(rdev, &ib);