|
|
@@ -91,16 +91,6 @@ static struct hmm *hmm_register(struct mm_struct *mm)
|
|
|
spin_lock_init(&hmm->lock);
|
|
|
hmm->mm = mm;
|
|
|
|
|
|
- /*
|
|
|
- * We should only get here if hold the mmap_sem in write mode ie on
|
|
|
- * registration of first mirror through hmm_mirror_register()
|
|
|
- */
|
|
|
- hmm->mmu_notifier.ops = &hmm_mmu_notifier_ops;
|
|
|
- if (__mmu_notifier_register(&hmm->mmu_notifier, mm)) {
|
|
|
- kfree(hmm);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
spin_lock(&mm->page_table_lock);
|
|
|
if (!mm->hmm)
|
|
|
mm->hmm = hmm;
|
|
|
@@ -108,12 +98,27 @@ static struct hmm *hmm_register(struct mm_struct *mm)
|
|
|
cleanup = true;
|
|
|
spin_unlock(&mm->page_table_lock);
|
|
|
|
|
|
- if (cleanup) {
|
|
|
- mmu_notifier_unregister(&hmm->mmu_notifier, mm);
|
|
|
- kfree(hmm);
|
|
|
- }
|
|
|
+ if (cleanup)
|
|
|
+ goto error;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We should only get here if hold the mmap_sem in write mode ie on
|
|
|
+ * registration of first mirror through hmm_mirror_register()
|
|
|
+ */
|
|
|
+ hmm->mmu_notifier.ops = &hmm_mmu_notifier_ops;
|
|
|
+ if (__mmu_notifier_register(&hmm->mmu_notifier, mm))
|
|
|
+ goto error_mm;
|
|
|
|
|
|
return mm->hmm;
|
|
|
+
|
|
|
+error_mm:
|
|
|
+ spin_lock(&mm->page_table_lock);
|
|
|
+ if (mm->hmm == hmm)
|
|
|
+ mm->hmm = NULL;
|
|
|
+ spin_unlock(&mm->page_table_lock);
|
|
|
+error:
|
|
|
+ kfree(hmm);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
void hmm_mm_destroy(struct mm_struct *mm)
|
|
|
@@ -278,12 +283,13 @@ void hmm_mirror_unregister(struct hmm_mirror *mirror)
|
|
|
if (!should_unregister || mm == NULL)
|
|
|
return;
|
|
|
|
|
|
+ mmu_notifier_unregister_no_release(&hmm->mmu_notifier, mm);
|
|
|
+
|
|
|
spin_lock(&mm->page_table_lock);
|
|
|
if (mm->hmm == hmm)
|
|
|
mm->hmm = NULL;
|
|
|
spin_unlock(&mm->page_table_lock);
|
|
|
|
|
|
- mmu_notifier_unregister_no_release(&hmm->mmu_notifier, mm);
|
|
|
kfree(hmm);
|
|
|
}
|
|
|
EXPORT_SYMBOL(hmm_mirror_unregister);
|