mm/migrate: add a flags parameter to migrate_vma

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.

Link: https://lore.kernel.org/r/20200723223004.9586-3-rcampbell@nvidia.com
Signed-off-by: Ralph Campbell <rcampbell@nvidia.com>
Reviewed-by: Bharata B Rao <bharata@linux.ibm.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Ralph Campbell 2020-07-23 15:30:00 -07:00 коммит произвёл Jason Gunthorpe
Родитель 1a77decd0c
Коммит 5143192cd4
5 изменённых файлов: 23 добавлений и 19 удалений

Просмотреть файл

@ -400,6 +400,7 @@ kvmppc_svm_page_in(struct vm_area_struct *vma, unsigned long start,
mig.end = end; mig.end = end;
mig.src = &src_pfn; mig.src = &src_pfn;
mig.dst = &dst_pfn; mig.dst = &dst_pfn;
mig.flags = MIGRATE_VMA_SELECT_SYSTEM;
/* /*
* We come here with mmap_lock write lock held just for * 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.end = end;
mig.src = &src_pfn; mig.src = &src_pfn;
mig.dst = &dst_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); mutex_lock(&kvm->arch.uvmem_lock);
/* The requested page is already paged-out, nothing to do */ /* The requested page is already paged-out, nothing to do */

Просмотреть файл

@ -182,7 +182,8 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
.end = vmf->address + PAGE_SIZE, .end = vmf->address + PAGE_SIZE,
.src = &src, .src = &src,
.dst = &dst, .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 = { struct migrate_vma args = {
.vma = vma, .vma = vma,
.start = start, .start = start,
.flags = MIGRATE_VMA_SELECT_SYSTEM,
}; };
unsigned long i; unsigned long i;
u64 *pfns; u64 *pfns;

Просмотреть файл

@ -180,6 +180,11 @@ static inline unsigned long migrate_pfn(unsigned long pfn)
return (pfn << MIGRATE_PFN_SHIFT) | MIGRATE_PFN_VALID; return (pfn << MIGRATE_PFN_SHIFT) | MIGRATE_PFN_VALID;
} }
enum migrate_vma_direction {
MIGRATE_VMA_SELECT_SYSTEM = 1 << 0,
MIGRATE_VMA_SELECT_DEVICE_PRIVATE = 1 << 1,
};
struct migrate_vma { struct migrate_vma {
struct vm_area_struct *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 * Set to the owner value also stored in page->pgmap->owner for
* migrating out of device private memory. If set only device * migrating out of device private memory. The flags also need to
* private pages with this owner are migrated. If not set * be set to MIGRATE_VMA_SELECT_DEVICE_PRIVATE.
* device private pages are not migrated at all.
*/ */
void *src_owner; void *pgmap_owner;
unsigned long flags;
}; };
int migrate_vma_setup(struct migrate_vma *args); int migrate_vma_setup(struct migrate_vma *args);

Просмотреть файл

@ -585,15 +585,6 @@ static void dmirror_migrate_alloc_and_copy(struct migrate_vma *args,
*/ */
spage = migrate_pfn_to_page(*src); 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); dpage = dmirror_devmem_alloc_page(mdevice);
if (!dpage) if (!dpage)
continue; continue;
@ -702,7 +693,8 @@ static int dmirror_migrate(struct dmirror *dmirror,
args.dst = dst_pfns; args.dst = dst_pfns;
args.start = addr; args.start = addr;
args.end = next; args.end = next;
args.src_owner = NULL; args.pgmap_owner = NULL;
args.flags = MIGRATE_VMA_SELECT_SYSTEM;
ret = migrate_vma_setup(&args); ret = migrate_vma_setup(&args);
if (ret) if (ret)
goto out; goto out;
@ -1053,7 +1045,8 @@ static vm_fault_t dmirror_devmem_fault(struct vm_fault *vmf)
args.end = args.start + PAGE_SIZE; args.end = args.start + PAGE_SIZE;
args.src = &src_pfns; args.src = &src_pfns;
args.dst = &dst_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)) if (migrate_vma_setup(&args))
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;

Просмотреть файл

@ -2287,7 +2287,9 @@ again:
goto next; goto next;
page = device_private_entry_to_page(entry); 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; goto next;
mpfn = migrate_pfn(page_to_pfn(page)) | mpfn = migrate_pfn(page_to_pfn(page)) |
@ -2295,7 +2297,7 @@ again:
if (is_write_device_private_entry(entry)) if (is_write_device_private_entry(entry))
mpfn |= MIGRATE_PFN_WRITE; mpfn |= MIGRATE_PFN_WRITE;
} else { } else {
if (migrate->src_owner) if (!(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM))
goto next; goto next;
pfn = pte_pfn(pte); pfn = pte_pfn(pte);
if (is_zero_pfn(pfn)) { if (is_zero_pfn(pfn)) {