drm/amdkfd: Factor PDD destruction out of kfd_process_wq_release

Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
This commit is contained in:
Felix Kuehling 2017-11-27 18:29:55 -05:00 committed by Oded Gabbay
parent 2d9b36f983
commit de1450a559
1 changed files with 24 additions and 16 deletions

View File

@ -152,28 +152,15 @@ void kfd_unref_process(struct kfd_process *p)
kref_put(&p->ref, kfd_process_ref_release); kref_put(&p->ref, kfd_process_ref_release);
} }
/* No process locking is needed in this function, because the process static void kfd_process_destroy_pdds(struct kfd_process *p)
* is not findable any more. We must assume that no other thread is
* using it any more, otherwise we couldn't safely free the process
* structure in the end.
*/
static void kfd_process_wq_release(struct work_struct *work)
{ {
struct kfd_process *p = container_of(work, struct kfd_process,
release_work);
struct kfd_process_device *pdd, *temp; struct kfd_process_device *pdd, *temp;
pr_debug("Releasing process (pasid %d) in workqueue\n",
p->pasid);
list_for_each_entry_safe(pdd, temp, &p->per_device_data, list_for_each_entry_safe(pdd, temp, &p->per_device_data,
per_device_list) { per_device_list) {
pr_debug("Releasing pdd (topology id %d) for process (pasid %d) in workqueue\n", pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n",
pdd->dev->id, p->pasid); pdd->dev->id, p->pasid);
if (pdd->bound == PDD_BOUND)
amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid);
list_del(&pdd->per_device_list); list_del(&pdd->per_device_list);
if (pdd->qpd.cwsr_kaddr) if (pdd->qpd.cwsr_kaddr)
@ -182,6 +169,27 @@ static void kfd_process_wq_release(struct work_struct *work)
kfree(pdd); kfree(pdd);
} }
}
/* No process locking is needed in this function, because the process
* is not findable any more. We must assume that no other thread is
* using it any more, otherwise we couldn't safely free the process
* structure in the end.
*/
static void kfd_process_wq_release(struct work_struct *work)
{
struct kfd_process *p = container_of(work, struct kfd_process,
release_work);
struct kfd_process_device *pdd;
pr_debug("Releasing process (pasid %d) in workqueue\n", p->pasid);
list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
if (pdd->bound == PDD_BOUND)
amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid);
}
kfd_process_destroy_pdds(p);
kfd_event_free_process(p); kfd_event_free_process(p);