aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <daenzer@vmware.com>2010-07-08 12:43:28 +1000
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 11:09:22 -0700
commit1e4966cc558d6aac892abeed6434591348103dff (patch)
tree2bc7c196b3b339628f2cd71323a833ab0b0d7a3b
parent37aa5ce0ed1e1535c22fc3d37f36e39dd82e80b1 (diff)
drm/radeon: fall back to GTT if bo creation/validation in VRAM fails.
commit e376573f7267390f4e1bdc552564b6fb913bce76 upstream. 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: Michel Dänzer <daenzer@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index d5b9373ce06..d33b6c91ced 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -110,6 +110,7 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
bo->surface_reg = -1;
INIT_LIST_HEAD(&bo->list);
+retry:
radeon_ttm_placement_from_domain(bo, domain);
/* Kernel allocation are uninterruptible */
mutex_lock(&rdev->vram_mutex);
@@ -118,10 +119,15 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj,
&radeon_ttm_bo_destroy);
mutex_unlock(&rdev->vram_mutex);
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,
"object_init failed for (%lu, 0x%08X)\n",
size, domain);
+ }
return r;
}
*bo_ptr = bo;
@@ -321,6 +327,7 @@ int radeon_bo_list_validate(struct list_head *head)
{
struct radeon_bo_list *lobj;
struct radeon_bo *bo;
+ u32 domain;
int r;
list_for_each_entry(lobj, head, list) {
@@ -333,17 +340,19 @@ int radeon_bo_list_validate(struct list_head *head)
list_for_each_entry(lobj, head, list) {
bo = lobj->bo;
if (!bo->pin_count) {
- if (lobj->wdomain) {
- radeon_ttm_placement_from_domain(bo,
- lobj->wdomain);
- } else {
- radeon_ttm_placement_from_domain(bo,
- lobj->rdomain);
- }
+ domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain;
+
+ retry:
+ radeon_ttm_placement_from_domain(bo, domain);
r = ttm_bo_validate(&bo->tbo, &bo->placement,
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;
+ }
}
lobj->gpu_offset = radeon_bo_gpu_offset(bo);
lobj->tiling_flags = bo->tiling_flags;