diff options
| author | Dave Airlie <airlied@redhat.com> | 2015-01-26 18:48:33 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2015-01-26 18:48:33 -0500 |
| commit | db9098ba1b51995c0518a621f58efd41bfeb4bfc (patch) | |
| tree | dd37528ea35d1fdda061bb9f00724ac8d5fab2fa | |
| parent | 22cbbceff65cb03ee37495b52f360809fa439293 (diff) | |
| parent | 9fa843e76d9092e5348aac7252cbb71f09902507 (diff) | |
Merge tag 'drm-amdkfd-fixes-2015-01-26' of git://people.freedesktop.org/~gabbayo/linux into drm-fixes
A couple of fixes for -rc7 in amdkfd:
- Forgot to free resources when creation of queue has failed
- Initialization of pipelines was incorrect (3 patches)
In addition, The patch "drm/amdkfd: Allow user to limit only queues per device"
is not a fix, but I would like to push it for 3.19 as it changes the ABI
between amdkfd and userspace (by changing the module parameters). I would
prefer *not* to support the two deprecated module parameters if I don't have
too, as amdkfd hasn't been released yet.
* tag 'drm-amdkfd-fixes-2015-01-26' of git://people.freedesktop.org/~gabbayo/linux:
drm/amdkfd: Fix bug in call to init_pipelines()
drm/amdkfd: Fix bug in pipelines initialization
drm/radeon: Don't increment pipe_id in kgd_init_pipeline
drm/amdkfd: Allow user to limit only queues per device
drm/amdkfd: PQM handle queue creation fault
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 78 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_module.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_pasid.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 17 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_kfd.c | 2 |
8 files changed, 106 insertions, 39 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 633532a2e7ec..25bc47f3c1cf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include "kfd_priv.h" | 27 | #include "kfd_priv.h" |
| 28 | #include "kfd_device_queue_manager.h" | 28 | #include "kfd_device_queue_manager.h" |
| 29 | #include "kfd_pm4_headers.h" | ||
| 29 | 30 | ||
| 30 | #define MQD_SIZE_ALIGNED 768 | 31 | #define MQD_SIZE_ALIGNED 768 |
| 31 | 32 | ||
| @@ -169,9 +170,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, | |||
| 169 | kfd->shared_resources = *gpu_resources; | 170 | kfd->shared_resources = *gpu_resources; |
| 170 | 171 | ||
| 171 | /* calculate max size of mqds needed for queues */ | 172 | /* calculate max size of mqds needed for queues */ |
| 172 | size = max_num_of_processes * | 173 | size = max_num_of_queues_per_device * |
| 173 | max_num_of_queues_per_process * | 174 | kfd->device_info->mqd_size_aligned; |
| 174 | kfd->device_info->mqd_size_aligned; | ||
| 175 | 175 | ||
| 176 | /* add another 512KB for all other allocations on gart */ | 176 | /* add another 512KB for all other allocations on gart */ |
| 177 | size += 512 * 1024; | 177 | size += 512 * 1024; |
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 30c8fda9622e..0d8694f015c1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
| @@ -183,6 +183,13 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, | |||
| 183 | 183 | ||
| 184 | mutex_lock(&dqm->lock); | 184 | mutex_lock(&dqm->lock); |
| 185 | 185 | ||
| 186 | if (dqm->total_queue_count >= max_num_of_queues_per_device) { | ||
| 187 | pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n", | ||
| 188 | dqm->total_queue_count); | ||
| 189 | mutex_unlock(&dqm->lock); | ||
| 190 | return -EPERM; | ||
| 191 | } | ||
| 192 | |||
| 186 | if (list_empty(&qpd->queues_list)) { | 193 | if (list_empty(&qpd->queues_list)) { |
| 187 | retval = allocate_vmid(dqm, qpd, q); | 194 | retval = allocate_vmid(dqm, qpd, q); |
| 188 | if (retval != 0) { | 195 | if (retval != 0) { |
| @@ -207,6 +214,14 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, | |||
| 207 | list_add(&q->list, &qpd->queues_list); | 214 | list_add(&q->list, &qpd->queues_list); |
| 208 | dqm->queue_count++; | 215 | dqm->queue_count++; |
| 209 | 216 | ||
| 217 | /* | ||
| 218 | * Unconditionally increment this counter, regardless of the queue's | ||
| 219 | * type or whether the queue is active. | ||
| 220 | */ | ||
| 221 | dqm->total_queue_count++; | ||
| 222 | pr_debug("Total of %d queues are accountable so far\n", | ||
| 223 | dqm->total_queue_count); | ||
| 224 | |||
| 210 | mutex_unlock(&dqm->lock); | 225 | mutex_unlock(&dqm->lock); |
| 211 | return 0; | 226 | return 0; |
| 212 | } | 227 | } |
| @@ -326,6 +341,15 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm, | |||
| 326 | if (list_empty(&qpd->queues_list)) | 341 | if (list_empty(&qpd->queues_list)) |
| 327 | deallocate_vmid(dqm, qpd, q); | 342 | deallocate_vmid(dqm, qpd, q); |
| 328 | dqm->queue_count--; | 343 | dqm->queue_count--; |
| 344 | |||
| 345 | /* | ||
| 346 | * Unconditionally decrement this counter, regardless of the queue's | ||
| 347 | * type | ||
| 348 | */ | ||
| 349 | dqm->total_queue_count--; | ||
| 350 | pr_debug("Total of %d queues are accountable so far\n", | ||
| 351 | dqm->total_queue_count); | ||
| 352 | |||
| 329 | out: | 353 | out: |
| 330 | mutex_unlock(&dqm->lock); | 354 | mutex_unlock(&dqm->lock); |
| 331 | return retval; | 355 | return retval; |
| @@ -541,10 +565,14 @@ static int init_pipelines(struct device_queue_manager *dqm, | |||
| 541 | 565 | ||
| 542 | for (i = 0; i < pipes_num; i++) { | 566 | for (i = 0; i < pipes_num; i++) { |
| 543 | inx = i + first_pipe; | 567 | inx = i + first_pipe; |
| 568 | /* | ||
| 569 | * HPD buffer on GTT is allocated by amdkfd, no need to waste | ||
| 570 | * space in GTT for pipelines we don't initialize | ||
| 571 | */ | ||
| 544 | pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; | 572 | pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; |
| 545 | pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); | 573 | pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); |
| 546 | /* = log2(bytes/4)-1 */ | 574 | /* = log2(bytes/4)-1 */ |
| 547 | kfd2kgd->init_pipeline(dqm->dev->kgd, i, | 575 | kfd2kgd->init_pipeline(dqm->dev->kgd, inx, |
| 548 | CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); | 576 | CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); |
| 549 | } | 577 | } |
| 550 | 578 | ||
| @@ -560,7 +588,7 @@ static int init_scheduler(struct device_queue_manager *dqm) | |||
| 560 | 588 | ||
| 561 | pr_debug("kfd: In %s\n", __func__); | 589 | pr_debug("kfd: In %s\n", __func__); |
| 562 | 590 | ||
| 563 | retval = init_pipelines(dqm, get_pipes_num(dqm), KFD_DQM_FIRST_PIPE); | 591 | retval = init_pipelines(dqm, get_pipes_num(dqm), get_first_pipe(dqm)); |
| 564 | if (retval != 0) | 592 | if (retval != 0) |
| 565 | return retval; | 593 | return retval; |
| 566 | 594 | ||
| @@ -752,6 +780,21 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm, | |||
| 752 | pr_debug("kfd: In func %s\n", __func__); | 780 | pr_debug("kfd: In func %s\n", __func__); |
| 753 | 781 | ||
| 754 | mutex_lock(&dqm->lock); | 782 | mutex_lock(&dqm->lock); |
| 783 | if (dqm->total_queue_count >= max_num_of_queues_per_device) { | ||
| 784 | pr_warn("amdkfd: Can't create new kernel queue because %d queues were already created\n", | ||
| 785 | dqm->total_queue_count); | ||
| 786 | mutex_unlock(&dqm->lock); | ||
| 787 | return -EPERM; | ||
| 788 | } | ||
| 789 | |||
| 790 | /* | ||
| 791 | * Unconditionally increment this counter, regardless of the queue's | ||
| 792 | * type or whether the queue is active. | ||
| 793 | */ | ||
| 794 | dqm->total_queue_count++; | ||
| 795 | pr_debug("Total of %d queues are accountable so far\n", | ||
| 796 | dqm->total_queue_count); | ||
| 797 | |||
| 755 | list_add(&kq->list, &qpd->priv_queue_list); | 798 | list_add(&kq->list, &qpd->priv_queue_list); |
| 756 | dqm->queue_count++; | 799 | dqm->queue_count++; |
| 757 | qpd->is_debug = true; | 800 | qpd->is_debug = true; |
| @@ -775,6 +818,13 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, | |||
| 775 | dqm->queue_count--; | 818 | dqm->queue_count--; |
| 776 | qpd->is_debug = false; | 819 | qpd->is_debug = false; |
| 777 | execute_queues_cpsch(dqm, false); | 820 | execute_queues_cpsch(dqm, false); |
| 821 | /* | ||
| 822 | * Unconditionally decrement this counter, regardless of the queue's | ||
| 823 | * type. | ||
| 824 | */ | ||
| 825 | dqm->total_queue_count++; | ||
| 826 | pr_debug("Total of %d queues are accountable so far\n", | ||
| 827 | dqm->total_queue_count); | ||
| 778 | mutex_unlock(&dqm->lock); | 828 | mutex_unlock(&dqm->lock); |
| 779 | } | 829 | } |
| 780 | 830 | ||
| @@ -793,6 +843,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, | |||
| 793 | 843 | ||
| 794 | mutex_lock(&dqm->lock); | 844 | mutex_lock(&dqm->lock); |
| 795 | 845 | ||
| 846 | if (dqm->total_queue_count >= max_num_of_queues_per_device) { | ||
| 847 | pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n", | ||
| 848 | dqm->total_queue_count); | ||
| 849 | retval = -EPERM; | ||
| 850 | goto out; | ||
| 851 | } | ||
| 852 | |||
| 796 | mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); | 853 | mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); |
| 797 | if (mqd == NULL) { | 854 | if (mqd == NULL) { |
| 798 | mutex_unlock(&dqm->lock); | 855 | mutex_unlock(&dqm->lock); |
| @@ -810,6 +867,15 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, | |||
| 810 | retval = execute_queues_cpsch(dqm, false); | 867 | retval = execute_queues_cpsch(dqm, false); |
| 811 | } | 868 | } |
| 812 | 869 | ||
