For the suspend and resume process, exclusive access is not required. Therefore, it can be moved out of the full access section to reduce the duration of exclusive access.
Signed-off-by: Emily Deng <emily.d...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 16 +++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 13 +++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 12 +++++-- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 40 ++++++++++++++++++---- 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index c166e059ead3..ccf898a73897 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -265,6 +265,22 @@ int amdgpu_amdkfd_resume(struct amdgpu_device *adev, bool run_pm) return r; } +void amdgpu_amdkfd_suspend_process(struct amdgpu_device *adev, bool run_pm) +{ + if (adev->kfd.dev) + kgd2kfd_suspend_process(adev->kfd.dev, run_pm, true); +} + +int amdgpu_amdkfd_resume_process(struct amdgpu_device *adev, bool run_pm) +{ + int r = 0; + + if (adev->kfd.dev) + r = kgd2kfd_resume_process(adev->kfd.dev, run_pm); + + return r; +} + int amdgpu_amdkfd_pre_reset(struct amdgpu_device *adev, struct amdgpu_reset_context *reset_context) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index 3a54f90ffcf8..78eaac829a58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -162,6 +162,8 @@ void amdgpu_amdkfd_fini(void); void amdgpu_amdkfd_suspend(struct amdgpu_device *adev, bool run_pm); int amdgpu_amdkfd_resume(struct amdgpu_device *adev, bool run_pm); +void amdgpu_amdkfd_suspend_process(struct amdgpu_device *adev, bool run_pm); +int amdgpu_amdkfd_resume_process(struct amdgpu_device *adev, bool run_pm); void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev, const void *ih_ring_entry); void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev); @@ -491,6 +493,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, void kgd2kfd_device_exit(struct kfd_dev *kfd); void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm, bool force); int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm); +void kgd2kfd_suspend_process(struct kfd_dev *kfd, bool run_pm, bool force); +int kgd2kfd_resume_process(struct kfd_dev *kfd, bool run_pm); int kgd2kfd_pre_reset(struct kfd_dev *kfd, struct amdgpu_reset_context *reset_context); int kgd2kfd_post_reset(struct kfd_dev *kfd); @@ -541,6 +545,15 @@ static inline int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm) return 0; } +static inline void kgd2kfd_suspend_process(struct kfd_dev *kfd, bool run_pm, bool force) +{ +} + +static inline int kgd2kfd_resume_process(struct kfd_dev *kfd, bool run_pm) +{ + return 0; +} + static inline int kgd2kfd_pre_reset(struct kfd_dev *kfd, struct amdgpu_reset_context *reset_context) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 4e343561a17d..34f040820546 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5032,7 +5032,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients) amdgpu_device_ip_suspend_phase1(adev); if (!adev->in_s0ix) - amdgpu_amdkfd_suspend(adev, adev->in_runpm); + amdgpu_amdkfd_suspend(adev, !amdgpu_sriov_runtime(adev) || adev->in_runpm); r = amdgpu_device_evict_resources(adev); if (r) @@ -5049,6 +5049,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients) if (amdgpu_sriov_vf(adev)) amdgpu_virt_release_full_gpu(adev, false); + if (!adev->in_s0ix) + amdgpu_amdkfd_suspend_process(adev, adev->in_runpm); + r = amdgpu_dpm_notify_rlc_state(adev, false); if (r) return r; @@ -5119,7 +5122,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients) } if (!adev->in_s0ix) { - r = amdgpu_amdkfd_resume(adev, adev->in_runpm); + r = amdgpu_amdkfd_resume(adev, !amdgpu_sriov_runtime(adev) || adev->in_runpm); if (r) goto exit; } @@ -5136,6 +5139,11 @@ int amdgpu_device_resume(struct drm_device *dev, bool notify_clients) amdgpu_virt_release_full_gpu(adev, true); } + if (!adev->in_s0ix) { + r = amdgpu_amdkfd_resume_process(adev, adev->in_runpm); + if (r) + goto exit; + } if (r) return r; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index bc8f4e8f9905..23c30320ca3a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -1061,13 +1061,8 @@ void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm, bool force) return; /* for runtime suspend, skip locking kfd */ - if (!run_pm) { - mutex_lock(&kfd_processes_mutex); - /* For first KFD device suspend all the KFD processes */ - if (++kfd_locked == 1) - kfd_suspend_all_processes(force); - mutex_unlock(&kfd_processes_mutex); - } + kgd2kfd_suspend_process(kfd, run_pm, force); + for (i = 0; i < kfd->num_nodes; i++) { node = kfd->nodes[i]; @@ -1088,6 +1083,37 @@ int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm) return ret; } + ret = kgd2kfd_resume_process(kfd, run_pm); + + + return ret; +} + +void kgd2kfd_suspend_process(struct kfd_dev *kfd, bool run_pm, bool force) +{ + struct kfd_node *node; + int i; + + if (!kfd->init_complete) + return; + + /* for runtime suspend, skip locking kfd */ + if (!run_pm) { + mutex_lock(&kfd_processes_mutex); + /* For first KFD device suspend all the KFD processes */ + if (++kfd_locked == 1) + kfd_suspend_all_processes(force); + mutex_unlock(&kfd_processes_mutex); + } +} + +int kgd2kfd_resume_process(struct kfd_dev *kfd, bool run_pm) +{ + int ret, i; + + if (!kfd->init_complete) + return 0; + /* for runtime resume, skip unlocking kfd */ if (!run_pm) { mutex_lock(&kfd_processes_mutex); -- 2.34.1