drm/amdgpu: check flush fence context instead of same ring v2
authorChristian König <christian.koenig@amd.com>
Fri, 8 Jul 2016 08:21:02 +0000 (10:21 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 14 Jul 2016 20:46:07 +0000 (16:46 -0400)
Otherwise we can run into the following situation:

1. Process A grabs ID 1 for ring 0.
2. Process B grabs ID 1 for ring 0.
3. Process A grabs ID 1 for ring 1.
4. Process A tries to reuse ID1 for ring 0 but things he doesn't need to flush.

v2: check the context of the flush fence instead of messing with the owner field.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c

index 2f8496d..a041168 100644 (file)
@@ -195,6 +195,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
                      struct amdgpu_job *job)
 {
        struct amdgpu_device *adev = ring->adev;
+       uint64_t fence_context = adev->fence_context + ring->idx;
        struct fence *updates = sync->last_vm_update;
        struct amdgpu_vm_id *id, *idle;
        struct fence **fences;
@@ -254,7 +255,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
        i = ring->idx;
        do {
                struct fence *flushed;
-               bool same_ring = ring->idx == i;
 
                id = vm->ids[i++];
                if (i == AMDGPU_MAX_RINGS)
@@ -272,8 +272,11 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
                if (job->vm_pd_addr != id->pd_gpu_addr)
                        continue;
 
-               if (!same_ring &&
-                   (!id->last_flush || !fence_is_signaled(id->last_flush)))
+               if (!id->last_flush)
+                       continue;
+
+               if (id->last_flush->context != fence_context &&
+                   !fence_is_signaled(id->last_flush))
                        continue;
 
                flushed  = id->flushed_updates;