Skip to content

Commit 0ccf7f1

Browse files
xzpeterakpm00
authored andcommitted
mm/thp: carry over dirty bit when thp splits on pmd
Carry over the dirty bit from pmd to pte when a huge pmd splits. It shouldn't be a correctness issue since when pmd_dirty() we'll have the page marked dirty anyway, however having dirty bit carried over helps the next initial writes of split ptes on some archs like x86. Link: https://lkml.kernel.org/r/20220811161331.37055-5-peterx@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com> Reviewed-by: Huang Ying <ying.huang@intel.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: Andi Kleen <andi.kleen@intel.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: David Hildenbrand <david@redhat.com> Cc: Hugh Dickins <hughd@google.com> Cc: "Kirill A . Shutemov" <kirill@shutemov.name> Cc: Minchan Kim <minchan@kernel.org> Cc: Nadav Amit <nadav.amit@gmail.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Dave Hansen <dave.hansen@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 0d206b5 commit 0ccf7f1

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

mm/huge_memory.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,7 +2037,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
20372037
pgtable_t pgtable;
20382038
pmd_t old_pmd, _pmd;
20392039
bool young, write, soft_dirty, pmd_migration = false, uffd_wp = false;
2040-
bool anon_exclusive = false;
2040+
bool anon_exclusive = false, dirty = false;
20412041
unsigned long addr;
20422042
int i;
20432043

@@ -2126,8 +2126,10 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
21262126
uffd_wp = pmd_swp_uffd_wp(old_pmd);
21272127
} else {
21282128
page = pmd_page(old_pmd);
2129-
if (pmd_dirty(old_pmd))
2129+
if (pmd_dirty(old_pmd)) {
2130+
dirty = true;
21302131
SetPageDirty(page);
2132+
}
21312133
write = pmd_write(old_pmd);
21322134
young = pmd_young(old_pmd);
21332135
soft_dirty = pmd_soft_dirty(old_pmd);
@@ -2195,6 +2197,9 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
21952197
entry = pte_wrprotect(entry);
21962198
if (!young)
21972199
entry = pte_mkold(entry);
2200+
/* NOTE: this may set soft-dirty too on some archs */
2201+
if (dirty)
2202+
entry = pte_mkdirty(entry);
21982203
if (soft_dirty)
21992204
entry = pte_mksoft_dirty(entry);
22002205
if (uffd_wp)

0 commit comments

Comments
 (0)