diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 74 |
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, | |||
355 | static int amdgpu_cs_bo_validate(struct amdgpu_cs_parser *p, | 355 | static 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 | ||
373 | retry: | 374 | retry: |
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 */ |
389 | static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p, | 390 | static 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 | ||
442 | static 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 | |||
440 | static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, | 459 | static 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; |