* [PATCH 1/6] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS flag v3 @ 2016-09-15 10:12 Christian König [not found] ` <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 0 siblings, 1 reply; 10+ messages in thread From: Christian König @ 2016-09-15 10:12 UTC (permalink / raw) To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW From: Christian König <christian.koenig@amd.com> Add a flag noting that a BO must be created using linear VRAM and set this flag on all in kernel users where appropriate. Hopefully I haven't missed anything. v2: add it in a few more places, fix CPU mapping. v3: rename to VRAM_CONTIGUOUS, fix typo in CS code. Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 6 ++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 9 +++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 12 ++++++++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 6 ++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 ++++-- drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 9 ++++++--- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 6 ++++-- include/uapi/drm/amdgpu_drm.h | 2 ++ 13 files changed, 53 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index f1c53a2..79a3b98 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -146,7 +146,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, switch(type) { case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB: case CGS_GPU_MEM_TYPE__VISIBLE_FB: - flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; + flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; domain = AMDGPU_GEM_DOMAIN_VRAM; if (max_offset > adev->mc.real_vram_size) return -EINVAL; @@ -157,7 +158,8 @@ static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, break; case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB: case CGS_GPU_MEM_TYPE__INVISIBLE_FB: - flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS; + flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; domain = AMDGPU_GEM_DOMAIN_VRAM; if (adev->mc.visible_vram_size < adev->mc.real_vram_size) { place.fpfn = diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index b0f6e69..187c366 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -1195,6 +1195,15 @@ int amdgpu_cs_sysvm_access_required(struct amdgpu_cs_parser *parser) r = amdgpu_ttm_bind(&bo->tbo, &bo->tbo.mem); if (unlikely(r)) return r; + + if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) + continue; + + bo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; + amdgpu_ttm_placement_from_domain(bo, bo->allowed_domains); + r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); + if (unlikely(r)) + return r; } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 9103e7b..5686d12 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -264,7 +264,8 @@ static int amdgpu_vram_scratch_init(struct amdgpu_device *adev) if (adev->vram_scratch.robj == NULL) { r = amdgpu_bo_create(adev, AMDGPU_GPU_PAGE_SIZE, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->vram_scratch.robj); if (r) { return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index 10e0211..95a4cdd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -148,7 +148,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, aligned_size = ALIGN(size, PAGE_SIZE); ret = amdgpu_gem_object_create(adev, aligned_size, 0, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, true, &gobj); if (ret) { printk(KERN_ERR "failed to allocate framebuffer (%d)\n", diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 0feea34..234cce4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -126,7 +126,8 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) if (adev->gart.robj == NULL) { r = amdgpu_bo_create(adev, adev->gart.table_size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->gart.robj); if (r) { return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 691707b..3bddc68 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -247,7 +247,8 @@ int amdgpu_bo_create_kernel(struct amdgpu_device *adev, int r; r = amdgpu_bo_create(adev, size, align, true, domain, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, bo_ptr); if (r) { dev_err(adev->dev, "(%d) failed to allocate kernel bo\n", r); @@ -646,6 +647,8 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, return 0; } + + bo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; amdgpu_ttm_placement_from_domain(bo, domain); for (i = 0; i < bo->placement.num_placement; i++) { /* force to pin into visible video ram */ @@ -888,7 +891,9 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) size = bo->mem.num_pages << PAGE_SHIFT; offset = bo->mem.start << PAGE_SHIFT; - if ((offset + size) <= adev->mc.visible_vram_size) + /* TODO: figure out how to map scattered VRAM to the CPU */ + if ((offset + size) <= adev->mc.visible_vram_size && + (abo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) return 0; /* Can't move a pinned BO to visible VRAM */ @@ -896,6 +901,7 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) return -EINVAL; /* hurrah the memory is not visible ! */ + abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM); lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; for (i = 0; i < abo->placement.num_placement; i++) { @@ -957,6 +963,8 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) WARN_ON_ONCE(!ww_mutex_is_locked(&bo->tbo.resv->lock) && !bo->pin_count); WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); + WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM && + !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)); return bo->tbo.offset; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 447c009..b1f5d73 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1116,7 +1116,8 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) r = amdgpu_bo_create(adev, 256 * 1024, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->stollen_vga_memory); if (r) { return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index cee7bc9a..e6842b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -1002,7 +1002,8 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &bo); if (r) return r; @@ -1051,7 +1052,8 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, r = amdgpu_bo_create(adev, 1024, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &bo); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index b0c6702..cc7b4cb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -157,7 +157,8 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) r = amdgpu_bo_create(adev, size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->vce.vcpu_bo); if (r) { dev_err(adev->dev, "(%d) failed to allocate VCE bo\n", r); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index a6a48ed..87c990e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1400,7 +1400,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, AMDGPU_GPU_PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_CREATE_NO_CPU_ACCESS | - AMDGPU_GEM_CREATE_SHADOW, + AMDGPU_GEM_CREATE_SHADOW | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, resv, &pt); if (r) goto error_free; @@ -1600,7 +1601,8 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) r = amdgpu_bo_create(adev, pd_size, align, true, AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_CREATE_NO_CPU_ACCESS | - AMDGPU_GEM_CREATE_SHADOW, + AMDGPU_GEM_CREATE_SHADOW | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &vm->page_directory); if (r) goto error_free_sched_entity; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 8c780f6..b0c9013 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -3227,7 +3227,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev) if (adev->gfx.rlc.save_restore_obj == NULL) { r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->gfx.rlc.save_restore_obj); if (r) { @@ -3271,7 +3272,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev) if (adev->gfx.rlc.clear_state_obj == NULL) { r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->gfx.rlc.clear_state_obj); if (r) { @@ -3311,7 +3313,8 @@ static int gfx_v7_0_rlc_init(struct amdgpu_device *adev) if (adev->gfx.rlc.cp_table_obj == NULL) { r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->gfx.rlc.cp_table_obj); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 4a6e07d..005089e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -1274,7 +1274,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) if (adev->gfx.rlc.clear_state_obj == NULL) { r = amdgpu_bo_create(adev, dws * 4, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->gfx.rlc.clear_state_obj); if (r) { @@ -1316,7 +1317,8 @@ static int gfx_v8_0_rlc_init(struct amdgpu_device *adev) if (adev->gfx.rlc.cp_table_obj == NULL) { r = amdgpu_bo_create(adev, adev->gfx.rlc.cp_table_size, PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, NULL, NULL, &adev->gfx.rlc.cp_table_obj); if (r) { diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 4797932..08c95bd 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -83,6 +83,8 @@ extern "C" { #define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3) /* Flag that create shadow bo(GTT) while allocating vram bo */ #define AMDGPU_GEM_CREATE_SHADOW (1 << 4) +/* Flag that allocating the BO should use linear VRAM */ +#define AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS (1 << 5) struct drm_amdgpu_gem_create_in { /** the requested memory size */ -- 2.5.0 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
[parent not found: <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>]
* [PATCH 2/6] drm/amdgpu: use explicit limit for VRAM_CONTIGUOUS [not found] ` <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> @ 2016-09-15 10:12 ` Christian König 2016-09-15 10:12 ` [PATCH 3/6] drm/amdgpu: set at least the node size in the gtt manager Christian König ` (3 subsequent siblings) 4 siblings, 0 replies; 10+ messages in thread From: Christian König @ 2016-09-15 10:12 UTC (permalink / raw) To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW From: Christian König <christian.koenig@amd.com> Split VRAM won't have a valid offset, so just set an explicit limit when the flag is given to trigger reallocation if necessary. Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 3bddc68..03c6bfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -123,12 +123,17 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, if (domain & AMDGPU_GEM_DOMAIN_VRAM) { unsigned visible_pfn = adev->mc.visible_vram_size >> PAGE_SHIFT; + unsigned lpfn = 0; + + /* This forces a reallocation if the flag wasn't set before */ + if (flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) + lpfn = adev->mc.real_vram_size >> PAGE_SHIFT; if (flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS && !(flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) && adev->mc.visible_vram_size < adev->mc.real_vram_size) { places[c].fpfn = visible_pfn; - places[c].lpfn = 0; + places[c].lpfn = lpfn; places[c].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM | TTM_PL_FLAG_TOPDOWN; @@ -136,7 +141,7 @@ static void amdgpu_ttm_placement_init(struct amdgpu_device *adev, } places[c].fpfn = 0; - places[c].lpfn = 0; + places[c].lpfn = lpfn; places[c].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) -- 2.5.0 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/6] drm/amdgpu: set at least the node size in the gtt manager [not found] ` <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 2016-09-15 10:12 ` [PATCH 2/6] drm/amdgpu: use explicit limit for VRAM_CONTIGUOUS Christian König @ 2016-09-15 10:12 ` Christian König 2016-09-15 10:12 ` [PATCH 4/6] drm/amdgpu: handle multiple MM nodes in the VMs v2 Christian König ` (2 subsequent siblings) 4 siblings, 0 replies; 10+ messages in thread From: Christian König @ 2016-09-15 10:12 UTC (permalink / raw) To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW From: Christian König <christian.koenig@amd.com> Otherwise the new VM code becomes confused. Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index 262e872..957a788 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c @@ -167,6 +167,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man, return -ENOMEM; node->start = AMDGPU_BO_INVALID_OFFSET; + node->size = mem->num_pages; mem->mm_node = node; if (place->fpfn || place->lpfn || place->flags & TTM_PL_FLAG_TOPDOWN) { -- 2.5.0 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/6] drm/amdgpu: handle multiple MM nodes in the VMs v2 [not found] ` <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 2016-09-15 10:12 ` [PATCH 2/6] drm/amdgpu: use explicit limit for VRAM_CONTIGUOUS Christian König 2016-09-15 10:12 ` [PATCH 3/6] drm/amdgpu: set at least the node size in the gtt manager Christian König @ 2016-09-15 10:12 ` Christian König 2016-09-15 10:12 ` [PATCH 5/6] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes v2 Christian König 2016-09-15 10:12 ` [PATCH 6/6] drm/amdgpu: add VRAM manager v2 Christian König 4 siblings, 0 replies; 10+ messages in thread From: Christian König @ 2016-09-15 10:12 UTC (permalink / raw) To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW From: Christian König <christian.koenig@amd.com> This allows us to map scattered VRAM BOs to the VMs. v2: fix offset handling, use pfn instead of offset, fix PAGE_SIZE != AMDGPU_GPU_PAGE_SIZE case Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 81 +++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 87c990e..d3a2d1f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1049,8 +1049,8 @@ error_free: * @pages_addr: DMA addresses to use for mapping * @vm: requested vm * @mapping: mapped range and flags to use for the update - * @addr: addr to set the area to * @flags: HW flags for the mapping + * @nodes: array of drm_mm_nodes with the MC addresses * @fence: optional resulting fence * * Split the mapping into smaller chunks so that each update fits @@ -1063,12 +1063,11 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, dma_addr_t *pages_addr, struct amdgpu_vm *vm, struct amdgpu_bo_va_mapping *mapping, - uint32_t flags, uint64_t addr, + uint32_t flags, + struct drm_mm_node *nodes, struct fence **fence) { - const uint64_t max_size = 64ULL * 1024ULL * 1024ULL / AMDGPU_GPU_PAGE_SIZE; - - uint64_t src = 0, start = mapping->it.start; + uint64_t pfn, src = 0, start = mapping->it.start; int r; /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here @@ -1081,23 +1080,40 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, trace_amdgpu_vm_bo_update(mapping); - if (pages_addr) { - if (flags == gtt_flags) - src = adev->gart.table_addr + (addr >> 12) * 8; - addr = 0; + pfn = mapping->offset >> PAGE_SHIFT; + if (nodes) { + while (pfn >= nodes->size) { + pfn -= nodes->size; + ++nodes; + } } - addr += mapping->offset; - if (!pages_addr || src) - return amdgpu_vm_bo_update_mapping(adev, exclusive, - src, pages_addr, vm, - start, mapping->it.last, - flags, addr, fence); + do { + uint64_t max_entries; + uint64_t addr, last; + + if (nodes) { + addr = nodes->start << PAGE_SHIFT; + max_entries = (nodes->size - pfn) * + (PAGE_SIZE / AMDGPU_GPU_PAGE_SIZE); + } else { + addr = 0; + max_entries = S64_MAX; + } - while (start != mapping->it.last + 1) { - uint64_t last; + if (pages_addr) { + if (flags == gtt_flags) + src = adev->gart.table_addr + + (addr >> AMDGPU_GPU_PAGE_SHIFT) * 8; + else + max_entries = min(max_entries, 16ull * 1024ull); + addr = 0; + } else if (flags & AMDGPU_PTE_VALID) { + addr += adev->vm_manager.vram_base_offset; + } + addr += pfn << PAGE_SHIFT; - last = min((uint64_t)mapping->it.last, start + max_size - 1); + last = min((uint64_t)mapping->it.last, start + max_entries - 1); r = amdgpu_vm_bo_update_mapping(adev, exclusive, src, pages_addr, vm, start, last, flags, addr, @@ -1105,9 +1121,14 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, if (r) return r; + pfn += last - start + 1; + if (nodes && nodes->size == pfn) { + pfn = 0; + ++nodes; + } start = last + 1; - addr += max_size * AMDGPU_GPU_PAGE_SIZE; - } + + } while (unlikely(start != mapping->it.last + 1)); return 0; } @@ -1131,34 +1152,24 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, dma_addr_t *pages_addr = NULL; uint32_t gtt_flags, flags; struct ttm_mem_reg *mem; + struct drm_mm_node *nodes; struct fence *exclusive; - uint64_t addr; int r; if (clear) { mem = NULL; - addr = 0; + nodes = NULL; exclusive = NULL; } else { struct ttm_dma_tt *ttm; mem = &bo_va->bo->tbo.mem; - addr = (u64)mem->start << PAGE_SHIFT; - switch (mem->mem_type) { - case TTM_PL_TT: + nodes = mem->mm_node; + if (mem->mem_type == TTM_PL_TT) { ttm = container_of(bo_va->bo->tbo.ttm, struct ttm_dma_tt, ttm); pages_addr = ttm->dma_address; - break; - - case TTM_PL_VRAM: - addr += adev->vm_manager.vram_base_offset; - break; - - default: - break; } - exclusive = reservation_object_get_excl(bo_va->bo->tbo.resv); } @@ -1174,7 +1185,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, list_for_each_entry(mapping, &bo_va->invalids, list) { r = amdgpu_vm_bo_split_mapping(adev, exclusive, gtt_flags, pages_addr, vm, - mapping, flags, addr, + mapping, flags, nodes, &bo_va->last_pt_update); if (r) return r; -- 2.5.0 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/6] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes v2 [not found] ` <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> ` (2 preceding siblings ...) 2016-09-15 10:12 ` [PATCH 4/6] drm/amdgpu: handle multiple MM nodes in the VMs v2 Christian König @ 2016-09-15 10:12 ` Christian König 2016-09-15 10:12 ` [PATCH 6/6] drm/amdgpu: add VRAM manager v2 Christian König 4 siblings, 0 replies; 10+ messages in thread From: Christian König @ 2016-09-15 10:12 UTC (permalink / raw) To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW From: Christian König <christian.koenig@amd.com> This allows us to move scattered buffers around. v2: fix a couple of typos, handle scattered to scattered moves as well. Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 118 +++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index b1f5d73..4b8b39c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -259,64 +259,116 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo, new_mem->mm_node = NULL; } -static int amdgpu_move_blit(struct ttm_buffer_object *bo, - bool evict, bool no_wait_gpu, - struct ttm_mem_reg *new_mem, - struct ttm_mem_reg *old_mem) +static int amdgpu_mm_node_addr(struct ttm_buffer_object *bo, + struct drm_mm_node *mm_node, + struct ttm_mem_reg *mem, + uint64_t *addr) { - struct amdgpu_device *adev; - struct amdgpu_ring *ring; - uint64_t old_start, new_start; - struct fence *fence; int r; - adev = amdgpu_get_adev(bo->bdev); - ring = adev->mman.buffer_funcs_ring; - old_start = (u64)old_mem->start << PAGE_SHIFT; - new_start = (u64)new_mem->start << PAGE_SHIFT; - - switch (old_mem->mem_type) { + switch (mem->mem_type) { case TTM_PL_TT: - r = amdgpu_ttm_bind(bo, old_mem); + r = amdgpu_ttm_bind(bo, mem); if (r) return r; case TTM_PL_VRAM: - old_start += bo->bdev->man[old_mem->mem_type].gpu_offset; + *addr = mm_node->start << PAGE_SHIFT; + *addr += bo->bdev->man[mem->mem_type].gpu_offset; break; default: - DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); + DRM_ERROR("Unknown placement %d\n", mem->mem_type); return -EINVAL; } - switch (new_mem->mem_type) { - case TTM_PL_TT: - r = amdgpu_ttm_bind(bo, new_mem); - if (r) - return r; - case TTM_PL_VRAM: - new_start += bo->bdev->man[new_mem->mem_type].gpu_offset; - break; - default: - DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); - return -EINVAL; - } + return 0; +} + +static int amdgpu_move_blit(struct ttm_buffer_object *bo, + bool evict, bool no_wait_gpu, + struct ttm_mem_reg *new_mem, + struct ttm_mem_reg *old_mem) +{ + struct amdgpu_device *adev = amdgpu_get_adev(bo->bdev); + struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring; + + struct drm_mm_node *old_mm, *new_mm; + uint64_t old_start, old_size, new_start, new_size; + unsigned long num_pages; + struct fence *fence = NULL; + int r; + + BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0); + if (!ring->ready) { DRM_ERROR("Trying to move memory with ring turned off.\n"); return -EINVAL; } - BUILD_BUG_ON((PAGE_SIZE % AMDGPU_GPU_PAGE_SIZE) != 0); + old_mm = old_mem->mm_node; + r = amdgpu_mm_node_addr(bo, old_mm, old_mem, &old_start); + if (r) + return r; + old_size = old_mm->size; + - r = amdgpu_copy_buffer(ring, old_start, new_start, - new_mem->num_pages * PAGE_SIZE, /* bytes */ - bo->resv, &fence, false); + new_mm = new_mem->mm_node; + r = amdgpu_mm_node_addr(bo, new_mm, new_mem, &new_start); if (r) return r; + new_size = new_mm->size; + + num_pages = new_mem->num_pages; + while (num_pages) { + unsigned long cur_pages = min(old_size, new_size); + struct fence *next; + + r = amdgpu_copy_buffer(ring, old_start, new_start, + cur_pages * PAGE_SIZE, + bo->resv, &next, false); + if (r) + goto error; + + fence_put(fence); + fence = next; + + num_pages -= cur_pages; + if (!num_pages) + break; + + old_size -= cur_pages; + if (!old_size) { + r = amdgpu_mm_node_addr(bo, ++old_mm, old_mem, + &old_start); + if (r) + goto error; + old_size = old_mm->size; + } else { + old_start += cur_pages * PAGE_SIZE; + } + + new_size -= cur_pages; + if (!new_size) { + r = amdgpu_mm_node_addr(bo, ++new_mm, new_mem, + &new_start); + if (r) + goto error; + + new_size = new_mm->size; + } else { + new_start += cur_pages * PAGE_SIZE; + } + } r = ttm_bo_pipeline_move(bo, fence, evict, new_mem); fence_put(fence); return r; + +error: + if (fence) + fence_wait(fence, false); + fence_put(fence); + return r; } static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, -- 2.5.0 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/6] drm/amdgpu: add VRAM manager v2 [not found] ` <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> ` (3 preceding siblings ...) 2016-09-15 10:12 ` [PATCH 5/6] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes v2 Christian König @ 2016-09-15 10:12 ` Christian König [not found] ` <1473934344-2106-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 4 siblings, 1 reply; 10+ messages in thread From: Christian König @ 2016-09-15 10:12 UTC (permalink / raw) To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW From: Christian König <christian.koenig@amd.com> Split VRAM allocations into 4MB blocks. v2: fix typo in comment, some suggested cleanups Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 + drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 222 +++++++++++++++++++++++++++ 8 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index f2b97cb..236e9df 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -30,7 +30,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ atombios_encoders.o amdgpu_sa.o atombios_i2c.o \ amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ - amdgpu_gtt_mgr.o + amdgpu_gtt_mgr.o amdgpu_vram_mgr.o # add asic specific block amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 588baaf..ee55763 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -98,6 +98,7 @@ extern char *amdgpu_disable_cu; extern int amdgpu_sclk_deep_sleep_en; extern char *amdgpu_virtual_display; extern unsigned amdgpu_pp_feature_mask; +extern int amdgpu_vram_page_split; #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 5686d12..f26b067 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1012,6 +1012,13 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev) amdgpu_vm_block_size); amdgpu_vm_block_size = 9; } + + if ((amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) || + !amdgpu_check_pot_argument(amdgpu_vram_page_split)) { + dev_warn(adev->dev, "invalid VRAM page split (%d)\n", + amdgpu_vram_page_split); + amdgpu_vram_page_split = 1024; + } } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 902da13..44e605d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -83,6 +83,7 @@ int amdgpu_vm_size = 64; int amdgpu_vm_block_size = -1; int amdgpu_vm_fault_stop = 0; int amdgpu_vm_debug = 0; +int amdgpu_vram_page_split = 1024; int amdgpu_exp_hw_support = 0; int amdgpu_dal = -1; int amdgpu_sched_jobs = 32; @@ -164,6 +165,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444); MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)"); module_param_named(vm_debug, amdgpu_vm_debug, int, 0644); +MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024)"); +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444); + MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 03c6bfc..d6e6c93 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -970,6 +970,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM && !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)); + WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); return bo->tbo.offset; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 4b8b39c..428ffb6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -168,7 +168,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, break; case TTM_PL_VRAM: /* "On-card" video ram */ - man->func = &ttm_bo_manager_func; + man->func = &amdgpu_vram_mgr_func; man->gpu_offset = adev->mc.vram_start; man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 9812c80..d1c00c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -66,6 +66,7 @@ struct amdgpu_mman { }; extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; +extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func; int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man, struct ttm_buffer_object *tbo, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c new file mode 100644 index 0000000..1125f7f --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -0,0 +1,222 @@ +/* + * Copyright 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Christian König + */ + +#include <drm/drmP.h> +#include "amdgpu.h" + +struct amdgpu_vram_mgr { + struct drm_mm mm; + spinlock_t lock; +}; + +/** + * amdgpu_vram_mgr_init - init VRAM manager and DRM MM + * + * @man: TTM memory type manager + * @p_size: maximum size of VRAM + * + * Allocate and initialize the VRAM manager. + */ +static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man, + unsigned long p_size) +{ + struct amdgpu_vram_mgr *mgr; + + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + if (!mgr) + return -ENOMEM; + + drm_mm_init(&mgr->mm, 0, p_size); + spin_lock_init(&mgr->lock); + man->priv = mgr; + return 0; +} + +/** + * amdgpu_vram_mgr_fini - free and destroy VRAM manager + * + * @man: TTM memory type manager + * + * Destroy and free the VRAM manager, returns -EBUSY if ranges are still + * allocated inside it. + */ +static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man) +{ + struct amdgpu_vram_mgr *mgr = man->priv; + + spin_lock(&mgr->lock); + if (!drm_mm_clean(&mgr->mm)) { + spin_unlock(&mgr->lock); + return -EBUSY; + } + + drm_mm_takedown(&mgr->mm); + spin_unlock(&mgr->lock); + kfree(mgr); + man->priv = NULL; + return 0; +} + +/** + * amdgpu_vram_mgr_new - allocate new ranges + * + * @man: TTM memory type manager + * @tbo: TTM BO we need this range for + * @place: placement flags and restrictions + * @mem: the resulting mem object + * + * Allocate VRAM for the given BO. + */ +static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, + struct ttm_buffer_object *tbo, + const struct ttm_place *place, + struct ttm_mem_reg *mem) +{ + struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo); + struct amdgpu_vram_mgr *mgr = man->priv; + struct drm_mm *mm = &mgr->mm; + struct drm_mm_node *nodes; + enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT; + enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT; + unsigned long lpfn, num_nodes, pages_per_node, pages_left; + unsigned i; + int r; + + lpfn = place->lpfn; + if (!lpfn) + lpfn = man->size; + + if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS || + amdgpu_vram_page_split == -1) { + pages_per_node = ~0ul; + num_nodes = 1; + } else { + pages_per_node = max((uint32_t)amdgpu_vram_page_split, + mem->page_alignment); + num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node); + } + + nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL); + if (!nodes) + return -ENOMEM; + + if (place->flags & TTM_PL_FLAG_TOPDOWN) { + sflags = DRM_MM_SEARCH_BELOW; + aflags = DRM_MM_CREATE_TOP; + } + + pages_left = mem->num_pages; + + spin_lock(&mgr->lock); + for (i = 0; i < num_nodes; ++i) { + unsigned long pages = min(pages_left, pages_per_node); + uint32_t alignment = mem->page_alignment; + + if (pages == pages_per_node) + alignment = pages_per_node; + else + sflags |= DRM_MM_SEARCH_BEST; + + r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages, + alignment, 0, + place->fpfn, lpfn, + sflags, aflags); + if (unlikely(r)) + goto error; + + pages_left -= pages; + } + spin_unlock(&mgr->lock); + + mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET; + mem->mm_node = nodes; + + return 0; + +error: + while (i--) + drm_mm_remove_node(&nodes[i]); + spin_unlock(&mgr->lock); + + kfree(nodes); + return r == -ENOSPC ? 0 : r; +} + +/** + * amdgpu_vram_mgr_del - free ranges + * + * @man: TTM memory type manager + * @tbo: TTM BO we need this range for + * @place: placement flags and restrictions + * @mem: TTM memory object + * + * Free the allocated VRAM again. + */ +static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man, + struct ttm_mem_reg *mem) +{ + struct amdgpu_vram_mgr *mgr = man->priv; + struct drm_mm_node *nodes = mem->mm_node; + unsigned pages = mem->num_pages; + + if (!mem->mm_node) + return; + + spin_lock(&mgr->lock); + while (pages) { + pages -= nodes->size; + drm_mm_remove_node(nodes); + ++nodes; + } + spin_unlock(&mgr->lock); + + kfree(mem->mm_node); + mem->mm_node = NULL; +} + +/** + * amdgpu_vram_mgr_debug - dump VRAM table + * + * @man: TTM memory type manager + * @prefix: text prefix + * + * Dump the table content using printk. + */ +static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man, + const char *prefix) +{ + struct amdgpu_vram_mgr *mgr = man->priv; + + spin_lock(&mgr->lock); + drm_mm_debug_table(&mgr->mm, prefix); + spin_unlock(&mgr->lock); +} + +const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = { + amdgpu_vram_mgr_init, + amdgpu_vram_mgr_fini, + amdgpu_vram_mgr_new, + amdgpu_vram_mgr_del, + amdgpu_vram_mgr_debug +}; -- 2.5.0 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
[parent not found: <1473934344-2106-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>]
* Re: [PATCH 6/6] drm/amdgpu: add VRAM manager v2 [not found] ` <1473934344-2106-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> @ 2016-09-15 14:44 ` Alex Deucher [not found] ` <CADnq5_NSW3A_7EqUzABsEUddyJYUKyfpUR2fW-Ku4x3VF0Rykw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 0 siblings, 1 reply; 10+ messages in thread From: Alex Deucher @ 2016-09-15 14:44 UTC (permalink / raw) To: Christian König; +Cc: amd-gfx list On Thu, Sep 15, 2016 at 6:12 AM, Christian König <deathsimple@vodafone.de> wrote: > From: Christian König <christian.koenig@amd.com> > > Split VRAM allocations into 4MB blocks. > > v2: fix typo in comment, some suggested cleanups > > Signed-off-by: Christian König <christian.koenig@amd.com> > --- > drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 + > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 + > drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 222 +++++++++++++++++++++++++++ > 8 files changed, 238 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c > > diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile > index f2b97cb..236e9df 100644 > --- a/drivers/gpu/drm/amd/amdgpu/Makefile > +++ b/drivers/gpu/drm/amd/amdgpu/Makefile > @@ -30,7 +30,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ > atombios_encoders.o amdgpu_sa.o atombios_i2c.o \ > amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ > amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ > - amdgpu_gtt_mgr.o > + amdgpu_gtt_mgr.o amdgpu_vram_mgr.o > > # add asic specific block > amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 588baaf..ee55763 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -98,6 +98,7 @@ extern char *amdgpu_disable_cu; > extern int amdgpu_sclk_deep_sleep_en; > extern char *amdgpu_virtual_display; > extern unsigned amdgpu_pp_feature_mask; > +extern int amdgpu_vram_page_split; > > #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 > #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > index 5686d12..f26b067 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -1012,6 +1012,13 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev) > amdgpu_vm_block_size); > amdgpu_vm_block_size = 9; > } > + > + if ((amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) || > + !amdgpu_check_pot_argument(amdgpu_vram_page_split)) { > + dev_warn(adev->dev, "invalid VRAM page split (%d)\n", > + amdgpu_vram_page_split); > + amdgpu_vram_page_split = 1024; > + } > } > > /** > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index 902da13..44e605d 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -83,6 +83,7 @@ int amdgpu_vm_size = 64; > int amdgpu_vm_block_size = -1; > int amdgpu_vm_fault_stop = 0; > int amdgpu_vm_debug = 0; > +int amdgpu_vram_page_split = 1024; > int amdgpu_exp_hw_support = 0; > int amdgpu_dal = -1; > int amdgpu_sched_jobs = 32; > @@ -164,6 +165,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444); > MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)"); > module_param_named(vm_debug, amdgpu_vm_debug, int, 0644); > > +MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024)"); > +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444); Not a big deal, but maybe make this unsigned instead of int? I don't see any use for negative values. Alex > + > MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); > module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > index 03c6bfc..d6e6c93 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c > @@ -970,6 +970,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) > WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); > WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM && > !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)); > + WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); > > return bo->tbo.offset; > } > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > index 4b8b39c..428ffb6 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > @@ -168,7 +168,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, > break; > case TTM_PL_VRAM: > /* "On-card" video ram */ > - man->func = &ttm_bo_manager_func; > + man->func = &amdgpu_vram_mgr_func; > man->gpu_offset = adev->mc.vram_start; > man->flags = TTM_MEMTYPE_FLAG_FIXED | > TTM_MEMTYPE_FLAG_MAPPABLE; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > index 9812c80..d1c00c0 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > @@ -66,6 +66,7 @@ struct amdgpu_mman { > }; > > extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; > +extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func; > > int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man, > struct ttm_buffer_object *tbo, > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c > new file mode 100644 > index 0000000..1125f7f > --- /dev/null > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c > @@ -0,0 +1,222 @@ > +/* > + * Copyright 2015 Advanced Micro Devices, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: Christian König > + */ > + > +#include <drm/drmP.h> > +#include "amdgpu.h" > + > +struct amdgpu_vram_mgr { > + struct drm_mm mm; > + spinlock_t lock; > +}; > + > +/** > + * amdgpu_vram_mgr_init - init VRAM manager and DRM MM > + * > + * @man: TTM memory type manager > + * @p_size: maximum size of VRAM > + * > + * Allocate and initialize the VRAM manager. > + */ > +static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man, > + unsigned long p_size) > +{ > + struct amdgpu_vram_mgr *mgr; > + > + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); > + if (!mgr) > + return -ENOMEM; > + > + drm_mm_init(&mgr->mm, 0, p_size); > + spin_lock_init(&mgr->lock); > + man->priv = mgr; > + return 0; > +} > + > +/** > + * amdgpu_vram_mgr_fini - free and destroy VRAM manager > + * > + * @man: TTM memory type manager > + * > + * Destroy and free the VRAM manager, returns -EBUSY if ranges are still > + * allocated inside it. > + */ > +static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man) > +{ > + struct amdgpu_vram_mgr *mgr = man->priv; > + > + spin_lock(&mgr->lock); > + if (!drm_mm_clean(&mgr->mm)) { > + spin_unlock(&mgr->lock); > + return -EBUSY; > + } > + > + drm_mm_takedown(&mgr->mm); > + spin_unlock(&mgr->lock); > + kfree(mgr); > + man->priv = NULL; > + return 0; > +} > + > +/** > + * amdgpu_vram_mgr_new - allocate new ranges > + * > + * @man: TTM memory type manager > + * @tbo: TTM BO we need this range for > + * @place: placement flags and restrictions > + * @mem: the resulting mem object > + * > + * Allocate VRAM for the given BO. > + */ > +static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, > + struct ttm_buffer_object *tbo, > + const struct ttm_place *place, > + struct ttm_mem_reg *mem) > +{ > + struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo); > + struct amdgpu_vram_mgr *mgr = man->priv; > + struct drm_mm *mm = &mgr->mm; > + struct drm_mm_node *nodes; > + enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT; > + enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT; > + unsigned long lpfn, num_nodes, pages_per_node, pages_left; > + unsigned i; > + int r; > + > + lpfn = place->lpfn; > + if (!lpfn) > + lpfn = man->size; > + > + if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS || > + amdgpu_vram_page_split == -1) { > + pages_per_node = ~0ul; > + num_nodes = 1; > + } else { > + pages_per_node = max((uint32_t)amdgpu_vram_page_split, > + mem->page_alignment); > + num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node); > + } > + > + nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL); > + if (!nodes) > + return -ENOMEM; > + > + if (place->flags & TTM_PL_FLAG_TOPDOWN) { > + sflags = DRM_MM_SEARCH_BELOW; > + aflags = DRM_MM_CREATE_TOP; > + } > + > + pages_left = mem->num_pages; > + > + spin_lock(&mgr->lock); > + for (i = 0; i < num_nodes; ++i) { > + unsigned long pages = min(pages_left, pages_per_node); > + uint32_t alignment = mem->page_alignment; > + > + if (pages == pages_per_node) > + alignment = pages_per_node; > + else > + sflags |= DRM_MM_SEARCH_BEST; > + > + r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages, > + alignment, 0, > + place->fpfn, lpfn, > + sflags, aflags); > + if (unlikely(r)) > + goto error; > + > + pages_left -= pages; > + } > + spin_unlock(&mgr->lock); > + > + mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET; > + mem->mm_node = nodes; > + > + return 0; > + > +error: > + while (i--) > + drm_mm_remove_node(&nodes[i]); > + spin_unlock(&mgr->lock); > + > + kfree(nodes); > + return r == -ENOSPC ? 0 : r; > +} > + > +/** > + * amdgpu_vram_mgr_del - free ranges > + * > + * @man: TTM memory type manager > + * @tbo: TTM BO we need this range for > + * @place: placement flags and restrictions > + * @mem: TTM memory object > + * > + * Free the allocated VRAM again. > + */ > +static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man, > + struct ttm_mem_reg *mem) > +{ > + struct amdgpu_vram_mgr *mgr = man->priv; > + struct drm_mm_node *nodes = mem->mm_node; > + unsigned pages = mem->num_pages; > + > + if (!mem->mm_node) > + return; > + > + spin_lock(&mgr->lock); > + while (pages) { > + pages -= nodes->size; > + drm_mm_remove_node(nodes); > + ++nodes; > + } > + spin_unlock(&mgr->lock); > + > + kfree(mem->mm_node); > + mem->mm_node = NULL; > +} > + > +/** > + * amdgpu_vram_mgr_debug - dump VRAM table > + * > + * @man: TTM memory type manager > + * @prefix: text prefix > + * > + * Dump the table content using printk. > + */ > +static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man, > + const char *prefix) > +{ > + struct amdgpu_vram_mgr *mgr = man->priv; > + > + spin_lock(&mgr->lock); > + drm_mm_debug_table(&mgr->mm, prefix); > + spin_unlock(&mgr->lock); > +} > + > +const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = { > + amdgpu_vram_mgr_init, > + amdgpu_vram_mgr_fini, > + amdgpu_vram_mgr_new, > + amdgpu_vram_mgr_del, > + amdgpu_vram_mgr_debug > +}; > -- > 2.5.0 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <CADnq5_NSW3A_7EqUzABsEUddyJYUKyfpUR2fW-Ku4x3VF0Rykw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH 6/6] drm/amdgpu: add VRAM manager v2 [not found] ` <CADnq5_NSW3A_7EqUzABsEUddyJYUKyfpUR2fW-Ku4x3VF0Rykw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> @ 2016-09-15 17:42 ` Christian König 0 siblings, 0 replies; 10+ messages in thread From: Christian König @ 2016-09-15 17:42 UTC (permalink / raw) To: Alex Deucher; +Cc: amd-gfx list Am 15.09.2016 um 16:44 schrieb Alex Deucher: > On Thu, Sep 15, 2016 at 6:12 AM, Christian König > <deathsimple@vodafone.de> wrote: >> From: Christian König <christian.koenig@amd.com> >> >> Split VRAM allocations into 4MB blocks. >> >> v2: fix typo in comment, some suggested cleanups >> >> Signed-off-by: Christian König <christian.koenig@amd.com> >> --- >> drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- >> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + >> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 + >> drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 + >> drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 1 + >> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- >> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 1 + >> drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 222 +++++++++++++++++++++++++++ >> 8 files changed, 238 insertions(+), 2 deletions(-) >> create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile >> index f2b97cb..236e9df 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/Makefile >> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile >> @@ -30,7 +30,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ >> atombios_encoders.o amdgpu_sa.o atombios_i2c.o \ >> amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ >> amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ >> - amdgpu_gtt_mgr.o >> + amdgpu_gtt_mgr.o amdgpu_vram_mgr.o >> >> # add asic specific block >> amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h >> index 588baaf..ee55763 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h >> @@ -98,6 +98,7 @@ extern char *amdgpu_disable_cu; >> extern int amdgpu_sclk_deep_sleep_en; >> extern char *amdgpu_virtual_display; >> extern unsigned amdgpu_pp_feature_mask; >> +extern int amdgpu_vram_page_split; >> >> #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 >> #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >> index 5686d12..f26b067 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >> @@ -1012,6 +1012,13 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev) >> amdgpu_vm_block_size); >> amdgpu_vm_block_size = 9; >> } >> + >> + if ((amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) || >> + !amdgpu_check_pot_argument(amdgpu_vram_page_split)) { >> + dev_warn(adev->dev, "invalid VRAM page split (%d)\n", >> + amdgpu_vram_page_split); >> + amdgpu_vram_page_split = 1024; >> + } >> } >> >> /** >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c >> index 902da13..44e605d 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c >> @@ -83,6 +83,7 @@ int amdgpu_vm_size = 64; >> int amdgpu_vm_block_size = -1; >> int amdgpu_vm_fault_stop = 0; >> int amdgpu_vm_debug = 0; >> +int amdgpu_vram_page_split = 1024; >> int amdgpu_exp_hw_support = 0; >> int amdgpu_dal = -1; >> int amdgpu_sched_jobs = 32; >> @@ -164,6 +165,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444); >> MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)"); >> module_param_named(vm_debug, amdgpu_vm_debug, int, 0644); >> >> +MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024)"); >> +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444); > Not a big deal, but maybe make this unsigned instead of int? I don't > see any use for negative values. -1 is used to disable the feature. I will update the parameter description. Christian. > Alex > >> + >> MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); >> module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c >> index 03c6bfc..d6e6c93 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c >> @@ -970,6 +970,7 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) >> WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); >> WARN_ON_ONCE(bo->tbo.mem.mem_type == TTM_PL_VRAM && >> !(bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)); >> + WARN_ON_ONCE(bo->tbo.mem.start == AMDGPU_BO_INVALID_OFFSET); >> >> return bo->tbo.offset; >> } >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c >> index 4b8b39c..428ffb6 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c >> @@ -168,7 +168,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, >> break; >> case TTM_PL_VRAM: >> /* "On-card" video ram */ >> - man->func = &ttm_bo_manager_func; >> + man->func = &amdgpu_vram_mgr_func; >> man->gpu_offset = adev->mc.vram_start; >> man->flags = TTM_MEMTYPE_FLAG_FIXED | >> TTM_MEMTYPE_FLAG_MAPPABLE; >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h >> index 9812c80..d1c00c0 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h >> @@ -66,6 +66,7 @@ struct amdgpu_mman { >> }; >> >> extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; >> +extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func; >> >> int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man, >> struct ttm_buffer_object *tbo, >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c >> new file mode 100644 >> index 0000000..1125f7f >> --- /dev/null >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c >> @@ -0,0 +1,222 @@ >> +/* >> + * Copyright 2015 Advanced Micro Devices, Inc. >> + * >> + * Permission is hereby granted, free of charge, to any person obtaining a >> + * copy of this software and associated documentation files (the "Software"), >> + * to deal in the Software without restriction, including without limitation >> + * the rights to use, copy, modify, merge, publish, distribute, sublicense, >> + * and/or sell copies of the Software, and to permit persons to whom the >> + * Software is furnished to do so, subject to the following conditions: >> + * >> + * The above copyright notice and this permission notice shall be included in >> + * all copies or substantial portions of the Software. >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR >> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, >> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR >> + * OTHER DEALINGS IN THE SOFTWARE. >> + * >> + * Authors: Christian König >> + */ >> + >> +#include <drm/drmP.h> >> +#include "amdgpu.h" >> + >> +struct amdgpu_vram_mgr { >> + struct drm_mm mm; >> + spinlock_t lock; >> +}; >> + >> +/** >> + * amdgpu_vram_mgr_init - init VRAM manager and DRM MM >> + * >> + * @man: TTM memory type manager >> + * @p_size: maximum size of VRAM >> + * >> + * Allocate and initialize the VRAM manager. >> + */ >> +static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man, >> + unsigned long p_size) >> +{ >> + struct amdgpu_vram_mgr *mgr; >> + >> + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); >> + if (!mgr) >> + return -ENOMEM; >> + >> + drm_mm_init(&mgr->mm, 0, p_size); >> + spin_lock_init(&mgr->lock); >> + man->priv = mgr; >> + return 0; >> +} >> + >> +/** >> + * amdgpu_vram_mgr_fini - free and destroy VRAM manager >> + * >> + * @man: TTM memory type manager >> + * >> + * Destroy and free the VRAM manager, returns -EBUSY if ranges are still >> + * allocated inside it. >> + */ >> +static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man) >> +{ >> + struct amdgpu_vram_mgr *mgr = man->priv; >> + >> + spin_lock(&mgr->lock); >> + if (!drm_mm_clean(&mgr->mm)) { >> + spin_unlock(&mgr->lock); >> + return -EBUSY; >> + } >> + >> + drm_mm_takedown(&mgr->mm); >> + spin_unlock(&mgr->lock); >> + kfree(mgr); >> + man->priv = NULL; >> + return 0; >> +} >> + >> +/** >> + * amdgpu_vram_mgr_new - allocate new ranges >> + * >> + * @man: TTM memory type manager >> + * @tbo: TTM BO we need this range for >> + * @place: placement flags and restrictions >> + * @mem: the resulting mem object >> + * >> + * Allocate VRAM for the given BO. >> + */ >> +static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, >> + struct ttm_buffer_object *tbo, >> + const struct ttm_place *place, >> + struct ttm_mem_reg *mem) >> +{ >> + struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo); >> + struct amdgpu_vram_mgr *mgr = man->priv; >> + struct drm_mm *mm = &mgr->mm; >> + struct drm_mm_node *nodes; >> + enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT; >> + enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT; >> + unsigned long lpfn, num_nodes, pages_per_node, pages_left; >> + unsigned i; >> + int r; >> + >> + lpfn = place->lpfn; >> + if (!lpfn) >> + lpfn = man->size; >> + >> + if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS || >> + amdgpu_vram_page_split == -1) { >> + pages_per_node = ~0ul; >> + num_nodes = 1; >> + } else { >> + pages_per_node = max((uint32_t)amdgpu_vram_page_split, >> + mem->page_alignment); >> + num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node); >> + } >> + >> + nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL); >> + if (!nodes) >> + return -ENOMEM; >> + >> + if (place->flags & TTM_PL_FLAG_TOPDOWN) { >> + sflags = DRM_MM_SEARCH_BELOW; >> + aflags = DRM_MM_CREATE_TOP; >> + } >> + >> + pages_left = mem->num_pages; >> + >> + spin_lock(&mgr->lock); >> + for (i = 0; i < num_nodes; ++i) { >> + unsigned long pages = min(pages_left, pages_per_node); >> + uint32_t alignment = mem->page_alignment; >> + >> + if (pages == pages_per_node) >> + alignment = pages_per_node; >> + else >> + sflags |= DRM_MM_SEARCH_BEST; >> + >> + r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages, >> + alignment, 0, >> + place->fpfn, lpfn, >> + sflags, aflags); >> + if (unlikely(r)) >> + goto error; >> + >> + pages_left -= pages; >> + } >> + spin_unlock(&mgr->lock); >> + >> + mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET; >> + mem->mm_node = nodes; >> + >> + return 0; >> + >> +error: >> + while (i--) >> + drm_mm_remove_node(&nodes[i]); >> + spin_unlock(&mgr->lock); >> + >> + kfree(nodes); >> + return r == -ENOSPC ? 0 : r; >> +} >> + >> +/** >> + * amdgpu_vram_mgr_del - free ranges >> + * >> + * @man: TTM memory type manager >> + * @tbo: TTM BO we need this range for >> + * @place: placement flags and restrictions >> + * @mem: TTM memory object >> + * >> + * Free the allocated VRAM again. >> + */ >> +static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man, >> + struct ttm_mem_reg *mem) >> +{ >> + struct amdgpu_vram_mgr *mgr = man->priv; >> + struct drm_mm_node *nodes = mem->mm_node; >> + unsigned pages = mem->num_pages; >> + >> + if (!mem->mm_node) >> + return; >> + >> + spin_lock(&mgr->lock); >> + while (pages) { >> + pages -= nodes->size; >> + drm_mm_remove_node(nodes); >> + ++nodes; >> + } >> + spin_unlock(&mgr->lock); >> + >> + kfree(mem->mm_node); >> + mem->mm_node = NULL; >> +} >> + >> +/** >> + * amdgpu_vram_mgr_debug - dump VRAM table >> + * >> + * @man: TTM memory type manager >> + * @prefix: text prefix >> + * >> + * Dump the table content using printk. >> + */ >> +static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man, >> + const char *prefix) >> +{ >> + struct amdgpu_vram_mgr *mgr = man->priv; >> + >> + spin_lock(&mgr->lock); >> + drm_mm_debug_table(&mgr->mm, prefix); >> + spin_unlock(&mgr->lock); >> +} >> + >> +const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = { >> + amdgpu_vram_mgr_init, >> + amdgpu_vram_mgr_fini, >> + amdgpu_vram_mgr_new, >> + amdgpu_vram_mgr_del, >> + amdgpu_vram_mgr_debug >> +}; >> -- >> 2.5.0 >> >> _______________________________________________ >> amd-gfx mailing list >> amd-gfx@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
* VRAM manager @ 2016-09-27 9:49 Christian König [not found] ` <1474969797-1882-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 0 siblings, 1 reply; 10+ messages in thread From: Christian König @ 2016-09-27 9:49 UTC (permalink / raw) To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW Hi guys, after fixing all those nasty little bugs this seems to be stable now. Anybody brave enough to give it an review? Cheers, Christian. _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <1474969797-1882-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>]
* [PATCH 6/6] drm/amdgpu: add VRAM manager v2 [not found] ` <1474969797-1882-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> @ 2016-09-27 9:49 ` Christian König [not found] ` <1474969797-1882-7-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 0 siblings, 1 reply; 10+ messages in thread From: Christian König @ 2016-09-27 9:49 UTC (permalink / raw) To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW From: Christian König <christian.koenig@amd.com> Split VRAM allocations into 4MB blocks. v2: fix typo in comment, some suggested cleanups v3: document how to disable the feature, fix rebase issue Signed-off-by: Christian König <christian.koenig@amd.com> --- drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 + drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 222 +++++++++++++++++++++++++++ 7 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 786b28a..2874bfe 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -30,7 +30,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ atombios_encoders.o amdgpu_sa.o atombios_i2c.o \ amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ - amdgpu_gtt_mgr.o + amdgpu_gtt_mgr.o amdgpu_vram_mgr.o # add asic specific block amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 73c9a2d..2a95827 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -99,6 +99,7 @@ extern char *amdgpu_disable_cu; extern int amdgpu_sclk_deep_sleep_en; extern char *amdgpu_virtual_display; extern unsigned amdgpu_pp_feature_mask; +extern int amdgpu_vram_page_split; #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 5ca6a38..d66a8df8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1053,6 +1053,13 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev) amdgpu_vm_block_size); amdgpu_vm_block_size = 9; } + + if ((amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) || + !amdgpu_check_pot_argument(amdgpu_vram_page_split)) { + dev_warn(adev->dev, "invalid VRAM page split (%d)\n", + amdgpu_vram_page_split); + amdgpu_vram_page_split = 1024; + } } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 08ba441..538d3a7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -84,6 +84,7 @@ int amdgpu_vm_size = 64; int amdgpu_vm_block_size = -1; int amdgpu_vm_fault_stop = 0; int amdgpu_vm_debug = 0; +int amdgpu_vram_page_split = 1024; int amdgpu_exp_hw_support = 0; int amdgpu_dal = -1; int amdgpu_sched_jobs = 32; @@ -165,6 +166,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444); MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)"); module_param_named(vm_debug, amdgpu_vm_debug, int, 0644); +MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024, -1 = disable)"); +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444); + MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index bd377d8..588e242 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -168,7 +168,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, break; case TTM_PL_VRAM: /* "On-card" video ram */ - man->func = &ttm_bo_manager_func; + man->func = &amdgpu_vram_mgr_func; man->gpu_offset = adev->mc.vram_start; man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 9812c80..d1c00c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -66,6 +66,7 @@ struct amdgpu_mman { }; extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; +extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func; int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man, struct ttm_buffer_object *tbo, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c new file mode 100644 index 0000000..1125f7f --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -0,0 +1,222 @@ +/* + * Copyright 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Christian König + */ + +#include <drm/drmP.h> +#include "amdgpu.h" + +struct amdgpu_vram_mgr { + struct drm_mm mm; + spinlock_t lock; +}; + +/** + * amdgpu_vram_mgr_init - init VRAM manager and DRM MM + * + * @man: TTM memory type manager + * @p_size: maximum size of VRAM + * + * Allocate and initialize the VRAM manager. + */ +static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man, + unsigned long p_size) +{ + struct amdgpu_vram_mgr *mgr; + + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + if (!mgr) + return -ENOMEM; + + drm_mm_init(&mgr->mm, 0, p_size); + spin_lock_init(&mgr->lock); + man->priv = mgr; + return 0; +} + +/** + * amdgpu_vram_mgr_fini - free and destroy VRAM manager + * + * @man: TTM memory type manager + * + * Destroy and free the VRAM manager, returns -EBUSY if ranges are still + * allocated inside it. + */ +static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man) +{ + struct amdgpu_vram_mgr *mgr = man->priv; + + spin_lock(&mgr->lock); + if (!drm_mm_clean(&mgr->mm)) { + spin_unlock(&mgr->lock); + return -EBUSY; + } + + drm_mm_takedown(&mgr->mm); + spin_unlock(&mgr->lock); + kfree(mgr); + man->priv = NULL; + return 0; +} + +/** + * amdgpu_vram_mgr_new - allocate new ranges + * + * @man: TTM memory type manager + * @tbo: TTM BO we need this range for + * @place: placement flags and restrictions + * @mem: the resulting mem object + * + * Allocate VRAM for the given BO. + */ +static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, + struct ttm_buffer_object *tbo, + const struct ttm_place *place, + struct ttm_mem_reg *mem) +{ + struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo); + struct amdgpu_vram_mgr *mgr = man->priv; + struct drm_mm *mm = &mgr->mm; + struct drm_mm_node *nodes; + enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT; + enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT; + unsigned long lpfn, num_nodes, pages_per_node, pages_left; + unsigned i; + int r; + + lpfn = place->lpfn; + if (!lpfn) + lpfn = man->size; + + if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS || + amdgpu_vram_page_split == -1) { + pages_per_node = ~0ul; + num_nodes = 1; + } else { + pages_per_node = max((uint32_t)amdgpu_vram_page_split, + mem->page_alignment); + num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node); + } + + nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL); + if (!nodes) + return -ENOMEM; + + if (place->flags & TTM_PL_FLAG_TOPDOWN) { + sflags = DRM_MM_SEARCH_BELOW; + aflags = DRM_MM_CREATE_TOP; + } + + pages_left = mem->num_pages; + + spin_lock(&mgr->lock); + for (i = 0; i < num_nodes; ++i) { + unsigned long pages = min(pages_left, pages_per_node); + uint32_t alignment = mem->page_alignment; + + if (pages == pages_per_node) + alignment = pages_per_node; + else + sflags |= DRM_MM_SEARCH_BEST; + + r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages, + alignment, 0, + place->fpfn, lpfn, + sflags, aflags); + if (unlikely(r)) + goto error; + + pages_left -= pages; + } + spin_unlock(&mgr->lock); + + mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET; + mem->mm_node = nodes; + + return 0; + +error: + while (i--) + drm_mm_remove_node(&nodes[i]); + spin_unlock(&mgr->lock); + + kfree(nodes); + return r == -ENOSPC ? 0 : r; +} + +/** + * amdgpu_vram_mgr_del - free ranges + * + * @man: TTM memory type manager + * @tbo: TTM BO we need this range for + * @place: placement flags and restrictions + * @mem: TTM memory object + * + * Free the allocated VRAM again. + */ +static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man, + struct ttm_mem_reg *mem) +{ + struct amdgpu_vram_mgr *mgr = man->priv; + struct drm_mm_node *nodes = mem->mm_node; + unsigned pages = mem->num_pages; + + if (!mem->mm_node) + return; + + spin_lock(&mgr->lock); + while (pages) { + pages -= nodes->size; + drm_mm_remove_node(nodes); + ++nodes; + } + spin_unlock(&mgr->lock); + + kfree(mem->mm_node); + mem->mm_node = NULL; +} + +/** + * amdgpu_vram_mgr_debug - dump VRAM table + * + * @man: TTM memory type manager + * @prefix: text prefix + * + * Dump the table content using printk. + */ +static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man, + const char *prefix) +{ + struct amdgpu_vram_mgr *mgr = man->priv; + + spin_lock(&mgr->lock); + drm_mm_debug_table(&mgr->mm, prefix); + spin_unlock(&mgr->lock); +} + +const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = { + amdgpu_vram_mgr_init, + amdgpu_vram_mgr_fini, + amdgpu_vram_mgr_new, + amdgpu_vram_mgr_del, + amdgpu_vram_mgr_debug +}; -- 2.5.0 _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply related [flat|nested] 10+ messages in thread
[parent not found: <1474969797-1882-7-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>]
* Re: [PATCH 6/6] drm/amdgpu: add VRAM manager v2 [not found] ` <1474969797-1882-7-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> @ 2016-09-27 9:57 ` zhoucm1 0 siblings, 0 replies; 10+ messages in thread From: zhoucm1 @ 2016-09-27 9:57 UTC (permalink / raw) To: Christian König, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW On 2016年09月27日 17:49, Christian König wrote: > From: Christian König <christian.koenig@amd.com> > > Split VRAM allocations into 4MB blocks. > > v2: fix typo in comment, some suggested cleanups > v3: document how to disable the feature, fix rebase issue > > Signed-off-by: Christian König <christian.koenig@amd.com> > --- > drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 + > drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 + > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 1 + > drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 222 +++++++++++++++++++++++++++ > 7 files changed, 237 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c > > diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile > index 786b28a..2874bfe 100644 > --- a/drivers/gpu/drm/amd/amdgpu/Makefile > +++ b/drivers/gpu/drm/amd/amdgpu/Makefile > @@ -30,7 +30,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ > atombios_encoders.o amdgpu_sa.o atombios_i2c.o \ > amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ > amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \ > - amdgpu_gtt_mgr.o > + amdgpu_gtt_mgr.o amdgpu_vram_mgr.o > > # add asic specific block > amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \ > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 73c9a2d..2a95827 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -99,6 +99,7 @@ extern char *amdgpu_disable_cu; > extern int amdgpu_sclk_deep_sleep_en; > extern char *amdgpu_virtual_display; > extern unsigned amdgpu_pp_feature_mask; > +extern int amdgpu_vram_page_split; > > #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 > #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > index 5ca6a38..d66a8df8 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -1053,6 +1053,13 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev) > amdgpu_vm_block_size); > amdgpu_vm_block_size = 9; > } > + > + if ((amdgpu_vram_page_split != -1 && amdgpu_vram_page_split < 16) || > + !amdgpu_check_pot_argument(amdgpu_vram_page_split)) { > + dev_warn(adev->dev, "invalid VRAM page split (%d)\n", > + amdgpu_vram_page_split); > + amdgpu_vram_page_split = 1024; > + } > } > > /** > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > index 08ba441..538d3a7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c > @@ -84,6 +84,7 @@ int amdgpu_vm_size = 64; > int amdgpu_vm_block_size = -1; > int amdgpu_vm_fault_stop = 0; > int amdgpu_vm_debug = 0; > +int amdgpu_vram_page_split = 1024; > int amdgpu_exp_hw_support = 0; > int amdgpu_dal = -1; > int amdgpu_sched_jobs = 32; > @@ -165,6 +166,9 @@ module_param_named(vm_fault_stop, amdgpu_vm_fault_stop, int, 0444); > MODULE_PARM_DESC(vm_debug, "Debug VM handling (0 = disabled (default), 1 = enabled)"); > module_param_named(vm_debug, amdgpu_vm_debug, int, 0644); > > +MODULE_PARM_DESC(vram_page_split, "Number of pages after we split VRAM allocations (default 1024, -1 = disable)"); > +module_param_named(vram_page_split, amdgpu_vram_page_split, int, 0444); > + > MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); > module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > index bd377d8..588e242 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > @@ -168,7 +168,7 @@ static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, > break; > case TTM_PL_VRAM: > /* "On-card" video ram */ > - man->func = &ttm_bo_manager_func; > + man->func = &amdgpu_vram_mgr_func; > man->gpu_offset = adev->mc.vram_start; > man->flags = TTM_MEMTYPE_FLAG_FIXED | > TTM_MEMTYPE_FLAG_MAPPABLE; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > index 9812c80..d1c00c0 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h > @@ -66,6 +66,7 @@ struct amdgpu_mman { > }; > > extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func; > +extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func; > > int amdgpu_gtt_mgr_alloc(struct ttm_mem_type_manager *man, > struct ttm_buffer_object *tbo, > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c > new file mode 100644 > index 0000000..1125f7f > --- /dev/null > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c > @@ -0,0 +1,222 @@ > +/* > + * Copyright 2015 Advanced Micro Devices, Inc. 2016 is expected. Regards, David Zhou > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: Christian König > + */ > + > +#include <drm/drmP.h> > +#include "amdgpu.h" > + > +struct amdgpu_vram_mgr { > + struct drm_mm mm; > + spinlock_t lock; > +}; > + > +/** > + * amdgpu_vram_mgr_init - init VRAM manager and DRM MM > + * > + * @man: TTM memory type manager > + * @p_size: maximum size of VRAM > + * > + * Allocate and initialize the VRAM manager. > + */ > +static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man, > + unsigned long p_size) > +{ > + struct amdgpu_vram_mgr *mgr; > + > + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); > + if (!mgr) > + return -ENOMEM; > + > + drm_mm_init(&mgr->mm, 0, p_size); > + spin_lock_init(&mgr->lock); > + man->priv = mgr; > + return 0; > +} > + > +/** > + * amdgpu_vram_mgr_fini - free and destroy VRAM manager > + * > + * @man: TTM memory type manager > + * > + * Destroy and free the VRAM manager, returns -EBUSY if ranges are still > + * allocated inside it. > + */ > +static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man) > +{ > + struct amdgpu_vram_mgr *mgr = man->priv; > + > + spin_lock(&mgr->lock); > + if (!drm_mm_clean(&mgr->mm)) { > + spin_unlock(&mgr->lock); > + return -EBUSY; > + } > + > + drm_mm_takedown(&mgr->mm); > + spin_unlock(&mgr->lock); > + kfree(mgr); > + man->priv = NULL; > + return 0; > +} > + > +/** > + * amdgpu_vram_mgr_new - allocate new ranges > + * > + * @man: TTM memory type manager > + * @tbo: TTM BO we need this range for > + * @place: placement flags and restrictions > + * @mem: the resulting mem object > + * > + * Allocate VRAM for the given BO. > + */ > +static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man, > + struct ttm_buffer_object *tbo, > + const struct ttm_place *place, > + struct ttm_mem_reg *mem) > +{ > + struct amdgpu_bo *bo = container_of(tbo, struct amdgpu_bo, tbo); > + struct amdgpu_vram_mgr *mgr = man->priv; > + struct drm_mm *mm = &mgr->mm; > + struct drm_mm_node *nodes; > + enum drm_mm_search_flags sflags = DRM_MM_SEARCH_DEFAULT; > + enum drm_mm_allocator_flags aflags = DRM_MM_CREATE_DEFAULT; > + unsigned long lpfn, num_nodes, pages_per_node, pages_left; > + unsigned i; > + int r; > + > + lpfn = place->lpfn; > + if (!lpfn) > + lpfn = man->size; > + > + if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS || > + amdgpu_vram_page_split == -1) { > + pages_per_node = ~0ul; > + num_nodes = 1; > + } else { > + pages_per_node = max((uint32_t)amdgpu_vram_page_split, > + mem->page_alignment); > + num_nodes = DIV_ROUND_UP(mem->num_pages, pages_per_node); > + } > + > + nodes = kcalloc(num_nodes, sizeof(*nodes), GFP_KERNEL); > + if (!nodes) > + return -ENOMEM; > + > + if (place->flags & TTM_PL_FLAG_TOPDOWN) { > + sflags = DRM_MM_SEARCH_BELOW; > + aflags = DRM_MM_CREATE_TOP; > + } > + > + pages_left = mem->num_pages; > + > + spin_lock(&mgr->lock); > + for (i = 0; i < num_nodes; ++i) { > + unsigned long pages = min(pages_left, pages_per_node); > + uint32_t alignment = mem->page_alignment; > + > + if (pages == pages_per_node) > + alignment = pages_per_node; > + else > + sflags |= DRM_MM_SEARCH_BEST; > + > + r = drm_mm_insert_node_in_range_generic(mm, &nodes[i], pages, > + alignment, 0, > + place->fpfn, lpfn, > + sflags, aflags); > + if (unlikely(r)) > + goto error; > + > + pages_left -= pages; > + } > + spin_unlock(&mgr->lock); > + > + mem->start = num_nodes == 1 ? nodes[0].start : AMDGPU_BO_INVALID_OFFSET; > + mem->mm_node = nodes; > + > + return 0; > + > +error: > + while (i--) > + drm_mm_remove_node(&nodes[i]); > + spin_unlock(&mgr->lock); > + > + kfree(nodes); > + return r == -ENOSPC ? 0 : r; > +} > + > +/** > + * amdgpu_vram_mgr_del - free ranges > + * > + * @man: TTM memory type manager > + * @tbo: TTM BO we need this range for > + * @place: placement flags and restrictions > + * @mem: TTM memory object > + * > + * Free the allocated VRAM again. > + */ > +static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man, > + struct ttm_mem_reg *mem) > +{ > + struct amdgpu_vram_mgr *mgr = man->priv; > + struct drm_mm_node *nodes = mem->mm_node; > + unsigned pages = mem->num_pages; > + > + if (!mem->mm_node) > + return; > + > + spin_lock(&mgr->lock); > + while (pages) { > + pages -= nodes->size; > + drm_mm_remove_node(nodes); > + ++nodes; > + } > + spin_unlock(&mgr->lock); > + > + kfree(mem->mm_node); > + mem->mm_node = NULL; > +} > + > +/** > + * amdgpu_vram_mgr_debug - dump VRAM table > + * > + * @man: TTM memory type manager > + * @prefix: text prefix > + * > + * Dump the table content using printk. > + */ > +static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man, > + const char *prefix) > +{ > + struct amdgpu_vram_mgr *mgr = man->priv; > + > + spin_lock(&mgr->lock); > + drm_mm_debug_table(&mgr->mm, prefix); > + spin_unlock(&mgr->lock); > +} > + > +const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = { > + amdgpu_vram_mgr_init, > + amdgpu_vram_mgr_fini, > + amdgpu_vram_mgr_new, > + amdgpu_vram_mgr_del, > + amdgpu_vram_mgr_debug > +}; _______________________________________________ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2016-09-27 9:57 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-09-15 10:12 [PATCH 1/6] drm/amdgpu: add AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS flag v3 Christian König [not found] ` <1473934344-2106-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 2016-09-15 10:12 ` [PATCH 2/6] drm/amdgpu: use explicit limit for VRAM_CONTIGUOUS Christian König 2016-09-15 10:12 ` [PATCH 3/6] drm/amdgpu: set at least the node size in the gtt manager Christian König 2016-09-15 10:12 ` [PATCH 4/6] drm/amdgpu: handle multiple MM nodes in the VMs v2 Christian König 2016-09-15 10:12 ` [PATCH 5/6] drm/amdgpu: enable amdgpu_move_blit to handle multiple MM nodes v2 Christian König 2016-09-15 10:12 ` [PATCH 6/6] drm/amdgpu: add VRAM manager v2 Christian König [not found] ` <1473934344-2106-6-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 2016-09-15 14:44 ` Alex Deucher [not found] ` <CADnq5_NSW3A_7EqUzABsEUddyJYUKyfpUR2fW-Ku4x3VF0Rykw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> 2016-09-15 17:42 ` Christian König 2016-09-27 9:49 VRAM manager Christian König [not found] ` <1474969797-1882-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 2016-09-27 9:49 ` [PATCH 6/6] drm/amdgpu: add VRAM manager v2 Christian König [not found] ` <1474969797-1882-7-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org> 2016-09-27 9:57 ` zhoucm1
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.