mirror of https://gitee.com/openkylin/linux.git
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:
parent
1a77decd0c
commit
5143192cd4
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = 1 << 0,
|
||||
MIGRATE_VMA_SELECT_DEVICE_PRIVATE = 1 << 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue