aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Kuehling <Felix.Kuehling@amd.com>2018-03-23 15:30:34 -0400
committerOded Gabbay <oded.gabbay@gmail.com>2018-03-23 15:30:34 -0400
commit72a01d231dcb22a276209c7a924a8cd475fbaa9b (patch)
tree9fa79e705b263b5936635cc4b0cc897e8b232620
parentc70a36268799cf2f902b5a31e452571fcb96bfe9 (diff)
drm/amdkfd: Deallocate SDMA queues correctly
Deallocate SDMA queues during abnormal process termination and when queue creation fails after the SDMA allocation. Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index b21285afa4ea..1bd5f26b3f00 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -821,13 +821,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
821 pr_warn("Can't create new usermode queue because %d queues were already created\n", 821 pr_warn("Can't create new usermode queue because %d queues were already created\n",
822 dqm->total_queue_count); 822 dqm->total_queue_count);
823 retval = -EPERM; 823 retval = -EPERM;
824 goto out; 824 goto out_unlock;
825 } 825 }
826 826
827 if (q->properties.type == KFD_QUEUE_TYPE_SDMA) { 827 if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
828 retval = allocate_sdma_queue(dqm, &q->sdma_id); 828 retval = allocate_sdma_queue(dqm, &q->sdma_id);
829 if (retval) 829 if (retval)
830 goto out; 830 goto out_unlock;
831 q->properties.sdma_queue_id = 831 q->properties.sdma_queue_id =
832 q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE; 832 q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE;
833 q->properties.sdma_engine_id = 833 q->properties.sdma_engine_id =
@@ -838,7 +838,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
838 838
839 if (!mqd) { 839 if (!mqd) {
840 retval = -ENOMEM; 840 retval = -ENOMEM;
841 goto out; 841 goto out_deallocate_sdma_queue;
842 } 842 }
843 843
844 dqm->asic_ops.init_sdma_vm(dqm, q, qpd); 844 dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
@@ -848,7 +848,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
848 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, 848 retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
849 &q->gart_mqd_addr, &q->properties); 849 &q->gart_mqd_addr, &q->properties);
850 if (retval) 850 if (retval)
851 goto out; 851 goto out_deallocate_sdma_queue;
852 852
853 list_add(&q->list, &qpd->queues_list); 853 list_add(&q->list, &qpd->queues_list);
854 qpd->queue_count++; 854 qpd->queue_count++;
@@ -869,7 +869,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
869 pr_debug("Total of %d queues are accountable so far\n", 869 pr_debug("Total of %d queues are accountable so far\n",
870 dqm->total_queue_count); 870 dqm->total_queue_count);
871 871
872out: 872 mutex_unlock(&dqm->lock);
873 return retval;
874
875out_deallocate_sdma_queue:
876 if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
877 deallocate_sdma_queue(dqm, q->sdma_id);
878out_unlock:
873 mutex_unlock(&dqm->lock); 879 mutex_unlock(&dqm->lock);
874 return retval; 880 return retval;
875} 881}
@@ -1188,8 +1194,10 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
1188 1194
1189 /* Clear all user mode queues */ 1195 /* Clear all user mode queues */
1190 list_for_each_entry(q, &qpd->queues_list, list) { 1196 list_for_each_entry(q, &qpd->queues_list, list) {
1191 if (q->properties.type == KFD_QUEUE_TYPE_SDMA) 1197 if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
1192 dqm->sdma_queue_count--; 1198 dqm->sdma_queue_count--;
1199 deallocate_sdma_queue(dqm, q->sdma_id);
1200 }
1193 1201
1194 if (q->properties.is_active) 1202 if (q->properties.is_active)
1195 dqm->queue_count--; 1203 dqm->queue_count--;