From 49c16d301a2567d7e231dfcb730534097faaea8c Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Tue, 24 Jan 2017 20:48:13 -0500 Subject: [PATCH 1217/4131] drm/amdkfd: Always release process in a work queue Run process clean-up triggered by kfd_unref_process in a work queue to avoid recursive locking issues. Change-Id: I27ac43548a986bbe49d3ebe7f7d655a25b6349d5 Signed-off-by: Felix Kuehling --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 63e85de..10bddc9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -327,9 +327,10 @@ 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 * stucture in the end. */ -static void kfd_process_ref_release(struct kref *ref) +static void kfd_process_wq_release(struct work_struct *work) { - struct kfd_process *p = container_of(ref, struct kfd_process, ref); + struct kfd_process *p = container_of(work, struct kfd_process, + release_work); struct kfd_process_device *pdd; pr_debug("Releasing process (pasid %d)\n", @@ -361,22 +362,21 @@ static void kfd_process_ref_release(struct kref *ref) kfree(p); } -static void kfd_process_wq_release(struct work_struct *work) +static void kfd_process_ref_release(struct kref *ref) { - struct kfd_process *p = container_of(work, struct kfd_process, - release_work); + struct kfd_process *p = container_of(ref, struct kfd_process, ref); - kref_put(&p->ref, kfd_process_ref_release); + BUG_ON(!kfd_process_wq); + + INIT_WORK(&p->release_work, kfd_process_wq_release); + queue_work(kfd_process_wq, &p->release_work); } static void kfd_process_destroy_delayed(struct rcu_head *rcu) { struct kfd_process *p = container_of(rcu, struct kfd_process, rcu); - BUG_ON(!kfd_process_wq); - - INIT_WORK(&p->release_work, kfd_process_wq_release); - queue_work(kfd_process_wq, &p->release_work); + kfd_unref_process(p); } static void kfd_process_notifier_release(struct mmu_notifier *mn, -- 2.7.4