Commit 5143192c authored by Ralph Campbell's avatar Ralph Campbell Committed by Jason Gunthorpe
Browse files

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: default avatarRalph Campbell <rcampbell@nvidia.com>
Reviewed-by: default avatarBharata B Rao <bharata@linux.ibm.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 1a77decd
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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 */
+3 −1
Original line number Diff line number Diff line
@@ -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;
+9 −4
Original line number Diff line number Diff line
@@ -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);
+4 −11
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -2287,7 +2287,9 @@ again:
				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 @@ again:
			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)) {