aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunwei Zhang <Jerry.Zhang@amd.com>2017-01-16 00:59:01 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-03-29 23:52:56 -0400
commitb85891bd6d1bf887b3398f4c44b7a30b37f4485e (patch)
treecdc0d0f596927a2c869866bcbfd29007e5ce44d1
parent284710fa6c3a5fddbc0f8c6b3a07861a312c18d2 (diff)
drm/amdgpu: IOCTL interface for PRT support v4
Till GFX8 we can only enable PRT support globally, but with the next hardware generation we can do this on a per page basis. Keep the interface consistent by adding PRT mappings and enable support globally on current hardware when the first mapping is made. v2: disable PRT support delayed and on all error paths v3: PRT and other permissions are mutal exclusive, PRT mappings don't need a BO. v4: update PRT mappings durign CS as well, make va_flags 64bit Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c16
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c62
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c10
-rw-r--r--include/uapi/drm/amdgpu_drm.h2
5 files changed, 64 insertions, 27 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 618f12884eed..b9212537b17d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -701,6 +701,7 @@ void amdgpu_ctx_mgr_fini(struct amdgpu_ctx_mgr *mgr);
701 701
702struct amdgpu_fpriv { 702struct amdgpu_fpriv {
703 struct amdgpu_vm vm; 703 struct amdgpu_vm vm;
704 struct amdgpu_bo_va *prt_va;
704 struct mutex bo_list_lock; 705 struct mutex bo_list_lock;
705 struct idr bo_list_handles; 706 struct idr bo_list_handles;
706 struct amdgpu_ctx_mgr ctx_mgr; 707 struct amdgpu_ctx_mgr ctx_mgr;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 99424cb8020b..89dcb07ab213 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -759,10 +759,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
759 amdgpu_bo_unref(&parser->uf_entry.robj); 759 amdgpu_bo_unref(&parser->uf_entry.robj);
760} 760}
761 761
762static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, 762static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p)
763 struct amdgpu_vm *vm)
764{ 763{
765 struct amdgpu_device *adev = p->adev; 764 struct amdgpu_device *adev = p->adev;
765 struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
766 struct amdgpu_vm *vm = &fpriv->vm;
766 struct amdgpu_bo_va *bo_va; 767 struct amdgpu_bo_va *bo_va;
767 struct amdgpu_bo *bo; 768 struct amdgpu_bo *bo;
768 int i, r; 769 int i, r;
@@ -779,6 +780,15 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
779 if (r) 780 if (r)
780 return r; 781 return r;
781 782
783 r = amdgpu_vm_bo_update(adev, fpriv->prt_va, false);
784 if (r)
785 return r;
786
787 r = amdgpu_sync_fence(adev, &p->job->sync,
788 fpriv->prt_va->last_pt_update);
789 if (r)
790 return r;
791
782 if (amdgpu_sriov_vf(adev)) { 792 if (amdgpu_sriov_vf(adev)) {
783 struct dma_fence *f; 793 struct dma_fence *f;
784 bo_va = vm->csa_bo_va; 794 bo_va = vm->csa_bo_va;
@@ -855,7 +865,7 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
855 if (p->job->vm) { 865 if (p->job->vm) {
856 p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); 866 p->job->vm_pd_addr = amdgpu_bo_gpu_offset(vm->page_directory);
857 867
858 r = amdgpu_bo_vm_update_pte(p, vm); 868 r = amdgpu_bo_vm_update_pte(p);
859 if (r) 869 if (r)
860 return r; 870 return r;
861 } 871 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index 106cf83c2e6b..3c22656aa1bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -553,6 +553,12 @@ error:
553int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, 553int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
554 struct drm_file *filp) 554 struct drm_file *filp)
555{ 555{
556 const uint32_t valid_flags = AMDGPU_VM_DELAY_UPDATE |
557 AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE |
558 AMDGPU_VM_PAGE_EXECUTABLE;
559 const uint32_t prt_flags = AMDGPU_VM_DELAY_UPDATE |
560 AMDGPU_VM_PAGE_PRT;
561
556 struct drm_amdgpu_gem_va *args = data; 562 struct drm_amdgpu_gem_va *args = data;
557 struct drm_gem_object *gobj; 563 struct drm_gem_object *gobj;
558 struct amdgpu_device *adev = dev->dev_private; 564 struct amdgpu_device *adev = dev->dev_private;
@@ -563,7 +569,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
563 struct ttm_validate_buffer tv; 569 struct ttm_validate_buffer tv;
564 struct ww_acquire_ctx ticket; 570 struct ww_acquire_ctx ticket;
565 struct list_head list; 571 struct list_head list;
566 uint32_t invalid_flags, va_flags = 0; 572 uint64_t va_flags = 0;
567 int r = 0; 573 int r = 0;
568 574
569 if (!adev->vm_manager.enabled) 575 if (!adev->vm_manager.enabled)
@@ -577,11 +583,9 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
577 return -EINVAL; 583 return -EINVAL;
578 } 584 }
579 585
580 invalid_flags = ~(AMDGPU_VM_DELAY_UPDATE | AMDGPU_VM_PAGE_READABLE | 586 if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) {
581 AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_PAGE_EXECUTABLE); 587 dev_err(&dev->pdev->dev, "invalid flags combination 0x%08X\n",
582 if ((args->flags & invalid_flags)) { 588 args->flags);
583 dev_err(&dev->pdev->dev, "invalid flags 0x%08X vs 0x%08X\n",
584 args->flags, invalid_flags);
585 return -EINVAL; 589 return -EINVAL;
586 } 590 }
587 591
@@ -595,28 +599,34 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
595 return -EINVAL; 599 return -EINVAL;
596 } 600 }
597 601
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); 602 INIT_LIST_HEAD(&list);
603 tv.bo = &abo->tbo; 603 if (!(args->flags & AMDGPU_VM_PAGE_PRT)) {
604 tv.shared = false; 604 gobj = drm_gem_object_lookup(filp, args->handle);
605 list_add(&tv.head, &list); 605 if (gobj == NULL)
606 return -ENOENT;
607 abo = gem_to_amdgpu_bo(gobj);
608 tv.bo = &abo->tbo;
609 tv.shared = false;
610 list_add(&tv.head, &list);
611 } else {
612 gobj = NULL;
613 abo = NULL;
614 }
606 615
607 amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd); 616 amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd);
608 617
609 r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); 618 r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
610 if (r) { 619 if (r)
611 drm_gem_object_unreference_unlocked(gobj); 620 goto error_unref;
612 return r;
613 }
614 621
615 bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo); 622 if (abo) {
616 if (!bo_va) { 623 bo_va = amdgpu_vm_bo_find(&fpriv->vm, abo);
617 ttm_eu_backoff_reservation(&ticket, &list); 624 if (!bo_va) {
618 drm_gem_object_unreference_unlocked(gobj); 625 r = -ENOENT;
619 return -ENOENT; 626 goto error_backoff;
627 }
628 } else {
629 bo_va = fpriv->prt_va;
620 } 630 }
621 631
622 switch (args->operation) { 632 switch (args->operation) {
@@ -627,6 +637,8 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
627 va_flags |= AMDGPU_PTE_WRITEABLE; 637 va_flags |= AMDGPU_PTE_WRITEABLE;
628 if (args->flags & AMDGPU_VM_PAGE_EXECUTABLE) 638 if (args->flags & AMDGPU_VM_PAGE_EXECUTABLE)
629 va_flags |= AMDGPU_PTE_EXECUTABLE; 639 va_flags |= AMDGPU_PTE_EXECUTABLE;
640 if (args->flags & AMDGPU_VM_PAGE_PRT)
641 va_flags |= AMDGPU_PTE_PRT;
630 r = amdgpu_vm_bo_map(adev, bo_va, args->va_address, 642 r = amdgpu_vm_bo_map(adev, bo_va, args->va_address,
631 args->offset_in_bo, args->map_size, 643 args->offset_in_bo, args->map_size,
632 va_flags); 644 va_flags);
@@ -637,11 +649,13 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
637 default: 649 default:
638 break; 650 break;
639 } 651 }
640 if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && 652 if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) && !amdgpu_vm_debug)
641 !amdgpu_vm_debug)
642 amdgpu_gem_va_update_vm(adev, bo_va, &list, args->operation); 653 amdgpu_gem_va_update_vm(adev, bo_va, &list, args->operation);
654
655error_backoff:
643 ttm_eu_backoff_reservation(&ticket, &list); 656 ttm_eu_backoff_reservation(&ticket, &list);
644 657
658error_unref:
645 drm_gem_object_unreference_unlocked(gobj); 659 drm_gem_object_unreference_unlocked(gobj);
646 return r; 660 return r;
647} 661}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 61d94c745672..49f93ee019e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -655,6 +655,14 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
655 goto out_suspend; 655 goto out_suspend;
656 } 656 }
657 657
658 fpriv->prt_va = amdgpu_vm_bo_add(adev, &fpriv->vm, NULL);
659 if (!fpriv->prt_va) {
660 r = -ENOMEM;
661 amdgpu_vm_fini(adev, &fpriv->vm);
662 kfree(fpriv);
663 goto out_suspend;
664 }
665
658 if (amdgpu_sriov_vf(adev)) { 666 if (amdgpu_sriov_vf(adev)) {
659 r = amdgpu_map_static_csa(adev, &fpriv->vm); 667 r = amdgpu_map_static_csa(adev, &fpriv->vm);
660 if (r) 668 if (r)
@@ -699,6 +707,8 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
699 amdgpu_uvd_free_handles(adev, file_priv); 707 amdgpu_uvd_free_handles(adev, file_priv);
700 amdgpu_vce_free_handles(adev, file_priv); 708 amdgpu_vce_free_handles(adev, file_priv);
701 709
710 amdgpu_vm_bo_rmv(adev, fpriv->prt_va);
711
702 if (amdgpu_sriov_vf(adev)) { 712 if (amdgpu_sriov_vf(adev)) {
703 /* TODO: how to handle reserve failure */ 713 /* TODO: how to handle reserve failure */
704 BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, false)); 714 BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, false));
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 5797283c2d79..1c0ddf71193e 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -361,6 +361,8 @@ struct drm_amdgpu_gem_op {
361#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2) 361#define AMDGPU_VM_PAGE_WRITEABLE (1 << 2)
362/* executable mapping, new for VI */ 362/* executable mapping, new for VI */
363#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3) 363#define AMDGPU_VM_PAGE_EXECUTABLE (1 << 3)
364/* partially resident texture */
365#define AMDGPU_VM_PAGE_PRT (1 << 4)
364 366
365struct drm_amdgpu_gem_va { 367struct drm_amdgpu_gem_va {
366 /** GEM object handle */ 368 /** GEM object handle */