diff --git a/mm/migrate.c b/mm/migrate.c index cf8c05ea821e9ff5e568e72d32011a211ec7bc65..0d79382f9697e938f0bb4f2734d94b1950e36ef6 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -820,6 +820,7 @@ static int __buffer_migrate_page(struct address_space *mapping, struct buffer_head *bh, *head; int rc; int expected_count; + bool copy_done = false; if (!page_has_buffers(page)) return migrate_page(mapping, newpage, page, mode); @@ -860,7 +861,13 @@ static int __buffer_migrate_page(struct address_space *mapping, } } - rc = migrate_page_move_mapping(mapping, newpage, page, 0); + if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ARCH_HAS_COPY_MC) && + (mode != MIGRATE_SYNC_NO_COPY)) { + rc = migrate_page_mc_extra(mapping, newpage, page, mode, 0); + copy_done = true; + } else { + rc = migrate_page_move_mapping(mapping, newpage, page, 0); + } if (rc != MIGRATEPAGE_SUCCESS) goto unlock_buffers; @@ -873,6 +880,9 @@ static int __buffer_migrate_page(struct address_space *mapping, } while (bh != head); + if (copy_done) + goto unlock_buffers; + if (mode != MIGRATE_SYNC_NO_COPY) migrate_page_copy(newpage, page); else