diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-07-19 10:26:14 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-07-19 10:26:14 +0000 |
commit | a0b1dd59daeab4c44c61ab95c51e644f149d5b7d (patch) | |
tree | 5904f80a7cf051e222bd9a27cfa79c1a4af57d01 /sys | |
parent | 0a55c0234c72e1991cdfdfbf75a1aebb74177976 (diff) |
drm/amdkfd: fix circular locking on get_wave_state
From Jonathan Kim
cd29db48bb65e53efe4b05c75e575c5f1af5ddaf in linux 5.10.y/5.10.51
63f6e01237257e7226efc5087f3f0b525d320f54 in mainline linux
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/drm/amd/amdkfd/kfd_device_queue_manager.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/sys/dev/pci/drm/amd/amdkfd/kfd_device_queue_manager.c b/sys/dev/pci/drm/amd/amdkfd/kfd_device_queue_manager.c index 6ea8a4b6efd..b971532e69e 100644 --- a/sys/dev/pci/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/sys/dev/pci/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1677,29 +1677,27 @@ static int get_wave_state(struct device_queue_manager *dqm, u32 *save_area_used_size) { struct mqd_manager *mqd_mgr; - int r; dqm_lock(dqm); - if (q->properties.type != KFD_QUEUE_TYPE_COMPUTE || - q->properties.is_active || !q->device->cwsr_enabled) { - r = -EINVAL; - goto dqm_unlock; - } - mqd_mgr = dqm->mqd_mgrs[KFD_MQD_TYPE_CP]; - if (!mqd_mgr->get_wave_state) { - r = -EINVAL; - goto dqm_unlock; + if (q->properties.type != KFD_QUEUE_TYPE_COMPUTE || + q->properties.is_active || !q->device->cwsr_enabled || + !mqd_mgr->get_wave_state) { + dqm_unlock(dqm); + return -EINVAL; } - r = mqd_mgr->get_wave_state(mqd_mgr, q->mqd, ctl_stack, - ctl_stack_used_size, save_area_used_size); - -dqm_unlock: dqm_unlock(dqm); - return r; + + /* + * get_wave_state is outside the dqm lock to prevent circular locking + * and the queue should be protected against destruction by the process + * lock. + */ + return mqd_mgr->get_wave_state(mqd_mgr, q->mqd, ctl_stack, + ctl_stack_used_size, save_area_used_size); } static int process_termination_cpsch(struct device_queue_manager *dqm, |