MQD used outside of dpm_lock is unsafe because of the queue
could be destroyed during the window of dqm_unlock, moving into
dqm_lock range is the best practice.

Signed-off-by: Eric Huang <[email protected]>
---
 drivers/gpu/drm/amd/amdkfd/kfd_process.c | 32 +++++++++++++-----------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index e0b885b2395a..1cf689cb5e2c 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -91,7 +91,6 @@ struct kfd_sdma_activity_handler_workarea {
 
 struct temp_sdma_queue_list {
        uint64_t __user *rptr;
-       void *mqd;
        uint64_t sdma_val;
        unsigned int queue_id;
        struct list_head list;
@@ -154,6 +153,22 @@ static void kfd_sdma_activity_worker(struct work_struct 
*work)
                    (q->properties.type != KFD_QUEUE_TYPE_SDMA_XGMI))
                        continue;
 
+               if (KFD_GC_VERSION(dqm->dev) > IP_VERSION(9, 4, 2)) {
+                       ret = dqm->dev->kfd2kgd->hqd_sdma_get_counter ?
+                             dqm->dev->kfd2kgd->hqd_sdma_get_counter(
+                                       dqm->dev->adev, q->mqd,
+                                       
dqm->dev->kfd->device_info.num_sdma_queues_per_engine,
+                                       &val) :
+                             -EOPNOTSUPP;
+
+                       if (ret)
+                               pr_debug("Failed to read SDMA queue active 
counter %i\n", ret);
+                       else
+                               workarea->sdma_activity_counter += val;
+
+                       continue;
+               }
+
                sdma_q = kzalloc(sizeof(struct temp_sdma_queue_list), 
GFP_KERNEL);
                if (!sdma_q) {
                        dqm_unlock(dqm);
@@ -162,7 +177,6 @@ static void kfd_sdma_activity_worker(struct work_struct 
*work)
 
                INIT_LIST_HEAD(&sdma_q->list);
                sdma_q->rptr = (uint64_t __user *)q->properties.read_ptr;
-               sdma_q->mqd = q->mqd;
                sdma_q->queue_id = q->properties.queue_id;
                list_add_tail(&sdma_q->list, &sdma_q_list.list);
        }
@@ -173,7 +187,7 @@ static void kfd_sdma_activity_worker(struct work_struct 
*work)
         * count
         */
        if (list_empty(&sdma_q_list.list)) {
-               workarea->sdma_activity_counter = 
pdd->sdma_past_activity_counter;
+               workarea->sdma_activity_counter += 
pdd->sdma_past_activity_counter;
                dqm_unlock(dqm);
                return;
        }
@@ -191,17 +205,7 @@ static void kfd_sdma_activity_worker(struct work_struct 
*work)
 
        list_for_each_entry(sdma_q, &sdma_q_list.list, list) {
                val = 0;
-
-               if (KFD_GC_VERSION(dqm->dev) <= IP_VERSION(9, 4, 2))
-                       ret = read_sdma_queue_counter(sdma_q->rptr, &val);
-               else
-                       ret = dqm->dev->kfd2kgd->hqd_sdma_get_counter ?
-                             dqm->dev->kfd2kgd->hqd_sdma_get_counter(
-                                       dqm->dev->adev, sdma_q->mqd,
-                                       
dqm->dev->kfd->device_info.num_sdma_queues_per_engine,
-                                       &val) :
-                             -EOPNOTSUPP;
-
+               ret = read_sdma_queue_counter(sdma_q->rptr, &val);
                if (ret) {
                        pr_debug("Failed to read SDMA queue active counter for 
queue id: %d",
                                 sdma_q->queue_id);
-- 
2.34.1

Reply via email to