diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 102 | 
1 files changed, 44 insertions, 58 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 970b065e9a6b..e552a2004868 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -55,8 +55,8 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,  	bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));  	p->uf_entry.priority = 0;  	p->uf_entry.tv.bo = &bo->tbo; -	/* One for TTM and one for the CS job */ -	p->uf_entry.tv.num_shared = 2; +	/* One for TTM and two for the CS job */ +	p->uf_entry.tv.num_shared = 3;  	drm_gem_object_put(gobj); @@ -128,6 +128,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs  		goto free_chunk;  	} +	mutex_lock(&p->ctx->lock); +  	/* skip guilty context job */  	if (atomic_read(&p->ctx->guilty) == 1) {  		ret = -ECANCELED; @@ -543,14 +545,15 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,  					GFP_KERNEL | __GFP_ZERO);  		if (!e->user_pages) {  			DRM_ERROR("kvmalloc_array failure\n"); -			return -ENOMEM; +			r = -ENOMEM; +			goto out_free_user_pages;  		}  		r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages);  		if (r) {  			kvfree(e->user_pages);  			e->user_pages = NULL; -			return r; +			goto out_free_user_pages;  		}  		for (i = 0; i < bo->tbo.ttm->num_pages; i++) { @@ -567,21 +570,13 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,  	if (unlikely(r != 0)) {  		if (r != -ERESTARTSYS)  			DRM_ERROR("ttm_eu_reserve_buffers failed.\n"); -		goto out; +		goto out_free_user_pages;  	}  	amdgpu_bo_list_for_each_entry(e, p->bo_list) {  		struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);  		e->bo_va = amdgpu_vm_bo_find(vm, bo); - -		if (bo->tbo.base.dma_buf && !amdgpu_bo_explicit_sync(bo)) { -			e->chain = dma_fence_chain_alloc(); -			if (!e->chain) { -				r = -ENOMEM; -				goto error_validate; -			} -		}  	}  	/* Move fence waiting after getting reservation lock of @@ -642,14 +637,21 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,  	}  error_validate: +	if (r) +		ttm_eu_backoff_reservation(&p->ticket, &p->validated); + +out_free_user_pages:  	if (r) { -		amdgpu_bo_list_for_each_entry(e, p->bo_list) { -			dma_fence_chain_free(e->chain); -			e->chain = NULL; +		amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { +			struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo); + +			if (!e->user_pages) +				continue; +			amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); +			kvfree(e->user_pages); +			e->user_pages = NULL;  		} -		ttm_eu_backoff_reservation(&p->ticket, &p->validated);  	} -out:  	return r;  } @@ -688,17 +690,9 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,  {  	unsigned i; -	if (error && backoff) { -		struct amdgpu_bo_list_entry *e; - -		amdgpu_bo_list_for_each_entry(e, parser->bo_list) { -			dma_fence_chain_free(e->chain); -			e->chain = NULL; -		} - +	if (error && backoff)  		ttm_eu_backoff_reservation(&parser->ticket,  					   &parser->validated); -	}  	for (i = 0; i < parser->num_post_deps; i++) {  		drm_syncobj_put(parser->post_deps[i].syncobj); @@ -709,6 +703,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,  	dma_fence_put(parser->fence);  	if (parser->ctx) { +		mutex_unlock(&parser->ctx->lock);  		amdgpu_ctx_put(parser->ctx);  	}  	if (parser->bo_list) @@ -806,22 +801,22 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)  	if (r)  		return r; -	r = amdgpu_vm_bo_update(adev, fpriv->prt_va, false, NULL); +	r = amdgpu_vm_bo_update(adev, fpriv->prt_va, false);  	if (r)  		return r; -	r = amdgpu_sync_vm_fence(&p->job->sync, fpriv->prt_va->last_pt_update); +	r = amdgpu_sync_fence(&p->job->sync, fpriv->prt_va->last_pt_update);  	if (r)  		return r;  	if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {  		bo_va = fpriv->csa_va;  		BUG_ON(!bo_va); -		r = amdgpu_vm_bo_update(adev, bo_va, false, NULL); +		r = amdgpu_vm_bo_update(adev, bo_va, false);  		if (r)  			return r; -		r = amdgpu_sync_vm_fence(&p->job->sync, bo_va->last_pt_update); +		r = amdgpu_sync_fence(&p->job->sync, bo_va->last_pt_update);  		if (r)  			return r;  	} @@ -836,11 +831,11 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)  		if (bo_va == NULL)  			continue; -		r = amdgpu_vm_bo_update(adev, bo_va, false, NULL); +		r = amdgpu_vm_bo_update(adev, bo_va, false);  		if (r)  			return r; -		r = amdgpu_sync_vm_fence(&p->job->sync, bo_va->last_pt_update); +		r = amdgpu_sync_fence(&p->job->sync, bo_va->last_pt_update);  		if (r)  			return r;  	} @@ -853,7 +848,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)  	if (r)  		return r; -	r = amdgpu_sync_vm_fence(&p->job->sync, vm->last_update); +	r = amdgpu_sync_fence(&p->job->sync, vm->last_update);  	if (r)  		return r; @@ -1157,6 +1152,9 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,  {  	int i, r; +	/* TODO: Investigate why we still need the context lock */ +	mutex_unlock(&p->ctx->lock); +  	for (i = 0; i < p->nchunks; ++i) {  		struct amdgpu_cs_chunk *chunk; @@ -1167,32 +1165,34 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,  		case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:  			r = amdgpu_cs_process_fence_dep(p, chunk);  			if (r) -				return r; +				goto out;  			break;  		case AMDGPU_CHUNK_ID_SYNCOBJ_IN:  			r = amdgpu_cs_process_syncobj_in_dep(p, chunk);  			if (r) -				return r; +				goto out;  			break;  		case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:  			r = amdgpu_cs_process_syncobj_out_dep(p, chunk);  			if (r) -				return r; +				goto out;  			break;  		case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:  			r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk);  			if (r) -				return r; +				goto out;  			break;  		case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:  			r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk);  			if (r) -				return r; +				goto out;  			break;  		}  	} -	return 0; +out: +	mutex_lock(&p->ctx->lock); +	return r;  }  static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) @@ -1272,24 +1272,9 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,  	amdgpu_vm_move_to_lru_tail(p->adev, &fpriv->vm); -	amdgpu_bo_list_for_each_entry(e, p->bo_list) { -		struct dma_resv *resv = e->tv.bo->base.resv; -		struct dma_fence_chain *chain = e->chain; - -		if (!chain) -			continue; - -		/* -		 * Work around dma_resv shortcomings by wrapping up the -		 * submission in a dma_fence_chain and add it as exclusive -		 * fence. -		 */ -		dma_fence_chain_init(chain, dma_resv_excl_fence(resv), -				     dma_fence_get(p->fence), 1); - -		rcu_assign_pointer(resv->fence_excl, &chain->base); -		e->chain = NULL; -	} +	/* Make sure all BOs are remembered as writers */ +	amdgpu_bo_list_for_each_entry(e, p->bo_list) +		e->tv.num_shared = 0;  	ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence);  	mutex_unlock(&p->adev->notifier_lock); @@ -1368,6 +1353,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  		goto out;  	r = amdgpu_cs_submit(&parser, cs); +  out:  	amdgpu_cs_parser_fini(&parser, r, reserved_buffers); | 
