Patch "drm/amdkfd: unbind only existing processes" has been added to the 4.4-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
drm/amdkfd: unbind only existing processes
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-amdkfd-unbind-only-existing-processes.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
121b78e679ee3ffab780115e260b2775d0cc1f73Mon Sep 17 00:00:00 2001
From: Oded Gabbay <[email protected]>
Date: Thu, 26 May 2016 08:41:08 +0300
Subject: drm/amdkfd: unbind only existing processes
From: Oded Gabbay <[email protected]>
commit 121b78e679ee3ffab780115e260b2775d0cc1f73 upstream.
When unbinding a process from a device (initiated by amd_iommu_v2), the driver needs to make sure that process still exists in the process table. There is a possibility that amdkfd's own notifier handler - kfd_process_notifier_release() - was called before the unbind function and it already removed the process from the process table.
v2:
Because there can be only one process with the specified pasid, and because *p can't be NULL inside the hash_for_each_rcu macro, it is more reasonable to just put the whole code inside the if statement that compares the pasid value. That way, when we exit hash_for_each_rcu, we simply exit the function as well.
--- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 60 ++++++++++++++++++------------- 1 file changed, 35 insertions(+), 25 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_process.c +35 -25
@@ -404,42 +404,52 @@ void kfd_unbind_process_from_device(stru idx =srcu_read_lock (&kfd_processes_srcu); +/* +* Look for the process that matches the pasid. If there is no such +* process, we either released it in amdkfd's own notifier, or there +* is a bug. Unfortunately, there is no way to tell... +*/ hash_for_each_rcu (kfd_processes_table, i, p, kfd_processes) -if (p->pasid == pasid) -break ; +if (p->pasid == pasid) { -srcu_read_unlock (&kfd_processes_srcu, idx); +srcu_read_unlock (&kfd_processes_srcu, idx); -BUG_ON (p->pasid != pasid); +pr_debug ("Unbinding process %d from IOMMU\n" , pasid); -mutex_lock (&p->mutex); +mutex_lock (&p->mutex); -if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) -kfd_dbgmgr_destroy (dev->dbgmgr); +if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) +kfd_dbgmgr_destroy (dev->dbgmgr); -pqm_uninit (&p->pqm); +pqm_uninit (&p->pqm); - pdd =kfd_get_process_device_data (dev, p); + pdd =kfd_get_process_device_data (dev, p); -if (!pdd) { -mutex_unlock (&p->mutex); -return ; - } +if (!pdd) { +mutex_unlock (&p->mutex); +return ; + } -if (pdd->reset_wavefronts) { -dbgdev_wave_reset_wavefronts (pdd->dev, p); - pdd->reset_wavefronts = false; - } +if (pdd->reset_wavefronts) { +dbgdev_wave_reset_wavefronts (pdd->dev, p); + pdd->reset_wavefronts = false; + } -/* -* Just mark pdd as unbound, because we still need it to call -* amd_iommu_unbind_pasid() in when the process exits. -* We don't call amd_iommu_unbind_pasid() here -* because the IOMMU called us. -*/ - pdd->bound = false; +/* +* Just mark pdd as unbound, because we still need it +* to call amd_iommu_unbind_pasid() in when the +* process exits. +* We don't call amd_iommu_unbind_pasid() here +* because the IOMMU called us. +*/ + pdd->bound = false; + +mutex_unlock (&p->mutex); -mutex_unlock (&p->mutex); +return ; + } + +srcu_read_unlock (&kfd_processes_srcu, idx); }struct kfd_process_device *kfd_get_first_process_device_data (struct kfd_process *p)
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/drm-amdkfd-unbind-only-existing-processes.patch queue-4.4/drm-amdkfd-destroy-dbgmgr-in-notifier-release.patch