diff options
Diffstat (limited to 'mm/rmap.c')
-rw-r--r-- | mm/rmap.c | 38 |
1 files changed, 24 insertions, 14 deletions
@@ -103,7 +103,7 @@ int anon_vma_prepare(struct vm_area_struct *vma) | |||
103 | spin_lock(&mm->page_table_lock); | 103 | spin_lock(&mm->page_table_lock); |
104 | if (likely(!vma->anon_vma)) { | 104 | if (likely(!vma->anon_vma)) { |
105 | vma->anon_vma = anon_vma; | 105 | vma->anon_vma = anon_vma; |
106 | list_add(&vma->anon_vma_node, &anon_vma->head); | 106 | list_add_tail(&vma->anon_vma_node, &anon_vma->head); |
107 | allocated = NULL; | 107 | allocated = NULL; |
108 | } | 108 | } |
109 | spin_unlock(&mm->page_table_lock); | 109 | spin_unlock(&mm->page_table_lock); |
@@ -127,7 +127,7 @@ void __anon_vma_link(struct vm_area_struct *vma) | |||
127 | struct anon_vma *anon_vma = vma->anon_vma; | 127 | struct anon_vma *anon_vma = vma->anon_vma; |
128 | 128 | ||
129 | if (anon_vma) { | 129 | if (anon_vma) { |
130 | list_add(&vma->anon_vma_node, &anon_vma->head); | 130 | list_add_tail(&vma->anon_vma_node, &anon_vma->head); |
131 | validate_anon_vma(vma); | 131 | validate_anon_vma(vma); |
132 | } | 132 | } |
133 | } | 133 | } |
@@ -138,7 +138,7 @@ void anon_vma_link(struct vm_area_struct *vma) | |||
138 | 138 | ||
139 | if (anon_vma) { | 139 | if (anon_vma) { |
140 | spin_lock(&anon_vma->lock); | 140 | spin_lock(&anon_vma->lock); |
141 | list_add(&vma->anon_vma_node, &anon_vma->head); | 141 | list_add_tail(&vma->anon_vma_node, &anon_vma->head); |
142 | validate_anon_vma(vma); | 142 | validate_anon_vma(vma); |
143 | spin_unlock(&anon_vma->lock); | 143 | spin_unlock(&anon_vma->lock); |
144 | } | 144 | } |
@@ -620,17 +620,27 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma, | |||
620 | 620 | ||
621 | if (PageAnon(page)) { | 621 | if (PageAnon(page)) { |
622 | swp_entry_t entry = { .val = page_private(page) }; | 622 | swp_entry_t entry = { .val = page_private(page) }; |
623 | /* | 623 | |
624 | * Store the swap location in the pte. | 624 | if (PageSwapCache(page)) { |
625 | * See handle_pte_fault() ... | 625 | /* |
626 | */ | 626 | * Store the swap location in the pte. |
627 | BUG_ON(!PageSwapCache(page)); | 627 | * See handle_pte_fault() ... |
628 | swap_duplicate(entry); | 628 | */ |
629 | if (list_empty(&mm->mmlist)) { | 629 | swap_duplicate(entry); |
630 | spin_lock(&mmlist_lock); | 630 | if (list_empty(&mm->mmlist)) { |
631 | if (list_empty(&mm->mmlist)) | 631 | spin_lock(&mmlist_lock); |
632 | list_add(&mm->mmlist, &init_mm.mmlist); | 632 | if (list_empty(&mm->mmlist)) |
633 | spin_unlock(&mmlist_lock); | 633 | list_add(&mm->mmlist, &init_mm.mmlist); |
634 | spin_unlock(&mmlist_lock); | ||
635 | } | ||
636 | } else { | ||
637 | /* | ||
638 | * Store the pfn of the page in a special migration | ||
639 | * pte. do_swap_page() will wait until the migration | ||
640 | * pte is removed and then restart fault handling. | ||
641 | */ | ||
642 | BUG_ON(!migration); | ||
643 | entry = make_migration_entry(page, pte_write(pteval)); | ||
634 | } | 644 | } |
635 | set_pte_at(mm, address, pte, swp_entry_to_pte(entry)); | 645 | set_pte_at(mm, address, pte, swp_entry_to_pte(entry)); |
636 | BUG_ON(pte_file(*pte)); | 646 | BUG_ON(pte_file(*pte)); |