diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 68 | 
1 files changed, 44 insertions, 24 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 365e3fb6a9e5..7b5ce00f0602 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -61,6 +61,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,  		amdgpu_ctx_put(p->ctx);  		return -ECANCELED;  	} + +	amdgpu_sync_create(&p->sync);  	return 0;  } @@ -294,12 +296,8 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,  	}  	for (i = 0; i < p->gang_size; ++i) { -		ret = amdgpu_job_alloc(p->adev, num_ibs[i], &p->jobs[i], vm); -		if (ret) -			goto free_all_kdata; - -		ret = drm_sched_job_init(&p->jobs[i]->base, p->entities[i], -					 &fpriv->vm); +		ret = amdgpu_job_alloc(p->adev, vm, p->entities[i], vm, +				       num_ibs[i], &p->jobs[i]);  		if (ret)  			goto free_all_kdata;  	} @@ -433,7 +431,7 @@ static int amdgpu_cs_p2_dependencies(struct amdgpu_cs_parser *p,  			dma_fence_put(old);  		} -		r = amdgpu_sync_fence(&p->gang_leader->sync, fence); +		r = amdgpu_sync_fence(&p->sync, fence);  		dma_fence_put(fence);  		if (r)  			return r; @@ -455,9 +453,8 @@ static int amdgpu_syncobj_lookup_and_add(struct amdgpu_cs_parser *p,  		return r;  	} -	r = amdgpu_sync_fence(&p->gang_leader->sync, fence); +	r = amdgpu_sync_fence(&p->sync, fence);  	dma_fence_put(fence); -  	return r;  } @@ -1106,7 +1103,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)  	if (r)  		return r; -	r = amdgpu_sync_fence(&job->sync, fpriv->prt_va->last_pt_update); +	r = amdgpu_sync_fence(&p->sync, fpriv->prt_va->last_pt_update);  	if (r)  		return r; @@ -1117,7 +1114,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)  		if (r)  			return r; -		r = amdgpu_sync_fence(&job->sync, bo_va->last_pt_update); +		r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);  		if (r)  			return r;  	} @@ -1136,7 +1133,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)  		if (r)  			return r; -		r = amdgpu_sync_fence(&job->sync, bo_va->last_pt_update); +		r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);  		if (r)  			return r;  	} @@ -1149,7 +1146,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)  	if (r)  		return r; -	r = amdgpu_sync_fence(&job->sync, vm->last_update); +	r = amdgpu_sync_fence(&p->sync, vm->last_update);  	if (r)  		return r; @@ -1181,11 +1178,19 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)  static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)  {  	struct amdgpu_fpriv *fpriv = p->filp->driver_priv; -	struct amdgpu_job *leader = p->gang_leader; +	struct drm_gpu_scheduler *sched;  	struct amdgpu_bo_list_entry *e; +	struct dma_fence *fence;  	unsigned int i;  	int r; +	r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entities[p->gang_leader_idx]); +	if (r) { +		if (r != -ERESTARTSYS) +			DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n"); +		return r; +	} +  	list_for_each_entry(e, &p->validated, tv.head) {  		struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);  		struct dma_resv *resv = bo->tbo.base.resv; @@ -1193,25 +1198,36 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)  		sync_mode = amdgpu_bo_explicit_sync(bo) ?  			AMDGPU_SYNC_EXPLICIT : AMDGPU_SYNC_NE_OWNER; -		r = amdgpu_sync_resv(p->adev, &leader->sync, resv, sync_mode, +		r = amdgpu_sync_resv(p->adev, &p->sync, resv, sync_mode,  				     &fpriv->vm);  		if (r)  			return r;  	}  	for (i = 0; i < p->gang_size; ++i) { -		if (p->jobs[i] == leader) +		r = amdgpu_sync_push_to_job(&p->sync, p->jobs[i]); +		if (r) +			return r; +	} + +	sched = p->gang_leader->base.entity->rq->sched; +	while ((fence = amdgpu_sync_get_fence(&p->sync))) { +		struct drm_sched_fence *s_fence = to_drm_sched_fence(fence); + +		/* +		 * When we have an dependency it might be necessary to insert a +		 * pipeline sync to make sure that all caches etc are flushed and the +		 * next job actually sees the results from the previous one +		 * before we start executing on the same scheduler ring. +		 */ +		if (!s_fence || s_fence->sched != sched)  			continue; -		r = amdgpu_sync_clone(&leader->sync, &p->jobs[i]->sync); +		r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence);  		if (r)  			return r;  	} - -	r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entities[p->gang_leader_idx]); -	if (r && r != -ERESTARTSYS) -		DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n"); -	return r; +	return 0;  }  static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) @@ -1251,9 +1267,12 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,  			continue;  		fence = &p->jobs[i]->base.s_fence->scheduled; -		r = amdgpu_sync_fence(&leader->sync, fence); -		if (r) +		dma_fence_get(fence); +		r = drm_sched_job_add_dependency(&leader->base, fence); +		if (r) { +			dma_fence_put(fence);  			goto error_cleanup; +		}  	}  	if (p->gang_size > 1) { @@ -1341,6 +1360,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser)  {  	unsigned i; +	amdgpu_sync_free(&parser->sync);  	for (i = 0; i < parser->num_post_deps; i++) {  		drm_syncobj_put(parser->post_deps[i].syncobj);  		kfree(parser->post_deps[i].chain); | 
