History

mm: handle multiple owners of device private pages in migrate_vma

Add a new src_owner field to struct migrate_vma. If the field is set, only device private pages with page->pgmap->owner equal to that field are migrated. If the field is not set only "normal" pages are migrated.

Christoph Hellwig committed 6 years ago

Commit 800bb1c1 parent f894ddd4 files · +16 −3Browse files

Unified · Split

4 files
  1. arch/powerpc/kvm/book3s_hv_uvmem.c +1 −0
  2. drivers/gpu/drm/nouveau/nouveau_dmem.c +1 −0
  3. include/linux/migrate.h +8 −0
  4. mm/migrate.c +6 −3
arch/powerpc/kvm/book3s_hv_uvmem.c+1−0
@@ -563,6 +563,7 @@ kvmppc_svm_page_out(struct vm_area_struct *vma, unsigned long start, · 562 unmodified lines
563563 mig.end = end;
564564 mig.src = &src_pfn;
565565 mig.dst = &dst_pfn;
566+ mig.src_owner = &kvmppc_uvmem_pgmap;
566567
567568 mutex_lock(&kvm->arch.uvmem_lock);
568569 /* The requested page is already paged-out, nothing to do */
drivers/gpu/drm/nouveau/nouveau_dmem.c+1−0
@@ -176,6 +176,7 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf) · 175 unmodified lines
176176 .end = vmf->address + PAGE_SIZE,
177177 .src = &src,
178178 .dst = &dst,
179+ .src_owner = drm->dev,
179180 };
180181
181182 /*
include/linux/migrate.h+8−0
@@ -196,6 +196,14 @@ struct migrate_vma { · 195 unmodified lines
196196 unsigned long npages;
197197 unsigned long start;
198198 unsigned long end;
199+
200+ /*
201+ * Set to the owner value also stored in page->pgmap->owner for
202+ * migrating out of device private memory. If set only device
203+ * private pages with this owner are migrated. If not set
204+ * device private pages are not migrated at all.
205+ */
206+ void *src_owner;
199207 };
200208
201209 int migrate_vma_setup(struct migrate_vma *args);
mm/migrate.c+6−3
@@ -2241,7 +2241,7 @@ again: · 2240 unmodified lines
22412241 arch_enter_lazy_mmu_mode();
22422242
22432243 for (; addr < end; addr += PAGE_SIZE, ptep++) {
2244− unsigned long mpfn, pfn;
2244+ unsigned long mpfn = 0, pfn;
22452245 struct page *page;
22462246 swp_entry_t entry;
22472247 pte_t pte;
@@ -2255,8 +2255,6 @@ again: · 7 unmodified lines
22552255 }
22562256
22572257 if (!pte_present(pte)) {
2258− mpfn = 0;
2259−
22602258 /*
22612259 * Only care about unaddressable device page special
22622260 * page table entry. Other special swap entries are not
@@ -2267,11 +2265,16 @@ again: · 4 unmodified lines
22672265 goto next;
22682266
22692267 page = device_private_entry_to_page(entry);
2268+ if (page->pgmap->owner != migrate->src_owner)
2269+ goto next;
2270+
22702271 mpfn = migrate_pfn(page_to_pfn(page)) |
22712272 MIGRATE_PFN_MIGRATE;
22722273 if (is_write_device_private_entry(entry))
22732274 mpfn |= MIGRATE_PFN_WRITE;
22742275 } else {
2276+ if (migrate->src_owner)
2277+ goto next;
22752278 pfn = pte_pfn(pte);
22762279 if (is_zero_pfn(pfn)) {
22772280 mpfn = MIGRATE_PFN_MIGRATE;