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 tongtiangen@huawei.com --- 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);
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/11659 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/N...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/11659 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/N...