diff options
author | Christian König <christian.koenig@amd.com> | 2016-09-05 11:00:57 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-09-14 15:10:30 -0400 |
commit | c855e25090cdafffb87119028eb018030a46dd9e (patch) | |
tree | 237c294ebfb71d5971e60f15cda0c007dd46d30b /drivers/gpu/drm/amd/amdgpu | |
parent | 71c76a086f04055e2da8d7d71c77e0b37ac310a2 (diff) |
drm/amdgpu: bind GTT on demand
We don't really need the GTT table any more most of the time. So bind it
only on demand.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 3 |
8 files changed, 84 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 717c3b4e1d54..2e8f469159c5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -2521,6 +2521,7 @@ static inline void amdgpu_acpi_fini(struct amdgpu_device *adev) { } | |||
2521 | struct amdgpu_bo_va_mapping * | 2521 | struct amdgpu_bo_va_mapping * |
2522 | amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, | 2522 | amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, |
2523 | uint64_t addr, struct amdgpu_bo **bo); | 2523 | uint64_t addr, struct amdgpu_bo **bo); |
2524 | int amdgpu_cs_sysvm_access_required(struct amdgpu_cs_parser *parser); | ||
2524 | 2525 | ||
2525 | #include "amdgpu_object.h" | 2526 | #include "amdgpu_object.h" |
2526 | #endif | 2527 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 61b7e25535bf..f7dccb10d965 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -639,8 +639,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
639 | } | 639 | } |
640 | } | 640 | } |
641 | 641 | ||
642 | if (p->uf_entry.robj) | 642 | if (!r && p->uf_entry.robj) { |
643 | p->job->uf_addr += amdgpu_bo_gpu_offset(p->uf_entry.robj); | 643 | struct amdgpu_bo *uf = p->uf_entry.robj; |
644 | |||
645 | r = amdgpu_ttm_bind(uf->tbo.ttm, &uf->tbo.mem); | ||
646 | p->job->uf_addr += amdgpu_bo_gpu_offset(uf); | ||
647 | } | ||
644 | 648 | ||
645 | error_validate: | 649 | error_validate: |
646 | if (r) { | 650 | if (r) { |
@@ -1163,3 +1167,29 @@ amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, | |||
1163 | 1167 | ||
1164 | return NULL; | 1168 | return NULL; |
1165 | } | 1169 | } |
1170 | |||
1171 | /** | ||
1172 | * amdgpu_cs_sysvm_access_required - make BOs accessible by the system VM | ||
1173 | * | ||
1174 | * @parser: command submission parser context | ||
1175 | * | ||
1176 | * Helper for UVD/VCE VM emulation, make sure BOs are accessible by the system VM. | ||
1177 | */ | ||
1178 | int amdgpu_cs_sysvm_access_required(struct amdgpu_cs_parser *parser) | ||
1179 | { | ||
1180 | unsigned i; | ||
1181 | int r; | ||
1182 | |||
1183 | if (!parser->bo_list) | ||
1184 | return 0; | ||
1185 | |||
1186 | for (i = 0; i < parser->bo_list->num_entries; i++) { | ||
1187 | struct amdgpu_bo *bo = parser->bo_list->array[i].robj; | ||
1188 | |||
1189 | r = amdgpu_ttm_bind(bo->tbo.ttm, &bo->tbo.mem); | ||
1190 | if (unlikely(r)) | ||
1191 | return r; | ||
1192 | } | ||
1193 | |||
1194 | return 0; | ||
1195 | } | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 162411bd8145..5a6216c9c007 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
@@ -675,6 +675,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, | |||
675 | dev_err(bo->adev->dev, "%p pin failed\n", bo); | 675 | dev_err(bo->adev->dev, "%p pin failed\n", bo); |
676 | goto error; | 676 | goto error; |
677 | } | 677 | } |
678 | r = amdgpu_ttm_bind(bo->tbo.ttm, &bo->tbo.mem); | ||
679 | if (unlikely(r)) { | ||
680 | dev_err(bo->adev->dev, "%p bind failed\n", bo); | ||
681 | goto error; | ||
682 | } | ||
678 | 683 | ||
679 | bo->pin_count = 1; | 684 | bo->pin_count = 1; |
680 | if (gpu_addr != NULL) | 685 | if (gpu_addr != NULL) |
@@ -947,6 +952,8 @@ void amdgpu_bo_fence(struct amdgpu_bo *bo, struct fence *fence, | |||
947 | u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) | 952 | u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) |
948 | { | 953 | { |
949 | WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM); | 954 | WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_SYSTEM); |
955 | WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_TT && | ||
956 | !amdgpu_ttm_is_bound(bo->tbo.ttm)); | ||
950 | WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) && | 957 | WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) && |
951 | !bo->pin_count); | 958 | !bo->pin_count); |
952 | 959 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index a4914b788517..73298fadd7f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -256,8 +256,12 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, | |||
256 | new_start = new_mem->start << PAGE_SHIFT; | 256 | new_start = new_mem->start << PAGE_SHIFT; |
257 | 257 | ||
258 | switch (old_mem->mem_type) { | 258 | switch (old_mem->mem_type) { |
259 | case TTM_PL_VRAM: | ||
260 | case TTM_PL_TT: | 259 | case TTM_PL_TT: |
260 | r = amdgpu_ttm_bind(bo->ttm, old_mem); | ||
261 | if (r) | ||
262 | return r; | ||
263 | |||
264 | case TTM_PL_VRAM: | ||
261 | old_start += bo->bdev->man[old_mem->mem_type].gpu_offset; | 265 | old_start += bo->bdev->man[old_mem->mem_type].gpu_offset; |
262 | break; | 266 | break; |
263 | default: | 267 | default: |
@@ -265,8 +269,12 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo, | |||
265 | return -EINVAL; | 269 | return -EINVAL; |
266 | } | 270 | } |
267 | switch (new_mem->mem_type) { | 271 | switch (new_mem->mem_type) { |
268 | case TTM_PL_VRAM: | ||
269 | case TTM_PL_TT: | 272 | case TTM_PL_TT: |
273 | r = amdgpu_ttm_bind(bo->ttm, new_mem); | ||
274 | if (r) | ||
275 | return r; | ||
276 | |||
277 | case TTM_PL_VRAM: | ||
270 | new_start += bo->bdev->man[new_mem->mem_type].gpu_offset; | 278 | new_start += bo->bdev->man[new_mem->mem_type].gpu_offset; |
271 | break; | 279 | break; |
272 | default: | 280 | default: |
@@ -638,7 +646,6 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, | |||
638 | struct ttm_mem_reg *bo_mem) | 646 | struct ttm_mem_reg *bo_mem) |
639 | { | 647 | { |
640 | struct amdgpu_ttm_tt *gtt = (void*)ttm; | 648 | struct amdgpu_ttm_tt *gtt = (void*)ttm; |
641 | uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem); | ||
642 | int r; | 649 | int r; |
643 | 650 | ||
644 | if (gtt->userptr) { | 651 | if (gtt->userptr) { |
@@ -659,6 +666,26 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, | |||
659 | bo_mem->mem_type == AMDGPU_PL_OA) | 666 | bo_mem->mem_type == AMDGPU_PL_OA) |
660 | return -EINVAL; | 667 | return -EINVAL; |
661 | 668 | ||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | bool amdgpu_ttm_is_bound(struct ttm_tt *ttm) | ||
673 | { | ||
674 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | ||
675 | |||
676 | return gtt && !list_empty(>t->list); | ||
677 | } | ||
678 | |||
679 | int amdgpu_ttm_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) | ||
680 | { | ||
681 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | ||
682 | uint32_t flags; | ||
683 | int r; | ||
684 | |||
685 | if (!ttm || amdgpu_ttm_is_bound(ttm)) | ||
686 | return 0; | ||
687 | |||
688 | flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem); | ||
662 | r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages, | 689 | r = amdgpu_gart_bind(gtt->adev, gtt->offset, ttm->num_pages, |
663 | ttm->pages, gtt->ttm.dma_address, flags); | 690 | ttm->pages, gtt->ttm.dma_address, flags); |
664 | 691 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 72f6bfc15d8f..214bae965fc6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | |||
@@ -77,4 +77,7 @@ int amdgpu_fill_buffer(struct amdgpu_bo *bo, | |||
77 | struct fence **fence); | 77 | struct fence **fence); |
78 | 78 | ||
79 | int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma); | 79 | int amdgpu_mmap(struct file *filp, struct vm_area_struct *vma); |
80 | bool amdgpu_ttm_is_bound(struct ttm_tt *ttm); | ||
81 | int amdgpu_ttm_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem); | ||
82 | |||
80 | #endif | 83 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index a71efeb5083b..25dd58a65905 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | |||
@@ -882,6 +882,10 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx) | |||
882 | return -EINVAL; | 882 | return -EINVAL; |
883 | } | 883 | } |
884 | 884 | ||
885 | r = amdgpu_cs_sysvm_access_required(parser); | ||
886 | if (r) | ||
887 | return r; | ||
888 | |||
885 | ctx.parser = parser; | 889 | ctx.parser = parser; |
886 | ctx.buf_sizes = buf_sizes; | 890 | ctx.buf_sizes = buf_sizes; |
887 | ctx.ib_idx = ib_idx; | 891 | ctx.ib_idx = ib_idx; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 9b71d6c2a968..b0c670294e2f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | |||
@@ -634,7 +634,11 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) | |||
634 | uint32_t allocated = 0; | 634 | uint32_t allocated = 0; |
635 | uint32_t tmp, handle = 0; | 635 | uint32_t tmp, handle = 0; |
636 | uint32_t *size = &tmp; | 636 | uint32_t *size = &tmp; |
637 | int i, r = 0, idx = 0; | 637 | int i, r, idx = 0; |
638 | |||
639 | r = amdgpu_cs_sysvm_access_required(p); | ||
640 | if (r) | ||
641 | return r; | ||
638 | 642 | ||
639 | while (idx < ib->length_dw) { | 643 | while (idx < ib->length_dw) { |
640 | uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); | 644 | uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index bf56f1814437..bd5af328154f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -1163,7 +1163,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, | |||
1163 | } | 1163 | } |
1164 | 1164 | ||
1165 | flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem); | 1165 | flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem); |
1166 | gtt_flags = (adev == bo_va->bo->adev) ? flags : 0; | 1166 | gtt_flags = (amdgpu_ttm_is_bound(bo_va->bo->tbo.ttm) && |
1167 | adev == bo_va->bo->adev) ? flags : 0; | ||
1167 | 1168 | ||
1168 | spin_lock(&vm->status_lock); | 1169 | spin_lock(&vm->status_lock); |
1169 | if (!list_empty(&bo_va->vm_status)) | 1170 | if (!list_empty(&bo_va->vm_status)) |