diff options
author | Christian König <christian.koenig@amd.com> | 2016-03-08 09:40:11 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-05-04 20:19:13 -0400 |
commit | bcb1ba35a87be34d1312f6e050f1b5cc4d32f096 (patch) | |
tree | a06cb56e8d388d33e8162b06d0320475e5caef29 /drivers/gpu | |
parent | bd4c72d1e9dd7efdb9a990225f32e0130c0884af (diff) |
drm/amdgpu: merge VM manager and VM context ID structure
No need to have two of them any more.
Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 139 |
2 files changed, 78 insertions, 78 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index b9a6fe9a2a31..c1b10046317e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -839,13 +839,6 @@ struct amdgpu_vm_pt { | |||
839 | uint64_t addr; | 839 | uint64_t addr; |
840 | }; | 840 | }; |
841 | 841 | ||
842 | struct amdgpu_vm_id { | ||
843 | struct amdgpu_vm_manager_id *mgr_id; | ||
844 | uint64_t pd_gpu_addr; | ||
845 | /* last flushed PD/PT update */ | ||
846 | struct fence *flushed_updates; | ||
847 | }; | ||
848 | |||
849 | struct amdgpu_vm { | 842 | struct amdgpu_vm { |
850 | /* tree of virtual addresses mapped */ | 843 | /* tree of virtual addresses mapped */ |
851 | struct rb_root va; | 844 | struct rb_root va; |
@@ -871,7 +864,7 @@ struct amdgpu_vm { | |||
871 | struct amdgpu_vm_pt *page_tables; | 864 | struct amdgpu_vm_pt *page_tables; |
872 | 865 | ||
873 | /* for id and flush management per ring */ | 866 | /* for id and flush management per ring */ |
874 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; | 867 | struct amdgpu_vm_id *ids[AMDGPU_MAX_RINGS]; |
875 | 868 | ||
876 | /* protecting freed */ | 869 | /* protecting freed */ |
877 | spinlock_t freed_lock; | 870 | spinlock_t freed_lock; |
@@ -880,11 +873,15 @@ struct amdgpu_vm { | |||
880 | struct amd_sched_entity entity; | 873 | struct amd_sched_entity entity; |
881 | }; | 874 | }; |
882 | 875 | ||
883 | struct amdgpu_vm_manager_id { | 876 | struct amdgpu_vm_id { |
884 | struct list_head list; | 877 | struct list_head list; |
885 | struct fence *active; | 878 | struct fence *active; |
886 | atomic_long_t owner; | 879 | atomic_long_t owner; |
887 | 880 | ||
881 | uint64_t pd_gpu_addr; | ||
882 | /* last flushed PD/PT update */ | ||
883 | struct fence *flushed_updates; | ||
884 | |||
888 | uint32_t gds_base; | 885 | uint32_t gds_base; |
889 | uint32_t gds_size; | 886 | uint32_t gds_size; |
890 | uint32_t gws_base; | 887 | uint32_t gws_base; |
@@ -898,7 +895,7 @@ struct amdgpu_vm_manager { | |||
898 | struct mutex lock; | 895 | struct mutex lock; |
899 | unsigned num_ids; | 896 | unsigned num_ids; |
900 | struct list_head ids_lru; | 897 | struct list_head ids_lru; |
901 | struct amdgpu_vm_manager_id ids[AMDGPU_NUM_VM]; | 898 | struct amdgpu_vm_id ids[AMDGPU_NUM_VM]; |
902 | 899 | ||
903 | uint32_t max_pfn; | 900 | uint32_t max_pfn; |
904 | /* vram base address for page table entry */ | 901 | /* vram base address for page table entry */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 0c92e0450694..8a758b4fb3a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -166,43 +166,41 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
166 | { | 166 | { |
167 | uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); | 167 | uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); |
168 | struct amdgpu_device *adev = ring->adev; | 168 | struct amdgpu_device *adev = ring->adev; |
169 | struct amdgpu_vm_id *id = &vm->ids[ring->idx]; | 169 | struct amdgpu_vm_id *id = vm->ids[ring->idx]; |
170 | struct fence *updates = sync->last_vm_update; | 170 | struct fence *updates = sync->last_vm_update; |
171 | int r; | 171 | int r; |
172 | 172 | ||
173 | mutex_lock(&adev->vm_manager.lock); | 173 | mutex_lock(&adev->vm_manager.lock); |
174 | 174 | ||
175 | /* check if the id is still valid */ | 175 | /* check if the id is still valid */ |
176 | if (id->mgr_id) { | 176 | if (id) { |
177 | struct fence *flushed = id->flushed_updates; | 177 | struct fence *flushed = id->flushed_updates; |
178 | bool is_later; | 178 | long owner = atomic_long_read(&id->owner); |
179 | long owner; | 179 | bool usable = pd_addr == id->pd_gpu_addr; |
180 | 180 | ||
181 | if (!flushed) | 181 | if (owner != (long)&vm->ids[ring->idx]) |
182 | is_later = true; | 182 | usable = false; |
183 | else if (!flushed) | ||
184 | usable = false; | ||
183 | else if (!updates) | 185 | else if (!updates) |
184 | is_later = false; | 186 | usable = true; |
185 | else | 187 | else |
186 | is_later = fence_is_later(updates, flushed); | 188 | usable = !fence_is_later(updates, flushed); |
187 | 189 | ||
188 | owner = atomic_long_read(&id->mgr_id->owner); | 190 | if (usable) { |
189 | if (!is_later && owner == (long)id && | ||
190 | pd_addr == id->pd_gpu_addr) { | ||
191 | 191 | ||
192 | r = amdgpu_sync_fence(ring->adev, sync, | 192 | r = amdgpu_sync_fence(ring->adev, sync, id->active); |
193 | id->mgr_id->active); | ||
194 | if (r) { | 193 | if (r) { |
195 | mutex_unlock(&adev->vm_manager.lock); | 194 | mutex_unlock(&adev->vm_manager.lock); |
196 | return r; | 195 | return r; |
197 | } | 196 | } |
198 | 197 | ||
199 | fence_put(id->mgr_id->active); | 198 | fence_put(id->active); |
200 | id->mgr_id->active = fence_get(fence); | 199 | id->active = fence_get(fence); |
201 | 200 | ||
202 | list_move_tail(&id->mgr_id->list, | 201 | list_move_tail(&id->list, &adev->vm_manager.ids_lru); |
203 | &adev->vm_manager.ids_lru); | ||
204 | 202 | ||
205 | *vm_id = id->mgr_id - adev->vm_manager.ids; | 203 | *vm_id = id - adev->vm_manager.ids; |
206 | *vm_pd_addr = AMDGPU_VM_NO_FLUSH; | 204 | *vm_pd_addr = AMDGPU_VM_NO_FLUSH; |
207 | trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, | 205 | trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, |
208 | *vm_pd_addr); | 206 | *vm_pd_addr); |
@@ -212,38 +210,41 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | |||
212 | } | 210 | } |
213 | } | 211 | } |
214 | 212 | ||
215 | id->mgr_id = list_first_entry(&adev->vm_manager.ids_lru, | 213 | id = list_first_entry(&adev->vm_manager.ids_lru, |
216 | struct amdgpu_vm_manager_id, | 214 | struct amdgpu_vm_id, |
217 | list); | 215 | list); |
218 | 216 | ||
219 | if (id->mgr_id->active && !fence_is_signaled(id->mgr_id->active)) { | 217 | if (id->active && !fence_is_signaled(id->active)) { |
220 | struct amdgpu_vm_manager_id *mgr_id, *tmp; | 218 | struct amdgpu_vm_id *tmp; |
221 | struct list_head *head = &adev->vm_manager.ids_lru; | 219 | struct list_head *head = &adev->vm_manager.ids_lru; |
222 | list_for_each_entry_safe(mgr_id, tmp, &adev->vm_manager.ids_lru, list) { | 220 | |
223 | if (mgr_id->active && fence_is_signaled(mgr_id->active)) { | 221 | list_for_each_entry_safe(id, tmp, &adev->vm_manager.ids_lru, |
224 | list_move(&mgr_id->list, head); | 222 | list) { |
225 | head = &mgr_id->list; | 223 | if (id->active && fence_is_signaled(id->active)) { |
224 | list_move(&id->list, head); | ||
225 | head = &id->list; | ||
226 | } | 226 | } |
227 | } | 227 | } |
228 | id->mgr_id = list_first_entry(&adev->vm_manager.ids_lru, | 228 | id = list_first_entry(&adev->vm_manager.ids_lru, |
229 | struct amdgpu_vm_manager_id, | 229 | struct amdgpu_vm_id, |
230 | list); | 230 | list); |
231 | } | 231 | } |
232 | 232 | ||
233 | r = amdgpu_sync_fence(ring->adev, sync, id->mgr_id->active); | 233 | r = amdgpu_sync_fence(ring->adev, sync, id->active); |
234 | if (!r) { | 234 | if (!r) { |
235 | fence_put(id->mgr_id->active); | 235 | fence_put(id->active); |
236 | id->mgr_id->active = fence_get(fence); | 236 | id->active = fence_get(fence); |
237 | 237 | ||
238 | fence_put(id->flushed_updates); | 238 | fence_put(id->flushed_updates); |
239 | id->flushed_updates = fence_get(updates); | 239 | id->flushed_updates = fence_get(updates); |
240 | 240 | ||
241 | id->pd_gpu_addr = pd_addr; | 241 | id->pd_gpu_addr = pd_addr; |
242 | 242 | ||
243 | list_move_tail(&id->mgr_id->list, &adev->vm_manager.ids_lru); | 243 | list_move_tail(&id->list, &adev->vm_manager.ids_lru); |
244 | atomic_long_set(&id->mgr_id->owner, (long)id); | 244 | atomic_long_set(&id->owner, (long)&vm->ids[ring->idx]); |
245 | vm->ids[ring->idx] = id; | ||
245 | 246 | ||
246 | *vm_id = id->mgr_id - adev->vm_manager.ids; | 247 | *vm_id = id - adev->vm_manager.ids; |
247 | *vm_pd_addr = pd_addr; | 248 | *vm_pd_addr = pd_addr; |
248 | trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, *vm_pd_addr); | 249 | trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, *vm_pd_addr); |
249 | } | 250 | } |
@@ -268,14 +269,14 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
268 | uint32_t oa_base, uint32_t oa_size) | 269 | uint32_t oa_base, uint32_t oa_size) |
269 | { | 270 | { |
270 | struct amdgpu_device *adev = ring->adev; | 271 | struct amdgpu_device *adev = ring->adev; |
271 | struct amdgpu_vm_manager_id *mgr_id = &adev->vm_manager.ids[vm_id]; | 272 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; |
272 | bool gds_switch_needed = ring->funcs->emit_gds_switch && ( | 273 | bool gds_switch_needed = ring->funcs->emit_gds_switch && ( |
273 | mgr_id->gds_base != gds_base || | 274 | id->gds_base != gds_base || |
274 | mgr_id->gds_size != gds_size || | 275 | id->gds_size != gds_size || |
275 | mgr_id->gws_base != gws_base || | 276 | id->gws_base != gws_base || |
276 | mgr_id->gws_size != gws_size || | 277 | id->gws_size != gws_size || |
277 | mgr_id->oa_base != oa_base || | 278 | id->oa_base != oa_base || |
278 | mgr_id->oa_size != oa_size); | 279 | id->oa_size != oa_size); |
279 | 280 | ||
280 | if (ring->funcs->emit_pipeline_sync && ( | 281 | if (ring->funcs->emit_pipeline_sync && ( |
281 | pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed)) | 282 | pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed)) |
@@ -287,12 +288,12 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
287 | } | 288 | } |
288 | 289 | ||
289 | if (gds_switch_needed) { | 290 | if (gds_switch_needed) { |
290 | mgr_id->gds_base = gds_base; | 291 | id->gds_base = gds_base; |
291 | mgr_id->gds_size = gds_size; | 292 | id->gds_size = gds_size; |
292 | mgr_id->gws_base = gws_base; | 293 | id->gws_base = gws_base; |
293 | mgr_id->gws_size = gws_size; | 294 | id->gws_size = gws_size; |
294 | mgr_id->oa_base = oa_base; | 295 | id->oa_base = oa_base; |
295 | mgr_id->oa_size = oa_size; | 296 | id->oa_size = oa_size; |
296 | amdgpu_ring_emit_gds_switch(ring, vm_id, | 297 | amdgpu_ring_emit_gds_switch(ring, vm_id, |
297 | gds_base, gds_size, | 298 | gds_base, gds_size, |
298 | gws_base, gws_size, | 299 | gws_base, gws_size, |
@@ -310,14 +311,14 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring, | |||
310 | */ | 311 | */ |
311 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id) | 312 | void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id) |
312 | { | 313 | { |
313 | struct amdgpu_vm_manager_id *mgr_id = &adev->vm_manager.ids[vm_id]; | 314 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[vm_id]; |
314 | 315 | ||
315 | mgr_id->gds_base = 0; | 316 | id->gds_base = 0; |
316 | mgr_id->gds_size = 0; | 317 | id->gds_size = 0; |
317 | mgr_id->gws_base = 0; | 318 | id->gws_base = 0; |
318 | mgr_id->gws_size = 0; | 319 | id->gws_size = 0; |
319 | mgr_id->oa_base = 0; | 320 | id->oa_base = 0; |
320 | mgr_id->oa_size = 0; | 321 | id->oa_size = 0; |
321 | } | 322 | } |
322 | 323 | ||
323 | /** | 324 | /** |
@@ -1345,10 +1346,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1345 | struct amd_sched_rq *rq; | 1346 | struct amd_sched_rq *rq; |
1346 | int i, r; | 1347 | int i, r; |
1347 | 1348 | ||
1348 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 1349 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) |
1349 | vm->ids[i].mgr_id = NULL; | 1350 | vm->ids[i] = NULL; |
1350 | vm->ids[i].flushed_updates = NULL; | ||
1351 | } | ||
1352 | vm->va = RB_ROOT; | 1351 | vm->va = RB_ROOT; |
1353 | spin_lock_init(&vm->status_lock); | 1352 | spin_lock_init(&vm->status_lock); |
1354 | INIT_LIST_HEAD(&vm->invalidated); | 1353 | INIT_LIST_HEAD(&vm->invalidated); |
@@ -1443,12 +1442,12 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1443 | fence_put(vm->page_directory_fence); | 1442 | fence_put(vm->page_directory_fence); |
1444 | 1443 | ||
1445 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { | 1444 | for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { |
1446 | struct amdgpu_vm_id *id = &vm->ids[i]; | 1445 | struct amdgpu_vm_id *id = vm->ids[i]; |
1447 | 1446 | ||
1448 | if (id->mgr_id) | 1447 | if (!id) |
1449 | atomic_long_cmpxchg(&id->mgr_id->owner, | 1448 | continue; |
1450 | (long)id, 0); | 1449 | |
1451 | fence_put(id->flushed_updates); | 1450 | atomic_long_cmpxchg(&id->owner, (long)&vm->ids[i], 0); |
1452 | } | 1451 | } |
1453 | } | 1452 | } |
1454 | 1453 | ||
@@ -1486,6 +1485,10 @@ void amdgpu_vm_manager_fini(struct amdgpu_device *adev) | |||
1486 | { | 1485 | { |
1487 | unsigned i; | 1486 | unsigned i; |
1488 | 1487 | ||
1489 | for (i = 0; i < AMDGPU_NUM_VM; ++i) | 1488 | for (i = 0; i < AMDGPU_NUM_VM; ++i) { |
1490 | fence_put(adev->vm_manager.ids[i].active); | 1489 | struct amdgpu_vm_id *id = &adev->vm_manager.ids[i]; |
1490 | |||
1491 | fence_put(id->active); | ||
1492 | fence_put(id->flushed_updates); | ||
1493 | } | ||
1491 | } | 1494 | } |