This case is used to migrate pages from device memory, back to system
memory. Device coherent type memory is cache coherent from device and CPU
point of view.

Signed-off-by: Alex Sierra <alex.sie...@amd.com>
Acked-by: Felix Kuehling <felix.kuehl...@amd.com>
Reviewed-by: Alistair Poppple <apop...@nvidia.com>
Signed-off-by: Christoph Hellwig <h...@lst.de>
---
 include/linux/migrate.h |  1 +
 mm/migrate_device.c     | 12 +++++++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 069a89e847f3..b84908debe5c 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -148,6 +148,7 @@ static inline unsigned long migrate_pfn(unsigned long pfn)
 enum migrate_vma_direction {
        MIGRATE_VMA_SELECT_SYSTEM = 1 << 0,
        MIGRATE_VMA_SELECT_DEVICE_PRIVATE = 1 << 1,
+       MIGRATE_VMA_SELECT_DEVICE_COHERENT = 1 << 2,
 };
 
 struct migrate_vma {
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index a4847ad65da3..18bc6483f63a 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -148,15 +148,21 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
                        if (is_writable_device_private_entry(entry))
                                mpfn |= MIGRATE_PFN_WRITE;
                } else {
-                       if (!(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
-                               goto next;
                        pfn = pte_pfn(pte);
-                       if (is_zero_pfn(pfn)) {
+                       if (is_zero_pfn(pfn) &&
+                           (migrate->flags & MIGRATE_VMA_SELECT_SYSTEM)) {
                                mpfn = MIGRATE_PFN_MIGRATE;
                                migrate->cpages++;
                                goto next;
                        }
                        page = vm_normal_page(migrate->vma, addr, pte);
+                       if (page && !is_zone_device_page(page) &&
+                           !(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
+                               goto next;
+                       else if (page && is_device_coherent_page(page) &&
+                           (!(migrate->flags & 
MIGRATE_VMA_SELECT_DEVICE_COHERENT) ||
+                            page->pgmap->owner != migrate->pgmap_owner))
+                               goto next;
                        mpfn = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
                        mpfn |= pte_write(pte) ? MIGRATE_PFN_WRITE : 0;
                }
-- 
2.32.0

Reply via email to