From de1450a5597a642bdc4987aa31873d8475810aae Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Mon, 27 Nov 2017 18:29:55 -0500 Subject: [PATCH] drm/amdkfd: Factor PDD destruction out of kfd_process_wq_release Signed-off-by: Felix Kuehling Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 40 ++++++++++++++---------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 88fc822c9e5a..096710c3766d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -152,28 +152,15 @@ void kfd_unref_process(struct kfd_process *p) kref_put(&p->ref, kfd_process_ref_release); } -/* 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) +static void kfd_process_destroy_pdds(struct kfd_process *p) { - struct kfd_process *p = container_of(work, struct kfd_process, - release_work); 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, - per_device_list) { - pr_debug("Releasing pdd (topology id %d) for process (pasid %d) in workqueue\n", + per_device_list) { + pr_debug("Releasing pdd (topology id %d) for process (pasid %d)\n", 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); if (pdd->qpd.cwsr_kaddr) @@ -182,6 +169,27 @@ static void kfd_process_wq_release(struct work_struct *work) 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);