Commit e376573f authored by Michel Dänzer's avatar Michel Dänzer Committed by Dave Airlie

drm/radeon: fall back to GTT if bo creation/validation in VRAM fails.

This fixes a problem where on low VRAM cards we'd run out of space for validation.

[airlied: Tested on my M7, Thinkpad T42, compiz works with no problems.]
Signed-off-by: default avatarMichel Dänzer <daenzer@vmware.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 351a52a2
...@@ -110,6 +110,7 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, ...@@ -110,6 +110,7 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
bo->surface_reg = -1; bo->surface_reg = -1;
INIT_LIST_HEAD(&bo->list); INIT_LIST_HEAD(&bo->list);
retry:
radeon_ttm_placement_from_domain(bo, domain); radeon_ttm_placement_from_domain(bo, domain);
/* Kernel allocation are uninterruptible */ /* Kernel allocation are uninterruptible */
mutex_lock(&rdev->vram_mutex); mutex_lock(&rdev->vram_mutex);
...@@ -118,10 +119,15 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, ...@@ -118,10 +119,15 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
&radeon_ttm_bo_destroy); &radeon_ttm_bo_destroy);
mutex_unlock(&rdev->vram_mutex); mutex_unlock(&rdev->vram_mutex);
if (unlikely(r != 0)) { if (unlikely(r != 0)) {
if (r != -ERESTARTSYS) if (r != -ERESTARTSYS) {
if (domain == RADEON_GEM_DOMAIN_VRAM) {
domain |= RADEON_GEM_DOMAIN_GTT;
goto retry;
}
dev_err(rdev->dev, dev_err(rdev->dev,
"object_init failed for (%lu, 0x%08X)\n", "object_init failed for (%lu, 0x%08X)\n",
size, domain); size, domain);
}
return r; return r;
} }
*bo_ptr = bo; *bo_ptr = bo;
...@@ -321,6 +327,7 @@ int radeon_bo_list_validate(struct list_head *head) ...@@ -321,6 +327,7 @@ int radeon_bo_list_validate(struct list_head *head)
{ {
struct radeon_bo_list *lobj; struct radeon_bo_list *lobj;
struct radeon_bo *bo; struct radeon_bo *bo;
u32 domain;
int r; int r;
list_for_each_entry(lobj, head, list) { list_for_each_entry(lobj, head, list) {
...@@ -333,18 +340,20 @@ int radeon_bo_list_validate(struct list_head *head) ...@@ -333,18 +340,20 @@ int radeon_bo_list_validate(struct list_head *head)
list_for_each_entry(lobj, head, list) { list_for_each_entry(lobj, head, list) {
bo = lobj->bo; bo = lobj->bo;
if (!bo->pin_count) { if (!bo->pin_count) {
if (lobj->wdomain) { domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain;
radeon_ttm_placement_from_domain(bo,
lobj->wdomain); retry:
} else { radeon_ttm_placement_from_domain(bo, domain);
radeon_ttm_placement_from_domain(bo,
lobj->rdomain);
}
r = ttm_bo_validate(&bo->tbo, &bo->placement, r = ttm_bo_validate(&bo->tbo, &bo->placement,
true, false, false); true, false, false);
if (unlikely(r)) if (unlikely(r)) {
if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) {
domain |= RADEON_GEM_DOMAIN_GTT;
goto retry;
}
return r; return r;
} }
}
lobj->gpu_offset = radeon_bo_gpu_offset(bo); lobj->gpu_offset = radeon_bo_gpu_offset(bo);
lobj->tiling_flags = bo->tiling_flags; lobj->tiling_flags = bo->tiling_flags;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment