From bcc457a6eb717c7b421c85ea2865c781f8e45be5 Mon Sep 17 00:00:00 2001 From: Tong Tiangen Date: Sat, 21 Sep 2024 16:42:56 +0800 Subject: [PATCH] mm/migration: do not folio copy in MIGRATE_SYNC_NO_COPY mode hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IASFAM -------------------------------- During page migration, if MIGRATE_SYNC_NO_COPY mode is used, the page content should not be migrated. This patch fix it. Fixes: 374fe8ea8082 ("fs: hugetlbfs: support poisoned recover from hugetlbfs_migrate_folio()") Fixes: 1d263184ba06 ("mm: migrate: support poisoned recover from migrate folio") Signed-off-by: Tong Tiangen --- fs/hugetlbfs/inode.c | 4 ++++ include/linux/migrate.h | 8 ++++++++ mm/migrate.c | 45 ++++++++++++++++++++++++++++------------- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8386d78eabe5..7f95b0fece82 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1146,6 +1146,10 @@ static int hugetlbfs_migrate_folio(struct address_space *mapping, { int rc; + rc = folio_migrate_mc_copy(mapping, dst, src, mode); + if (rc != MIGRATEPAGE_SUCCESS) + return rc; + rc = migrate_huge_page_move_mapping(mapping, dst, src); if (rc != MIGRATEPAGE_SUCCESS) return rc; diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 517f70b70620..68083e8432e8 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -79,6 +79,8 @@ void folio_migrate_flags(struct folio *newfolio, struct folio *folio); void folio_migrate_copy(struct folio *newfolio, struct folio *folio); int folio_migrate_mapping(struct address_space *mapping, struct folio *newfolio, struct folio *folio, int extra_count); +int folio_migrate_mc_copy(struct address_space *mapping, struct folio *dst, + struct folio *src, enum migrate_mode mode); #else @@ -98,6 +100,12 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping, { return -ENOSYS; } +static inline int folio_migrate_mc_copy(struct address_space *mapping, + struct folio *dst, struct folio *src, + enum migrate_mode mode) +{ + return -ENOSYS; +} #endif /* CONFIG_MIGRATION */ diff --git a/mm/migrate.c b/mm/migrate.c index efcca5330568..577c559b56fd 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -552,16 +552,10 @@ int migrate_huge_page_move_mapping(struct address_space *mapping, struct folio *dst, struct folio *src) { XA_STATE(xas, &mapping->i_pages, folio_index(src)); - int rc, expected_count = folio_expected_refs(mapping, src); - - if (folio_ref_count(src) != expected_count) - return -EAGAIN; - - rc = folio_mc_copy(dst, src); - if (unlikely(rc)) - return rc; + int expected_count; xas_lock_irq(&xas); + expected_count = folio_expected_refs(mapping, src); if (!folio_ref_freeze(src, expected_count)) { xas_unlock_irq(&xas); return -EAGAIN; @@ -681,6 +675,33 @@ void folio_migrate_copy(struct folio *newfolio, struct folio *folio) } EXPORT_SYMBOL(folio_migrate_copy); + +static int __folio_migrate_mc_copy(struct folio *dst, struct folio *src, + enum migrate_mode mode, int expected_count) +{ + int rc; + + /* Check whether src does not have extra refs before we do more work */ + if (folio_ref_count(src) != expected_count) + return -EAGAIN; + + if (mode != MIGRATE_SYNC_NO_COPY) { + rc = folio_mc_copy(dst, src); + if (unlikely(rc)) + return rc; + } + + return MIGRATEPAGE_SUCCESS; +} + +int folio_migrate_mc_copy(struct address_space *mapping, struct folio *dst, + struct folio *src, enum migrate_mode mode) +{ + int expected_count = folio_expected_refs(mapping, src); + + return __folio_migrate_mc_copy(dst, src, mode, expected_count); +} + /************************************************************ * Migration functions ***********************************************************/ @@ -691,12 +712,8 @@ static int __migrate_folio(struct address_space *mapping, struct folio *dst, { int rc, expected_count = folio_expected_refs(mapping, src); - /* Check whether src does not have extra refs before we do more work */ - if (folio_ref_count(src) != expected_count) - return -EAGAIN; - - rc = folio_mc_copy(dst, src); - if (unlikely(rc)) + rc = __folio_migrate_mc_copy(dst, src, mode, expected_count); + if (rc != MIGRATEPAGE_SUCCESS) return rc; rc = __folio_migrate_mapping(mapping, dst, src, expected_count); -- Gitee