|
@@ -827,7 +827,6 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
|
|
int rc = 0;
|
|
int rc = 0;
|
|
int *result = NULL;
|
|
int *result = NULL;
|
|
struct page *new_hpage = get_new_page(hpage, private, &result);
|
|
struct page *new_hpage = get_new_page(hpage, private, &result);
|
|
- int rcu_locked = 0;
|
|
|
|
struct anon_vma *anon_vma = NULL;
|
|
struct anon_vma *anon_vma = NULL;
|
|
|
|
|
|
if (!new_hpage)
|
|
if (!new_hpage)
|
|
@@ -842,12 +841,10 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
|
|
}
|
|
}
|
|
|
|
|
|
if (PageAnon(hpage)) {
|
|
if (PageAnon(hpage)) {
|
|
- rcu_read_lock();
|
|
|
|
- rcu_locked = 1;
|
|
|
|
-
|
|
|
|
- if (page_mapped(hpage)) {
|
|
|
|
- anon_vma = page_anon_vma(hpage);
|
|
|
|
- atomic_inc(&anon_vma->external_refcount);
|
|
|
|
|
|
+ anon_vma = page_lock_anon_vma(hpage);
|
|
|
|
+ if (anon_vma) {
|
|
|
|
+ get_anon_vma(anon_vma);
|
|
|
|
+ page_unlock_anon_vma(anon_vma);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -859,16 +856,8 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
|
|
if (rc)
|
|
if (rc)
|
|
remove_migration_ptes(hpage, hpage);
|
|
remove_migration_ptes(hpage, hpage);
|
|
|
|
|
|
- if (anon_vma && atomic_dec_and_lock(&anon_vma->external_refcount,
|
|
|
|
- &anon_vma->lock)) {
|
|
|
|
- int empty = list_empty(&anon_vma->head);
|
|
|
|
- spin_unlock(&anon_vma->lock);
|
|
|
|
- if (empty)
|
|
|
|
- anon_vma_free(anon_vma);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (rcu_locked)
|
|
|
|
- rcu_read_unlock();
|
|
|
|
|
|
+ if (anon_vma)
|
|
|
|
+ drop_anon_vma(anon_vma);
|
|
out:
|
|
out:
|
|
unlock_page(hpage);
|
|
unlock_page(hpage);
|
|
|
|
|