aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-03-30 21:47:18 -0400
committerDave Airlie <airlied@redhat.com>2017-03-30 21:47:18 -0400
commit8cd3ac52963f2e99f4c21d1c9ce89531ce66c2d6 (patch)
tree94f7d4526fe19a32643308d6e00d0fc5442af277 /drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
parent8bcad07a45637fb88e799466e4eee83859e8ffd3 (diff)
parent60508d3df2d2052881190ac82802a12cabcef53c (diff)
Merge branch 'drm-next-4.12' of git://people.freedesktop.org/~agd5f/linux into drm-next
New stuff for 4.12: - Preliminary vega10 support - Support for multi-level page tables - GPU sensor stuff for mesa - job tracing improvements - PRT support for sparse buffers - Additional SR-IOV improvements - ttm improvements - misc bug fixes and code cleanups * 'drm-next-4.12' of git://people.freedesktop.org/~agd5f/linux: (315 commits) drm/amdgpu: Fix 32bit x86 compilation warning drm/amdgpu: just disallow reading untouched registers drm/amdgpu: remove duplicate allowed reg CP_CPF_BUSY_STAT drm/amdgpu/soc15: enable psp block for SRIOV drm/amdgpu/soc15: bypass pp block for vf drm/amdgpu/psp: add check sOS sign drm/amd/amdgpu: Correct ring wptr address in debugfs (v2) drm/amdgpu: Fix multi-level page table bugs for large BOs v3 drm/amdgpu: Fix Vega10 VM initialization drm/amdgpu: Make max_pfn 64-bit drm/amdgpu: drop GB_GPU_ID from the golden settings drm/amdgpu: fix vm pte pde flags to 64-bit for sdma (v3) drm/amd/amdgpu: fix Tonga S3 resume hang on rhel6.8 drm/ttm: decrease ttm bo priority number drm/amd/amdgpu: fix performance drop when VRAM pressure drm/amdgpu: Couple small warning fixes drm/amdgpu: Clean up GFX 9 VM fault messages drm/amdgpu: Register UTCL2 as a source of VM faults drm/amdgpu/soc15: drop support for reading some registers drm/amdgpu/soc15: return cached values for some registers (v2) ...
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c122
1 files changed, 86 insertions, 36 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 106cf83c2e6b..f85520d4e711 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -152,6 +152,7 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
152 struct ttm_validate_buffer tv; 152 struct ttm_validate_buffer tv;
153 struct ww_acquire_ctx ticket; 153 struct ww_acquire_ctx ticket;
154 struct amdgpu_bo_va *bo_va; 154 struct amdgpu_bo_va *bo_va;
155 struct dma_fence *fence = NULL;
155 int r; 156 int r;
156 157
157 INIT_LIST_HEAD(&list); 158 INIT_LIST_HEAD(&list);
@@ -173,6 +174,17 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,
173 if (bo_va) { 174 if (bo_va) {
174 if (--bo_va->ref_count == 0) { 175 if (--bo_va->ref_count == 0) {
175 amdgpu_vm_bo_rmv(adev, bo_va); 176 amdgpu_vm_bo_rmv(adev, bo_va);
177
178 r = amdgpu_vm_clear_freed(adev, vm, &fence);
179 if (unlikely(r)) {
180 dev_err(adev->dev, "failed to clear page "
181 "tables on GEM object close (%d)\n", r);
182 }
183
184 if (fence) {
185 amdgpu_bo_fence(bo, fence, true);
186 dma_fence_put(fence);
187 }
176 } 188 }
177 } 189 }
178 ttm_eu_backoff_reservation(&ticket, &list); 190 ttm_eu_backoff_reservation(&ticket, &list);
@@ -507,14 +519,16 @@ static int amdgpu_gem_va_check(void *param, struct amdgpu_bo *bo)
507 * amdgpu_gem_va_update_vm -update the bo_va in its VM 519 * amdgpu_gem_va_update_vm -update the bo_va in its VM
508 * 520 *
509 * @adev: amdgpu_device pointer 521 * @adev: amdgpu_device pointer
522 * @vm: vm to update
510 * @bo_va: bo_va to update 523 * @bo_va: bo_va to update
511 * @list: validation list 524 * @list: validation list
512 * @operation: map or unmap 525 * @operation: map, unmap or clear
513 * 526 *
514 * Update the bo_va directly after setting its address. Errors are not 527 * Update the bo_va directly after setting its address. Errors are not
515 * vital here, so they are not reported back to userspace. 528 * vital here, so they are not reported back to userspace.
516 */ 529 */
517static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, 530static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
531 struct amdgpu_vm *vm,
518 struct amdgpu_bo_va *bo_va, 532 struct amdgpu_bo_va *bo_va,
519 struct list_head *list, 533 struct list_head *list,
520 uint32_t operation) 534 uint32_t operation)
@@ -529,20 +543,21 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
529 goto error; 543 goto error;
530 } 544 }
531 545
532 r = amdgpu_vm_validate_pt_bos(adev, bo_va->vm, amdgpu_gem_va_check, 546 r = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_gem_va_check,
533 NULL); 547 NULL);
534 if (r) 548 if (r)
535 goto error; 549 goto error;
536 550
537 r = amdgpu_vm_update_page_directory(adev, bo_va->vm); 551 r = amdgpu_vm_update_directories(adev, vm);
538 if (r) 552 if (r)
539 goto error; 553 goto error;
540 554
541 r = amdgpu_vm_clear_freed(adev, bo_va->vm); 555 r = amdgpu_vm_clear_freed(adev, vm, NULL);
542 if (r) 556 if (r)
543 goto error; 557 goto error;
544 558
545 if (operation == AMDGPU_VA_OP_MAP) 559 if (operation == AMDGPU_VA_OP_MAP ||
560 operation == AMDGPU_VA_OP_REPLACE)
546 r = amdgpu_vm_bo_update(adev, bo_va, false); 561 r = amdgpu_vm_bo_update(adev, bo_va, false);
547 562
548error: 563error:
@@ -553,6 +568,12 @@ error:
553int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, 568int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
554 struct drm_file *filp) 569 struct drm_file *filp)
555{ 570{
571 const uint32_t valid_flags = AMDGPU_VM_DELAY_UPDATE |
572 AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE |
573 AMDGPU_VM_PAGE_EXECUTABLE | AMDGPU_VM_MTYPE_MASK;
574 const uint32_t prt_flags = AMDGPU_VM_DELAY_UPDATE |
575 AMDGPU_VM_PAGE_PRT;
576
556 struct drm_amdgpu_gem_va *args = data; 577 struct drm_amdgpu_gem_va *args = data;
557 struct drm_gem_object *gobj; 578 struct drm_gem_object *gobj;
558 struct amdgpu_device *adev = dev->dev_private; 579 struct amdgpu_device *adev = dev->dev_private;
@@ -563,7 +584,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
563 struct ttm_validate_buffer tv; 584 struct ttm_validate_buffer tv;
564 struct ww_acquire_ctx ticket; 585 struct ww_acquire_ctx ticket;
565 struct list_head list; 586 struct list_head list;
566 uint32_t invalid_flags, va_flags = 0; 587 uint64_t va_flags;
567 int r = 0; 588 int r = 0;
568 589
569 if (!adev->vm_manager.enabled) 590 if (!adev->vm_manager.enabled)
@@ -577,17 +598,17 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
577 return -EINVAL; 598 return -EINVAL;
578 } 599 }
579 600
580 invalid_flags = ~(AMDGPU_VM_DELAY_UPDATE | AMDGPU_VM_PAGE_READABLE | 601 if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) {
581 AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_PAGE_EXECUTABLE); 602 dev_err(&dev->pdev->dev, "invalid flags combination 0x%08X\n",
582 if ((args->flags & invalid_flags)) { 603 args->flags);
583 dev_err(&dev->pdev->dev, "invalid flags 0x%08X vs 0x%08X\n",
584 args->flags, invalid_flags);
585 return -EINVAL; 604 return -EINVAL;
586 } 605 }
587 606
588 switch (args->operation) { 607 switch (args->operation) {
589 case AMDGPU_VA_OP_MAP: 608 case AMDGPU_VA_OP_MAP:
590 case AMDGPU_VA_OP_UNMAP: 609 case AMDGPU_VA_OP_UNMAP:
610 case AMDGPU_VA_OP_CLEAR:
611 case AMDGPU_VA_OP_REPLACE:
591 break; 612 break;
592 default: 613 default:
593 dev_err(&dev->pdev->dev, "unsupported operation %d\n", 614 dev_err(&dev->pdev->dev, "unsupported operation %d\n",
@@ -595,38 +616,47 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
595 return -EINVAL; 616 return -EINVAL;
596 } 617 }
597 618
598 gobj = drm_gem_object_lookup(filp, args->handle);
599 if (gobj == NULL)
600 return -ENOENT;
601 abo = gem_to_amdgpu_bo(gobj);
602 INIT_LIST_HEAD(&list); 619 INIT_LIST_HEAD(&list);
603 tv.bo = &abo->tbo; 620 if ((args->operation != AMDGPU_VA_OP_CLEAR) &&
604 tv.shared = false; 621 !(args->flags & AMDGPU_VM_PAGE_PRT)) {
605 list_add(&tv.head, &list); 622 gobj = drm_gem_object_lookup(filp, args->handle);
623 if (gobj == NULL)
624 return -ENOENT;
625 abo = gem_to_amdgpu_bo(gobj);
626 tv.bo = &abo->tbo;
627 tv.shared = false;
628 list_add(&tv.head, &list);
629 } else {
630 gobj = NULL;
631 abo = NULL;
632 }
606 633
607 amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd); 634 amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd);
608 635
609 r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); 636 r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
610 if (r) { 637 if (r)
611 drm_gem_object_unreference_unlocked(gobj); 638 goto error_unref;
612 return r;
613 }
614 639
615 bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo); 640 if (abo) {
616 if (!bo_va) { 641 bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo);
617 ttm_eu_backoff_reservation(&ticket, &list); 642 if (!bo_va) {
618 drm_gem_object_unreference_unlocked(gobj); 643 r = -ENOENT;
619 return -ENOENT; 644 goto error_backoff;
645 }
646 } else if (args->operation != AMDGPU_VA_OP_CLEAR) {
647 bo_va = fpriv->prt_va;
648 } else {
649 bo_va = NULL;
620 } 650 }
621 651
622 switch (args->operation) { 652 switch (args->operation) {
623 case AMDGPU_VA_OP_MAP: 653 case AMDGPU_VA_OP_MAP:
624 if (args->flags & AMDGPU_VM_PAGE_READABLE) 654 r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address,
625 va_flags |= AMDGPU_PTE_READABLE; 655 args->map_size);
626 if (args->flags & AMDGPU_VM_PAGE_WRITEABLE) 656 if (r)
627 va_flags |= AMDGPU_PTE_WRITEABLE; 657 goto error_backoff;
628 if (args->flags & AMDGPU_VM_PAGE_EXECUTABLE) 658
629 va_flags |= AMDGPU_PTE_EXECUTABLE; 659 va_flags = amdgpu_vm_get_pte_flags(adev, args->flags);
630 r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, 660 r = amdgpu_vm_bo_map(adev, bo_va, args->va_address,
631 args->offset_in_bo, args->map_size, 661 args->offset_in_bo, args->map_size,
632 va_flags); 662 va_flags);
@@ -634,14 +664,34 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
634 case AMDGPU_VA_OP_UNMAP: 664 case AMDGPU_VA_OP_UNMAP:
635 r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address); 665 r = amdgpu_vm_bo_unmap(adev, bo_va, args->va_address);
636 break; 666 break;
667
668 case AMDGPU_VA_OP_CLEAR:
669 r = amdgpu_vm_bo_clear_mappings(adev, &fpriv->vm,
670 args->va_address,
671 args->map_size);
672 break;
673 case AMDGPU_VA_OP_REPLACE:
674 r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address,
675 args->map_size);
676 if (r)
677 goto error_backoff;
678
679 va_flags = amdgpu_vm_get_pte_flags(adev, args->flags);
680 r = amdgpu_vm_bo_replace_map(adev, bo_va, args->va_address,
681 args->offset_in_bo, args->map_size,
682 va_flags);
683 break;
637 default: 684 default:
638 break; 685 break;
639 } 686 }
640 if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && 687 if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && !amdgpu_vm_debug)
641 !amdgpu_vm_debug) 688 amdgpu_gem_va_update_vm(adev, &fpriv->vm, bo_va, &list,
642 amdgpu_gem_va_update_vm(adev, bo_va, &list, args->operation); 689 args->operation);
690
691error_backoff:
643 ttm_eu_backoff_reservation(&ticket, &list); 692 ttm_eu_backoff_reservation(&ticket, &list);
644 693
694error_unref:
645 drm_gem_object_unreference_unlocked(gobj); 695 drm_gem_object_unreference_unlocked(gobj);
646 return r; 696 return r;
647} 697}