diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2727-drm-amdkfd-Add-support-for-doorbell-BOs.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2727-drm-amdkfd-Add-support-for-doorbell-BOs.patch | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2727-drm-amdkfd-Add-support-for-doorbell-BOs.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2727-drm-amdkfd-Add-support-for-doorbell-BOs.patch new file mode 100644 index 00000000..5becb18b --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2727-drm-amdkfd-Add-support-for-doorbell-BOs.patch @@ -0,0 +1,179 @@ +From eace5958a8fdac8d2650d1a60c9c253a8bc85fff Mon Sep 17 00:00:00 2001 +From: Felix Kuehling <Felix.Kuehling@amd.com> +Date: Tue, 20 Nov 2018 21:44:27 -0500 +Subject: [PATCH 2727/2940] drm/amdkfd: Add support for doorbell BOs + +This allows user mode to map doorbell pages into GPUVM address space. +That way GPUs can submit to user mode queues (self-dispatch). + +Acked-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 59 +++++++++++++++++-- + drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 6 ++ + .../gpu/drm/amd/include/kgd_kfd_interface.h | 4 +- + 3 files changed, 62 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +index 0b105783e3b3..b1cc59490f96 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +@@ -878,6 +878,24 @@ static int map_bo_to_gpuvm(struct amdgpu_device *adev, + return ret; + } + ++static struct sg_table *create_doorbell_sg(uint64_t addr, uint32_t size) ++{ ++ struct sg_table *sg = kmalloc(sizeof(*sg), GFP_KERNEL); ++ ++ if (!sg) ++ return NULL; ++ if (sg_alloc_table(sg, 1, GFP_KERNEL)) { ++ kfree(sg); ++ return NULL; ++ } ++ sg->sgl->dma_address = addr; ++ sg->sgl->length = size; ++#ifdef CONFIG_NEED_SG_DMA_LENGTH ++ sg->sgl->dma_length = size; ++#endif ++ return sg; ++} ++ + static int process_validate_vms(struct amdkfd_process_info *process_info) + { + struct amdgpu_vm *peer_vm; +@@ -1161,6 +1179,8 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( + { + struct amdgpu_device *adev = get_amdgpu_device(kgd); + struct amdgpu_vm *avm = (struct amdgpu_vm *)vm; ++ enum ttm_bo_type bo_type = ttm_bo_type_device; ++ struct sg_table *sg = NULL; + uint64_t user_addr = 0; + struct amdgpu_bo *bo; + struct amdgpu_bo_param bp; +@@ -1189,13 +1209,25 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( + if (!offset || !*offset) + return -EINVAL; + user_addr = *offset; ++ } else if (flags & ALLOC_MEM_FLAGS_DOORBELL) { ++ domain = AMDGPU_GEM_DOMAIN_GTT; ++ alloc_domain = AMDGPU_GEM_DOMAIN_CPU; ++ bo_type = ttm_bo_type_sg; ++ alloc_flags = 0; ++ if (size > UINT_MAX) ++ return -EINVAL; ++ sg = create_doorbell_sg(*offset, size); ++ if (!sg) ++ return -ENOMEM; + } else { + return -EINVAL; + } + + *mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL); +- if (!*mem) +- return -ENOMEM; ++ if (!*mem) { ++ ret = -ENOMEM; ++ goto err; ++ } + INIT_LIST_HEAD(&(*mem)->bo_va_list); + mutex_init(&(*mem)->lock); + (*mem)->aql_queue = !!(flags & ALLOC_MEM_FLAGS_AQL_QUEUE_MEM); +@@ -1228,7 +1260,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( + + amdgpu_sync_create(&(*mem)->sync); + +- ret = amdgpu_amdkfd_reserve_mem_limit(adev, size, alloc_domain, false); ++ ret = amdgpu_amdkfd_reserve_mem_limit(adev, size, alloc_domain, !!sg); + if (ret) { + pr_debug("Insufficient system memory\n"); + goto err_reserve_limit; +@@ -1242,7 +1274,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( + bp.byte_align = byte_align; + bp.domain = alloc_domain; + bp.flags = alloc_flags; +- bp.type = ttm_bo_type_device; ++ bp.type = bo_type; + bp.resv = NULL; + ret = amdgpu_bo_create(adev, &bp, &bo); + if (ret) { +@@ -1250,6 +1282,10 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( + domain_string(alloc_domain), ret); + goto err_bo_create; + } ++ if (bo_type == ttm_bo_type_sg) { ++ bo->tbo.sg = sg; ++ bo->tbo.ttm->sg = sg; ++ } + bo->kfd_bo = *mem; + (*mem)->bo = bo; + if (user_addr) +@@ -1281,10 +1317,15 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( + /* Don't unreserve system mem limit twice */ + goto err_reserve_limit; + err_bo_create: +- unreserve_mem_limit(adev, size, alloc_domain, false); ++ unreserve_mem_limit(adev, size, alloc_domain, !!sg); + err_reserve_limit: + mutex_destroy(&(*mem)->lock); + kfree(*mem); ++err: ++ if (sg) { ++ sg_free_table(sg); ++ kfree(sg); ++ } + return ret; + } + +@@ -1354,6 +1395,14 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( + /* Free the sync object */ + amdgpu_sync_free(&mem->sync); + ++ /* If the SG is not NULL, it's one we created for a doorbell ++ * BO. We need to free it. ++ */ ++ if (mem->bo->tbo.sg) { ++ sg_free_table(mem->bo->tbo.sg); ++ kfree(mem->bo->tbo.sg); ++ } ++ + /* Free the BO*/ + amdgpu_bo_unref(&mem->bo); + mutex_destroy(&mem->lock); +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +index ae3ae0fb2602..3623538baf6f 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +@@ -1274,6 +1274,12 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, + return -EINVAL; + } + ++ if (flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) { ++ if (args->size != kfd_doorbell_process_slice(dev)) ++ return -EINVAL; ++ offset = kfd_get_process_doorbells(dev, p); ++ } ++ + mutex_lock(&p->mutex); + + pdd = kfd_bind_process_to_device(dev, p); +diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +index 8fbd7a52a49d..0285e1a71fa4 100644 +--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h ++++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +@@ -160,8 +160,8 @@ struct tile_config { + */ + #define ALLOC_MEM_FLAGS_VRAM (1 << 0) + #define ALLOC_MEM_FLAGS_GTT (1 << 1) +-#define ALLOC_MEM_FLAGS_USERPTR (1 << 2) /* TODO */ +-#define ALLOC_MEM_FLAGS_DOORBELL (1 << 3) /* TODO */ ++#define ALLOC_MEM_FLAGS_USERPTR (1 << 2) ++#define ALLOC_MEM_FLAGS_DOORBELL (1 << 3) + + /* + * Allocation flags attributes/access options. +-- +2.17.1 + |