mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
drm/amdkfd: avoid race condition of mqd when reading sdma counter
MQD used outside of dpm_lock is unsafe because 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 <jinhuieric.huang@amd.com> Reviewed-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
272e584fc0
commit
cc80854eda
|
|
@ -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,21 @@ static void kfd_sdma_activity_worker(struct work_struct *work)
|
|||
(q->properties.type != KFD_QUEUE_TYPE_SDMA_XGMI))
|
||||
continue;
|
||||
|
||||
if (dqm->dev->kfd2kgd->hqd_sdma_get_counter) {
|
||||
val = 0;
|
||||
ret = dqm->dev->kfd2kgd->hqd_sdma_get_counter(
|
||||
dqm->dev->adev, q->mqd,
|
||||
dqm->dev->kfd->device_info.num_sdma_queues_per_engine,
|
||||
&val);
|
||||
|
||||
if (ret)
|
||||
pr_debug("Failed to read SDMA queue active counter %i\n", ret);
|
||||
else
|
||||
workarea->sdma_activity_counter += val;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
sdma_q = kzalloc_obj(struct temp_sdma_queue_list);
|
||||
if (!sdma_q) {
|
||||
dqm_unlock(dqm);
|
||||
|
|
@ -162,7 +176,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 +186,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,15 +204,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 (dqm->dev->kfd2kgd->hqd_sdma_get_counter)
|
||||
ret = dqm->dev->kfd2kgd->hqd_sdma_get_counter(
|
||||
dqm->dev->adev, sdma_q->mqd,
|
||||
dqm->dev->kfd->device_info.num_sdma_queues_per_engine,
|
||||
&val);
|
||||
else
|
||||
ret = read_sdma_queue_counter(sdma_q->rptr, &val);
|
||||
|
||||
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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user