The commit is pushed to "branch-rh9-5.14.0-362.8.1.vz9.35.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh9-5.14.0-362.8.1.vz9.35.14 ------> commit 6ceb6de48cca9eeb7de349aabd4ef62b31169610 Author: Pavel Tikhomirov <ptikhomi...@virtuozzo.com> Date: Wed Mar 6 16:36:04 2024 +0800
mm: migrate page private for high-order folios in swap cache correctly We have a check in do_swap_page that page from lookup_swap_cache should have private field equal to the swapcache index we searched it at (page_private(page) != entry.val). So folio_migrate_mapping should preserve page private for each page of a huge folio to satisfy this check else we get infinite loop in: +-> mmap_read_lock +-> __get_user_pages_locked +-> for-loop # taken once +-> __get_user_pages +-> retry-loop # constantly spinning +-> faultin_page # return 0 to trigger retry +-> handle_mm_fault +-> __handle_mm_fault +-> handle_pte_fault +-> do_swap_page +-> lookup_swap_cache # returns non-NULL +-> if (swapcache) +-> if (!folio_test_swapcache || page_private(page) != entry.val) +-> goto out_page +-> return 0 And this loop is under mmap_lock so we have secondary problem of multiple processes hanging on attempt to take mmap_lock. Note: We don't need this after we stop using private in this ms patch: cfeed8ffe55b ("mm/swap: stop using page->private on tail pages for THP_SWAP") https://virtuozzo.atlassian.net/browse/PSBM-153264 Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com> Feature: fix mm --- mm/huge_memory.c | 5 +++++ mm/migrate.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index f893ede92e7d..c48202dc239c 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2523,6 +2523,11 @@ static void __split_huge_page_tail(struct page *head, int tail, * page->private should not be set in tail pages with the exception * of swap cache pages that store the swp_entry_t in tail pages. * Fix up and warn once if private is unexpectedly set. + * + * NOTE: drop the patch ("mm: migrate page private for high-order + * folios in swap cache correctly") once ms commit cfeed8ffe55b + * ("mm/swap: stop using page->private on tail pages for THP_SWAP") + * is applied. */ if (!folio_test_swapcache(page_folio(head))) { VM_WARN_ON_ONCE_PAGE(page_tail->private != 0, page_tail); diff --git a/mm/migrate.c b/mm/migrate.c index d950f42c0708..357a0a4c59e6 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -424,6 +424,10 @@ int folio_migrate_mapping(struct address_space *mapping, if (folio_test_swapcache(folio)) { folio_set_swapcache(newfolio); newfolio->private = folio_get_private(folio); + + /* Swap cache needs private for each page of huge page */ + for (i = 1; i < nr; i++) + set_page_private(folio_page(newfolio, i), folio_page(folio, i)->private); } entries = nr; } else { _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel