Skip to content

Commit

Permalink
mm: convert page_mkclean_one() to use page_vma_mapped_walk()
Browse files Browse the repository at this point in the history
For consistency, it worth converting all page_check_address() to
page_vma_mapped_walk(), so we could drop the former.

PMD handling here is future-proofing, we don't have users yet.  ext4
with huge pages will be the first.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Kirill A. Shutemov <[email protected]>
Cc: Andrea Arcangeli <[email protected]>
Cc: Hillf Danton <[email protected]>
Cc: Hugh Dickins <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Rik van Riel <[email protected]>
Cc: Srikar Dronamraju <[email protected]>
Cc: Vladimir Davydov <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
kiryl authored and torvalds committed Feb 25, 2017
1 parent a8fa41a commit f27176c
Showing 1 changed file with 45 additions and 23 deletions.
68 changes: 45 additions & 23 deletions mm/rmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1017,34 +1017,56 @@ int page_referenced(struct page *page,
static int page_mkclean_one(struct page *page, struct vm_area_struct *vma,
unsigned long address, void *arg)
{
struct mm_struct *mm = vma->vm_mm;
pte_t *pte;
spinlock_t *ptl;
int ret = 0;
struct page_vma_mapped_walk pvmw = {
.page = page,
.vma = vma,
.address = address,
.flags = PVMW_SYNC,
};
int *cleaned = arg;

pte = page_check_address(page, mm, address, &ptl, 1);
if (!pte)
goto out;

if (pte_dirty(*pte) || pte_write(*pte)) {
pte_t entry;
while (page_vma_mapped_walk(&pvmw)) {
int ret = 0;
address = pvmw.address;
if (pvmw.pte) {
pte_t entry;
pte_t *pte = pvmw.pte;

if (!pte_dirty(*pte) && !pte_write(*pte))
continue;

flush_cache_page(vma, address, pte_pfn(*pte));
entry = ptep_clear_flush(vma, address, pte);
entry = pte_wrprotect(entry);
entry = pte_mkclean(entry);
set_pte_at(vma->vm_mm, address, pte, entry);
ret = 1;
} else {
#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE
pmd_t *pmd = pvmw.pmd;
pmd_t entry;

if (!pmd_dirty(*pmd) && !pmd_write(*pmd))
continue;

flush_cache_page(vma, address, page_to_pfn(page));
entry = pmdp_huge_clear_flush(vma, address, pmd);
entry = pmd_wrprotect(entry);
entry = pmd_mkclean(entry);
set_pmd_at(vma->vm_mm, address, pmd, entry);
ret = 1;
#else
/* unexpected pmd-mapped page? */
WARN_ON_ONCE(1);
#endif
}

flush_cache_page(vma, address, pte_pfn(*pte));
entry = ptep_clear_flush(vma, address, pte);
entry = pte_wrprotect(entry);
entry = pte_mkclean(entry);
set_pte_at(mm, address, pte, entry);
ret = 1;
if (ret) {
mmu_notifier_invalidate_page(vma->vm_mm, address);
(*cleaned)++;
}
}

pte_unmap_unlock(pte, ptl);

if (ret) {
mmu_notifier_invalidate_page(mm, address);
(*cleaned)++;
}
out:
return SWAP_AGAIN;
}

Expand Down

0 comments on commit f27176c

Please sign in to comment.