diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2022-10-10 08:30:23 +0300 | 
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2022-10-10 08:30:23 +0300 | 
| commit | 5f8f8574c7f5585b09a9623f0f13462e4eb67b4d (patch) | |
| tree | 8f1d5e88bf9604a9e39fbcce0e37b3d8cee451bb /drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | |
| parent | e62563db857f81d75c5726a35bc0180bed6d1540 (diff) | |
| parent | fe5b6aaef72a0f7daa06e7960e0bee45c2984e41 (diff) | |
| download | linux-5f8f8574c7f5585b09a9623f0f13462e4eb67b4d.tar.xz | |
Merge branch 'next' into for-linus
Prepare input updates for 6.1 merge window.
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 57 | 
1 files changed, 52 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index d16c8c1f72db..8adeb7469f1e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -39,6 +39,7 @@  #include <drm/drm_drv.h>  #include "amdgpu.h"  #include "amdgpu_trace.h" +#include "amdgpu_reset.h"  /*   * Fences @@ -46,7 +47,7 @@   * for GPU/CPU synchronization.  When the fence is written,   * it is expected that all buffers associated with that fence   * are no longer in use by the associated ring on the GPU and - * that the the relevant GPU caches have been flushed. + * that the relevant GPU caches have been flushed.   */  struct amdgpu_fence { @@ -163,11 +164,16 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, struct amd  	if (job && job->job_run_counter) {  		/* reinit seq for resubmitted jobs */  		fence->seqno = seq; +		/* TO be inline with external fence creation and other drivers */ +		dma_fence_get(fence);  	} else { -		if (job) +		if (job) {  			dma_fence_init(fence, &amdgpu_job_fence_ops,  				       &ring->fence_drv.lock,  				       adev->fence_context + ring->idx, seq); +			/* Against remove in amdgpu_job_{free, free_cb} */ +			dma_fence_get(fence); +		}  		else  			dma_fence_init(fence, &amdgpu_fence_ops,  				       &ring->fence_drv.lock, @@ -531,6 +537,24 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev)  	}  } +/* Will either stop and flush handlers for amdgpu interrupt or reanble it */ +void amdgpu_fence_driver_isr_toggle(struct amdgpu_device *adev, bool stop) +{ +	int i; + +	for (i = 0; i < AMDGPU_MAX_RINGS; i++) { +		struct amdgpu_ring *ring = adev->rings[i]; + +		if (!ring || !ring->fence_drv.initialized || !ring->fence_drv.irq_src) +			continue; + +		if (stop) +			disable_irq(adev->irq.irq); +		else +			enable_irq(adev->irq.irq); +	} +} +  void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev)  {  	unsigned int i, j; @@ -594,8 +618,10 @@ void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring)  	for (i = 0; i <= ring->fence_drv.num_fences_mask; i++) {  		ptr = &ring->fence_drv.fences[i];  		old = rcu_dereference_protected(*ptr, 1); -		if (old && old->ops == &amdgpu_job_fence_ops) +		if (old && old->ops == &amdgpu_job_fence_ops) {  			RCU_INIT_POINTER(*ptr, NULL); +			dma_fence_put(old); +		}  	}  } @@ -798,7 +824,10 @@ static int gpu_recover_get(void *data, u64 *val)  		return 0;  	} -	*val = amdgpu_device_gpu_recover(adev, NULL); +	if (amdgpu_reset_domain_schedule(adev->reset_domain, &adev->reset_work)) +		flush_work(&adev->reset_work); + +	*val = atomic_read(&adev->reset_domain->reset_res);  	pm_runtime_mark_last_busy(dev->dev);  	pm_runtime_put_autosuspend(dev->dev); @@ -810,6 +839,21 @@ DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_fence_info);  DEFINE_DEBUGFS_ATTRIBUTE(amdgpu_debugfs_gpu_recover_fops, gpu_recover_get, NULL,  			 "%lld\n"); +static void amdgpu_debugfs_reset_work(struct work_struct *work) +{ +	struct amdgpu_device *adev = container_of(work, struct amdgpu_device, +						  reset_work); + +	struct amdgpu_reset_context reset_context; +	memset(&reset_context, 0, sizeof(reset_context)); + +	reset_context.method = AMD_RESET_METHOD_NONE; +	reset_context.reset_req_dev = adev; +	set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); + +	amdgpu_device_gpu_recover(adev, NULL, &reset_context); +} +  #endif  void amdgpu_debugfs_fence_init(struct amdgpu_device *adev) @@ -821,9 +865,12 @@ void amdgpu_debugfs_fence_init(struct amdgpu_device *adev)  	debugfs_create_file("amdgpu_fence_info", 0444, root, adev,  			    &amdgpu_debugfs_fence_info_fops); -	if (!amdgpu_sriov_vf(adev)) +	if (!amdgpu_sriov_vf(adev)) { + +		INIT_WORK(&adev->reset_work, amdgpu_debugfs_reset_work);  		debugfs_create_file("amdgpu_gpu_recover", 0444, root, adev,  				    &amdgpu_debugfs_gpu_recover_fops); +	}  #endif  }  | 
