diff options
| author | Dmitry Torokhov <[email protected]> | 2022-12-12 10:47:03 -0800 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2022-12-12 10:47:03 -0800 | 
| commit | e291c116f60f3c1ca98090f0f8e7c77e658562fb (patch) | |
| tree | 2fbe810f2a6f8b29f1cdaefd87b24debbfa0ec07 /drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | |
| parent | 8c9a59939deb4bfafdc451100c03d1e848b4169b (diff) | |
| parent | c3991107a28a5ad0bd90660ca3bbf8c2c220ea98 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.2 merge window.
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_job.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 59 | 
1 files changed, 51 insertions, 8 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 5071b96be982..46c99331d7f1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -49,6 +49,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)  	}  	memset(&ti, 0, sizeof(struct amdgpu_task_info)); +	adev->job_hang = true;  	if (amdgpu_gpu_recovery &&  	    amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) { @@ -71,6 +72,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)  		reset_context.method = AMD_RESET_METHOD_NONE;  		reset_context.reset_req_dev = adev;  		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); +		clear_bit(AMDGPU_SKIP_MODE2_RESET, &reset_context.flags);  		r = amdgpu_device_gpu_recover(ring->adev, job, &reset_context);  		if (r) @@ -82,6 +84,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)  	}  exit: +	adev->job_hang = false;  	drm_dev_exit(idx);  	return DRM_GPU_SCHED_STAT_NOMINAL;  } @@ -102,7 +105,6 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs,  	 */  	(*job)->base.sched = &adev->rings[0]->sched;  	(*job)->vm = vm; -	(*job)->num_ibs = num_ibs;  	amdgpu_sync_create(&(*job)->sync);  	amdgpu_sync_create(&(*job)->sched_sync); @@ -122,6 +124,7 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,  	if (r)  		return r; +	(*job)->num_ibs = 1;  	r = amdgpu_ib_get(adev, NULL, size, pool_type, &(*job)->ibs[0]);  	if (r)  		kfree(*job); @@ -129,6 +132,23 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size,  	return r;  } +void amdgpu_job_set_resources(struct amdgpu_job *job, struct amdgpu_bo *gds, +			      struct amdgpu_bo *gws, struct amdgpu_bo *oa) +{ +	if (gds) { +		job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT; +		job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT; +	} +	if (gws) { +		job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT; +		job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT; +	} +	if (oa) { +		job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT; +		job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT; +	} +} +  void amdgpu_job_free_resources(struct amdgpu_job *job)  {  	struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); @@ -153,13 +173,34 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)  	dma_fence_put(&job->hw_fence);  } +void amdgpu_job_set_gang_leader(struct amdgpu_job *job, +				struct amdgpu_job *leader) +{ +	struct dma_fence *fence = &leader->base.s_fence->scheduled; + +	WARN_ON(job->gang_submit); + +	/* +	 * Don't add a reference when we are the gang leader to avoid circle +	 * dependency. +	 */ +	if (job != leader) +		dma_fence_get(fence); +	job->gang_submit = fence; +} +  void amdgpu_job_free(struct amdgpu_job *job)  {  	amdgpu_job_free_resources(job);  	amdgpu_sync_free(&job->sync);  	amdgpu_sync_free(&job->sched_sync); +	if (job->gang_submit != &job->base.s_fence->scheduled) +		dma_fence_put(job->gang_submit); -	dma_fence_put(&job->hw_fence); +	if (!job->hw_fence.ops) +		kfree(job); +	else +		dma_fence_put(&job->hw_fence);  }  int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity, @@ -224,12 +265,16 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job,  		fence = amdgpu_sync_get_fence(&job->sync);  	} +	if (!fence && job->gang_submit) +		fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit); +  	return fence;  }  static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)  {  	struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched); +	struct amdgpu_device *adev = ring->adev;  	struct dma_fence *fence = NULL, *finished;  	struct amdgpu_job *job;  	int r = 0; @@ -241,8 +286,10 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)  	trace_amdgpu_sched_run_job(job); -	if (job->vram_lost_counter != atomic_read(&ring->adev->vram_lost_counter)) -		dma_fence_set_error(finished, -ECANCELED);/* skip IB as well if VRAM lost */ +	/* Skip job if VRAM is lost and never resubmit gangs */ +	if (job->vram_lost_counter != atomic_read(&adev->vram_lost_counter) || +	    (job->job_run_counter && job->gang_submit)) +		dma_fence_set_error(finished, -ECANCELED);  	if (finished->error < 0) {  		DRM_INFO("Skip scheduling IBs!\n"); @@ -272,10 +319,6 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched)  	/* Signal all jobs not yet scheduled */  	for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {  		struct drm_sched_rq *rq = &sched->sched_rq[i]; - -		if (!rq) -			continue; -  		spin_lock(&rq->lock);  		list_for_each_entry(s_entity, &rq->entities, list) {  			while ((s_job = to_drm_sched_job(spsc_queue_pop(&s_entity->job_queue)))) { |