diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/ksm.c | 5 | ||||
-rw-r--r-- | mm/memory.c | 4 | ||||
-rw-r--r-- | mm/mmap.c | 7 |
3 files changed, 3 insertions, 13 deletions
@@ -1416,8 +1416,7 @@ int __ksm_enter(struct mm_struct *mm) | |||
1416 | return 0; | 1416 | return 0; |
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | void __ksm_exit(struct mm_struct *mm, | 1419 | void __ksm_exit(struct mm_struct *mm) |
1420 | struct mmu_gather **tlbp, unsigned long end) | ||
1421 | { | 1420 | { |
1422 | struct mm_slot *mm_slot; | 1421 | struct mm_slot *mm_slot; |
1423 | int easy_to_free = 0; | 1422 | int easy_to_free = 0; |
@@ -1450,10 +1449,8 @@ void __ksm_exit(struct mm_struct *mm, | |||
1450 | clear_bit(MMF_VM_MERGEABLE, &mm->flags); | 1449 | clear_bit(MMF_VM_MERGEABLE, &mm->flags); |
1451 | mmdrop(mm); | 1450 | mmdrop(mm); |
1452 | } else if (mm_slot) { | 1451 | } else if (mm_slot) { |
1453 | tlb_finish_mmu(*tlbp, 0, end); | ||
1454 | down_write(&mm->mmap_sem); | 1452 | down_write(&mm->mmap_sem); |
1455 | up_write(&mm->mmap_sem); | 1453 | up_write(&mm->mmap_sem); |
1456 | *tlbp = tlb_gather_mmu(mm, 1); | ||
1457 | } | 1454 | } |
1458 | } | 1455 | } |
1459 | 1456 | ||
diff --git a/mm/memory.c b/mm/memory.c index f47ffe971012..05feaa11d87c 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2648,7 +2648,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2648 | entry = maybe_mkwrite(pte_mkdirty(entry), vma); | 2648 | entry = maybe_mkwrite(pte_mkdirty(entry), vma); |
2649 | 2649 | ||
2650 | page_table = pte_offset_map_lock(mm, pmd, address, &ptl); | 2650 | page_table = pte_offset_map_lock(mm, pmd, address, &ptl); |
2651 | if (!pte_none(*page_table) || ksm_test_exit(mm)) | 2651 | if (!pte_none(*page_table)) |
2652 | goto release; | 2652 | goto release; |
2653 | 2653 | ||
2654 | inc_mm_counter(mm, anon_rss); | 2654 | inc_mm_counter(mm, anon_rss); |
@@ -2792,7 +2792,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2792 | * handle that later. | 2792 | * handle that later. |
2793 | */ | 2793 | */ |
2794 | /* Only go through if we didn't race with anybody else... */ | 2794 | /* Only go through if we didn't race with anybody else... */ |
2795 | if (likely(pte_same(*page_table, orig_pte) && !ksm_test_exit(mm))) { | 2795 | if (likely(pte_same(*page_table, orig_pte))) { |
2796 | flush_icache_page(vma, page); | 2796 | flush_icache_page(vma, page); |
2797 | entry = mk_pte(page, vma->vm_page_prot); | 2797 | entry = mk_pte(page, vma->vm_page_prot); |
2798 | if (flags & FAULT_FLAG_WRITE) | 2798 | if (flags & FAULT_FLAG_WRITE) |
@@ -2113,13 +2113,6 @@ void exit_mmap(struct mm_struct *mm) | |||
2113 | end = unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL); | 2113 | end = unmap_vmas(&tlb, vma, 0, -1, &nr_accounted, NULL); |
2114 | vm_unacct_memory(nr_accounted); | 2114 | vm_unacct_memory(nr_accounted); |
2115 | 2115 | ||
2116 | /* | ||
2117 | * For KSM to handle OOM without deadlock when it's breaking COW in a | ||
2118 | * likely victim of the OOM killer, we must serialize with ksm_exit() | ||
2119 | * after freeing mm's pages but before freeing its page tables. | ||
2120 | */ | ||
2121 | ksm_exit(mm, &tlb, end); | ||
2122 | |||
2123 | free_pgtables(tlb, vma, FIRST_USER_ADDRESS, 0); | 2116 | free_pgtables(tlb, vma, FIRST_USER_ADDRESS, 0); |
2124 | tlb_finish_mmu(tlb, 0, end); | 2117 | tlb_finish_mmu(tlb, 0, end); |
2125 | 2118 | ||