@@ -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;
}
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(-)