On Fre, 2010-11-19 at 16:34 -0500, jglisse@redhat.com wrote:
From: Jerome Glisse jglisse@redhat.com
Forbid allocating buffer bigger than visible VRAM or GTT, also properly set lpfn field.
v2 - use max macro
- silence warning
Signed-off-by: Jerome Glisse jglisse@redhat.com
drivers/gpu/drm/radeon/radeon_object.c | 34 ++++++++++++++++++++++++++----- 1 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d06774..c2fa64c 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -69,18 +69,28 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) u32 c = 0;
rbo->placement.fpfn = 0;
- rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT;
- rbo->placement.lpfn = 0; rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements;
- if (domain & RADEON_GEM_DOMAIN_VRAM)
- if (domain & RADEON_GEM_DOMAIN_VRAM) {
rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;rbo->placement.lpfn = max((unsigned)rbo->placement.lpfn, (unsigned)rbo->rdev->mc.active_vram_size >> PAGE_SHIFT);
- if (domain & RADEON_GEM_DOMAIN_GTT)
- }
- if (domain & RADEON_GEM_DOMAIN_GTT) {
rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;rbo->placement.lpfn = max((unsigned)rbo->placement.lpfn, (unsigned)rbo->rdev->mc.gtt_size >> PAGE_SHIFT);
- if (domain & RADEON_GEM_DOMAIN_CPU)
- }
- if (domain & RADEON_GEM_DOMAIN_CPU) {
/* 4G limit for CPU domain */
rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;rbo->placement.lpfn = max(rbo->placement.lpfn, 0xFFFFFFFF >> PAGE_SHIFT);
- if (!c)
- }
- if (!c) {
/* 4G limit for CPU domain */
rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;rbo->placement.lpfn = max(rbo->placement.lpfn, 0xFFFFFFFF >> PAGE_SHIFT);
- }
I don't think taxing the maximum is the right thing to do: If domain is (RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT) and VRAM doesn't happen to be the same size as GTT, lpfn will end up larger than one of them.
AFAICT radeon_ttm_placement_from_domain() should just set lpfn to 0 (i.e. unrestricted), the callers that need it to be non-0 already set it afterwards.
Out of curiosity, where does the 4G limit come from?
@@ -104,6 +115,17 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, } *bo_ptr = NULL;
- /* maximun bo size is the minimun btw visible vram and gtt size */
- max_size = rdev->mc.visible_vram_size;
- if (max_size > rdev->mc.gtt_size) {
max_size = rdev->mc.gtt_size;
- }
max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size);
Except I think this should actually be max(...).
- if ((page_align << PAGE_SHIFT) >= max_size) {
printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n",
__func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20);
return -ENOMEM;
- }
Maybe this should be rate-limited, or userspace can spam dmesg.