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
