aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-03-08 09:40:11 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-05-04 20:19:13 -0400
commitbcb1ba35a87be34d1312f6e050f1b5cc4d32f096 (patch)
treea06cb56e8d388d33e8162b06d0320475e5caef29 /drivers/gpu
parentbd4c72d1e9dd7efdb9a990225f32e0130c0884af (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.h17
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c139
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
842struct 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
849struct amdgpu_vm { 842struct 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
883struct amdgpu_vm_manager_id { 876struct 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 */
311void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id) 312void 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}