2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

drm/amdkfd: Move the process suspend and resume out of full access

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.

v3:
Move suspend processes before hardware fini.
Remove twice call for bare metal.

v4:
Refine code

Signed-off-by: Emily Deng <Emily.Deng@amd.com>
Acked-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Emily Deng 2025-05-27 11:42:11 +08:00 committed by Alex Deucher
parent b49e3d7ca7
commit 54f7a24e14
6 changed files with 86 additions and 36 deletions

View File

@ -248,18 +248,34 @@ void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
kgd2kfd_interrupt(adev->kfd.dev, ih_ring_entry);
}
void amdgpu_amdkfd_suspend(struct amdgpu_device *adev, bool run_pm)
void amdgpu_amdkfd_suspend(struct amdgpu_device *adev, bool suspend_proc)
{
if (adev->kfd.dev)
kgd2kfd_suspend(adev->kfd.dev, run_pm);
kgd2kfd_suspend(adev->kfd.dev, suspend_proc);
}
int amdgpu_amdkfd_resume(struct amdgpu_device *adev, bool run_pm)
int amdgpu_amdkfd_resume(struct amdgpu_device *adev, bool resume_proc)
{
int r = 0;
if (adev->kfd.dev)
r = kgd2kfd_resume(adev->kfd.dev, run_pm);
r = kgd2kfd_resume(adev->kfd.dev, resume_proc);
return r;
}
void amdgpu_amdkfd_suspend_process(struct amdgpu_device *adev)
{
if (adev->kfd.dev)
kgd2kfd_suspend_process(adev->kfd.dev);
}
int amdgpu_amdkfd_resume_process(struct amdgpu_device *adev)
{
int r = 0;
if (adev->kfd.dev)
r = kgd2kfd_resume_process(adev->kfd.dev);
return r;
}

View File

@ -154,8 +154,10 @@ struct amdkfd_process_info {
int amdgpu_amdkfd_init(void);
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(struct amdgpu_device *adev, bool suspend_proc);
int amdgpu_amdkfd_resume(struct amdgpu_device *adev, bool resume_proc);
void amdgpu_amdkfd_suspend_process(struct amdgpu_device *adev);
int amdgpu_amdkfd_resume_process(struct amdgpu_device *adev);
void amdgpu_amdkfd_interrupt(struct amdgpu_device *adev,
const void *ih_ring_entry);
void amdgpu_amdkfd_device_probe(struct amdgpu_device *adev);
@ -411,8 +413,10 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf);
bool kgd2kfd_device_init(struct kfd_dev *kfd,
const struct kgd2kfd_shared_resources *gpu_resources);
void kgd2kfd_device_exit(struct kfd_dev *kfd);
void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm);
int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm);
void kgd2kfd_suspend(struct kfd_dev *kfd, bool suspend_proc);
int kgd2kfd_resume(struct kfd_dev *kfd, bool resume_proc);
void kgd2kfd_suspend_process(struct kfd_dev *kfd);
int kgd2kfd_resume_process(struct kfd_dev *kfd);
int kgd2kfd_pre_reset(struct kfd_dev *kfd,
struct amdgpu_reset_context *reset_context);
int kgd2kfd_post_reset(struct kfd_dev *kfd);
@ -454,11 +458,20 @@ static inline void kgd2kfd_device_exit(struct kfd_dev *kfd)
{
}
static inline void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
static inline void kgd2kfd_suspend(struct kfd_dev *kfd, bool suspend_proc)
{
}
static inline int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
static inline int kgd2kfd_resume(struct kfd_dev *kfd, bool resume_proc)
{
return 0;
}
static inline void kgd2kfd_suspend_process(struct kfd_dev *kfd)
{
}
static inline int kgd2kfd_resume_process(struct kfd_dev *kfd)
{
return 0;
}

View File

