diff options
author | Chunming Zhou <david1.zhou@amd.com> | 2015-08-20 06:33:59 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-08-25 10:53:05 -0400 |
commit | 3c62338c26bf2677c8285b406cd769b92ee0dc10 (patch) | |
tree | b0e1e6592c3298fd0fed935740c1827307bcf48e | |
parent | f38fdfddfaab070e3ff2333a79e45169ee33dc28 (diff) |
drm/amdgpu: fix last_vm_update fence is not effetive for sched fence
Signed-off-by: Chunming Zhou <david1.zhou@amd.com>
Reviewed-by: Christian K?nig <christian.koenig@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 24 |
4 files changed, 58 insertions, 18 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 19a8cbead48b..c9160430b5ac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -705,7 +705,7 @@ struct amdgpu_sync { | |||
705 | struct amdgpu_semaphore *semaphores[AMDGPU_NUM_SYNCS]; | 705 | struct amdgpu_semaphore *semaphores[AMDGPU_NUM_SYNCS]; |
706 | struct amdgpu_fence *sync_to[AMDGPU_MAX_RINGS]; | 706 | struct amdgpu_fence *sync_to[AMDGPU_MAX_RINGS]; |
707 | DECLARE_HASHTABLE(fences, 4); | 707 | DECLARE_HASHTABLE(fences, 4); |
708 | struct amdgpu_fence *last_vm_update; | 708 | struct fence *last_vm_update; |
709 | }; | 709 | }; |
710 | 710 | ||
711 | void amdgpu_sync_create(struct amdgpu_sync *sync); | 711 | void amdgpu_sync_create(struct amdgpu_sync *sync); |
@@ -963,7 +963,7 @@ struct amdgpu_vm_id { | |||
963 | unsigned id; | 963 | unsigned id; |
964 | uint64_t pd_gpu_addr; | 964 | uint64_t pd_gpu_addr; |
965 | /* last flushed PD/PT update */ | 965 | /* last flushed PD/PT update */ |
966 | struct amdgpu_fence *flushed_updates; | 966 | struct fence *flushed_updates; |
967 | /* last use of vmid */ | 967 | /* last use of vmid */ |
968 | struct amdgpu_fence *last_id_use; | 968 | struct amdgpu_fence *last_id_use; |
969 | }; | 969 | }; |
@@ -2349,7 +2349,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
2349 | struct amdgpu_sync *sync); | 2349 | struct amdgpu_sync *sync); |
2350 | void amdgpu_vm_flush(struct amdgpu_ring *ring, | 2350 | void amdgpu_vm_flush(struct amdgpu_ring *ring, |
2351 | struct amdgpu_vm *vm, | 2351 | struct amdgpu_vm *vm, |
2352 | struct amdgpu_fence *updates); | 2352 | struct fence *updates); |
2353 | void amdgpu_vm_fence(struct amdgpu_device *adev, | 2353 | void amdgpu_vm_fence(struct amdgpu_device *adev, |
2354 | struct amdgpu_vm *vm, | 2354 | struct amdgpu_vm *vm, |
2355 | struct amdgpu_fence *fence); | 2355 | struct amdgpu_fence *fence); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c index 4f5c0874ad2a..757058d539f4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |||
@@ -119,5 +119,6 @@ int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, | |||
119 | return r; | 119 | return r; |
120 | *f = fence_get(&ibs[num_ibs - 1].fence->base); | 120 | *f = fence_get(&ibs[num_ibs - 1].fence->base); |
121 | } | 121 | } |
122 | |||
122 | return 0; | 123 | return 0; |
123 | } | 124 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index febbf37b1412..4fffb2539331 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | |||
@@ -58,6 +58,29 @@ void amdgpu_sync_create(struct amdgpu_sync *sync) | |||
58 | sync->last_vm_update = NULL; | 58 | sync->last_vm_update = NULL; |
59 | } | 59 | } |
60 | 60 | ||
61 | static bool amdgpu_sync_same_dev(struct amdgpu_device *adev, struct fence *f) | ||
62 | { | ||
63 | struct amdgpu_fence *a_fence = to_amdgpu_fence(f); | ||
64 | struct amd_sched_fence *s_fence = to_amd_sched_fence(f); | ||
65 | |||
66 | if (a_fence) | ||
67 | return a_fence->ring->adev == adev; | ||
68 | if (s_fence) | ||
69 | return (struct amdgpu_device *)s_fence->scheduler->priv == adev; | ||
70 | return false; | ||
71 | } | ||
72 | |||
73 | static bool amdgpu_sync_test_owner(struct fence *f, void *owner) | ||
74 | { | ||
75 | struct amdgpu_fence *a_fence = to_amdgpu_fence(f); | ||
76 | struct amd_sched_fence *s_fence = to_amd_sched_fence(f); | ||
77 | if (s_fence) | ||
78 | return s_fence->owner == owner; | ||
79 | if (a_fence) | ||
80 | return a_fence->owner == owner; | ||
81 | return false; | ||
82 | } | ||
83 | |||
61 | /** | 84 | /** |
62 | * amdgpu_sync_fence - remember to sync to this fence | 85 | * amdgpu_sync_fence - remember to sync to this fence |
63 | * | 86 | * |
@@ -71,10 +94,23 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, | |||
71 | struct amdgpu_sync_entry *e; | 94 | struct amdgpu_sync_entry *e; |
72 | struct amdgpu_fence *fence; | 95 | struct amdgpu_fence *fence; |
73 | struct amdgpu_fence *other; | 96 | struct amdgpu_fence *other; |
97 | struct fence *tmp, *later; | ||
74 | 98 | ||
75 | if (!f) | 99 | if (!f) |
76 | return 0; | 100 | return 0; |
77 | 101 | ||
102 | if (amdgpu_sync_same_dev(adev, f) && | ||
103 | amdgpu_sync_test_owner(f, AMDGPU_FENCE_OWNER_VM)) { | ||
104 | if (sync->last_vm_update) { | ||
105 | tmp = sync->last_vm_update; | ||
106 | BUG_ON(f->context != tmp->context); | ||
107 | later = (f->seqno - tmp->seqno <= INT_MAX) ? f : tmp; | ||
108 | sync->last_vm_update = fence_get(later); | ||
109 | fence_put(tmp); | ||
110 | } else | ||
111 | sync->last_vm_update = fence_get(f); | ||
112 | } | ||
113 | |||
78 | fence = to_amdgpu_fence(f); | 114 | fence = to_amdgpu_fence(f); |
79 | if (!fence || fence->ring->adev != adev) { | 115 | if (!fence || fence->ring->adev != adev) { |
80 | hash_for_each_possible(sync->fences, e, node, f->context) { | 116 | hash_for_each_possible(sync->fences, e, node, f->context) { |
@@ -103,13 +139,6 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, | |||
103 | amdgpu_fence_later(fence, other)); | 139 | amdgpu_fence_later(fence, other)); |
104 | amdgpu_fence_unref(&other); | 140 | amdgpu_fence_unref(&other); |
105 | 141 | ||
106 | if (fence->owner == AMDGPU_FENCE_OWNER_VM) { | ||
107 | other = sync->last_vm_update; | ||
108 | sync->last_vm_update = amdgpu_fence_ref( | ||
109 | amdgpu_fence_later(fence, other)); | ||
110 | amdgpu_fence_unref(&other); | ||
111 | } | ||
112 | |||
113 | return 0; | 142 | return 0; |
114 | } | 143 | } |
115 | 144 | ||
@@ -296,5 +325,5 @@ void amdgpu_sync_free(struct amdgpu_device *adev, | |||
296 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) | 325 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) |
297 | amdgpu_fence_unref(&sync->sync_to[i]); | 326 | amdgpu_fence_unref(&sync->sync_to[i]); |
298 | 327 | ||
299 | amdgpu_fence_unref(&sync->last_vm_update); | 328 | fence_put(sync->last_vm_update); |
300 | } | 329 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 5b99214d0ba6..677266b90c74 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -200,19 +200,29 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
200 | */ | 200 | */ |
201 | void amdgpu_vm_flush(struct amdgpu_ring *ring, | 201 | void amdgpu_vm_flush(struct amdgpu_ring *ring, |
202 | struct amdgpu_vm *vm, | 202 | struct amdgpu_vm *vm, |
203 | struct amdgpu_fence *updates) | 203 | struct fence *updates) |
204 | { | 204 | { |
205 | uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); | 205 | uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); |
206 | struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; | 206 | struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; |
207 | struct amdgpu_fence *flushed_updates = vm_id->flushed_updates; | 207 | struct fence *flushed_updates = vm_id->flushed_updates; |
208 | bool is_earlier = false; | ||
209 | |||
210 | if (flushed_updates && updates) { | ||
211 | BUG_ON(flushed_updates->context != updates->context); | ||
212 | is_earlier = (updates->seqno - flushed_updates->seqno <= | ||
213 | INT_MAX) ? true : false; | ||
214 | } | ||
208 | 215 | ||
209 | if (pd_addr != vm_id->pd_gpu_addr || !flushed_updates || | 216 | if (pd_addr != vm_id->pd_gpu_addr || !flushed_updates || |
210 | (updates && amdgpu_fence_is_earlier(flushed_updates, updates))) { | 217 | is_earlier) { |
211 | 218 | ||
212 | trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id->id); | 219 | trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id->id); |
213 | vm_id->flushed_updates = amdgpu_fence_ref( | 220 | if (is_earlier) { |
214 | amdgpu_fence_later(flushed_updates, updates)); | 221 | vm_id->flushed_updates = fence_get(updates); |
215 | amdgpu_fence_unref(&flushed_updates); | 222 | fence_put(flushed_updates); |
223 | } | ||
224 | if (!flushed_updates) | ||
225 | vm_id->flushed_updates = fence_get(updates); | ||
216 | vm_id->pd_gpu_addr = pd_addr; | 226 | vm_id->pd_gpu_addr = pd_addr; |
217 | amdgpu_ring_emit_vm_flush(ring, vm_id->id, vm_id->pd_gpu_addr); | 227 | amdgpu_ring_emit_vm_flush(ring, vm_id->id, vm_id->pd_gpu_addr); |
218 | } | 228 | } |
@@ -1347,7 +1357,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1347 | fence_put(vm->page_directory_fence); | 1357 | fence_put(vm->page_directory_fence); |
1348 | 1358 | ||
1349 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 1359 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
1350 | amdgpu_fence_unref(&vm->ids[i].flushed_updates); | 1360 | fence_put(vm->ids[i].flushed_updates); |
1351 | amdgpu_fence_unref(&vm->ids[i].last_id_use); | 1361 | amdgpu_fence_unref(&vm->ids[i].last_id_use); |
1352 | } | 1362 | } |
1353 | 1363 | ||