The src_owner field in struct migrate_vma is being used for two purposes,
it acts as a selection filter for which types of pages are to be migrated
and it identifies device private pages owned by the caller. Split this
into separate parameters so the src_owner field can be used just to
identify device private pages owned by the caller of migrate_vma_setup().
Rename the src_owner field to pgmap_owner to reflect it is now used only
to identify which device private pages to migrate.

Signed-off-by: Ralph Campbell <rcampb...@nvidia.com>
Reviewed-by: Bharata B Rao <bhar...@linux.ibm.com>
---
 arch/powerpc/kvm/book3s_hv_uvmem.c     |  4 +++-
 drivers/gpu/drm/nouveau/nouveau_dmem.c |  4 +++-
 include/linux/migrate.h                | 13 +++++++++----
 lib/test_hmm.c                         | 15 ++++-----------
 mm/migrate.c                           |  6 ++++--
 5 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c 
b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 09d8119024db..6850bd04bcb9 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -400,6 +400,7 @@ kvmppc_svm_page_in(struct vm_area_struct *vma, unsigned 
long start,
        mig.end = end;
        mig.src = &src_pfn;
        mig.dst = &dst_pfn;
+       mig.flags = MIGRATE_VMA_SELECT_SYSTEM;
 
        /*
         * We come here with mmap_lock write lock held just for
@@ -577,7 +578,8 @@ kvmppc_svm_page_out(struct vm_area_struct *vma, unsigned 
long start,
        mig.end = end;
        mig.src = &src_pfn;
        mig.dst = &dst_pfn;
-       mig.src_owner = &kvmppc_uvmem_pgmap;
+       mig.pgmap_owner = &kvmppc_uvmem_pgmap;
+       mig.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
 
        mutex_lock(&kvm->arch.uvmem_lock);
        /* The requested page is already paged-out, nothing to do */
diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c 
b/drivers/gpu/drm/nouveau/nouveau_dmem.c
index e5c230d9ae24..78b9e3c2a5b3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
@@ -182,7 +182,8 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct 
vm_fault *vmf)
                .end            = vmf->address + PAGE_SIZE,
                .src            = &src,
                .dst            = &dst,
-               .src_owner      = drm->dev,
+               .pgmap_owner    = drm->dev,
+               .flags          = MIGRATE_VMA_SELECT_DEVICE_PRIVATE,
        };
 
        /*
@@ -615,6 +616,7 @@ nouveau_dmem_migrate_vma(struct nouveau_drm *drm,
        struct migrate_vma args = {
                .vma            = vma,
                .start          = start,
+               .flags          = MIGRATE_VMA_SELECT_SYSTEM,
        };
        unsigned long i;
        u64 *pfns;
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 3e546cbf03dd..aafec0ca7b41 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -180,6 +180,11 @@ static inline unsigned long migrate_pfn(unsigned long pfn)
        return (pfn << MIGRATE_PFN_SHIFT) | MIGRATE_PFN_VALID;
 }
 
+enum migrate_vma_direction {
+       MIGRATE_VMA_SELECT_SYSTEM         = (1UL << 0),
+       MIGRATE_VMA_SELECT_DEVICE_PRIVATE = (1UL << 1),
+};
+
 struct migrate_vma {
        struct vm_area_struct   *vma;
        /*
@@ -199,11 +204,11 @@ struct migrate_vma {
 
        /*
         * Set to the owner value also stored in page->pgmap->owner for
-        * migrating out of device private memory.  If set only device
-        * private pages with this owner are migrated.  If not set
-        * device private pages are not migrated at all.
+        * migrating out of device private memory. The flags also need to
+        * be set to MIGRATE_VMA_SELECT_DEVICE_PRIVATE.
         */
-       void                    *src_owner;
+       void                    *pgmap_owner;
+       unsigned long           flags;
 };
 
 int migrate_vma_setup(struct migrate_vma *args);
diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index 9aa577afc269..e78a1414f58e 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -585,15 +585,6 @@ static void dmirror_migrate_alloc_and_copy(struct 
migrate_vma *args,
                 */
                spage = migrate_pfn_to_page(*src);
 
-               /*
-                * Don't migrate device private pages from our own driver or
-                * others. For our own we would do a device private memory copy
-                * not a migration and for others, we would need to fault the
-                * other device's page into system memory first.
-                */
-               if (spage && is_zone_device_page(spage))
-                       continue;
-
                dpage = dmirror_devmem_alloc_page(mdevice);
                if (!dpage)
                        continue;
@@ -702,7 +693,8 @@ static int dmirror_migrate(struct dmirror *dmirror,
                args.dst = dst_pfns;
                args.start = addr;
                args.end = next;
-               args.src_owner = NULL;
+               args.pgmap_owner = NULL;
+               args.flags = MIGRATE_VMA_SELECT_SYSTEM;
                ret = migrate_vma_setup(&args);
                if (ret)
                        goto out;
@@ -1053,7 +1045,8 @@ static vm_fault_t dmirror_devmem_fault(struct vm_fault 
*vmf)
        args.end = args.start + PAGE_SIZE;
        args.src = &src_pfns;
        args.dst = &dst_pfns;
-       args.src_owner = dmirror->mdevice;
+       args.pgmap_owner = dmirror->mdevice;
+       args.flags = MIGRATE_VMA_SELECT_DEVICE_PRIVATE;
 
        if (migrate_vma_setup(&args))
                return VM_FAULT_SIGBUS;
diff --git a/mm/migrate.c b/mm/migrate.c
index f37729673558..e3ea68e3a08b 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2287,7 +2287,9 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
                                goto next;
 
                        page = device_private_entry_to_page(entry);
-                       if (page->pgmap->owner != migrate->src_owner)
+                       if (!(migrate->flags &
+                               MIGRATE_VMA_SELECT_DEVICE_PRIVATE) ||
+                           page->pgmap->owner != migrate->pgmap_owner)
                                goto next;
 
                        mpfn = migrate_pfn(page_to_pfn(page)) |
@@ -2295,7 +2297,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
                        if (is_write_device_private_entry(entry))
                                mpfn |= MIGRATE_PFN_WRITE;
                } else {
-                       if (migrate->src_owner)
+                       if (!(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
                                goto next;
                        pfn = pte_pfn(pte);
                        if (is_zero_pfn(pfn)) {
-- 
2.20.1

Reply via email to