x86/sgx: Use a loop to release mm_struct's in sgx_release()
diff mbox series

Message ID 20190712125640.18650-1-jarkko.sakkinen@linux.intel.com
State New
Headers show
Series
  • x86/sgx: Use a loop to release mm_struct's in sgx_release()
Related show

Commit Message

Jarkko Sakkinen July 12, 2019, 12:56 p.m. UTC
Instead of an awkward goto-construct use a loop-construct to delete
entries from the list of mm_struct's.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
Still problems with my test env so only compilation test at this point.
 arch/x86/kernel/cpu/sgx/driver/main.c | 39 +++++++++++++--------------
 1 file changed, 18 insertions(+), 21 deletions(-)

Patch
diff mbox series

diff --git a/arch/x86/kernel/cpu/sgx/driver/main.c b/arch/x86/kernel/cpu/sgx/driver/main.c
index 27cf271b25f6..bb7f1932529f 100644
--- a/arch/x86/kernel/cpu/sgx/driver/main.c
+++ b/arch/x86/kernel/cpu/sgx/driver/main.c
@@ -55,30 +55,27 @@  static int sgx_release(struct inode *inode, struct file *file)
 	struct sgx_encl *encl = file->private_data;
 	struct sgx_encl_mm *encl_mm;
 
-	/*
-	 * Objects can't be *moved* off an RCU protected list (deletion is ok),
-	 * nor can the object be freed until after synchronize_srcu().
-	 */
-restart:
-	spin_lock(&encl->mm_lock);
-	if (list_empty(&encl->mm_list)) {
-		encl_mm = NULL;
-	} else {
-		encl_mm = list_first_entry(&encl->mm_list, struct sgx_encl_mm,
-					   list);
-		list_del_rcu(&encl_mm->list);
-	}
-	spin_unlock(&encl->mm_lock);
+	for ( ; ; )  {
+		spin_lock(&encl->mm_lock);
+
+		if (list_empty(&encl->mm_list)) {
+			encl_mm = NULL;
+		} else {
+			encl_mm = list_first_entry(&encl->mm_list,
+						   struct sgx_encl_mm, list);
+			list_del_rcu(&encl_mm->list);
+		}
 
-	if (encl_mm) {
-		synchronize_srcu(&encl->srcu);
+		spin_unlock(&encl->mm_lock);
 
-		mmu_notifier_unregister(&encl_mm->mmu_notifier, encl_mm->mm);
+		/* The list is empty, ready to go. */
+		if (!encl_mm)
+			break;
 
+		synchronize_srcu(&encl->srcu);
+		mmu_notifier_unregister(&encl_mm->mmu_notifier, encl_mm->mm);
 		kfree(encl_mm);
-
-		goto restart;
-	}
+	};
 
 	mutex_lock(&encl->lock);
 	encl->flags |= SGX_ENCL_DEAD;
@@ -86,8 +83,8 @@  static int sgx_release(struct inode *inode, struct file *file)
 
 	if (encl->work.func)
 		flush_work(&encl->work);
-	kref_put(&encl->refcount, sgx_encl_release);
 
+	kref_put(&encl->refcount, sgx_encl_release);
 	return 0;
 }