diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_object.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 71 |
1 files changed, 44 insertions, 27 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index aa074fac0c7f..6efa8d73b394 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
@@ -88,18 +88,19 @@ static void amdgpu_update_memory_usage(struct amdgpu_device *adev, | |||
88 | 88 | ||
89 | static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) | 89 | static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) |
90 | { | 90 | { |
91 | struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev); | ||
91 | struct amdgpu_bo *bo; | 92 | struct amdgpu_bo *bo; |
92 | 93 | ||
93 | bo = container_of(tbo, struct amdgpu_bo, tbo); | 94 | bo = container_of(tbo, struct amdgpu_bo, tbo); |
94 | 95 | ||
95 | amdgpu_update_memory_usage(bo->adev, &bo->tbo.mem, NULL); | 96 | amdgpu_update_memory_usage(adev, &bo->tbo.mem, NULL); |
96 | 97 | ||
97 | drm_gem_object_release(&bo->gem_base); | 98 | drm_gem_object_release(&bo->gem_base); |
98 | amdgpu_bo_unref(&bo->parent); | 99 | amdgpu_bo_unref(&bo->parent); |
99 | if (!list_empty(&bo->shadow_list)) { | 100 | if (!list_empty(&bo->shadow_list)) { |
100 | mutex_lock(&bo->adev->shadow_list_lock); | 101 | mutex_lock(&adev->shadow_list_lock); |
101 | list_del_init(&bo->shadow_list); | 102 | list_del_init(&bo->shadow_list); |
102 | mutex_unlock(&bo->adev->shadow_list_lock); | 103 | mutex_unlock(&adev->shadow_list_lock); |
103 | } | 104 | } |
104 | kfree(bo->metadata); | 105 | kfree(bo->metadata); |
105 | kfree(bo); | 106 | kfree(bo); |
@@ -121,12 +122,17 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, | |||
121 | 122 | ||
122 | if (domain & AMDGPU_GEM_DOMAIN_VRAM) { | 123 | if (domain & AMDGPU_GEM_DOMAIN_VRAM) { |
123 | unsigned visible_pfn = adev->mc.visible_vram_size >> PAGE_SHIFT; | 124 | unsigned visible_pfn = adev->mc.visible_vram_size >> PAGE_SHIFT; |
125 | unsigned lpfn = 0; | ||
126 | |||
127 | /* This forces a reallocation if the flag wasn't set before */ | ||
128 | if (flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) | ||
129 | lpfn = adev->mc.real_vram_size >> PAGE_SHIFT; | ||
124 | 130 | ||
125 | if (flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS && | 131 | if (flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS && |
126 | !(flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && | 132 | !(flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && |
127 | adev->mc.visible_vram_size < adev->mc.real_vram_size) { | 133 | adev->mc.visible_vram_size < adev->mc.real_vram_size) { |
128 | places[c].fpfn = visible_pfn; | 134 | places[c].fpfn = visible_pfn; |
129 | places[c].lpfn = 0; | 135 | places[c].lpfn = lpfn; |
130 | places[c].flags = TTM_PL_FLAG_WC | | 136 | places[c].flags = TTM_PL_FLAG_WC | |
131 | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM | | 137 | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM | |
132 | TTM_PL_FLAG_TOPDOWN; | 138 | TTM_PL_FLAG_TOPDOWN; |
@@ -134,7 +140,7 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, | |||
134 | } | 140 | } |
135 | 141 | ||
136 | places[c].fpfn = 0; | 142 | places[c].fpfn = 0; |
137 | places[c].lpfn = 0; | 143 | places[c].lpfn = lpfn; |
138 | places[c].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | | 144 | places[c].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | |
139 | TTM_PL_FLAG_VRAM; | 145 | TTM_PL_FLAG_VRAM; |
140 | if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) | 146 | if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) |
@@ -205,8 +211,10 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, | |||
205 | 211 | ||
206 | void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain) | 212 | void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain) |
207 | { | 213 | { |
208 | amdgpu_ttm_placement_init(abo->adev, &abo->placement, | 214 | struct amdgpu_device *adev = amdgpu_ttm_adev(abo->tbo.bdev); |
209 | abo->placements, domain, abo->flags); | 215 | |
216 | amdgpu_ttm_placement_init(adev, &abo->placement, abo->placements, | ||
217 | domain, abo->flags); | ||
210 | } | 218 | } |
211 | 219 | ||
212 | static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo, | 220 | static void amdgpu_fill_placement_to_bo(struct amdgpu_bo *bo, |
@@ -245,7 +253,8 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev, | |||
245 | int r; | 253 | int r; |
246 | 254 | ||
247 | r = amdgpu_bo_create(adev, size, align, true, domain, | 255 | r = amdgpu_bo_create(adev, size, align, true, domain, |
248 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, | 256 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | |
257 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, | ||
249 | NULL, NULL, bo_ptr); | 258 | NULL, NULL, bo_ptr); |
250 | if (r) { | 259 | if (r) { |
251 | dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r); | 260 | dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r); |
@@ -351,7 +360,6 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, | |||
351 | kfree(bo); | 360 | kfree(bo); |
352 | return r; | 361 | return r; |
353 | } | 362 | } |
354 | bo->adev = adev; | ||
355 | INIT_LIST_HEAD(&bo->shadow_list); | 363 | INIT_LIST_HEAD(&bo->shadow_list); |
356 | INIT_LIST_HEAD(&bo->va); | 364 | INIT_LIST_HEAD(&bo->va); |
357 | bo->prefered_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM | | 365 | bo->prefered_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM | |
@@ -616,6 +624,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, | |||
616 | u64 min_offset, u64 max_offset, | 624 | u64 min_offset, u64 max_offset, |
617 | u64 *gpu_addr) | 625 | u64 *gpu_addr) |
618 | { | 626 | { |
627 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); | ||
619 | int r, i; | 628 | int r, i; |
620 | unsigned fpfn, lpfn; | 629 | unsigned fpfn, lpfn; |
621 | 630 | ||
@@ -643,18 +652,20 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, | |||
643 | 652 | ||
644 | return 0; | 653 | return 0; |
645 | } | 654 | } |
655 | |||
656 | bo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; | ||
646 | amdgpu_ttm_placement_from_domain(bo, domain); | 657 | amdgpu_ttm_placement_from_domain(bo, domain); |
647 | for (i = 0; i < bo->placement.num_placement; i++) { | 658 | for (i = 0; i < bo->placement.num_placement; i++) { |
648 | /* force to pin into visible video ram */ | 659 | /* force to pin into visible video ram */ |
649 | if ((bo->placements[i].flags & TTM_PL_FLAG_VRAM) && | 660 | if ((bo->placements[i].flags & TTM_PL_FLAG_VRAM) && |
650 | !(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) && | 661 | !(bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) && |
651 | (!max_offset || max_offset > | 662 | (!max_offset || max_offset > |
652 | bo->adev->mc.visible_vram_size)) { | 663 | adev->mc.visible_vram_size)) { |
653 | if (WARN_ON_ONCE(min_offset > | 664 | if (WARN_ON_ONCE(min_offset > |
654 | bo->adev->mc.visible_vram_size)) | 665 | adev->mc.visible_vram_size)) |
655 | return -EINVAL; | 666 | return -EINVAL; |
656 | fpfn = min_offset >> PAGE_SHIFT; | 667 | fpfn = min_offset >> PAGE_SHIFT; |
657 | lpfn = bo->adev->mc.visible_vram_size >> PAGE_SHIFT; | 668 | lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; |
658 | } else { | 669 | } else { |
659 | fpfn = min_offset >> PAGE_SHIFT; | 670 | fpfn = min_offset >> PAGE_SHIFT; |
660 | lpfn = max_offset >> PAGE_SHIFT; | 671 | lpfn = max_offset >> PAGE_SHIFT; |
@@ -669,12 +680,12 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, | |||
669 | 680 | ||
670 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); | 681 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); |
671 | if (unlikely(r)) { | 682 | if (unlikely(r)) { |
672 | dev_err(bo->adev->dev, "%p pin failed\n", bo); | 683 | dev_err(adev->dev, "%p pin failed\n", bo); |
673 | goto error; | 684 | goto error; |
674 | } | 685 | } |
675 | r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem); | 686 | r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem); |
676 | if (unlikely(r)) { | 687 | if (unlikely(r)) { |
677 | dev_err(bo->adev->dev, "%p bind failed\n", bo); | 688 | dev_err(adev->dev, "%p bind failed\n", bo); |
678 | goto error; | 689 | goto error; |
679 | } | 690 | } |
680 | 691 | ||
@@ -682,11 +693,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, | |||
682 | if (gpu_addr != NULL) | 693 | if (gpu_addr != NULL) |
683 | *gpu_addr = amdgpu_bo_gpu_offset(bo); | 694 | *gpu_addr = amdgpu_bo_gpu_offset(bo); |
684 | if (domain == AMDGPU_GEM_DOMAIN_VRAM) { | 695 | if (domain == AMDGPU_GEM_DOMAIN_VRAM) { |
685 | bo->adev->vram_pin_size += amdgpu_bo_size(bo); | 696 | adev->vram_pin_size += amdgpu_bo_size(bo); |
686 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) | 697 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) |
687 | bo->adev->invisible_pin_size += amdgpu_bo_size(bo); | 698 | adev->invisible_pin_size += amdgpu_bo_size(bo); |
688 | } else if (domain == AMDGPU_GEM_DOMAIN_GTT) { | 699 | } else if (domain == AMDGPU_GEM_DOMAIN_GTT) { |
689 | bo->adev->gart_pin_size += amdgpu_bo_size(bo); | 700 | adev->gart_pin_size += amdgpu_bo_size(bo); |
690 | } | 701 | } |
691 | 702 | ||
692 | error: | 703 | error: |
@@ -700,10 +711,11 @@ int amdgpu_bo_pin(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr) | |||
700 | 711 | ||
701 | int amdgpu_bo_unpin(struct amdgpu_bo *bo) | 712 | int amdgpu_bo_unpin(struct amdgpu_bo *bo) |
702 | { | 713 | { |
714 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); | ||
703 | int r, i; | 715 | int r, i; |
704 | 716 | ||
705 | if (!bo->pin_count) { | 717 | if (!bo->pin_count) { |
706 | dev_warn(bo->adev->dev, "%p unpin not necessary\n", bo); | 718 | dev_warn(adev->dev, "%p unpin not necessary\n", bo); |
707 | return 0; | 719 | return 0; |
708 | } | 720 | } |
709 | bo->pin_count--; | 721 | bo->pin_count--; |
@@ -715,16 +727,16 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo) | |||
715 | } | 727 | } |
716 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); | 728 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); |
717 | if (unlikely(r)) { | 729 | if (unlikely(r)) { |
718 | dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo); | 730 | dev_err(adev->dev, "%p validate failed for unpin\n", bo); |
719 | goto error; | 731 | goto error; |
720 | } | 732 | } |
721 | 733 | ||
722 | if (bo->tbo.mem.mem_type == TTM_PL_VRAM) { | 734 | if (bo->tbo.mem.mem_type == TTM_PL_VRAM) { |
723 | bo->adev->vram_pin_size -= amdgpu_bo_size(bo); | 735 | adev->vram_pin_size -= amdgpu_bo_size(bo); |
724 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) | 736 | if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) |
725 | bo->adev->invisible_pin_size -= amdgpu_bo_size(bo); | 737 | adev->invisible_pin_size -= amdgpu_bo_size(bo); |
726 | } else if (bo->tbo.mem.mem_type == TTM_PL_TT) { | 738 | } else if (bo->tbo.mem.mem_type == TTM_PL_TT) { |
727 | bo->adev->gart_pin_size -= amdgpu_bo_size(bo); | 739 | adev->gart_pin_size -= amdgpu_bo_size(bo); |
728 | } | 740 | } |
729 | 741 | ||
730 | error: | 742 | error: |
@@ -849,6 +861,7 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, | |||
849 | void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, | 861 | void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, |
850 | struct ttm_mem_reg *new_mem) | 862 | struct ttm_mem_reg *new_mem) |
851 | { | 863 | { |
864 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); | ||
852 | struct amdgpu_bo *abo; | 865 | struct amdgpu_bo *abo; |
853 | struct ttm_mem_reg *old_mem = &bo->mem; | 866 | struct ttm_mem_reg *old_mem = &bo->mem; |
854 | 867 | ||
@@ -856,21 +869,21 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, | |||
856 | return; | 869 | return; |
857 | 870 | ||
858 | abo = container_of(bo, struct amdgpu_bo, tbo); | 871 | abo = container_of(bo, struct amdgpu_bo, tbo); |
859 | amdgpu_vm_bo_invalidate(abo->adev, abo); | 872 | amdgpu_vm_bo_invalidate(adev, abo); |
860 | 873 | ||
861 | /* update statistics */ | 874 | /* update statistics */ |
862 | if (!new_mem) | 875 | if (!new_mem) |
863 | return; | 876 | return; |
864 | 877 | ||
865 | /* move_notify is called before move happens */ | 878 | /* move_notify is called before move happens */ |
866 | amdgpu_update_memory_usage(abo->adev, &bo->mem, new_mem); | 879 | amdgpu_update_memory_usage(adev, &bo->mem, new_mem); |
867 | 880 | ||
868 | trace_amdgpu_ttm_bo_move(abo, new_mem->mem_type, old_mem->mem_type); | 881 | trace_amdgpu_ttm_bo_move(abo, new_mem->mem_type, old_mem->mem_type); |
869 | } | 882 | } |
870 | 883 | ||
871 | int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) | 884 | int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) |
872 | { | 885 | { |
873 | struct amdgpu_device *adev; | 886 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); |
874 | struct amdgpu_bo *abo; | 887 | struct amdgpu_bo *abo; |
875 | unsigned long offset, size, lpfn; | 888 | unsigned long offset, size, lpfn; |
876 | int i, r; | 889 | int i, r; |
@@ -879,13 +892,14 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) | |||
879 | return 0; | 892 | return 0; |
880 | 893 | ||
881 | abo = container_of(bo, struct amdgpu_bo, tbo); | 894 | abo = container_of(bo, struct amdgpu_bo, tbo); |
882 | adev = abo->adev; | ||
883 | if (bo->mem.mem_type != TTM_PL_VRAM) | 895 | if (bo->mem.mem_type != TTM_PL_VRAM) |
884 | return 0; | 896 | return 0; |
885 | 897 | ||
886 | size = bo->mem.num_pages << PAGE_SHIFT; | 898 | size = bo->mem.num_pages << PAGE_SHIFT; |
887 | offset = bo->mem.start << PAGE_SHIFT; | 899 | offset = bo->mem.start << PAGE_SHIFT; |
888 | if ((offset + size) <= adev->mc.visible_vram_size) | 900 | /* TODO: figure out how to map scattered VRAM to the CPU */ |
901 | if ((offset + size) <= adev->mc.visible_vram_size && | ||
902 | (abo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) | ||
889 | return 0; | 903 | return 0; |
890 | 904 | ||
891 | /* Can't move a pinned BO to visible VRAM */ | 905 | /* Can't move a pinned BO to visible VRAM */ |
@@ -893,6 +907,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) | |||
893 | return -EINVAL; | 907 | return -EINVAL; |
894 | 908 | ||
895 | /* hurrah the memory is not visible ! */ | 909 | /* hurrah the memory is not visible ! */ |
910 | abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; | ||
896 | amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM); | 911 | amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM); |
897 | lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; | 912 | lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; |
898 | for (i = 0; i < abo->placement.num_placement; i++) { | 913 | for (i = 0; i < abo->placement.num_placement; i++) { |
@@ -954,6 +969,8 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) | |||
954 | WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) && | 969 | WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) && |
955 | !bo->pin_count); | 970 | !bo->pin_count); |
956 | WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); | 971 | WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); |
972 | WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM && | ||
973 | !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)); | ||
957 | 974 | ||
958 | return bo->tbo.offset; | 975 | return bo->tbo.offset; |
959 | } | 976 | } |