drm/amdkfd: Walk through list with dqm lock hold
authorxinhui pan <xinhui.pan@amd.com>
Tue, 15 Jun 2021 07:11:07 +0000 (15:11 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 18 Jun 2021 21:14:13 +0000 (17:14 -0400)
To avoid any list corruption.

Signed-off-by: xinhui pan <xinhui.pan@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c

index c069fa2..16a1713 100644 (file)
@@ -1709,7 +1709,7 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
                struct qcm_process_device *qpd)
 {
        int retval;
-       struct queue *q, *next;
+       struct queue *q;
        struct kernel_queue *kq, *kq_next;
        struct mqd_manager *mqd_mgr;
        struct device_process_node *cur, *next_dpn;
@@ -1766,24 +1766,26 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
                qpd->reset_wavefronts = false;
        }
 
-       dqm_unlock(dqm);
-
-       /* Outside the DQM lock because under the DQM lock we can't do
-        * reclaim or take other locks that others hold while reclaiming.
-        */
-       if (found)
-               kfd_dec_compute_active(dqm->dev);
-
        /* Lastly, free mqd resources.
         * Do free_mqd() after dqm_unlock to avoid circular locking.
         */
-       list_for_each_entry_safe(q, next, &qpd->queues_list, list) {
+       while (!list_empty(&qpd->queues_list)) {
+               q = list_first_entry(&qpd->queues_list, struct queue, list);
                mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
                                q->properties.type)];
                list_del(&q->list);
                qpd->queue_count--;
+               dqm_unlock(dqm);
                mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
+               dqm_lock(dqm);
        }
+       dqm_unlock(dqm);
+
+       /* Outside the DQM lock because under the DQM lock we can't do
+        * reclaim or take other locks that others hold while reclaiming.
+        */
+       if (found)
+               kfd_dec_compute_active(dqm->dev);
 
        return retval;
 }