diff options
author | Felix Kuehling <Felix.Kuehling@amd.com> | 2018-03-23 15:30:34 -0400 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@gmail.com> | 2018-03-23 15:30:34 -0400 |
commit | 72a01d231dcb22a276209c7a924a8cd475fbaa9b (patch) | |
tree | 9fa79e705b263b5936635cc4b0cc897e8b232620 | |
parent | c70a36268799cf2f902b5a31e452571fcb96bfe9 (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.c | 20 |
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 | ||
872 | out: | 872 | mutex_unlock(&dqm->lock); |
873 | return retval; | ||
874 | |||
875 | out_deallocate_sdma_queue: | ||
876 | if (q->properties.type == KFD_QUEUE_TYPE_SDMA) | ||
877 | deallocate_sdma_queue(dqm, q->sdma_id); | ||
878 | out_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--; |