Skip to content

Commit 20f664a

Browse files
minchanktorvalds
authored andcommitted
mm: pmd dirty emulation in page fault handler
Andreas reported [1] made a test in jemalloc hang in THP mode in arm64: http://lkml.kernel.org/r/[email protected] The problem is currently page fault handler doesn't supports dirty bit emulation of pmd for non-HW dirty-bit architecture so that application stucks until VM marked the pmd dirty. How the emulation work depends on the architecture. In case of arm64, when it set up pte firstly, it sets pte PTE_RDONLY to get a chance to mark the pte dirty via triggering page fault when store access happens. Once the page fault occurs, VM marks the pmd dirty and arch code for setting pmd will clear PTE_RDONLY for application to proceed. IOW, if VM doesn't mark the pmd dirty, application hangs forever by repeated fault(i.e., store op but the pmd is PTE_RDONLY). This patch enables pmd dirty-bit emulation for those architectures. [1] b8d3c4c, mm/huge_memory.c: don't split THP page when MADV_FREE syscall is called Fixes: b8d3c4c ("mm/huge_memory.c: don't split THP page when MADV_FREE syscall is called") Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Minchan Kim <[email protected]> Reported-by: Andreas Schwab <[email protected]> Tested-by: Andreas Schwab <[email protected]> Acked-by: Kirill A. Shutemov <[email protected]> Acked-by: Michal Hocko <[email protected]> Cc: Jason Evans <[email protected]> Cc: Will Deacon <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: <[email protected]> [4.5+] Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent c626bc4 commit 20f664a

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

mm/huge_memory.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,15 +883,17 @@ void huge_pmd_set_accessed(struct vm_fault *vmf, pmd_t orig_pmd)
883883
{
884884
pmd_t entry;
885885
unsigned long haddr;
886+
bool write = vmf->flags & FAULT_FLAG_WRITE;
886887

887888
vmf->ptl = pmd_lock(vmf->vma->vm_mm, vmf->pmd);
888889
if (unlikely(!pmd_same(*vmf->pmd, orig_pmd)))
889890
goto unlock;
890891

891892
entry = pmd_mkyoung(orig_pmd);
893+
if (write)
894+
entry = pmd_mkdirty(entry);
892895
haddr = vmf->address & HPAGE_PMD_MASK;
893-
if (pmdp_set_access_flags(vmf->vma, haddr, vmf->pmd, entry,
894-
vmf->flags & FAULT_FLAG_WRITE))
896+
if (pmdp_set_access_flags(vmf->vma, haddr, vmf->pmd, entry, write))
895897
update_mmu_cache_pmd(vmf->vma, vmf->address, vmf->pmd);
896898

897899
unlock:

0 commit comments

Comments
 (0)