[RFC 04/11] mm/migrate_device: THP migration of zone device pages
Mika Penttilä
mpenttil at redhat.com
Thu Mar 6 09:24:58 UTC 2025
Hi,
On 3/6/25 06:42, Balbir Singh wrote:
...
>
> /*
> * The only time there is no vma is when called from
> @@ -728,15 +1000,47 @@ static void __migrate_device_pages(unsigned long *src_pfns,
> migrate->pgmap_owner);
> mmu_notifier_invalidate_range_start(&range);
> }
> - migrate_vma_insert_page(migrate, addr, newpage,
> +
> + if ((src_pfns[i] & MIGRATE_PFN_COMPOUND) &&
> + (!(dst_pfns[i] & MIGRATE_PFN_COMPOUND))) {
> + nr = HPAGE_PMD_NR;
> + src_pfns[i] &= ~MIGRATE_PFN_COMPOUND;
> + src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
> + goto next;
> + }
> +
> + migrate_vma_insert_page(migrate, addr, &dst_pfns[i],
> &src_pfns[i]);
> - continue;
> + goto next;
> }
>
> newfolio = page_folio(newpage);
> folio = page_folio(page);
> mapping = folio_mapping(folio);
>
> + /*
> + * If THP migration is enabled, check if both src and dst
> + * can migrate large pages
> + */
> + if (thp_migration_supported()) {
> + if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
> + (src_pfns[i] & MIGRATE_PFN_COMPOUND) &&
> + !(dst_pfns[i] & MIGRATE_PFN_COMPOUND)) {
> +
> + if (!migrate) {
> + src_pfns[i] &= ~(MIGRATE_PFN_MIGRATE |
> + MIGRATE_PFN_COMPOUND);
> + goto next;
> + }
> + src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
This looks strange as is but patch 08 changes this to split and then
migrate.
> + } else if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
> + (dst_pfns[i] & MIGRATE_PFN_COMPOUND) &&
> + !(src_pfns[i] & MIGRATE_PFN_COMPOUND)) {
> + src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
Should there be goto next; or similar here also, we are not migrating
this src?
> + }
> + }
> +
> +
> if (folio_is_device_private(newfolio) ||
> folio_is_device_coherent(newfolio)) {
> if (mapping) {
> @@ -749,7 +1053,7 @@ static void __migrate_device_pages(unsigned long *src_pfns,
> if (!folio_test_anon(folio) ||
> !folio_free_swap(folio)) {
> src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
> - continue;
> + goto next;
> }
> }
> } else if (folio_is_zone_device(newfolio)) {
> @@ -757,7 +1061,7 @@ static void __migrate_device_pages(unsigned long *src_pfns,
> * Other types of ZONE_DEVICE page are not supported.
> */
> src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
> - continue;
> + goto next;
> }
>
> BUG_ON(folio_test_writeback(folio));
> @@ -769,6 +1073,8 @@ static void __migrate_device_pages(unsigned long *src_pfns,
> src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
> else
> folio_migrate_flags(newfolio, folio);
> +next:
> + i += nr;
> }
>
> if (notified)
> @@ -899,24 +1205,40 @@ EXPORT_SYMBOL(migrate_vma_finalize);
> int migrate_device_range(unsigned long *src_pfns, unsigned long start,
> unsigned long npages)
> {
> - unsigned long i, pfn;
> + unsigned long i, j, pfn;
>
> - for (pfn = start, i = 0; i < npages; pfn++, i++) {
> - struct folio *folio;
> + i = 0;
> + pfn = start;
> + while (i < npages) {
> + struct page *page = pfn_to_page(pfn);
> + struct folio *folio = page_folio(page);
> + unsigned int nr = 1;
>
> folio = folio_get_nontail_page(pfn_to_page(pfn));
> if (!folio) {
> src_pfns[i] = 0;
> - continue;
> + goto next;
> }
>
> if (!folio_trylock(folio)) {
> src_pfns[i] = 0;
> folio_put(folio);
> - continue;
> + goto next;
> }
>
> src_pfns[i] = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
> + nr = folio_nr_pages(folio);
> + if (nr > 1) {
> + src_pfns[i] |= MIGRATE_PFN_COMPOUND;
> + for (j = 1; j < nr; j++)
> + src_pfns[i+j] = 0;
> + i += j;
> + pfn += j;
> + continue;
> + }
> +next:
> + i++;
> + pfn++;
> }
>
> migrate_device_unmap(src_pfns, npages, NULL);
--Mika
More information about the dri-devel
mailing list