mm/huge_memory.c: fix data loss when splitting a file pmd
Subsystems (3)
[email protected]
maintainerPATCH 5/6 mm/huge_memory.c: fix data loss when splitting a file pmd
From: Hugh Dickins <[email protected]>
Subject: mm/huge_memory.c: fix data loss when splitting a file pmd
__split_huge_pmd_locked() must check if the cleared huge pmd was dirty, and propagate that to PageDirty: otherwise, data may be lost when a huge tmpfs page is modified then split then reclaimed.
How has this taken so long to be noticed? Because there was no problem when the huge page is written by a write system call (shmem_write_end() calls set_page_dirty()), nor when the page is allocated for a write fault (fault_dirty_shared_page() calls set_page_dirty()); but when allocated for a read fault (which MAP_POPULATE simulates), no set_page_dirty().
Fixes d21b9e57c74c ("thp: handle file pages in split_huge_pmd()")
Signed-off-by Hugh Dickins <[email protected]>
Reported-by Ashwin Chaugule <[email protected]>
Reviewed-by Yang Shi <[email protected]>
Reviewed-by Kirill A. Shutemov <[email protected]>
Cc "Huang, Ying" <[email protected]>
Cc <[email protected]> [4.8+]
Signed-off-by Andrew Morton <[email protected]>
---
mm/huge_memory.c | 2 ++ 1 file changed, 2 insertions(+)
mm/huge_memory.c renamed from mm/huge_memory.c~thp-fix-data-loss-when-splitting-a-file-pmd +2 -0
@@ -2084,6 +2084,8 @@ static void __split_huge_pmd_locked(struif (vma_is_dax (vma))return ; page =pmd_page (_pmd); +if (!PageDirty (page) &&pmd_dirty (_pmd)) +set_page_dirty (page);if (!PageReferenced (page) &&pmd_young (_pmd))SetPageReferenced (page);page_remove_rmap (page, true);
_