Skip to content
Permalink
Browse files
mm/khugepaged: remove reuse_swap_page() usage
reuse_swap_page() currently indicates if we can write to an anon page
without COW. A COW is required if the page is shared by multiple
processes (either already mapped or via swap entries) or if there is
concurrent writeback that cannot tolerate concurrent page modifications.

reuse_swap_page() doesn't check for pending references from other
processes that already unmapped the page, however,
is_refcount_suitable() essentially does the same thing. kuhgepaged is
the last remaining reuse_swap_page() user.

In the context of khugepaged, we are not actually going to write to the
page and we don't really care about other processes mapping the page:
for example, without swap, we don't check for multiple users.

Having to guess due to lack of comments, the current logics really only
wants to make sure that the page isn't in the swapcache and that it
cannot be re-added to the swapcache by another process mapping the page
until we're done.

Instead of relying on reuse_swap_page(), let's unconditionally
try_to_free_swap(), special casing PageKSM() just like reuse_swap_page()
would have done. Maybe the PageKSM() isn't required, but that better be
done separately. try_to_free_swap() will fail if there are still swap
entries targeting the page or if the page is under writeback.

We're keeping all pages locked and removed from the LRU until we actually
perform the copy. So once we succeeded removing a page from the swapcache,
it cannot be re-added until we're done copying. Add a comment stating
that.

Signed-off-by: David Hildenbrand <david@redhat.com>
  • Loading branch information
davidhildenbrand committed Jan 25, 2022
1 parent f71d4cd commit a872bc92d703c5048a66505acae4480615a0d634
Showing 1 changed file with 9 additions and 2 deletions.
@@ -683,9 +683,9 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
goto out;
}
if (!pte_write(pteval) && PageSwapCache(page) &&
!reuse_swap_page(page)) {
(PageKSM(page) || !try_to_free_swap(page))) {
/*
* Page is in the swap cache and cannot be re-used.
* Page cannot be removed from the swapache.
* It cannot be collapsed into a THP.
*/
unlock_page(page);
@@ -702,6 +702,13 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
result = SCAN_DEL_PAGE_LRU;
goto out;
}

/*
* We're holding the page lock and removed the page from the
* LRU. Once done copying, we'll unlock and readd to the
* LRU via release_pte_page(). The page cannot get added
* to the swapcache in the meantime.
*/
mod_node_page_state(page_pgdat(page),
NR_ISOLATED_ANON + page_is_file_lru(page),
compound_nr(page));

0 comments on commit a872bc9

Please sign in to comment.