@ -320,7 +320,7 @@ static void set_barrier_auto_waitcnt(struct amdgpu_device *adev, bool enable_wai
if (!down_read_trylock(&adev->reset_domain->sem))
return;
amdgpu_amdkfd_suspend(adev, false);
amdgpu_amdkfd_suspend(adev, true);
if (suspend_resume_compute_scheduler(adev, true))
goto out;
@ -333,7 +333,7 @@ static void set_barrier_auto_waitcnt(struct amdgpu_device *adev, bool enable_wai
out:
suspend_resume_compute_scheduler(adev, false);
amdgpu_amdkfd_resume(adev, false);
amdgpu_amdkfd_resume(adev, true);
up_read(&adev->reset_domain->sem);
}

View File

@ -3524,7 +3524,7 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
amdgpu_amdkfd_suspend(adev, false);
amdgpu_amdkfd_suspend(adev, true);
amdgpu_userq_suspend(adev);
/* Workaround for ASICs need to disable SMC first */
@ -5083,6 +5083,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
adev->in_suspend = true;
if (amdgpu_sriov_vf(adev)) {
if (!adev->in_s0ix && !adev->in_runpm)
amdgpu_amdkfd_suspend_process(adev);
amdgpu_virt_fini_data_exchange(adev);
r = amdgpu_virt_request_full_gpu(adev, false);
if (r)
@ -5102,7 +5104,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_vf(adev) && !adev->in_runpm);
amdgpu_userq_suspend(adev);
}
@ -5200,7 +5202,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_vf(adev) && !adev->in_runpm);
if (r)
goto exit;
@ -5219,6 +5221,9 @@ exit:
if (amdgpu_sriov_vf(adev)) {
amdgpu_virt_init_data_exchange(adev);
amdgpu_virt_release_full_gpu(adev, true);
if (!adev->in_s0ix && !r && !adev->in_runpm)
r = amdgpu_amdkfd_resume_process(adev);
}
if (r)

View File

@ -1679,9 +1679,9 @@ static int sdma_v4_4_2_reset_queue(struct amdgpu_ring *ring, unsigned int vmid)
if (!(adev->sdma.supported_reset & AMDGPU_RESET_TYPE_PER_QUEUE))
return -EOPNOTSUPP;
amdgpu_amdkfd_suspend(adev, false);
amdgpu_amdkfd_suspend(adev, true);
r = amdgpu_sdma_reset_engine(adev, id);
amdgpu_amdkfd_resume(adev, false);
amdgpu_amdkfd_resume(adev, true);
return r;
}

View File

@ -971,7 +971,7 @@ int kgd2kfd_pre_reset(struct kfd_dev *kfd,
kfd_smi_event_update_gpu_reset(node, false, reset_context);
}
kgd2kfd_suspend(kfd, false);
kgd2kfd_suspend(kfd, true);
for (i = 0; i < kfd->num_nodes; i++)
kfd_signal_reset_event(kfd->nodes[i]);
@ -1039,7 +1039,7 @@ bool kfd_is_locked(struct kfd_dev *kfd)
return false;
}
void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
void kgd2kfd_suspend(struct kfd_dev *kfd, bool suspend_proc)
{
struct kfd_node *node;
int i;
@ -1047,14 +1047,8 @@ void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
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();
mutex_unlock(&kfd_processes_mutex);
}
if (suspend_proc)
kgd2kfd_suspend_process(kfd);
for (i = 0; i < kfd->num_nodes; i++) {
node = kfd->nodes[i];
@ -1062,7 +1056,7 @@ void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
}
}
int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
int kgd2kfd_resume(struct kfd_dev *kfd, bool resume_proc)
{
int ret, i;
@ -1075,14 +1069,36 @@ int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
return ret;
}
/* for runtime resume, skip unlocking kfd */
if (!run_pm) {
if (resume_proc)
ret = kgd2kfd_resume_process(kfd);
return ret;
}
void kgd2kfd_suspend_process(struct kfd_dev *kfd)
{
if (!kfd->init_complete)
return;
mutex_lock(&kfd_processes_mutex);
/* For first KFD device suspend all the KFD processes */
if (++kfd_locked == 1)
kfd_suspend_all_processes();
mutex_unlock(&kfd_processes_mutex);
}
int kgd2kfd_resume_process(struct kfd_dev *kfd)
{
int ret = 0;
if (!kfd->init_complete)
return 0;
mutex_lock(&kfd_processes_mutex);
if (--kfd_locked == 0)
ret = kfd_resume_all_processes();
WARN_ONCE(kfd_locked < 0, "KFD suspend / resume ref. error");
mutex_unlock(&kfd_processes_mutex);
}
return ret;
}