summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2021-07-19 10:26:14 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2021-07-19 10:26:14 +0000
commita0b1dd59daeab4c44c61ab95c51e644f149d5b7d (patch)
tree5904f80a7cf051e222bd9a27cfa79c1a4af57d01 /sys
parent0a55c0234c72e1991cdfdfbf75a1aebb74177976 (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.c28
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,