drm/amdgpu: introduce AMDGPU_GEM_CREATE_EXPLICIT_SYNC v2
authorAndres Rodriguez <andresx7@gmail.com>
Sat, 16 Sep 2017 00:44:06 +0000 (20:44 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 9 Oct 2017 20:30:19 +0000 (16:30 -0400)
Introduce a flag to signal that access to a BO will be synchronized
through an external mechanism.

Currently all buffers shared between contexts are subject to implicit
synchronization. However, this is only required for protocols that
currently don't support an explicit synchronization mechanism (DRI2/3).

This patch introduces the AMDGPU_GEM_CREATE_EXPLICIT_SYNC, so that
users can specify when it is safe to disable implicit sync.

v2: only disable explicit sync in amdgpu_cs_ioctl

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Andres Rodriguez <andresx7@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
include/uapi/drm/amdgpu_drm.h

index ab83dfcabb41c85ace7017f327238d18ab1831da..38027a00f8ab9ca94044a3ef4eb8ac400233ca0d 100644 (file)
@@ -705,7 +705,8 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
 
        list_for_each_entry(e, &p->validated, tv.head) {
                struct reservation_object *resv = e->robj->tbo.resv;
-               r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, p->filp);
+               r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, p->filp,
+                                    amdgpu_bo_explicit_sync(e->robj));
 
                if (r)
                        return r;
index b0d45c8e6bb3f7762357f09cb3a570607cee5bb8..21e99366cab3de933968edf8298b8f69c2eb4efd 100644 (file)
@@ -212,7 +212,9 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
                      AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
                      AMDGPU_GEM_CREATE_CPU_GTT_USWC |
                      AMDGPU_GEM_CREATE_VRAM_CLEARED |
-                     AMDGPU_GEM_CREATE_VM_ALWAYS_VALID))
+                     AMDGPU_GEM_CREATE_VM_ALWAYS_VALID |
+                     AMDGPU_GEM_CREATE_EXPLICIT_SYNC))
+
                return -EINVAL;
 
        /* reject invalid gem domains */
index c26ef53604af5166f0082a7f4745236af414b499..428aae048f4b19bb2f31dbb168a9a12cb6ae5a2b 100644 (file)
@@ -193,6 +193,14 @@ static inline bool amdgpu_bo_gpu_accessible(struct amdgpu_bo *bo)
        }
 }
 
+/**
+ * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced
+ */
+static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo)
+{
+       return bo->flags & AMDGPU_GEM_CREATE_EXPLICIT_SYNC;
+}
+
 int amdgpu_bo_create(struct amdgpu_device *adev,
                            unsigned long size, int byte_align,
                            bool kernel, u32 domain, u64 flags,
index c586f44312f9772fb93f8b1442827c842d610594..a4bf21f8f1c187e9c7f45bfc4c30171760647eea 100644 (file)
@@ -169,14 +169,14 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
  *
  * @sync: sync object to add fences from reservation object to
  * @resv: reservation object with embedded fence
- * @shared: true if we should only sync to the exclusive fence
+ * @explicit_sync: true if we should only sync to the exclusive fence
  *
  * Sync to the fence
  */
 int amdgpu_sync_resv(struct amdgpu_device *adev,
                     struct amdgpu_sync *sync,
                     struct reservation_object *resv,
-                    void *owner)
+                    void *owner, bool explicit_sync)
 {
        struct reservation_object_list *flist;
        struct dma_fence *f;
@@ -191,6 +191,9 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
        f = reservation_object_get_excl(resv);
        r = amdgpu_sync_fence(adev, sync, f);
 
+       if (explicit_sync)
+               return r;
+
        flist = reservation_object_get_list(resv);
        if (!flist || r)
                return r;
index dc7687993317041546db1a559489095b8011be27..70d7e3a279a052c9be7453311886d985751417b6 100644 (file)
@@ -45,7 +45,8 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
 int amdgpu_sync_resv(struct amdgpu_device *adev,
                     struct amdgpu_sync *sync,
                     struct reservation_object *resv,
-                    void *owner);
+                    void *owner,
+                    bool explicit_sync);
 struct dma_fence *amdgpu_sync_peek_fence(struct amdgpu_sync *sync,
                                     struct amdgpu_ring *ring);
 struct dma_fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync);
index 10952c3e5eb6dcc73b0e9c4859240c890de6ba9b..a2282bacf9604c8bbf1d646e8531e4c4c102a50c 100644 (file)
@@ -1489,7 +1489,8 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, uint64_t src_offset,
        job->vm_needs_flush = vm_needs_flush;
        if (resv) {
                r = amdgpu_sync_resv(adev, &job->sync, resv,
-                                    AMDGPU_FENCE_OWNER_UNDEFINED);
+                                    AMDGPU_FENCE_OWNER_UNDEFINED,
+                                    false);
                if (r) {
                        DRM_ERROR("sync failed (%d).\n", r);
                        goto error_free;
@@ -1581,7 +1582,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo,
 
        if (resv) {
                r = amdgpu_sync_resv(adev, &job->sync, resv,
-                                    AMDGPU_FENCE_OWNER_UNDEFINED);
+                                    AMDGPU_FENCE_OWNER_UNDEFINED, false);
                if (r) {
                        DRM_ERROR("sync failed (%d).\n", r);
                        goto error_free;
index eb4a01c14eee9f0093e4bc6a527b4576a07d7429..c559d76ff695f7f5940c0f3a79da0879611036ba 100644 (file)
@@ -1035,7 +1035,7 @@ static int amdgpu_vm_wait_pd(struct amdgpu_device *adev, struct amdgpu_vm *vm,
        int r;
 
        amdgpu_sync_create(&sync);
-       amdgpu_sync_resv(adev, &sync, vm->root.base.bo->tbo.resv, owner);
+       amdgpu_sync_resv(adev, &sync, vm->root.base.bo->tbo.resv, owner, false);
        r = amdgpu_sync_wait(&sync, true);
        amdgpu_sync_free(&sync);
 
@@ -1176,11 +1176,11 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev,
                        amdgpu_ring_pad_ib(ring, params.ib);
                        amdgpu_sync_resv(adev, &job->sync,
                                         parent->base.bo->tbo.resv,
-                                        AMDGPU_FENCE_OWNER_VM);
+                                        AMDGPU_FENCE_OWNER_VM, false);
                        if (shadow)
                                amdgpu_sync_resv(adev, &job->sync,
                                                 shadow->tbo.resv,
-                                                AMDGPU_FENCE_OWNER_VM);
+                                                AMDGPU_FENCE_OWNER_VM, false);
 
                        WARN_ON(params.ib->length_dw > ndw);
                        r = amdgpu_job_submit(job, ring, &vm->entity,
@@ -1644,7 +1644,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
                goto error_free;
 
        r = amdgpu_sync_resv(adev, &job->sync, vm->root.base.bo->tbo.resv,
-                            owner);
+                            owner, false);
        if (r)
                goto error_free;
 
index 4c6e8c482ee498d564592fd063ba23229e0bed3d..b62484af8ccbc7770be707e42e04107d95d35540 100644 (file)
@@ -91,6 +91,8 @@ extern "C" {
 #define AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS      (1 << 5)
 /* Flag that BO is always valid in this VM */
 #define AMDGPU_GEM_CREATE_VM_ALWAYS_VALID      (1 << 6)
+/* Flag that BO sharing will be explicitly synchronized */
+#define AMDGPU_GEM_CREATE_EXPLICIT_SYNC                (1 << 7)
 
 struct drm_amdgpu_gem_create_in  {
        /** the requested memory size */