mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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:
		
							parent
							
								
									0665f9f852
								
							
						
					
					
						commit
						4f49ec92be
					
				
					 7 changed files with 20 additions and 24 deletions
				
			
		| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue