diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-29 12:01:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-29 12:01:01 -0500 |
commit | f55e1014f9e567d830eb3a7f57d879a34872af4b (patch) | |
tree | 7d3b834a71f6fbaec70bb4a5700424be15e9e1d3 | |
parent | 43570f0383d6d5879ae585e6c3cf027ba321546f (diff) |
Revert "mm, thp: Do not make pmd/pud dirty without a reason"
This reverts commit 152e93af3cfe2d29d8136cc0a02a8612507136ee.
It was a nice cleanup in theory, but as Nicolai Stange points out, we do
need to make the page dirty for the copy-on-write case even when we
didn't end up making it writable, since the dirty bit is what we use to
check that we've gone through a COW cycle.
Reported-by: Michal Hocko <mhocko@kernel.org>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/huge_memory.c | 31 | ||||
-rw-r--r-- | mm/internal.h | 3 | ||||
-rw-r--r-- | mm/khugepaged.c | 2 | ||||
-rw-r--r-- | mm/memory.c | 2 | ||||
-rw-r--r-- | mm/migrate.c | 2 |
5 files changed, 16 insertions, 24 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index f22401fd83b5..0e7ded98d114 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -474,13 +474,10 @@ out: | |||
474 | } | 474 | } |
475 | __setup("transparent_hugepage=", setup_transparent_hugepage); | 475 | __setup("transparent_hugepage=", setup_transparent_hugepage); |
476 | 476 | ||
477 | pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma, bool dirty) | 477 | pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma) |
478 | { | 478 | { |
479 | if (likely(vma->vm_flags & VM_WRITE)) { | 479 | if (likely(vma->vm_flags & VM_WRITE)) |
480 | pmd = pmd_mkwrite(pmd); | 480 | pmd = pmd_mkwrite(pmd); |
481 | if (dirty) | ||
482 | pmd = pmd_mkdirty(pmd); | ||
483 | } | ||
484 | return pmd; | 481 | return pmd; |
485 | } | 482 | } |
486 | 483 | ||
@@ -602,7 +599,7 @@ static int __do_huge_pmd_anonymous_page(struct vm_fault *vmf, struct page *page, | |||
602 | } | 599 | } |
603 | 600 | ||
604 | entry = mk_huge_pmd(page, vma->vm_page_prot); | 601 | entry = mk_huge_pmd(page, vma->vm_page_prot); |
605 | entry = maybe_pmd_mkwrite(entry, vma, true); | 602 | entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); |
606 | page_add_new_anon_rmap(page, vma, haddr, true); | 603 | page_add_new_anon_rmap(page, vma, haddr, true); |
607 | mem_cgroup_commit_charge(page, memcg, false, true); | 604 | mem_cgroup_commit_charge(page, memcg, false, true); |
608 | lru_cache_add_active_or_unevictable(page, vma); | 605 | lru_cache_add_active_or_unevictable(page, vma); |
@@ -744,8 +741,8 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr, | |||
744 | if (pfn_t_devmap(pfn)) | 741 | if (pfn_t_devmap(pfn)) |
745 | entry = pmd_mkdevmap(entry); | 742 | entry = pmd_mkdevmap(entry); |
746 | if (write) { | 743 | if (write) { |
747 | entry = pmd_mkyoung(entry); | 744 | entry = pmd_mkyoung(pmd_mkdirty(entry)); |
748 | entry = maybe_pmd_mkwrite(entry, vma, true); | 745 | entry = maybe_pmd_mkwrite(entry, vma); |
749 | } | 746 | } |
750 | 747 | ||
751 | if (pgtable) { | 748 | if (pgtable) { |
@@ -791,14 +788,10 @@ int vmf_insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr, | |||
791 | EXPORT_SYMBOL_GPL(vmf_insert_pfn_pmd); | 788 | EXPORT_SYMBOL_GPL(vmf_insert_pfn_pmd); |
792 | 789 | ||
793 | #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD | 790 | #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD |
794 | static pud_t maybe_pud_mkwrite(pud_t pud, struct vm_area_struct *vma, | 791 | static pud_t maybe_pud_mkwrite(pud_t pud, struct vm_area_struct *vma) |
795 | bool dirty) | ||
796 | { | 792 | { |
797 | if (likely(vma->vm_flags & VM_WRITE)) { | 793 | if (likely(vma->vm_flags & VM_WRITE)) |
798 | pud = pud_mkwrite(pud); | 794 | pud = pud_mkwrite(pud); |
799 | if (dirty) | ||
800 | pud = pud_mkdirty(pud); | ||
801 | } | ||
802 | return pud; | 795 | return pud; |
803 | } | 796 | } |
804 | 797 | ||
@@ -814,8 +807,8 @@ static void insert_pfn_pud(struct vm_area_struct *vma, unsigned long addr, | |||
814 | if (pfn_t_devmap(pfn)) | 807 | if (pfn_t_devmap(pfn)) |
815 | entry = pud_mkdevmap(entry); | 808 | entry = pud_mkdevmap(entry); |
816 | if (write) { | 809 | if (write) { |
817 | entry = pud_mkyoung(entry); | 810 | entry = pud_mkyoung(pud_mkdirty(entry)); |
818 | entry = maybe_pud_mkwrite(entry, vma, true); | 811 | entry = maybe_pud_mkwrite(entry, vma); |
819 | } | 812 | } |
820 | set_pud_at(mm, addr, pud, entry); | 813 | set_pud_at(mm, addr, pud, entry); |
821 | update_mmu_cache_pud(vma, addr, pud); | 814 | update_mmu_cache_pud(vma, addr, pud); |
@@ -1286,7 +1279,7 @@ int do_huge_pmd_wp_page(struct vm_fault *vmf, pmd_t orig_pmd) | |||
1286 | if (reuse_swap_page(page, NULL)) { | 1279 | if (reuse_swap_page(page, NULL)) { |
1287 | pmd_t entry; | 1280 | pmd_t entry; |
1288 | entry = pmd_mkyoung(orig_pmd); | 1281 | entry = pmd_mkyoung(orig_pmd); |
1289 | entry = maybe_pmd_mkwrite(entry, vma, true); | 1282 | entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); |
1290 | if (pmdp_set_access_flags(vma, haddr, vmf->pmd, entry, 1)) | 1283 | if (pmdp_set_access_flags(vma, haddr, vmf->pmd, entry, 1)) |
1291 | update_mmu_cache_pmd(vma, vmf->address, vmf->pmd); | 1284 | update_mmu_cache_pmd(vma, vmf->address, vmf->pmd); |
1292 | ret |= VM_FAULT_WRITE; | 1285 | ret |= VM_FAULT_WRITE; |
@@ -1356,7 +1349,7 @@ alloc: | |||
1356 | } else { | 1349 | } else { |
1357 | pmd_t entry; | 1350 | pmd_t entry; |
1358 | entry = mk_huge_pmd(new_page, vma->vm_page_prot); | 1351 | entry = mk_huge_pmd(new_page, vma->vm_page_prot); |
1359 | entry = maybe_pmd_mkwrite(entry, vma, true); | 1352 | entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); |
1360 | pmdp_huge_clear_flush_notify(vma, haddr, vmf->pmd); | 1353 | pmdp_huge_clear_flush_notify(vma, haddr, vmf->pmd); |
1361 | page_add_new_anon_rmap(new_page, vma, haddr, true); | 1354 | page_add_new_anon_rmap(new_page, vma, haddr, true); |
1362 | mem_cgroup_commit_charge(new_page, memcg, false, true); | 1355 | mem_cgroup_commit_charge(new_page, memcg, false, true); |
@@ -2935,7 +2928,7 @@ void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new) | |||
2935 | if (pmd_swp_soft_dirty(*pvmw->pmd)) | 2928 | if (pmd_swp_soft_dirty(*pvmw->pmd)) |
2936 | pmde = pmd_mksoft_dirty(pmde); | 2929 | pmde = pmd_mksoft_dirty(pmde); |
2937 | if (is_write_migration_entry(entry)) | 2930 | if (is_write_migration_entry(entry)) |
2938 | pmde = maybe_pmd_mkwrite(pmde, vma, false); | 2931 | pmde = maybe_pmd_mkwrite(pmde, vma); |
2939 | 2932 | ||
2940 | flush_cache_range(vma, mmun_start, mmun_start + HPAGE_PMD_SIZE); | 2933 | flush_cache_range(vma, mmun_start, mmun_start + HPAGE_PMD_SIZE); |
2941 | page_add_anon_rmap(new, vma, mmun_start, true); | 2934 | page_add_anon_rmap(new, vma, mmun_start, true); |
diff --git a/mm/internal.h b/mm/internal.h index b35cdebda0ce..e6bd35182dae 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -328,8 +328,7 @@ static inline void mlock_migrate_page(struct page *newpage, struct page *page) | |||
328 | } | 328 | } |
329 | } | 329 | } |
330 | 330 | ||
331 | extern pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma, | 331 | extern pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma); |
332 | bool dirty); | ||
333 | 332 | ||
334 | /* | 333 | /* |
335 | * At what user virtual address is page expected in @vma? | 334 | * At what user virtual address is page expected in @vma? |
diff --git a/mm/khugepaged.c b/mm/khugepaged.c index db43dc8a8ae6..ea4ff259b671 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c | |||
@@ -1057,7 +1057,7 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
1057 | pgtable = pmd_pgtable(_pmd); | 1057 | pgtable = pmd_pgtable(_pmd); |
1058 | 1058 | ||
1059 | _pmd = mk_huge_pmd(new_page, vma->vm_page_prot); | 1059 | _pmd = mk_huge_pmd(new_page, vma->vm_page_prot); |
1060 | _pmd = maybe_pmd_mkwrite(_pmd, vma, false); | 1060 | _pmd = maybe_pmd_mkwrite(pmd_mkdirty(_pmd), vma); |
1061 | 1061 | ||
1062 | /* | 1062 | /* |
1063 | * spin_lock() below is not the equivalent of smp_wmb(), so | 1063 | * spin_lock() below is not the equivalent of smp_wmb(), so |
diff --git a/mm/memory.c b/mm/memory.c index b10c1d26f675..85e7a87da79f 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -3335,7 +3335,7 @@ static int do_set_pmd(struct vm_fault *vmf, struct page *page) | |||
3335 | 3335 | ||
3336 | entry = mk_huge_pmd(page, vma->vm_page_prot); | 3336 | entry = mk_huge_pmd(page, vma->vm_page_prot); |
3337 | if (write) | 3337 | if (write) |
3338 | entry = maybe_pmd_mkwrite(entry, vma, true); | 3338 | entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); |
3339 | 3339 | ||
3340 | add_mm_counter(vma->vm_mm, MM_FILEPAGES, HPAGE_PMD_NR); | 3340 | add_mm_counter(vma->vm_mm, MM_FILEPAGES, HPAGE_PMD_NR); |
3341 | page_add_file_rmap(page, true); | 3341 | page_add_file_rmap(page, true); |
diff --git a/mm/migrate.c b/mm/migrate.c index 57865fc8cfe3..4d0be47a322a 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -2068,7 +2068,7 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, | |||
2068 | } | 2068 | } |
2069 | 2069 | ||
2070 | entry = mk_huge_pmd(new_page, vma->vm_page_prot); | 2070 | entry = mk_huge_pmd(new_page, vma->vm_page_prot); |
2071 | entry = maybe_pmd_mkwrite(entry, vma, false); | 2071 | entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma); |
2072 | 2072 | ||
2073 | /* | 2073 | /* |
2074 | * Clear the old entry under pagetable lock and establish the new PTE. | 2074 | * Clear the old entry under pagetable lock and establish the new PTE. |