diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 99 | 
1 files changed, 45 insertions, 54 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 3b4c19412625..dc262d2c2925 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -424,8 +424,9 @@ error:  static bool amdgpu_mem_visible(struct amdgpu_device *adev,  			       struct ttm_resource *mem)  { -	uint64_t mem_size = (u64)mem->num_pages << PAGE_SHIFT; +	u64 mem_size = (u64)mem->num_pages << PAGE_SHIFT;  	struct amdgpu_res_cursor cursor; +	u64 end;  	if (mem->mem_type == TTM_PL_SYSTEM ||  	    mem->mem_type == TTM_PL_TT) @@ -434,12 +435,18 @@ static bool amdgpu_mem_visible(struct amdgpu_device *adev,  		return false;  	amdgpu_res_first(mem, 0, mem_size, &cursor); +	end = cursor.start + cursor.size; +	while (cursor.remaining) { +		amdgpu_res_next(&cursor, cursor.size); -	/* ttm_resource_ioremap only supports contiguous memory */ -	if (cursor.size != mem_size) -		return false; +		/* ttm_resource_ioremap only supports contiguous memory */ +		if (end != cursor.start) +			return false; + +		end = cursor.start + cursor.size; +	} -	return cursor.start + cursor.size <= adev->gmc.visible_vram_size; +	return end <= adev->gmc.visible_vram_size;  }  /* @@ -471,7 +478,8 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,  	adev = amdgpu_ttm_adev(bo->bdev); -	if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { +	if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM && +			 bo->ttm == NULL)) {  		ttm_bo_move_null(bo, new_mem);  		goto out;  	} @@ -637,6 +645,8 @@ struct amdgpu_ttm_tt {  #endif  }; +#define ttm_to_amdgpu_ttm_tt(ptr)	container_of(ptr, struct amdgpu_ttm_tt, ttm) +  #ifdef CONFIG_DRM_AMDGPU_USERPTR  /*   * amdgpu_ttm_tt_get_user_pages - get device accessible pages that back user @@ -648,7 +658,7 @@ struct amdgpu_ttm_tt {  int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)  {  	struct ttm_tt *ttm = bo->tbo.ttm; -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	unsigned long start = gtt->userptr;  	struct vm_area_struct *vma;  	struct mm_struct *mm; @@ -702,7 +712,7 @@ out_unlock:   */  bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)  { -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	bool r = false;  	if (!gtt || !gtt->userptr) @@ -751,7 +761,7 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_device *bdev,  				     struct ttm_tt *ttm)  {  	struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);  	enum dma_data_direction direction = write ?  		DMA_BIDIRECTIONAL : DMA_TO_DEVICE; @@ -788,7 +798,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_device *bdev,  					struct ttm_tt *ttm)  {  	struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);  	enum dma_data_direction direction = write ?  		DMA_BIDIRECTIONAL : DMA_TO_DEVICE; @@ -822,7 +832,7 @@ static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev,  {  	struct amdgpu_bo *abo = ttm_to_amdgpu_bo(tbo);  	struct ttm_tt *ttm = tbo->ttm; -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	if (amdgpu_bo_encrypted(abo))  		flags |= AMDGPU_PTE_TMZ; @@ -860,7 +870,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_device *bdev,  				   struct ttm_resource *bo_mem)  {  	struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); -	struct amdgpu_ttm_tt *gtt = (void*)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	uint64_t flags;  	int r; @@ -927,7 +937,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo)  {  	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);  	struct ttm_operation_ctx ctx = { false, false }; -	struct amdgpu_ttm_tt *gtt = (void *)bo->ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(bo->ttm);  	struct ttm_placement placement;  	struct ttm_place placements;  	struct ttm_resource *tmp; @@ -998,7 +1008,7 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,  				      struct ttm_tt *ttm)  {  	struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	/* if the pages have userptr pinning then clear that first */  	if (gtt->userptr) { @@ -1025,7 +1035,7 @@ static void amdgpu_ttm_backend_unbind(struct ttm_device *bdev,  static void amdgpu_ttm_backend_destroy(struct ttm_device *bdev,  				       struct ttm_tt *ttm)  { -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	if (gtt->usertask)  		put_task_struct(gtt->usertask); @@ -1079,7 +1089,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev,  				  struct ttm_operation_ctx *ctx)  {  	struct amdgpu_device *adev = amdgpu_ttm_adev(bdev); -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	pgoff_t i;  	int ret; @@ -1113,7 +1123,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev,  static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev,  				     struct ttm_tt *ttm)  { -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	struct amdgpu_device *adev;  	pgoff_t i; @@ -1182,7 +1192,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,  	/* Set TTM_TT_FLAG_EXTERNAL before populate but after create. */  	bo->ttm->page_flags |= TTM_TT_FLAG_EXTERNAL; -	gtt = (void *)bo->ttm; +	gtt = ttm_to_amdgpu_ttm_tt(bo->ttm);  	gtt->userptr = addr;  	gtt->userflags = flags; @@ -1199,7 +1209,7 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,   */  struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)  { -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	if (gtt == NULL)  		return NULL; @@ -1218,7 +1228,7 @@ struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm)  bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,  				  unsigned long end, unsigned long *userptr)  { -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	unsigned long size;  	if (gtt == NULL || !gtt->userptr) @@ -1241,7 +1251,7 @@ bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,   */  bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm)  { -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	if (gtt == NULL || !gtt->userptr)  		return false; @@ -1254,7 +1264,7 @@ bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm)   */  bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm)  { -	struct amdgpu_ttm_tt *gtt = (void *)ttm; +	struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm);  	if (gtt == NULL)  		return false; @@ -1327,11 +1337,12 @@ uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,  static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,  					    const struct ttm_place *place)  { -	unsigned long num_pages = bo->resource->num_pages;  	struct dma_resv_iter resv_cursor; -	struct amdgpu_res_cursor cursor;  	struct dma_fence *f; +	if (!amdgpu_bo_is_amdgpu_bo(bo)) +		return ttm_bo_eviction_valuable(bo, place); +  	/* Swapout? */  	if (bo->resource->mem_type == TTM_PL_SYSTEM)  		return true; @@ -1350,40 +1361,20 @@ static bool amdgpu_ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,  			return false;  	} -	switch (bo->resource->mem_type) { -	case AMDGPU_PL_PREEMPT: -		/* Preemptible BOs don't own system resources managed by the -		 * driver (pages, VRAM, GART space). They point to resources -		 * owned by someone else (e.g. pageable memory in user mode -		 * or a DMABuf). They are used in a preemptible context so we -		 * can guarantee no deadlocks and good QoS in case of MMU -		 * notifiers or DMABuf move notifiers from the resource owner. -		 */ +	/* Preemptible BOs don't own system resources managed by the +	 * driver (pages, VRAM, GART space). They point to resources +	 * owned by someone else (e.g. pageable memory in user mode +	 * or a DMABuf). They are used in a preemptible context so we +	 * can guarantee no deadlocks and good QoS in case of MMU +	 * notifiers or DMABuf move notifiers from the resource owner. +	 */ +	if (bo->resource->mem_type == AMDGPU_PL_PREEMPT)  		return false; -	case TTM_PL_TT: -		if (amdgpu_bo_is_amdgpu_bo(bo) && -		    amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo))) -			return false; -		return true; -	case TTM_PL_VRAM: -		/* Check each drm MM node individually */ -		amdgpu_res_first(bo->resource, 0, (u64)num_pages << PAGE_SHIFT, -				 &cursor); -		while (cursor.remaining) { -			if (place->fpfn < PFN_DOWN(cursor.start + cursor.size) -			    && !(place->lpfn && -				 place->lpfn <= PFN_DOWN(cursor.start))) -				return true; - -			amdgpu_res_next(&cursor, cursor.size); -		} +	if (bo->resource->mem_type == TTM_PL_TT && +	    amdgpu_bo_encrypted(ttm_to_amdgpu_bo(bo)))  		return false; -	default: -		break; -	} -  	return ttm_bo_eviction_valuable(bo, place);  } |