aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch112
1 files changed, 112 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch
new file mode 100644
index 00000000..fda6d4fc
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch
@@ -0,0 +1,112 @@
+From 2ac66eb37891b15f0ad0470354669a3e8f0a8396 Mon Sep 17 00:00:00 2001
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+Date: Wed, 29 May 2019 00:00:35 -0400
+Subject: [PATCH 2793/2940] drm/amdkfd: Handle unmapping of doorbell VMAs
+ correctly
+
+KFDTest with --gtest_repeat will unmap and map doorbells for each
+test. When the doorbells are unmapped, we need to forget the doorbell
+VMA. The next time they are mapped, a new VMA is created.
+
+If the process is evicted during unmap, we need to remember that the
+doorbells are supposed to be zapped so they can be zapped on the next
+map.
+
+Whether or not queues exist shouldn't matter for the purposes of
+zapping and remapping doorbells. Only the existence of a VMA matters.
+
+Change-Id: I885f5b386997cfdc5e2f95ae43c9d6f4e13c5d0d
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c | 21 ++++++++++++---------
+ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 9 ++++++++-
+ 2 files changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+index de5366685535..278bc22edf49 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
+@@ -128,18 +128,21 @@ void kfd_doorbell_fini(struct kfd_dev *kfd)
+
+ static int kfd_doorbell_vm_fault(struct vm_fault *vmf)
+ {
+- struct kfd_process *process = vmf->vma->vm_private_data;
+-
++ struct kfd_process_device *pdd = vmf->vma->vm_private_data;
+ pr_debug("Process %d doorbell vm page fault\n", process->pasid);
++ if (!pdd)
++ return VM_FAULT_SIGBUS;
+
+- kfd_process_remap_doorbells_locked(process);
+-
+- kfd_process_schedule_restore(process);
++ pr_debug("Process %d doorbell vm page fault\n", pdd->process->pasid);
++ kfd_process_remap_doorbells_locked(pdd->process);
+
++ kfd_process_schedule_restore(pdd->process);
+ return VM_FAULT_NOPAGE;
+ }
+
+ static const struct vm_operations_struct kfd_doorbell_vm_ops = {
++ .open = kfd_doorbell_open,
++ .close = kfd_doorbell_close,
+ .fault = kfd_doorbell_vm_fault,
+ };
+
+@@ -150,10 +153,10 @@ void kfd_doorbell_unmap_locked(struct kfd_process_device *pdd)
+ size_t size;
+
+ vma = pdd->qpd.doorbell_vma;
+- /* If process is evicted before queue is created
+- * doorbell is not mapped to user space yet
++ /* Remember if the process was evicted without doorbells
++ * mapped to user mode.
+ */
+- if (!vma || !pdd->qpd.queue_count) {
++ if (!vma) {
+ pdd->qpd.doorbell_mapped = -1;
+ return;
+ }
+@@ -249,7 +252,7 @@ int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
+
+ if (!ret && keep_idle_process_evicted) {
+ vma->vm_ops = &kfd_doorbell_vm_ops;
+- vma->vm_private_data = process;
++ vma->vm_private_data = pdd;
+ pdd->qpd.doorbell_vma = vma;
+
+ /* If process is evicted before the first queue is created,
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index 18fa6c75e97d..6da0f3d8f3e9 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -379,6 +379,7 @@ static void kfd_process_destroy_pdds(struct kfd_process *p)
+ kfree(pdd->qpd.doorbell_bitmap);
+ idr_destroy(&pdd->alloc_idr);
+ mutex_destroy(&pdd->qpd.doorbell_lock);
++
+ kfree(pdd);
+ }
+ }
+@@ -453,11 +454,17 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
+
+ /* Iterate over all process device data structures and if the
+ * pdd is in debug mode, we should first force unregistration,
+- * then we will be able to destroy the queues
++ * then we will be able to destroy the queues. Also invalidate
++ * doorbell_vma private data because the pdds are about to be
++ * destroyed, which can race with the kfd_doorbell_close
++ * vm_ops callback.
+ */
+ list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
+ struct kfd_dev *dev = pdd->dev;
+
++ if (pdd->qpd.doorbell_vma)
++ pdd->qpd.doorbell_vma->vm_private_data = NULL;
++
+ /* Old (deprecated) debugger for GFXv8 and older */
+ mutex_lock(kfd_get_dbgmgr_mutex());
+ if (dev && dev->dbgmgr && dev->dbgmgr->pasid == p->pasid) {
+--
+2.17.1
+