diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/2793-drm-amdkfd-Handle-unmapping-of-doorbell-VMAs-correct.patch b/common/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/common/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 + |