Commit 91e1a520 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: deal with foreign fences in amdgpu_sync

This also requires some error handling from the callers of that function.
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarJammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: default avatarChunming Zhou <david1.zhou@amd.com>
parent 0b492a4c
...@@ -699,8 +699,8 @@ struct amdgpu_sync { ...@@ -699,8 +699,8 @@ struct amdgpu_sync {
}; };
void amdgpu_sync_create(struct amdgpu_sync *sync); void amdgpu_sync_create(struct amdgpu_sync *sync);
void amdgpu_sync_fence(struct amdgpu_sync *sync, int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
struct amdgpu_fence *fence); struct fence *f);
int amdgpu_sync_resv(struct amdgpu_device *adev, int amdgpu_sync_resv(struct amdgpu_device *adev,
struct amdgpu_sync *sync, struct amdgpu_sync *sync,
struct reservation_object *resv, struct reservation_object *resv,
......
...@@ -482,6 +482,8 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, ...@@ -482,6 +482,8 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
if (p->bo_list) { if (p->bo_list) {
for (i = 0; i < p->bo_list->num_entries; i++) { for (i = 0; i < p->bo_list->num_entries; i++) {
struct fence *f;
/* ignore duplicates */ /* ignore duplicates */
bo = p->bo_list->array[i].robj; bo = p->bo_list->array[i].robj;
if (!bo) if (!bo)
...@@ -495,7 +497,10 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, ...@@ -495,7 +497,10 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
if (r) if (r)
return r; return r;
amdgpu_sync_fence(&p->ibs[0].sync, bo_va->last_pt_update); f = &bo_va->last_pt_update->base;
r = amdgpu_sync_fence(adev, &p->ibs[0].sync, f);
if (r)
return r;
} }
} }
...@@ -715,9 +720,12 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, ...@@ -715,9 +720,12 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
return r; return r;
} }
amdgpu_sync_fence(&ib->sync, fence); r = amdgpu_sync_fence(adev, &ib->sync, &fence->base);
amdgpu_fence_unref(&fence); amdgpu_fence_unref(&fence);
amdgpu_ctx_put(ctx); amdgpu_ctx_put(ctx);
if (r)
return r;
} }
} }
......
...@@ -167,7 +167,11 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, ...@@ -167,7 +167,11 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,
/* grab a vm id if necessary */ /* grab a vm id if necessary */
struct amdgpu_fence *vm_id_fence = NULL; struct amdgpu_fence *vm_id_fence = NULL;
vm_id_fence = amdgpu_vm_grab_id(ibs->ring, ibs->vm); vm_id_fence = amdgpu_vm_grab_id(ibs->ring, ibs->vm);
amdgpu_sync_fence(&ibs->sync, vm_id_fence); r = amdgpu_sync_fence(adev, &ibs->sync, &vm_id_fence->base);
if (r) {
amdgpu_ring_unlock_undo(ring);
return r;
}
} }
r = amdgpu_sync_rings(&ibs->sync, ring); r = amdgpu_sync_rings(&ibs->sync, ring);
......
...@@ -53,20 +53,24 @@ void amdgpu_sync_create(struct amdgpu_sync *sync) ...@@ -53,20 +53,24 @@ void amdgpu_sync_create(struct amdgpu_sync *sync)
} }
/** /**
* amdgpu_sync_fence - use the semaphore to sync to a fence * amdgpu_sync_fence - remember to sync to this fence
* *
* @sync: sync object to add fence to * @sync: sync object to add fence to
* @fence: fence to sync to * @fence: fence to sync to
* *
* Sync to the fence using the semaphore objects
*/ */
void amdgpu_sync_fence(struct amdgpu_sync *sync, int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync,
struct amdgpu_fence *fence) struct fence *f)
{ {
struct amdgpu_fence *fence;
struct amdgpu_fence *other; struct amdgpu_fence *other;
if (!fence) if (!f)
return; return 0;
fence = to_amdgpu_fence(f);
if (!fence || fence->ring->adev != adev)
return fence_wait(f, true);
other = sync->sync_to[fence->ring->idx]; other = sync->sync_to[fence->ring->idx];
sync->sync_to[fence->ring->idx] = amdgpu_fence_ref( sync->sync_to[fence->ring->idx] = amdgpu_fence_ref(
...@@ -79,6 +83,8 @@ void amdgpu_sync_fence(struct amdgpu_sync *sync, ...@@ -79,6 +83,8 @@ void amdgpu_sync_fence(struct amdgpu_sync *sync,
amdgpu_fence_later(fence, other)); amdgpu_fence_later(fence, other));
amdgpu_fence_unref(&other); amdgpu_fence_unref(&other);
} }
return 0;
} }
/** /**
...@@ -106,11 +112,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, ...@@ -106,11 +112,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
/* always sync to the exclusive fence */ /* always sync to the exclusive fence */
f = reservation_object_get_excl(resv); f = reservation_object_get_excl(resv);
fence = f ? to_amdgpu_fence(f) : NULL; r = amdgpu_sync_fence(adev, sync, f);
if (fence && fence->ring->adev == adev)
amdgpu_sync_fence(sync, fence);
else if (f)
r = fence_wait(f, true);
flist = reservation_object_get_list(resv); flist = reservation_object_get_list(resv);
if (!flist || r) if (!flist || r)
...@@ -120,16 +122,15 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, ...@@ -120,16 +122,15 @@ int amdgpu_sync_resv(struct amdgpu_device *adev,
f = rcu_dereference_protected(flist->shared[i], f = rcu_dereference_protected(flist->shared[i],
reservation_object_held(resv)); reservation_object_held(resv));
fence = f ? to_amdgpu_fence(f) : NULL; fence = f ? to_amdgpu_fence(f) : NULL;
if (fence && fence->ring->adev == adev) { if (fence && fence->ring->adev == adev &&
if (fence->owner != owner || fence->owner == owner &&
fence->owner == AMDGPU_FENCE_OWNER_UNDEFINED) fence->owner != AMDGPU_FENCE_OWNER_UNDEFINED)
amdgpu_sync_fence(sync, fence); continue;
} else if (f) {
r = fence_wait(f, true); r = amdgpu_sync_fence(adev, sync, f);
if (r) if (r)
break; break;
} }
}
return r; return r;
} }
......
...@@ -732,7 +732,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ...@@ -732,7 +732,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
struct amdgpu_fence *f = vm->ids[i].last_id_use; struct amdgpu_fence *f = vm->ids[i].last_id_use;
amdgpu_sync_fence(&ib.sync, f); r = amdgpu_sync_fence(adev, &ib.sync, &f->base);
if (r)
return r;
} }
} }
...@@ -861,7 +863,7 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, ...@@ -861,7 +863,7 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
struct amdgpu_vm *vm, struct amdgpu_sync *sync) struct amdgpu_vm *vm, struct amdgpu_sync *sync)
{ {
struct amdgpu_bo_va *bo_va = NULL; struct amdgpu_bo_va *bo_va = NULL;
int r; int r = 0;
spin_lock(&vm->status_lock); spin_lock(&vm->status_lock);
while (!list_empty(&vm->invalidated)) { while (!list_empty(&vm->invalidated)) {
...@@ -878,8 +880,9 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, ...@@ -878,8 +880,9 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev,
spin_unlock(&vm->status_lock); spin_unlock(&vm->status_lock);
if (bo_va) if (bo_va)
amdgpu_sync_fence(sync, bo_va->last_pt_update); r = amdgpu_sync_fence(adev, sync, &bo_va->last_pt_update->base);
return 0;
return r;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment