[RFC V2 17/37] mm, dmemfs: support unmap_page_range() for dmemfs pmd

From: yulei . kernel
Date: Mon Dec 07 2020 - 06:38:00 EST


From: Yulei Zhang <yuleixzhang@xxxxxxxxxxx>

It is required by munmap() for dmemfs mapping.

Signed-off-by: Chen Zhuo <sagazchen@xxxxxxxxxxx>
Signed-off-by: Yulei Zhang <yuleixzhang@xxxxxxxxxxx>
---
mm/huge_memory.c | 2 ++
mm/memory.c | 8 +++++---
2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 31f9e83..2a818ec 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1664,6 +1664,8 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
spin_unlock(ptl);
if (is_huge_zero_pmd(orig_pmd))
tlb_remove_page_size(tlb, pmd_page(orig_pmd), HPAGE_PMD_SIZE);
+ } else if (pmd_special(orig_pmd)) {
+ spin_unlock(ptl);
} else if (is_huge_zero_pmd(orig_pmd)) {
zap_deposited_table(tlb->mm, pmd);
spin_unlock(ptl);
diff --git a/mm/memory.c b/mm/memory.c
index c48f8df..6b60981 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1338,10 +1338,12 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
pmd = pmd_offset(pud, addr);
do {
next = pmd_addr_end(addr, end);
- if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) || pmd_devmap(*pmd)) {
- if (next - addr != HPAGE_PMD_SIZE)
+ if (is_swap_pmd(*pmd) || pmd_trans_huge(*pmd) ||
+ pmd_devmap(*pmd) || pmd_special(*pmd)) {
+ if (next - addr != HPAGE_PMD_SIZE) {
+ VM_BUG_ON(pmd_special(*pmd));
__split_huge_pmd(vma, pmd, addr, false, NULL);
- else if (zap_huge_pmd(tlb, vma, pmd, addr))
+ } else if (zap_huge_pmd(tlb, vma, pmd, addr))
goto next;
/* fall through */
}
--
1.8.3.1