diff options
author | Christian König <christian.koenig@amd.com> | 2015-07-06 16:06:40 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-08-17 16:50:13 -0400 |
commit | 91e1a5207edec9e4f888e44478a9a254186e0ba8 (patch) | |
tree | d03a1e06f744981034fb67eeb15b8d1644816278 /drivers/gpu/drm/amd | |
parent | 0b492a4c92050862a9780b941d52c05923fcd669 (diff) |
drm/amdgpu: deal with foreign fences in amdgpu_sync
This also requires some error handling from the callers of that function.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 11 |
5 files changed, 45 insertions, 29 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 069cc28941ba..70e783a849ed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -699,8 +699,8 @@ struct amdgpu_sync { | |||
699 | }; | 699 | }; |
700 | 700 | ||
701 | void amdgpu_sync_create(struct amdgpu_sync *sync); | 701 | void amdgpu_sync_create(struct amdgpu_sync *sync); |
702 | void amdgpu_sync_fence(struct amdgpu_sync *sync, | 702 | int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, |
703 | struct amdgpu_fence *fence); | 703 | struct fence *f); |
704 | int amdgpu_sync_resv(struct amdgpu_device *adev, | 704 | int amdgpu_sync_resv(struct amdgpu_device *adev, |
705 | struct amdgpu_sync *sync, | 705 | struct amdgpu_sync *sync, |
706 | struct reservation_object *resv, | 706 | struct reservation_object *resv, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 1f040d85ac47..53e6a10fe9f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -482,6 +482,8 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, | |||
482 | 482 | ||
483 | if (p->bo_list) { | 483 | if (p->bo_list) { |
484 | for (i = 0; i < p->bo_list->num_entries; i++) { | 484 | for (i = 0; i < p->bo_list->num_entries; i++) { |
485 | struct fence *f; | ||
486 | |||
485 | /* ignore duplicates */ | 487 | /* ignore duplicates */ |
486 | bo = p->bo_list->array[i].robj; | 488 | bo = p->bo_list->array[i].robj; |
487 | if (!bo) | 489 | if (!bo) |
@@ -495,7 +497,10 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, | |||
495 | if (r) | 497 | if (r) |
496 | return r; | 498 | return r; |
497 | 499 | ||
498 | amdgpu_sync_fence(&p->ibs[0].sync, bo_va->last_pt_update); | 500 | f = &bo_va->last_pt_update->base; |
501 | r = amdgpu_sync_fence(adev, &p->ibs[0].sync, f); | ||
502 | if (r) | ||
503 | return r; | ||
499 | } | 504 | } |
500 | } | 505 | } |
501 | 506 | ||
@@ -715,9 +720,12 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, | |||
715 | return r; | 720 | return r; |
716 | } | 721 | } |
717 | 722 | ||
718 | amdgpu_sync_fence(&ib->sync, fence); | 723 | r = amdgpu_sync_fence(adev, &ib->sync, &fence->base); |
719 | amdgpu_fence_unref(&fence); | 724 | amdgpu_fence_unref(&fence); |
720 | amdgpu_ctx_put(ctx); | 725 | amdgpu_ctx_put(ctx); |
726 | |||
727 | if (r) | ||
728 | return r; | ||
721 | } | 729 | } |
722 | } | 730 | } |
723 | 731 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index bc0fac618a3f..2722815eddbb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | |||
@@ -167,7 +167,11 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, | |||
167 | /* grab a vm id if necessary */ | 167 | /* grab a vm id if necessary */ |
168 | struct amdgpu_fence *vm_id_fence = NULL; | 168 | struct amdgpu_fence *vm_id_fence = NULL; |
169 | vm_id_fence = amdgpu_vm_grab_id(ibs->ring, ibs->vm); | 169 | vm_id_fence = amdgpu_vm_grab_id(ibs->ring, ibs->vm); |
170 | amdgpu_sync_fence(&ibs->sync, vm_id_fence); | 170 | r = amdgpu_sync_fence(adev, &ibs->sync, &vm_id_fence->base); |
171 | if (r) { | ||
172 | amdgpu_ring_unlock_undo(ring); | ||
173 | return r; | ||
174 | } | ||
171 | } | 175 | } |
172 | 176 | ||
173 | r = amdgpu_sync_rings(&ibs->sync, ring); | 177 | r = amdgpu_sync_rings(&ibs->sync, ring); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index 21accbdd0a1a..9c292cf770f4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | |||
@@ -53,20 +53,24 @@ void amdgpu_sync_create(struct amdgpu_sync *sync) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * amdgpu_sync_fence - use the semaphore to sync to a fence | 56 | * amdgpu_sync_fence - remember to sync to this fence |
57 | * | 57 | * |
58 | * @sync: sync object to add fence to | 58 | * @sync: sync object to add fence to |
59 | * @fence: fence to sync to | 59 | * @fence: fence to sync to |
60 | * | 60 | * |
61 | * Sync to the fence using the semaphore objects | ||
62 | */ | 61 | */ |
63 | void amdgpu_sync_fence(struct amdgpu_sync *sync, | 62 | int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, |
64 | struct amdgpu_fence *fence) | 63 | struct fence *f) |
65 | { | 64 | { |
65 | struct amdgpu_fence *fence; | ||
66 | struct amdgpu_fence *other; | 66 | struct amdgpu_fence *other; |
67 | 67 | ||
68 | if (!fence) | 68 | if (!f) |
69 | return; | 69 | return 0; |
70 | |||
71 | fence = to_amdgpu_fence(f); | ||
72 | if (!fence || fence->ring->adev != adev) | ||
73 | return fence_wait(f, true); | ||
70 | 74 | ||
71 | other = sync->sync_to[fence->ring->idx]; | 75 | other = sync->sync_to[fence->ring->idx]; |
72 | sync->sync_to[fence->ring->idx] = amdgpu_fence_ref( | 76 | sync->sync_to[fence->ring->idx] = amdgpu_fence_ref( |
@@ -79,6 +83,8 @@ void amdgpu_sync_fence(struct amdgpu_sync *sync, | |||
79 | amdgpu_fence_later(fence, other)); | 83 | amdgpu_fence_later(fence, other)); |
80 | amdgpu_fence_unref(&other); | 84 | amdgpu_fence_unref(&other); |
81 | } | 85 | } |
86 | |||
87 | return 0; | ||
82 | } | 88 | } |
83 | 89 | ||
84 | /** | 90 | /** |
@@ -106,11 +112,7 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, | |||
106 | 112 | ||
107 | /* always sync to the exclusive fence */ | 113 | /* always sync to the exclusive fence */ |
108 | f = reservation_object_get_excl(resv); | 114 | f = reservation_object_get_excl(resv); |
109 | fence = f ? to_amdgpu_fence(f) : NULL; | 115 | r = amdgpu_sync_fence(adev, sync, f); |
110 | if (fence && fence->ring->adev == adev) | ||
111 | amdgpu_sync_fence(sync, fence); | ||
112 | else if (f) | ||
113 | r = fence_wait(f, true); | ||
114 | 116 | ||
115 | flist = reservation_object_get_list(resv); | 117 | flist = reservation_object_get_list(resv); |
116 | if (!flist || r) | 118 | if (!flist || r) |
@@ -120,15 +122,14 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, | |||
120 | f = rcu_dereference_protected(flist->shared[i], | 122 | f = rcu_dereference_protected(flist->shared[i], |
121 | reservation_object_held(resv)); | 123 | reservation_object_held(resv)); |
122 | fence = f ? to_amdgpu_fence(f) : NULL; | 124 | fence = f ? to_amdgpu_fence(f) : NULL; |
123 | if (fence && fence->ring->adev == adev) { | 125 | if (fence && fence->ring->adev == adev && |
124 | if (fence->owner != owner || | 126 | fence->owner == owner && |
125 | fence->owner == AMDGPU_FENCE_OWNER_UNDEFINED) | 127 | fence->owner != AMDGPU_FENCE_OWNER_UNDEFINED) |
126 | amdgpu_sync_fence(sync, fence); | 128 | continue; |
127 | } else if (f) { | 129 | |
128 | r = fence_wait(f, true); | 130 | r = amdgpu_sync_fence(adev, sync, f); |
129 | if (r) | 131 | if (r) |
130 | break; | 132 | break; |
131 | } | ||
132 | } | 133 | } |
133 | return r; | 134 | return r; |
134 | } | 135 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 9a4e3b63f1cb..0c8c9904d880 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -732,7 +732,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, | |||
732 | 732 | ||
733 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 733 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
734 | struct amdgpu_fence *f = vm->ids[i].last_id_use; | 734 | struct amdgpu_fence *f = vm->ids[i].last_id_use; |
735 | amdgpu_sync_fence(&ib.sync, f); | 735 | r = amdgpu_sync_fence(adev, &ib.sync, &f->base); |
736 | if (r) | ||
737 | return r; | ||
736 | } | 738 | } |
737 | } | 739 | } |
738 | 740 | ||
@@ -861,7 +863,7 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, | |||
861 | struct amdgpu_vm *vm, struct amdgpu_sync *sync) | 863 | struct amdgpu_vm *vm, struct amdgpu_sync *sync) |
862 | { | 864 | { |
863 | struct amdgpu_bo_va *bo_va = NULL; | 865 | struct amdgpu_bo_va *bo_va = NULL; |
864 | int r; | 866 | int r = 0; |
865 | 867 | ||
866 | spin_lock(&vm->status_lock); | 868 | spin_lock(&vm->status_lock); |
867 | while (!list_empty(&vm->invalidated)) { | 869 | while (!list_empty(&vm->invalidated)) { |
@@ -878,8 +880,9 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, | |||
878 | spin_unlock(&vm->status_lock); | 880 | spin_unlock(&vm->status_lock); |
879 | 881 | ||
880 | if (bo_va) | 882 | if (bo_va) |
881 | amdgpu_sync_fence(sync, bo_va->last_pt_update); | 883 | r = amdgpu_sync_fence(adev, sync, &bo_va->last_pt_update->base); |
882 | return 0; | 884 | |
885 | return r; | ||
883 | } | 886 | } |
884 | 887 | ||
885 | /** | 888 | /** |