From 2ac66eb37891b15f0ad0470354669a3e8f0a8396 Mon Sep 17 00:00:00 2001 From: Felix Kuehling 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 --- 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