diff options
-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 | /** |