diff options
29 files changed, 315 insertions, 188 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 | |||
