drm/amdgpu: wait interruptible when semaphores are disabled v2
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_sync.c
index 4921de15b45158fe89af11d540eebcf998e2983c..dd005c336c974ad708827c25edc4a4534772bb2c 100644 (file)
@@ -87,6 +87,15 @@ static bool amdgpu_sync_test_owner(struct fence *f, void *owner)
        return false;
 }
 
+static void amdgpu_sync_keep_later(struct fence **keep, struct fence *fence)
+{
+       if (*keep && fence_is_later(*keep, fence))
+               return;
+
+       fence_put(*keep);
+       *keep = fence_get(fence);
+}
+
 /**
  * amdgpu_sync_fence - remember to sync to this fence
  *
@@ -99,35 +108,21 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
 {
        struct amdgpu_sync_entry *e;
        struct amdgpu_fence *fence;
-       struct amdgpu_fence *other;
-       struct fence *tmp, *later;
 
        if (!f)
                return 0;
 
        if (amdgpu_sync_same_dev(adev, f) &&
-           amdgpu_sync_test_owner(f, AMDGPU_FENCE_OWNER_VM)) {
-               if (sync->last_vm_update) {
-                       tmp = sync->last_vm_update;
-                       BUG_ON(f->context != tmp->context);
-                       later = (f->seqno - tmp->seqno <= INT_MAX) ? f : tmp;
-                       sync->last_vm_update = fence_get(later);
-                       fence_put(tmp);
-               } else
-                       sync->last_vm_update = fence_get(f);
-       }
+           amdgpu_sync_test_owner(f, AMDGPU_FENCE_OWNER_VM))
+               amdgpu_sync_keep_later(&sync->last_vm_update, f);
 
        fence = to_amdgpu_fence(f);
        if (!fence || fence->ring->adev != adev) {
                hash_for_each_possible(sync->fences, e, node, f->context) {
-                       struct fence *new;
                        if (unlikely(e->fence->context != f->context))
                                continue;
-                       new = fence_get(fence_later(e->fence, f));
-                       if (new) {
-                               fence_put(e->fence);
-                               e->fence = new;
-                       }
+
+                       amdgpu_sync_keep_later(&e->fence, f);
                        return 0;
                }
 
@@ -140,10 +135,7 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
                return 0;
        }
 
-       other = sync->sync_to[fence->ring->idx];
-       sync->sync_to[fence->ring->idx] = amdgpu_fence_ref(
-               amdgpu_fence_later(fence, other));
-       amdgpu_fence_unref(&other);
+       amdgpu_sync_keep_later(&sync->sync_to[fence->ring->idx], f);
 
        return 0;
 }
@@ -199,8 +191,8 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
                         * for other VM updates and moves.
                         */
                        fence_owner = amdgpu_sync_get_owner(f);
-                       if ((owner != AMDGPU_FENCE_OWNER_MOVE) &&
-                           (fence_owner != AMDGPU_FENCE_OWNER_MOVE) &&
+                       if ((owner != AMDGPU_FENCE_OWNER_UNDEFINED) &&
+                           (fence_owner != AMDGPU_FENCE_OWNER_UNDEFINED) &&
                            ((owner == AMDGPU_FENCE_OWNER_VM) !=
                             (fence_owner == AMDGPU_FENCE_OWNER_VM)))
                                continue;
@@ -262,11 +254,11 @@ int amdgpu_sync_wait(struct amdgpu_sync *sync)
                return 0;
 
        for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
-               struct amdgpu_fence *fence = sync->sync_to[i];
+               struct fence *fence = sync->sync_to[i];
                if (!fence)
                        continue;
 
-               r = fence_wait(&fence->base, false);
+               r = fence_wait(fence, false);
                if (r)
                        return r;
        }
@@ -291,9 +283,14 @@ int amdgpu_sync_rings(struct amdgpu_sync *sync,
        int i, r;
 
        for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
-               struct amdgpu_fence *fence = sync->sync_to[i];
-               struct amdgpu_semaphore *semaphore;
                struct amdgpu_ring *other = adev->rings[i];
+               struct amdgpu_semaphore *semaphore;
+               struct amdgpu_fence *fence;
+
+               if (!sync->sync_to[i])
+                       continue;
+
+               fence = to_amdgpu_fence(sync->sync_to[i]);
 
                /* check if we really need to sync */
                if (!amdgpu_fence_need_sync(fence, ring))
@@ -305,8 +302,14 @@ int amdgpu_sync_rings(struct amdgpu_sync *sync,
                        return -EINVAL;
                }
 
-               if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores ||
-                   (count >= AMDGPU_NUM_SYNCS)) {
+               if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores) {
+                       r = fence_wait(&fence->base, true);
+                       if (r)
+                               return r;
+                       continue;
+               }
+
+               if (count >= AMDGPU_NUM_SYNCS) {
                        /* not enough room, wait manually */
                        r = fence_wait(&fence->base, false);
                        if (r)
@@ -378,7 +381,7 @@ void amdgpu_sync_free(struct amdgpu_device *adev,
                amdgpu_semaphore_free(adev, &sync->semaphores[i], fence);
 
        for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
-               amdgpu_fence_unref(&sync->sync_to[i]);
+               fence_put(sync->sync_to[i]);
 
        fence_put(sync->last_vm_update);
 }