aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3712-drm-amdgpu-Add-kfd2kgd-interface-to-acquire-an-exist.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3712-drm-amdgpu-Add-kfd2kgd-interface-to-acquire-an-exist.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3712-drm-amdgpu-Add-kfd2kgd-interface-to-acquire-an-exist.patch273
1 files changed, 273 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3712-drm-amdgpu-Add-kfd2kgd-interface-to-acquire-an-exist.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3712-drm-amdgpu-Add-kfd2kgd-interface-to-acquire-an-exist.patch
new file mode 100644
index 00000000..05398543
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3712-drm-amdgpu-Add-kfd2kgd-interface-to-acquire-an-exist.patch
@@ -0,0 +1,273 @@
+From 0c0eab46de7471a1b78ef336781178564a31088e Mon Sep 17 00:00:00 2001
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+Date: Sat, 24 Feb 2018 18:33:49 -0500
+Subject: [PATCH 3712/4131] drm/amdgpu: Add kfd2kgd interface to acquire an
+ existing VM
+
+This allows acquiring an existing VM from a render node FD to use it
+for a compute process.
+
+Such VMs get destroyed when the original file descriptor is released.
+Added a callback from amdgpu_vm_fini to handle KFD VM destruction
+correctly in this case.
+
+Change-Id: I2240988bef70c5a7a22fa4da091a46e870352aaa
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 162 +++++++++++++++--------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +
+ 2 files changed, 110 insertions(+), 54 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 998cab1..4e67ce6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -978,32 +978,16 @@ static int process_update_pds(struct amdkfd_process_info *process_info,
+ return 0;
+ }
+
+-int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
+- void **process_info,
+- struct dma_fence **ef)
++static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
++ struct dma_fence **ef)
+ {
+- int ret;
+- struct amdgpu_vm *new_vm;
+ struct amdkfd_process_info *info = NULL;
+- struct amdgpu_device *adev = get_amdgpu_device(kgd);
+-
+- new_vm = kzalloc(sizeof(*new_vm), GFP_KERNEL);
+- if (!new_vm)
+- return -ENOMEM;
+-
+- /* Initialize the VM context, allocate the page directory and zero it */
+- ret = amdgpu_vm_init(adev, new_vm, AMDGPU_VM_CONTEXT_COMPUTE, 0);
+- if (ret) {
+- pr_err("Failed init vm ret %d\n", ret);
+- goto vm_init_fail;
+- }
++ int ret;
+
+ if (!*process_info) {
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+- if (!info) {
+- ret = -ENOMEM;
+- goto alloc_process_info_fail;
+- }
++ if (!info)
++ return -ENOMEM;
+
+ mutex_init(&info->lock);
+ INIT_LIST_HEAD(&info->vm_list_head);
+@@ -1016,11 +1000,11 @@ int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
+ current->mm);
+ if (!info->eviction_fence) {
+ pr_err("Failed to create eviction fence\n");
++ ret = -ENOMEM;
+ goto create_evict_fence_fail;
+ }
+
+- info->pid = get_task_pid(current->group_leader,
+- PIDTYPE_PID);
++ info->pid = get_task_pid(current->group_leader, PIDTYPE_PID);
+ atomic_set(&info->evicted_bos, 0);
+ INIT_DELAYED_WORK(&info->work,
+ amdgpu_amdkfd_restore_userptr_worker);
+@@ -1029,72 +1013,131 @@ int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
+ *ef = dma_fence_get(&info->eviction_fence->base);
+ }
+
+- new_vm->process_info = *process_info;
++ vm->process_info = *process_info;
+
+ /* Validate page directory and attach eviction fence */
+- ret = amdgpu_bo_reserve(new_vm->root.base.bo, true);
++ ret = amdgpu_bo_reserve(vm->root.base.bo, true);
+ if (ret)
+ goto reserve_pd_fail;
+- ret = vm_validate_pt_pd_bos(new_vm);
++ ret = vm_validate_pt_pd_bos(vm);
+ if (ret) {
+ pr_err("validate_pt_pd_bos() failed\n");
+ goto validate_pd_fail;
+ }
+- amdgpu_bo_fence(new_vm->root.base.bo,
+- &new_vm->process_info->eviction_fence->base, true);
+- amdgpu_bo_unreserve(new_vm->root.base.bo);
++ amdgpu_bo_fence(vm->root.base.bo,
++ &vm->process_info->eviction_fence->base, true);
++ amdgpu_bo_unreserve(vm->root.base.bo);
+
+ /* Update process info */
+- mutex_lock(&new_vm->process_info->lock);
+- list_add_tail(&new_vm->vm_list_node,
+- &(new_vm->process_info->vm_list_head));
+- new_vm->process_info->n_vms++;
+- mutex_unlock(&new_vm->process_info->lock);
++ mutex_lock(&vm->process_info->lock);
++ list_add_tail(&vm->vm_list_node,
++ &(vm->process_info->vm_list_head));
++ vm->process_info->n_vms++;
++ mutex_unlock(&vm->process_info->lock);
+
+- *vm = (void *) new_vm;
+-
+- pr_debug("Created process vm %p\n", *vm);
+-
+- return ret;
++ return 0;
+
+ validate_pd_fail:
+- amdgpu_bo_unreserve(new_vm->root.base.bo);
++ amdgpu_bo_unreserve(vm->root.base.bo);
+ reserve_pd_fail:
++ vm->process_info = NULL;
++ if (info) {
++ /* Two fence references: one in info and one in *ef */
++ dma_fence_put(&info->eviction_fence->base);
++ dma_fence_put(*ef);
++ *ef = NULL;
++ *process_info = NULL;
+ create_evict_fence_fail:
+- kfree(info);
+-alloc_process_info_fail:
++ kfree(info);
++ }
++ return ret;
++}
++
++int amdgpu_amdkfd_gpuvm_create_process_vm(struct kgd_dev *kgd, void **vm,
++ void **process_info,
++ struct dma_fence **ef)
++{
++ struct amdgpu_device *adev = get_amdgpu_device(kgd);
++ struct amdgpu_vm *new_vm;
++ int ret;
++
++ new_vm = kzalloc(sizeof(*new_vm), GFP_KERNEL);
++ if (!new_vm)
++ return -ENOMEM;
++
++ /* Initialize AMDGPU part of the VM */
++ ret = amdgpu_vm_init(adev, new_vm, AMDGPU_VM_CONTEXT_COMPUTE, 0);
++ if (ret) {
++ pr_err("Failed init vm ret %d\n", ret);
++ goto amdgpu_vm_init_fail;
++ }
++
++ /* Initialize KFD part of the VM and process info */
++ ret = init_kfd_vm(new_vm, process_info, ef);
++ if (ret)
++ goto init_kfd_vm_fail;
++
++ *vm = (void *) new_vm;
++
++ return 0;
++
++init_kfd_vm_fail:
+ amdgpu_vm_fini(adev, new_vm);
+-vm_init_fail:
++amdgpu_vm_init_fail:
+ kfree(new_vm);
+ return ret;
+-
+ }
+
+-void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm)
++int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct kgd_dev *kgd,
++ struct file *filp,
++ void **vm, void **process_info,
++ struct dma_fence **ef)
+ {
+ struct amdgpu_device *adev = get_amdgpu_device(kgd);
+- struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
+- struct amdgpu_bo *pd;
+- struct amdkfd_process_info *process_info;
++ struct drm_file *drm_priv = filp->private_data;
++ struct amdgpu_fpriv *drv_priv = drm_priv->driver_priv;
++ struct amdgpu_vm *avm = &drv_priv->vm;
++ int ret;
+
+- if (WARN_ON(!kgd || !vm))
++ /* Convert VM into a compute VM */
++ ret = amdgpu_vm_make_compute(adev, avm);
++ if (ret)
++ return ret;
++
++ /* Initialize KFD part of the VM and process info */
++ ret = init_kfd_vm(avm, process_info, ef);
++ if (ret)
++ return ret;
++
++ *vm = (void *)avm;
++
++ return 0;
++}
++
++void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
++ struct amdgpu_vm *vm)
++{
++ struct amdkfd_process_info *process_info = vm->process_info;
++ struct amdgpu_bo *pd = vm->root.base.bo;
++
++ if (vm->vm_context != AMDGPU_VM_CONTEXT_COMPUTE)
+ return;
+
+- pr_debug("Destroying process vm %p\n", vm);
+ /* Release eviction fence from PD */
+- pd = avm->root.base.bo;
+ amdgpu_bo_reserve(pd, false);
+ amdgpu_bo_fence(pd, NULL, false);
+ amdgpu_bo_unreserve(pd);
+
+- process_info = avm->process_info;
++ if (!process_info)
++ return;
+
++ /* Update process info */
+ mutex_lock(&process_info->lock);
+ process_info->n_vms--;
+- list_del(&avm->vm_list_node);
++ list_del(&vm->vm_list_node);
+ mutex_unlock(&process_info->lock);
+
+- /* Release per-process resources */
++ /* Release per-process resources when last compute VM is destroyed */
+ if (!process_info->n_vms) {
+ WARN_ON(!list_empty(&process_info->kfd_bo_list));
+ WARN_ON(!list_empty(&process_info->userptr_valid_list));
+@@ -1105,6 +1148,17 @@ void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm)
+ put_pid(process_info->pid);
+ kfree(process_info);
+ }
++}
++
++void amdgpu_amdkfd_gpuvm_destroy_process_vm(struct kgd_dev *kgd, void *vm)
++{
++ struct amdgpu_device *adev = get_amdgpu_device(kgd);
++ struct amdgpu_vm *avm = (struct amdgpu_vm *)vm;
++
++ if (WARN_ON(!kgd || !vm))
++ return;
++
++ pr_debug("Destroying process vm %p\n", vm);
+
+ /* Release the VM context */
+ amdgpu_vm_fini(adev, avm);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 5a78082..b97c360 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -2641,6 +2641,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
+ u64 fault;
+ int i, r;
+
++ amdgpu_amdkfd_gpuvm_destroy_cb(adev, vm);
++
+ /* Clear pending page faults from IH when the VM is destroyed */
+ while (kfifo_get(&vm->faults, &fault))
+ amdgpu_ih_clear_fault(adev, fault);
+--
+2.7.4
+