qxl: allow creation of pre-pinned objects and use for releases.

In order to fix an issue with reservations we need to create the releases
as pre-pinned objects, this changes the placement interface and bo creation
interface to allow creating pinned objects to save nested reservations later.

This is just a stepping stone to main fix which follows to actually fix how
qxl deals with reservations.

Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie 2013-07-23 14:06:07 +10:00
parent 0665f9f852
commit 4f49ec92be
7 changed files with 20 additions and 24 deletions

View file

@ -266,7 +266,7 @@ int qxl_alloc_bo_reserved(struct qxl_device *qdev, unsigned long size,
int ret; int ret;
ret = qxl_bo_create(qdev, size, false /* not kernel - device */, ret = qxl_bo_create(qdev, size, false /* not kernel - device */,
QXL_GEM_DOMAIN_VRAM, NULL, &bo); false, QXL_GEM_DOMAIN_VRAM, NULL, &bo);
if (ret) { if (ret) {
DRM_ERROR("failed to allocate VRAM BO\n"); DRM_ERROR("failed to allocate VRAM BO\n");
return ret; return ret;

View file

@ -55,7 +55,7 @@ int qxl_gem_object_create(struct qxl_device *qdev, int size,
/* At least align on page size */ /* At least align on page size */
if (alignment < PAGE_SIZE) if (alignment < PAGE_SIZE)
alignment = PAGE_SIZE; alignment = PAGE_SIZE;
r = qxl_bo_create(qdev, size, kernel, initial_domain, surf, &qbo); r = qxl_bo_create(qdev, size, kernel, false, initial_domain, surf, &qbo);
if (r) { if (r) {
if (r != -ERESTARTSYS) if (r != -ERESTARTSYS)
DRM_ERROR( DRM_ERROR(

View file

@ -305,7 +305,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data,
goto out; goto out;
if (!qobj->pin_count) { if (!qobj->pin_count) {
qxl_ttm_placement_from_domain(qobj, qobj->type); qxl_ttm_placement_from_domain(qobj, qobj->type, false);
ret = ttm_bo_validate(&qobj->tbo, &qobj->placement, ret = ttm_bo_validate(&qobj->tbo, &qobj->placement,
true, false); true, false);
if (unlikely(ret)) if (unlikely(ret))

View file

@ -51,20 +51,21 @@ bool qxl_ttm_bo_is_qxl_bo(struct ttm_buffer_object *bo)
return false; return false;
} }
void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain) void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned)
{ {
u32 c = 0; u32 c = 0;
u32 pflag = pinned ? TTM_PL_FLAG_NO_EVICT : 0;
qbo->placement.fpfn = 0; qbo->placement.fpfn = 0;
qbo->placement.lpfn = 0; qbo->placement.lpfn = 0;
qbo->placement.placement = qbo->placements; qbo->placement.placement = qbo->placements;
qbo->placement.busy_placement = qbo->placements; qbo->placement.busy_placement = qbo->placements;
if (domain == QXL_GEM_DOMAIN_VRAM) if (domain == QXL_GEM_DOMAIN_VRAM)
qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_VRAM; qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_VRAM | pflag;
if (domain == QXL_GEM_DOMAIN_SURFACE) if (domain == QXL_GEM_DOMAIN_SURFACE)
qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_PRIV0; qbo->placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_PRIV0 | pflag;
if (domain == QXL_GEM_DOMAIN_CPU) if (domain == QXL_GEM_DOMAIN_CPU)
qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM | pflag;
if (!c) if (!c)
qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; qbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
qbo->placement.num_placement = c; qbo->placement.num_placement = c;
@ -73,7 +74,7 @@ void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain)
int qxl_bo_create(struct qxl_device *qdev, int qxl_bo_create(struct qxl_device *qdev,
unsigned long size, bool kernel, u32 domain, unsigned long size, bool kernel, bool pinned, u32 domain,
struct qxl_surface *surf, struct qxl_surface *surf,
struct qxl_bo **bo_ptr) struct qxl_bo **bo_ptr)
{ {
@ -99,7 +100,7 @@ int qxl_bo_create(struct qxl_device *qdev,
} }
bo->gem_base.driver_private = NULL; bo->gem_base.driver_private = NULL;
bo->type = domain; bo->type = domain;
bo->pin_count = 0; bo->pin_count = pinned ? 1 : 0;
bo->surface_id = 0; bo->surface_id = 0;
qxl_fence_init(qdev, &bo->fence); qxl_fence_init(qdev, &bo->fence);
INIT_LIST_HEAD(&bo->list); INIT_LIST_HEAD(&bo->list);
@ -107,7 +108,7 @@ int qxl_bo_create(struct qxl_device *qdev,
if (surf) if (surf)
bo->surf = *surf; bo->surf = *surf;
qxl_ttm_placement_from_domain(bo, domain); qxl_ttm_placement_from_domain(bo, domain, pinned);
r = ttm_bo_init(&qdev->mman.bdev, &bo->tbo, size, type, r = ttm_bo_init(&qdev->mman.bdev, &bo->tbo, size, type,
&bo->placement, 0, !kernel, NULL, size, &bo->placement, 0, !kernel, NULL, size,
@ -228,7 +229,7 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr) int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
{ {
struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private; struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private;
int r, i; int r;
if (bo->pin_count) { if (bo->pin_count) {
bo->pin_count++; bo->pin_count++;
@ -236,9 +237,7 @@ int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr)
*gpu_addr = qxl_bo_gpu_offset(bo); *gpu_addr = qxl_bo_gpu_offset(bo);
return 0; return 0;
} }
qxl_ttm_placement_from_domain(bo, domain); qxl_ttm_placement_from_domain(bo, domain, true);
for (i = 0; i < bo->placement.num_placement; i++)
bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
if (likely(r == 0)) { if (likely(r == 0)) {
bo->pin_count = 1; bo->pin_count = 1;
@ -350,7 +349,7 @@ int qxl_bo_list_add(struct qxl_reloc_list *reloc_list, struct qxl_bo *bo)
return ret; return ret;
if (!bo->pin_count) { if (!bo->pin_count) {
qxl_ttm_placement_from_domain(bo, bo->type); qxl_ttm_placement_from_domain(bo, bo->type, false);
ret = ttm_bo_validate(&bo->tbo, &bo->placement, ret = ttm_bo_validate(&bo->tbo, &bo->placement,
true, false); true, false);
if (ret) if (ret)

View file

@ -88,7 +88,7 @@ static inline int qxl_bo_wait(struct qxl_bo *bo, u32 *mem_type,
extern int qxl_bo_create(struct qxl_device *qdev, extern int qxl_bo_create(struct qxl_device *qdev,
unsigned long size, unsigned long size,
bool kernel, u32 domain, bool kernel, bool pinned, u32 domain,
struct qxl_surface *surf, struct qxl_surface *surf,
struct qxl_bo **bo_ptr); struct qxl_bo **bo_ptr);
extern int qxl_bo_kmap(struct qxl_bo *bo, void **ptr); extern int qxl_bo_kmap(struct qxl_bo *bo, void **ptr);
@ -99,7 +99,7 @@ extern struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo);
extern void qxl_bo_unref(struct qxl_bo **bo); extern void qxl_bo_unref(struct qxl_bo **bo);
extern int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr); extern int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr);
extern int qxl_bo_unpin(struct qxl_bo *bo); extern int qxl_bo_unpin(struct qxl_bo *bo);
extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain); extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain, bool pinned);
extern bool qxl_ttm_bo_is_qxl_bo(struct ttm_buffer_object *bo); extern bool qxl_ttm_bo_is_qxl_bo(struct ttm_buffer_object *bo);
extern int qxl_bo_list_add(struct qxl_reloc_list *reloc_list, struct qxl_bo *bo); extern int qxl_bo_list_add(struct qxl_reloc_list *reloc_list, struct qxl_bo *bo);

View file

@ -118,7 +118,9 @@ static int qxl_release_bo_alloc(struct qxl_device *qdev,
struct qxl_bo **bo) struct qxl_bo **bo)
{ {
int ret; int ret;
ret = qxl_bo_create(qdev, PAGE_SIZE, false, QXL_GEM_DOMAIN_VRAM, NULL, /* pin releases bo's they are too messy to evict */
ret = qxl_bo_create(qdev, PAGE_SIZE, false, true,
QXL_GEM_DOMAIN_VRAM, NULL,
bo); bo);
return ret; return ret;
} }
@ -216,11 +218,6 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
mutex_unlock(&qdev->release_mutex); mutex_unlock(&qdev->release_mutex);
return ret; return ret;
} }
/* pin releases bo's they are too messy to evict */
ret = qxl_bo_reserve(qdev->current_release_bo[cur_idx], false);
qxl_bo_pin(qdev->current_release_bo[cur_idx], QXL_GEM_DOMAIN_VRAM, NULL);
qxl_bo_unreserve(qdev->current_release_bo[cur_idx]);
} }
bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]); bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]);

View file

@ -206,7 +206,7 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo,
return; return;
} }
qbo = container_of(bo, struct qxl_bo, tbo); qbo = container_of(bo, struct qxl_bo, tbo);
qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU); qxl_ttm_placement_from_domain(qbo, QXL_GEM_DOMAIN_CPU, false);
*placement = qbo->placement; *placement = qbo->placement;
} }