diff options
Diffstat (limited to 'drivers/gpu/drm/amd')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 42 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 21 |
4 files changed, 60 insertions, 35 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 1c874fd525a0..848e4ed7e32a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -915,8 +915,9 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); | |||
| 915 | void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, | 915 | void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, |
| 916 | struct list_head *validated, | 916 | struct list_head *validated, |
| 917 | struct amdgpu_bo_list_entry *entry); | 917 | struct amdgpu_bo_list_entry *entry); |
| 918 | void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 918 | int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
| 919 | struct list_head *duplicates); | 919 | int (*callback)(void *p, struct amdgpu_bo *bo), |
| 920 | void *param); | ||
| 920 | void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, | 921 | void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, |
| 921 | struct amdgpu_vm *vm); | 922 | struct amdgpu_vm *vm); |
| 922 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | 923 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 504ae09d3991..a13e551e67cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
| @@ -388,9 +388,9 @@ retry: | |||
| 388 | 388 | ||
| 389 | /* Last resort, try to evict something from the current working set */ | 389 | /* Last resort, try to evict something from the current working set */ |
| 390 | static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p, | 390 | static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p, |
| 391 | struct amdgpu_bo_list_entry *lobj) | 391 | struct amdgpu_bo *validated) |
| 392 | { | 392 | { |
| 393 | uint32_t domain = lobj->robj->allowed_domains; | 393 | uint32_t domain = validated->allowed_domains; |
| 394 | int r; | 394 | int r; |
| 395 | 395 | ||
| 396 | if (!p->evictable) | 396 | if (!p->evictable) |
| @@ -406,7 +406,7 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p, | |||
| 406 | uint32_t other; | 406 | uint32_t other; |
| 407 | 407 | ||
| 408 | /* If we reached our current BO we can forget it */ | 408 | /* If we reached our current BO we can forget it */ |
| 409 | if (candidate == lobj) | 409 | if (candidate->robj == validated) |
| 410 | break; | 410 | break; |
| 411 | 411 | ||
| 412 | other = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); | 412 | other = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); |
| @@ -439,6 +439,23 @@ static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p, | |||
| 439 | return false; | 439 | return false; |
| 440 | } | 440 | } |
| 441 | 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 | |||
| 442 | static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, | 459 | static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, |
| 443 | struct list_head *validated) | 460 | struct list_head *validated) |
| 444 | { | 461 | { |
| @@ -466,18 +483,10 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, | |||
| 466 | if (p->evictable == lobj) | 483 | if (p->evictable == lobj) |
| 467 | p->evictable = NULL; | 484 | p->evictable = NULL; |
| 468 | 485 | ||
| 469 | do { | 486 | r = amdgpu_cs_validate(p, bo); |
| 470 | r = amdgpu_cs_bo_validate(p, bo); | ||
| 471 | } while (r == -ENOMEM && amdgpu_cs_try_evict(p, lobj)); | ||
| 472 | if (r) | 487 | if (r) |
| 473 | return r; | 488 | return r; |
| 474 | 489 | ||
| 475 | if (bo->shadow) { | ||
| 476 | r = amdgpu_cs_bo_validate(p, bo); | ||
| 477 | if (r) | ||
| 478 | return r; | ||
| 479 | } | ||
| 480 | |||
| 481 | if (binding_userptr) { | 490 | if (binding_userptr) { |
| 482 | drm_free_large(lobj->user_pages); | 491 | drm_free_large(lobj->user_pages); |
| 483 | lobj->user_pages = NULL; | 492 | lobj->user_pages = NULL; |
| @@ -595,14 +604,19 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
| 595 | list_splice(&need_pages, &p->validated); | 604 | list_splice(&need_pages, &p->validated); |
| 596 | } | 605 | } |
| 597 | 606 | ||
| 598 | amdgpu_vm_get_pt_bos(p->adev, &fpriv->vm, &duplicates); | ||
| 599 | |||
| 600 | 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); |
| 601 | p->bytes_moved = 0; | 608 | p->bytes_moved = 0; |
| 602 | p->evictable = list_last_entry(&p->validated, | 609 | p->evictable = list_last_entry(&p->validated, |
| 603 | struct amdgpu_bo_list_entry, | 610 | struct amdgpu_bo_list_entry, |
| 604 | tv.head); | 611 | tv.head); |
| 605 | 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 | |||
| 606 | r = amdgpu_cs_list_validate(p, &duplicates); | 620 | r = amdgpu_cs_list_validate(p, &duplicates); |
| 607 | if (r) { | 621 | if (r) { |
| 608 | DRM_ERROR("amdgpu_cs_list_validate(duplicates) failed.\n"); | 622 | DRM_ERROR("amdgpu_cs_list_validate(duplicates) failed.\n"); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index d4fce326502b..5dc0158b12db 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |||
| @@ -469,6 +469,16 @@ out: | |||
| 469 | return r; | 469 | return r; |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | static int amdgpu_gem_va_check(void *param, struct amdgpu_bo *bo) | ||
| 473 | { | ||
| 474 | unsigned domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); | ||
| 475 | |||
| 476 | /* if anything is swapped out don't swap it in here, | ||
| 477 | just abort and wait for the next CS */ | ||
| 478 | |||
| 479 | return domain == AMDGPU_GEM_DOMAIN_CPU ? -ERESTARTSYS : 0; | ||
| 480 | } | ||
| 481 | |||
| 472 | /** | 482 | /** |
| 473 | * amdgpu_gem_va_update_vm -update the bo_va in its VM | 483 | * amdgpu_gem_va_update_vm -update the bo_va in its VM |
| 474 | * | 484 | * |
| @@ -479,7 +489,8 @@ out: | |||
| 479 | * vital here, so they are not reported back to userspace. | 489 | * vital here, so they are not reported back to userspace. |
| 480 | */ | 490 | */ |
| 481 | static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | 491 | static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, |
| 482 | struct amdgpu_bo_va *bo_va, uint32_t operation) | 492 | struct amdgpu_bo_va *bo_va, |
| 493 | uint32_t operation) | ||
| 483 | { | 494 | { |
| 484 | struct ttm_validate_buffer tv, *entry; | 495 | struct ttm_validate_buffer tv, *entry; |
| 485 | struct amdgpu_bo_list_entry vm_pd; | 496 | struct amdgpu_bo_list_entry vm_pd; |
| @@ -502,7 +513,6 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | |||
| 502 | if (r) | 513 | if (r) |
| 503 | goto error_print; | 514 | goto error_print; |
| 504 | 515 | ||
| 505 | amdgpu_vm_get_pt_bos(adev, bo_va->vm, &duplicates); | ||
| 506 | list_for_each_entry(entry, &list, head) { | 516 | list_for_each_entry(entry, &list, head) { |
| 507 | domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); | 517 | domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); |
| 508 | /* if anything is swapped out don't swap it in here, | 518 | /* if anything is swapped out don't swap it in here, |
| @@ -510,13 +520,10 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | |||
| 510 | if (domain == AMDGPU_GEM_DOMAIN_CPU) | 520 | if (domain == AMDGPU_GEM_DOMAIN_CPU) |
| 511 | goto error_unreserve; | 521 | goto error_unreserve; |
| 512 | } | 522 | } |
| 513 | list_for_each_entry(entry, &duplicates, head) { | 523 | r = amdgpu_vm_validate_pt_bos(adev, bo_va->vm, amdgpu_gem_va_check, |
| 514 | domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); | 524 | NULL); |
| 515 | /* if anything is swapped out don't swap it in here, | 525 | if (r) |
| 516 | just abort and wait for the next CS */ | 526 | goto error_unreserve; |
| 517 | if (domain == AMDGPU_GEM_DOMAIN_CPU) | ||
| 518 | goto error_unreserve; | ||
| 519 | } | ||
| 520 | 527 | ||
| 521 | r = amdgpu_vm_update_page_directory(adev, bo_va->vm); | 528 | r = amdgpu_vm_update_page_directory(adev, bo_va->vm); |
| 522 | if (r) | 529 | if (r) |
| @@ -537,8 +544,6 @@ error_print: | |||
| 537 | DRM_ERROR("Couldn't update BO_VA (%d)\n", r); | 544 | DRM_ERROR("Couldn't update BO_VA (%d)\n", r); |
| 538 | } | 545 | } |
| 539 | 546 | ||
| 540 | |||
| 541 | |||
| 542 | int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | 547 | int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, |
| 543 | struct drm_file *filp) | 548 | struct drm_file *filp) |
| 544 | { | 549 | { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index f4b78b66444d..c171b16cf0f1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
| @@ -116,27 +116,29 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, | |||
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | /** | 118 | /** |
| 119 | * amdgpu_vm_get_bos - add the vm BOs to a duplicates list | 119 | * amdgpu_vm_validate_pt_bos - validate the page table BOs |
| 120 | * | 120 | * |
| 121 | * @adev: amdgpu device pointer | 121 | * @adev: amdgpu device pointer |
| 122 | * @vm: vm providing the BOs | 122 | * @vm: vm providing the BOs |
| 123 | * @duplicates: head of duplicates list | 123 | * @validate: callback to do the validation |
| 124 | * @param: parameter for the validation callback | ||
| 124 | * | 125 | * |
| 125 | * Add the page directory to the BO duplicates list | 126 | * Validate the page table BOs on command submission if neccessary. |
| 126 | * for command submission. | ||
| 127 | */ | 127 | */ |
| 128 | void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | 128 | int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
| 129 | struct list_head *duplicates) | 129 | int (*validate)(void *p, struct amdgpu_bo *bo), |
| 130 | void *param) | ||
| 130 | { | 131 | { |
| 131 | uint64_t num_evictions; | 132 | uint64_t num_evictions; |
| 132 | unsigned i; | 133 | unsigned i; |
| 134 | int r; | ||
| 133 | 135 | ||
| 134 | /* We only need to validate the page tables | 136 | /* We only need to validate the page tables |
| 135 | * if they aren't already valid. | 137 | * if they aren't already valid. |
| 136 | */ | 138 | */ |
| 137 | num_evictions = atomic64_read(&adev->num_evictions); | 139 | num_evictions = atomic64_read(&adev->num_evictions); |
| 138 | if (num_evictions == vm->last_eviction_counter) | 140 | if (num_evictions == vm->last_eviction_counter) |
| 139 | return; | 141 | return 0; |
| 140 | 142 | ||
| 141 | /* add the vm page table to the list */ | 143 | /* add the vm page table to the list */ |
| 142 | for (i = 0; i <= vm->max_pde_used; ++i) { | 144 | for (i = 0; i <= vm->max_pde_used; ++i) { |
| @@ -145,9 +147,12 @@ void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, | |||
| 145 | if (!entry->robj) | 147 | if (!entry->robj) |
| 146 | continue; | 148 | continue; |
| 147 | 149 | ||
| 148 | list_add(&entry->tv.head, duplicates); | 150 | r = validate(param, entry->robj); |
| 151 | if (r) | ||
| 152 | return r; | ||
| 149 | } | 153 | } |
| 150 | 154 | ||
| 155 | return 0; | ||
| 151 | } | 156 | } |
| 152 | 157 | ||
| 153 | /** | 158 | /** |
