mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-24 17:59:32 +00:00
drm/ttm: Fix memory space allocation v2
In the event that TTM doesn't find a compatible memory type for the driver's first placement choice (placement without eviction), TTM returns -EINVAL without trying the driver's second choice. This causes problems on vmwgfx when VRAM is disabled before first modeset and during VT switches when fbdev is not enabled. Fix this by also trying the driver's second choice before returning -EINVAL. v2: Also check that man->use_type is true for the driver's second choice. Fixes a bug where disallowed memory types could be used. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com>
This commit is contained in:
parent
2e586a7e01
commit
e30f3963f2
1 changed files with 16 additions and 12 deletions
|
@ -882,6 +882,8 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
|
|||
if (ret)
|
||||
return ret;
|
||||
man = &bdev->man[mem_type];
|
||||
if (!man->has_type || !man->use_type)
|
||||
continue;
|
||||
|
||||
type_ok = ttm_bo_mt_compatible(man, mem_type, place,
|
||||
&cur_flags);
|
||||
|
@ -889,6 +891,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
|
|||
if (!type_ok)
|
||||
continue;
|
||||
|
||||
type_found = true;
|
||||
cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
|
||||
cur_flags);
|
||||
/*
|
||||
|
@ -901,12 +904,10 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
|
|||
if (mem_type == TTM_PL_SYSTEM)
|
||||
break;
|
||||
|
||||
if (man->has_type && man->use_type) {
|
||||
type_found = true;
|
||||
ret = (*man->func->get_node)(man, bo, place, mem);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
}
|
||||
ret = (*man->func->get_node)(man, bo, place, mem);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
|
||||
if (mem->mm_node)
|
||||
break;
|
||||
}
|
||||
|
@ -917,9 +918,6 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!type_found)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < placement->num_busy_placement; ++i) {
|
||||
const struct ttm_place *place = &placement->busy_placement[i];
|
||||
|
||||
|
@ -927,11 +925,12 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
|
|||
if (ret)
|
||||
return ret;
|
||||
man = &bdev->man[mem_type];
|
||||
if (!man->has_type)
|
||||
if (!man->has_type || !man->use_type)
|
||||
continue;
|
||||
if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
|
||||
continue;
|
||||
|
||||
type_found = true;
|
||||
cur_flags = ttm_bo_select_caching(man, bo->mem.placement,
|
||||
cur_flags);
|
||||
/*
|
||||
|
@ -957,8 +956,13 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
|
|||
if (ret == -ERESTARTSYS)
|
||||
has_erestartsys = true;
|
||||
}
|
||||
ret = (has_erestartsys) ? -ERESTARTSYS : -ENOMEM;
|
||||
return ret;
|
||||
|
||||
if (!type_found) {
|
||||
printk(KERN_ERR TTM_PFX "No compatible memory type found.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return (has_erestartsys) ? -ERESTARTSYS : -ENOMEM;
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_mem_space);
|
||||
|
||||
|
|
Loading…
Reference in a new issue