aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1317-drm-amdkfd-Simplify-process-locking.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1317-drm-amdkfd-Simplify-process-locking.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1317-drm-amdkfd-Simplify-process-locking.patch284
1 files changed, 284 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1317-drm-amdkfd-Simplify-process-locking.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1317-drm-amdkfd-Simplify-process-locking.patch
new file mode 100644
index 00000000..57b7da33
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1317-drm-amdkfd-Simplify-process-locking.patch
@@ -0,0 +1,284 @@
+From d1c2cff99402bc9f20390f612b9286d04ef9bff5 Mon Sep 17 00:00:00 2001
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+Date: Tue, 25 Jul 2017 15:32:23 -0400
+Subject: [PATCH 1317/4131] drm/amdkfd: Simplify process locking
+
+It's no longer necessary to drop the process lock when calling into
+amdgpu. The reason is that the process lock isn't taken any more when
+amdgpu calls KFD functions ever since this use of the process lock
+was replaced by a process reference count.
+
+Change-Id: I43059e4f0a10b4e76e57f12dce1825ef4645299b
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+
+ Conflicts[4.12]:
+ drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 63 ++++++++++++++++----------------
+ drivers/gpu/drm/amd/amdkfd/kfd_ipc.c | 33 ++++++++++-------
+ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 5 +--
+ 3 files changed, 51 insertions(+), 50 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+index 70ee1f6..8f47d4d 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+@@ -1205,12 +1205,6 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
+ if (!dev)
+ return -EINVAL;
+
+- mutex_lock(&p->mutex);
+- pdd = kfd_bind_process_to_device(dev, p);
+- mutex_unlock(&p->mutex);
+- if (IS_ERR(pdd))
+- return PTR_ERR(pdd);
+-
+ if (flags & KFD_IOC_ALLOC_MEM_FLAGS_USERPTR) {
+ /* Check if the userptr corresponds to another (or third-party)
+ * device local memory. If so treat is as a doorbell. User
+@@ -1232,25 +1226,31 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
+ offset = kfd_get_process_doorbells(dev, p);
+ }
+
++ mutex_lock(&p->mutex);
++
++ pdd = kfd_bind_process_to_device(dev, p);
++ if (IS_ERR(pdd)) {
++ err = PTR_ERR(pdd);
++ goto err_unlock;
++ }
++
+ err = dev->kfd2kgd->alloc_memory_of_gpu(
+ dev->kgd, args->va_addr, args->size,
+ pdd->vm, (struct kgd_mem **) &mem, &offset,
+ NULL, flags);
+
+- if (err != 0)
+- return err;
++ if (err)
++ goto err_unlock;
+
+- mutex_lock(&p->mutex);
+ idr_handle = kfd_process_device_create_obj_handle(pdd, mem,
+ args->va_addr, args->size, NULL);
+- mutex_unlock(&p->mutex);
+ if (idr_handle < 0) {
+- dev->kfd2kgd->free_memory_of_gpu(dev->kgd,
+- (struct kgd_mem *) mem,
+- pdd->vm);
+- return -EFAULT;
++ err = -EFAULT;
++ goto err_free;
+ }
+
++ mutex_unlock(&p->mutex);
++
+ args->handle = MAKE_HANDLE(args->gpu_id, idr_handle);
+ if ((args->flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) != 0 &&
+ !kfd_is_large_bar(dev)) {
+@@ -1263,6 +1263,14 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
+ }
+
+ return 0;
++
++err_free:
++ dev->kfd2kgd->free_memory_of_gpu(dev->kgd,
++ (struct kgd_mem *) mem,
++ pdd->vm);
++err_unlock:
++ mutex_unlock(&p->mutex);
++ return err;
+ }
+
+ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
+@@ -1295,22 +1303,15 @@ static int kfd_ioctl_free_memory_of_gpu(struct file *filep,
+ }
+ run_rdma_free_callback(buf_obj);
+
+- mutex_unlock(&p->mutex);
+-
+ ret = dev->kfd2kgd->free_memory_of_gpu(dev->kgd, buf_obj->mem,
+ pdd->vm);
+
+ /* If freeing the buffer failed, leave the handle in place for
+ * clean-up during process tear-down.
+ */
+- if (ret == 0) {
+- mutex_lock(&p->mutex);
++ if (ret == 0)
+ kfd_process_device_remove_obj_handle(
+ pdd, GET_IDR_HANDLE(args->handle));
+- mutex_unlock(&p->mutex);
+- }
+-
+- return ret;
+
+ err_unlock:
+ mutex_unlock(&p->mutex);
+@@ -1363,8 +1364,6 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
+
+ mem = kfd_process_device_translate_handle(pdd,
+ GET_IDR_HANDLE(args->handle));
+- mutex_unlock(&p->mutex);
+-
+ if (!mem) {
+ err = PTR_ERR(mem);
+ goto get_mem_obj_from_handle_failed;
+@@ -1380,9 +1379,8 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
+ err = -EFAULT;
+ goto get_mem_obj_from_handle_failed;
+ }
+- mutex_lock(&p->mutex);
++
+ peer_pdd = kfd_bind_process_to_device(peer, p);
+- mutex_unlock(&p->mutex);
+ if (!peer_pdd) {
+ err = -EFAULT;
+ goto get_mem_obj_from_handle_failed;
+@@ -1399,6 +1397,8 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
+ pr_err("Failed to map\n");
+ }
+
++ mutex_unlock(&p->mutex);
++
+ err = dev->kfd2kgd->sync_memory(dev->kgd, (struct kgd_mem *) mem, true);
+ if (err) {
+ pr_debug("Sync memory failed, wait interrupted by user signal\n");
+@@ -1426,8 +1426,8 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
+ return err;
+
+ bind_process_to_device_failed:
+- mutex_unlock(&p->mutex);
+ get_mem_obj_from_handle_failed:
++ mutex_unlock(&p->mutex);
+ copy_from_user_failed:
+ sync_memory_failed:
+ kfree(devices_arr);
+@@ -1496,8 +1496,6 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
+
+ mem = kfd_process_device_translate_handle(pdd,
+ GET_IDR_HANDLE(args->handle));
+- mutex_unlock(&p->mutex);
+-
+ if (!mem) {
+ err = PTR_ERR(mem);
+ goto get_mem_obj_from_handle_failed;
+@@ -1511,9 +1509,8 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
+ err = -EFAULT;
+ goto get_mem_obj_from_handle_failed;
+ }
+- mutex_lock(&p->mutex);
++
+ peer_pdd = kfd_get_process_device_data(peer, p);
+- mutex_unlock(&p->mutex);
+ if (!peer_pdd) {
+ err = -EFAULT;
+ goto get_mem_obj_from_handle_failed;
+@@ -1524,11 +1521,13 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
+ } else
+ kfd_unmap_memory_from_gpu(mem, pdd);
+
++ mutex_unlock(&p->mutex);
++
+ return 0;
+
+ bind_process_to_device_failed:
+- mutex_unlock(&p->mutex);
+ get_mem_obj_from_handle_failed:
++ mutex_unlock(&p->mutex);
+ copy_from_user_failed:
+ kfree(devices_arr);
+ return err;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_ipc.c b/drivers/gpu/drm/amd/amdkfd/kfd_ipc.c
+index da3765d..c6be3ba 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_ipc.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_ipc.c
+@@ -127,35 +127,42 @@ static int kfd_import_dmabuf_create_kfd_bo(struct kfd_dev *dev,
+ return -EINVAL;
+
+ mutex_lock(&p->mutex);
++
+ pdd = kfd_bind_process_to_device(dev, p);
+- mutex_unlock(&p->mutex);
+- if (IS_ERR(pdd))
+- return PTR_ERR(pdd);
++ if (IS_ERR(pdd)) {
++ r = PTR_ERR(pdd);
++ goto err_unlock;
++ }
+
+ r = dev->kfd2kgd->import_dmabuf(dev->kgd, dmabuf,
+ va_addr, pdd->vm,
+ (struct kgd_mem **)&mem, &size,
+ mmap_offset);
+ if (r)
+- return r;
++ goto err_unlock;
+
+- mutex_lock(&p->mutex);
+ idr_handle = kfd_process_device_create_obj_handle(pdd, mem,
+ va_addr, size,
+ ipc_obj);
+- mutex_unlock(&p->mutex);
+ if (idr_handle < 0) {
+- dev->kfd2kgd->free_memory_of_gpu(dev->kgd,
+- (struct kgd_mem *)mem,
+- pdd->vm);
+- return -EFAULT;
++ r = -EFAULT;
++ goto err_free;
+ }
+
+- *handle = MAKE_HANDLE(gpu_id, idr_handle);
++ mutex_unlock(&p->mutex);
+
++ *handle = MAKE_HANDLE(gpu_id, idr_handle);
+ if (mmap_offset)
+ *mmap_offset = (kfd_mmap_flags << PAGE_SHIFT) | *mmap_offset;
+
++ return 0;
++
++err_free:
++ dev->kfd2kgd->free_memory_of_gpu(dev->kgd,
++ (struct kgd_mem *)mem,
++ pdd->vm);
++err_unlock:
++ mutex_unlock(&p->mutex);
+ return r;
+ }
+
+@@ -241,14 +248,12 @@ int kfd_ipc_export_as_handle(struct kfd_dev *dev, struct kfd_process *p,
+
+ mutex_lock(&p->mutex);
+ pdd = kfd_bind_process_to_device(dev, p);
+- mutex_unlock(&p->mutex);
+-
+ if (IS_ERR(pdd)) {
++ mutex_unlock(&p->mutex);
+ pr_err("Failed to get pdd\n");
+ return PTR_ERR(pdd);
+ }
+
+- mutex_lock(&p->mutex);
+ kfd_bo = kfd_process_device_find_bo(pdd, GET_IDR_HANDLE(handle));
+ mutex_unlock(&p->mutex);
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index d51ec08..39d9e6d2 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -113,10 +113,7 @@ static void kfd_process_free_gpuvm(struct kgd_mem *mem,
+ * This function should be only called right after the process
+ * is created and when kfd_processes_mutex is still being held
+ * to avoid concurrency. Because of that exclusiveness, we do
+- * not need to take p->mutex. Because kfd_processes_mutex instead
+- * of p->mutex is held, we do not need to release the lock when
+- * calling into kgd through functions such as alloc_memory_of_gpu()
+- * etc.
++ * not need to take p->mutex.
+ */
+ static int kfd_process_alloc_gpuvm(struct kfd_process *p,
+ struct kfd_dev *kdev, uint64_t gpu_va, uint32_t size,
+--
+2.7.4
+