aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c42
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c27
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c21
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);
915void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, 915void 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);
918void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, 918int 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);
920void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, 921void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
921 struct amdgpu_vm *vm); 922 struct amdgpu_vm *vm);
922int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, 923int 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 */
390static bool amdgpu_cs_try_evict(struct amdgpu_cs_parser *p, 390static 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
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
442static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, 459static 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
472static 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 */
481static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, 491static 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
542int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, 547int 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 */
128void amdgpu_vm_get_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm, 128int 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/**