aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-09-01 06:13:18 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-09-02 11:30:41 -0400
commit662bfa61fff1de4dd96029d556d7b301e27c3556 (patch)
tree8881927927e64ad51de168d749dcfcec8f140e1f /drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
parent1abdc3d73dd9dc2f3dc619d466d378e70cbcc24a (diff)
drm/amdgpu: prevent command submission failures under memory pressure v2
As last resort try to evict BOs from the current working set into other memory domains. This effectively prevents command submission failures when VM page tables have been swapped out. v2: fix typos Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index d7a957376a90..e29e7b9ca3a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -379,6 +379,58 @@ retry:
379 return r; 379 return r;
380} 380}
381 381
382/* Last resort, try to evict something from the current working set */
383static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
384 struct amdgpu_bo_list_entry *lobj)
385{
386 uint32_t domain = lobj->robj->allowed_domains;
387 int r;
388
389 if (!p->evictable)
390 return false;
391
392 for (;&p->evictable->tv.head != &p->validated;
393 p->evictable = list_prev_entry(p->evictable, tv.head)) {
394
395 struct amdgpu_bo_list_entry *candidate = p->evictable;
396 struct amdgpu_bo *bo = candidate->robj;
397 u64 initial_bytes_moved;
398 uint32_t other;
399
400 /* If we reached our current BO we can forget it */
401 if (candidate == lobj)
402 break;
403
404 other = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
405
406 /* Check if this BO is in one of the domains we need space for */
407 if (!(other & domain))
408 continue;
409
410 /* Check if we can move this BO somewhere else */
411 other = bo->allowed_domains & ~domain;
412 if (!other)
413 continue;
414
415 /* Good we can try to move this BO somewhere else */
416 amdgpu_ttm_placement_from_domain(bo, other);
417 initial_bytes_moved = atomic64_read(&bo->adev->num_bytes_moved);
418 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
419 p->bytes_moved += atomic64_read(&bo->adev->num_bytes_moved) -
420 initial_bytes_moved;
421
422 if (unlikely(r))
423 break;
424
425 p->evictable = list_prev_entry(p->evictable, tv.head);
426 list_move(&candidate->tv.head, &p->validated);
427
428 return true;
429 }
430
431 return false;
432}
433
382int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, 434int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
383 struct list_head *validated) 435 struct list_head *validated)
384{ 436{
@@ -403,9 +455,15 @@ int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
403 binding_userptr = true; 455 binding_userptr = true;
404 } 456 }
405 457
406 r = amdgpu_cs_bo_validate(p, bo); 458 if (p->evictable == lobj)
459 p->evictable = NULL;
460
461 do {
462 r = amdgpu_cs_bo_validate(p, bo);
463 } while (r == -ENOMEM && amdgpu_cs_try_evict(p, lobj));
407 if (r) 464 if (r)
408 return r; 465 return r;
466
409 if (bo->shadow) { 467 if (bo->shadow) {
410 r = amdgpu_cs_bo_validate(p, bo); 468 r = amdgpu_cs_bo_validate(p, bo);
411 if (r) 469 if (r)
@@ -533,6 +591,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
533 591
534 p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev); 592 p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev);
535 p->bytes_moved = 0; 593 p->bytes_moved = 0;
594 p->evictable = list_last_entry(&p->validated,
595 struct amdgpu_bo_list_entry,
596 tv.head);
536 597
537 r = amdgpu_cs_list_validate(p, &duplicates); 598 r = amdgpu_cs_list_validate(p, &duplicates);
538 if (r) { 599 if (r) {