From: Jerome Glisse <jglisse@xxxxxxxxxx> Forbid allocating buffer bigger than VRAM or GTT, also properly set lpfn field of placement if VRAM is too small. Signed-off-by: Jerome Glisse <jglisse@xxxxxxxxxx> --- drivers/gpu/drm/radeon/radeon.h | 2 +- drivers/gpu/drm/radeon/radeon_object.c | 19 ++++++++++++++----- drivers/gpu/drm/radeon/radeon_ttm.c | 6 +++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 73f600d..2068cf4 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1361,7 +1361,7 @@ extern void radeon_surface_init(struct radeon_device *rdev); extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); -extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); +extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain, u32 size); extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 8eb1834..a09d076 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -64,12 +64,18 @@ bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo) return false; } -void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) +void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain, u32 size) { u32 c = 0; rbo->placement.fpfn = 0; rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; + /* size bigger than vram directly fallback to GTT*/ + if (size >= rbo->rdev->mc.active_vram_size) { + rbo->placement.lpfn = rbo->rdev->mc.gtt_size >> PAGE_SHIFT; + if (!(domain & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_CPU))) + domain |= RADEON_GEM_DOMAIN_GTT; + } rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements; if (domain & RADEON_GEM_DOMAIN_VRAM) @@ -102,6 +108,9 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, type = ttm_bo_type_device; } *bo_ptr = NULL; + if (size >= rdev->mc.active_vram_size && size >= rdev->mc.gtt_size) { + return -ENOMEM; + } retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); @@ -111,7 +120,7 @@ retry: bo->gobj = gobj; bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); - radeon_ttm_placement_from_domain(bo, domain); + radeon_ttm_placement_from_domain(bo, domain, size); /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, @@ -197,7 +206,7 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) *gpu_addr = radeon_bo_gpu_offset(bo); return 0; } - radeon_ttm_placement_from_domain(bo, domain); + radeon_ttm_placement_from_domain(bo, domain, bo->tbo.num_pages << PAGE_SHIFT); if (domain == RADEON_GEM_DOMAIN_VRAM) { /* force to pin into visible video ram */ bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT; @@ -343,7 +352,7 @@ int radeon_bo_list_validate(struct list_head *head) domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; retry: - radeon_ttm_placement_from_domain(bo, domain); + radeon_ttm_placement_from_domain(bo, domain, bo->tbo.num_pages << PAGE_SHIFT); r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false, false); if (unlikely(r)) { @@ -535,7 +544,7 @@ int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) offset = bo->mem.start << PAGE_SHIFT; if ((offset + size) > rdev->mc.visible_vram_size) { /* hurrah the memory is not visible ! */ - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM); + radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM, bo->num_pages << PAGE_SHIFT); rbo->placement.lpfn = rdev->mc.visible_vram_size >> PAGE_SHIFT; r = ttm_bo_validate(bo, &rbo->placement, false, true, false); if (unlikely(r != 0)) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 01c2c73..8695319 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -207,13 +207,13 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, switch (bo->mem.mem_type) { case TTM_PL_VRAM: if (rbo->rdev->cp.ready == false) - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); + radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU, bo->num_pages << PAGE_SHIFT); else - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); + radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT, bo->num_pages << PAGE_SHIFT); break; case TTM_PL_TT: default: - radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); + radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU, bo->num_pages << PAGE_SHIFT); } *placement = rbo->placement; } -- 1.7.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel