aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c74
1 files changed, 50 insertions, 24 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index b0f6e6957536..cf03f9f01f40 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -355,6 +355,7 @@ static void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev,
355static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p, 355static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
356 struct amdgpu_bo *bo) 356 struct amdgpu_bo *bo)
357{ 357{
358 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
358 u64 initial_bytes_moved; 359 u64 initial_bytes_moved;
359 uint32_t domain; 360 uint32_t domain;
360 int r; 361 int r;
@@ -372,9 +373,9 @@ static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p,
372 373
373retry: 374retry:
374 amdgpu_ttm_placement_from_domain(bo, domain); 375 amdgpu_ttm_placement_from_domain(bo, domain);
375 initial_bytes_moved = atomic64_read(&bo->adev->num_bytes_moved); 376 initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
376 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); 377 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
377 p->bytes_moved += atomic64_read(&bo->adev->num_bytes_moved) - 378 p->bytes_moved += atomic64_read(&adev->num_bytes_moved) -
378 initial_bytes_moved; 379 initial_bytes_moved;
379 380
380 if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) { 381 if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
@@ -387,9 +388,9 @@ retry:
387 388
388/* Last resort, try to evict something from the current working set */ 389/* Last resort, try to evict something from the current working set */
389static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p, 390static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
390 struct amdgpu_bo_list_entry *lobj) 391 struct amdgpu_bo *validated)
391{ 392{
392 uint32_t domain = lobj->robj->allowed_domains; 393 uint32_t domain = validated->allowed_domains;
393 int r; 394 int r;
394 395
395 if (!p->evictable) 396 if (!p->evictable)
@@ -400,11 +401,12 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
400 401
401 struct amdgpu_bo_list_entry *candidate = p->evictable; 402 struct amdgpu_bo_list_entry *candidate = p->evictable;
402 struct amdgpu_bo *bo = candidate->robj; 403 struct amdgpu_bo *bo = candidate->robj;
404 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
403 u64 initial_bytes_moved; 405 u64 initial_bytes_moved;
404 uint32_t other; 406 uint32_t other;
405 407
406 /* If we reached our current BO we can forget it */ 408 /* If we reached our current BO we can forget it */
407 if (candidate == lobj) 409 if (candidate->robj == validated)
408 break; 410 break;
409 411
410 other = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); 412 other = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);
@@ -420,9 +422,9 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
420 422
421 /* Good we can try to move this BO somewhere else */ 423 /* Good we can try to move this BO somewhere else */
422 amdgpu_ttm_placement_from_domain(bo, other); 424 amdgpu_ttm_placement_from_domain(bo, other);
423 initial_bytes_moved = atomic64_read(&bo->adev->num_bytes_moved); 425 initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
424 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); 426 r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false);
425 p->bytes_moved += atomic64_read(&bo->adev->num_bytes_moved) - 427 p->bytes_moved += atomic64_read(&adev->num_bytes_moved) -
426 initial_bytes_moved; 428 initial_bytes_moved;
427 429
428 if (unlikely(r)) 430 if (unlikely(r))
@@ -437,6 +439,23 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p,
437 return false; 439 return false;
438} 440}
439 441
442static int amdgpu_cs_validate(void *param, struct amdgpu_bo *bo)
443{
444 struct amdgpu_cs_parser *p = param;
445 int r;
446
447 do {
448 r = amdgpu_cs_bo_validate(p, bo);
449 } while (r == -ENOMEM && amdgpu_cs_try_evict(p, bo));
450 if (r)
451 return r;
452
453 if (bo->shadow)
454 r = amdgpu_cs_bo_validate(p, bo);
455
456 return r;
457}
458
440static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, 459static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
441 struct list_head *validated) 460 struct list_head *validated)
442{ 461{
@@ -464,18 +483,10 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
464 if (p->evictable == lobj) 483 if (p->evictable == lobj)
465 p->evictable = NULL; 484 p->evictable = NULL;
466 485
467 do { 486 r = amdgpu_cs_validate(p, bo);
468 r = amdgpu_cs_bo_validate(p, bo);
469 } while (r == -ENOMEM && amdgpu_cs_try_evict(p, lobj));
470 if (r) 487 if (r)
471 return r; 488 return r;
472 489
473 if (bo->shadow) {
474 r = amdgpu_cs_bo_validate(p, bo);
475 if (r)
476 return r;
477 }
478
479 if (binding_userptr) { 490 if (binding_userptr) {
480 drm_free_large(lobj->user_pages); 491 drm_free_large(lobj->user_pages);
481 lobj->user_pages = NULL; 492 lobj->user_pages = NULL;
@@ -593,14 +604,19 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
593 list_splice(&need_pages, &p->validated); 604 list_splice(&need_pages, &p->validated);
594 } 605 }
595 606
596 amdgpu_vm_get_pt_bos(p->adev, &fpriv->vm, &duplicates);
597
598 p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev); 607 p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev);
599 p->bytes_moved = 0; 608 p->bytes_moved = 0;
600 p->evictable = list_last_entry(&p->validated, 609 p->evictable = list_last_entry(&p->validated,
601 struct amdgpu_bo_list_entry, 610 struct amdgpu_bo_list_entry,
602 tv.head); 611 tv.head);
603 612
613 r = amdgpu_vm_validate_pt_bos(p->adev, &fpriv->vm,
614 amdgpu_cs_validate, p);
615 if (r) {
616 DRM_ERROR("amdgpu_vm_validate_pt_bos() failed.\n");
617 goto error_validate;
618 }
619
604 r = amdgpu_cs_list_validate(p, &duplicates); 620 r = amdgpu_cs_list_validate(p, &duplicates);
605 if (r) { 621 if (r) {
606 DRM_ERROR("amdgpu_cs_list_validate(duplicates) failed.\n"); 622 DRM_ERROR("amdgpu_cs_list_validate(duplicates) failed.\n");
@@ -806,13 +822,14 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
806 822
807 /* Only for UVD/VCE VM emulation */ 823 /* Only for UVD/VCE VM emulation */
808 if (ring->funcs->parse_cs) { 824 if (ring->funcs->parse_cs) {
809 p->job->vm = NULL;
810 for (i = 0; i < p->job->num_ibs; i++) { 825 for (i = 0; i < p->job->num_ibs; i++) {
811 r = amdgpu_ring_parse_cs(ring, p, i); 826 r = amdgpu_ring_parse_cs(ring, p, i);
812 if (r) 827 if (r)
813 return r; 828 return r;
814 } 829 }
815 } else { 830 }
831
832 if (p->job->vm) {
816 p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); 833 p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->page_directory);
817 834
818 r = amdgpu_bo_vm_update_pte(p, vm); 835 r = amdgpu_bo_vm_update_pte(p, vm);
@@ -901,7 +918,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
901 offset = ((uint64_t)m->it.start) * AMDGPU_GPU_PAGE_SIZE; 918 offset = ((uint64_t)m->it.start) * AMDGPU_GPU_PAGE_SIZE;
902 kptr += chunk_ib->va_start - offset; 919 kptr += chunk_ib->va_start - offset;
903 920
904 r = amdgpu_ib_get(adev, NULL, chunk_ib->ib_bytes, ib); 921 r = amdgpu_ib_get(adev, vm, chunk_ib->ib_bytes, ib);
905 if (r) { 922 if (r) {
906 DRM_ERROR("Failed to get ib !\n"); 923 DRM_ERROR("Failed to get ib !\n");
907 return r; 924 return r;
@@ -916,9 +933,9 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
916 return r; 933 return r;
917 } 934 }
918 935
919 ib->gpu_addr = chunk_ib->va_start;
920 } 936 }
921 937
938 ib->gpu_addr = chunk_ib->va_start;
922 ib->length_dw = chunk_ib->ib_bytes / 4; 939 ib->length_dw = chunk_ib->ib_bytes / 4;
923 ib->flags = chunk_ib->flags; 940 ib->flags = chunk_ib->flags;
924 j++; 941 j++;
@@ -926,8 +943,8 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
926 943
927 /* UVD & VCE fw doesn't support user fences */ 944 /* UVD & VCE fw doesn't support user fences */
928 if (parser->job->uf_addr && ( 945 if (parser->job->uf_addr && (
929 parser->job->ring->type == AMDGPU_RING_TYPE_UVD || 946 parser->job->ring->funcs->type == AMDGPU_RING_TYPE_UVD ||
930 parser->job->ring->type == AMDGPU_RING_TYPE_VCE)) 947 parser->job->ring->funcs->type == AMDGPU_RING_TYPE_VCE))
931 return -EINVAL; 948 return -EINVAL;
932 949
933 return 0; 950 return 0;
@@ -1195,6 +1212,15 @@ int amdgpu_cs_sysvm_access_required(struct amdgpu_cs_parser *parser)
1195 r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem); 1212 r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem);
1196 if (unlikely(r)) 1213 if (unlikely(r))
1197 return r; 1214 return r;
1215
1216 if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)
1217 continue;
1218
1219 bo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1220 amdgpu_ttm_placement_from_domain(bo, bo->allowed_domains);
1221 r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
1222 if (unlikely(r))
1223 return r;
1198 } 1224 }
1199 1225
1200 return 0; 1226 return 0;