If page migration is turne on in the config and the page is migrating, we may loose soft dirty bit. If fork and mprotect if called on migrating pages (once migration is complete) pages do not obtain soft dirty bit in correspond pte entries. Fix it adding appropriate test on swap entries.
Signed-off-by: Cyrill Gorcunov <[email protected]> Cc: Pavel Emelyanov <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Matt Mackall <[email protected]> Cc: Xiao Guangrong <[email protected]> Cc: Marcelo Tosatti <[email protected]> Cc: KOSAKI Motohiro <[email protected]> Cc: Stephen Rothwell <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: "Aneesh Kumar K.V" <[email protected]> --- mm/memory.c | 2 ++ mm/migrate.c | 2 ++ mm/mprotect.c | 7 +++++-- 3 files changed, 9 insertions(+), 2 deletions(-) Index: linux-2.6.git/mm/memory.c =================================================================== --- linux-2.6.git.orig/mm/memory.c +++ linux-2.6.git/mm/memory.c @@ -837,6 +837,8 @@ copy_one_pte(struct mm_struct *dst_mm, s */ make_migration_entry_read(&entry); pte = swp_entry_to_pte(entry); + if (pte_swp_soft_dirty(*src_pte)) + pte = pte_swp_mksoft_dirty(pte); set_pte_at(src_mm, addr, src_pte, pte); } } Index: linux-2.6.git/mm/migrate.c =================================================================== --- linux-2.6.git.orig/mm/migrate.c +++ linux-2.6.git/mm/migrate.c @@ -161,6 +161,8 @@ static int remove_migration_pte(struct p get_page(new); pte = pte_mkold(mk_pte(new, vma->vm_page_prot)); + if (pte_swp_soft_dirty(*ptep)) + pte = pte_mksoft_dirty(pte); if (is_write_migration_entry(entry)) pte = pte_mkwrite(pte); #ifdef CONFIG_HUGETLB_PAGE Index: linux-2.6.git/mm/mprotect.c =================================================================== --- linux-2.6.git.orig/mm/mprotect.c +++ linux-2.6.git/mm/mprotect.c @@ -94,13 +94,16 @@ static unsigned long change_pte_range(st swp_entry_t entry = pte_to_swp_entry(oldpte); if (is_write_migration_entry(entry)) { + pte_t newpte; /* * A protection check is difficult so * just be safe and disable write */ make_migration_entry_read(&entry); - set_pte_at(mm, addr, pte, - swp_entry_to_pte(entry)); + newpte = swp_entry_to_pte(entry); + if (pte_swp_soft_dirty(oldpte)) + newpte = pte_swp_mksoft_dirty(newpte); + set_pte_at(mm, addr, pte, newpte); } pages++; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/

