From: Jerome Glisse <jgli...@redhat.com>

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 <jgli...@redhat.com>
---
 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to