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.
Unified · Split
| @@ -563,6 +563,7 @@ kvmppc_svm_page_out(struct vm_area_struct *vma, unsigned long start, · 562 unmodified lines | |||
| 563 | mig.end = end; | 563 | mig.end = end; |
| 564 | mig.src = &src_pfn; | 564 | mig.src = &src_pfn; |
| 565 | mig.dst = &dst_pfn; | 565 | mig.dst = &dst_pfn; |
| 566 | mig.src_owner = &kvmppc_uvmem_pgmap; | ||
| 566 | 567 | ||
| 567 | mutex_lock(&kvm->arch.uvmem_lock); | 568 | mutex_lock(&kvm->arch.uvmem_lock); |
| 568 | /* The requested page is already paged-out, nothing to do */ | 569 | /* The requested page is already paged-out, nothing to do */ |
| @@ -176,6 +176,7 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf) · 175 unmodified lines | |||
| 176 | .end = vmf->address + PAGE_SIZE, | 176 | .end = vmf->address + PAGE_SIZE, |
| 177 | .src = &src, | 177 | .src = &src, |
| 178 | .dst = &dst, | 178 | .dst = &dst, |
| 179 | .src_owner = drm->dev, | ||
| 179 | }; | 180 | }; |
| 180 | 181 | ||
| 181 | /* | 182 | /* |
| @@ -196,6 +196,14 @@ struct migrate_vma { · 195 unmodified lines | |||
| 196 | unsigned long npages; | 196 | unsigned long npages; |
| 197 | unsigned long start; | 197 | unsigned long start; |
| 198 | unsigned long end; | 198 | 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; | ||
| 199 | }; | 207 | }; |
| 200 | 208 | ||
| 201 | int migrate_vma_setup(struct migrate_vma *args); | 209 | int migrate_vma_setup(struct migrate_vma *args); |
| @@ -2241,7 +2241,7 @@ again: · 2240 unmodified lines | |||
| 2241 | arch_enter_lazy_mmu_mode(); | 2241 | arch_enter_lazy_mmu_mode(); |
| 2242 | 2242 | ||
| 2243 | for (; addr < end; addr += PAGE_SIZE, ptep++) { | 2243 | for (; addr < end; addr += PAGE_SIZE, ptep++) { |
| 2244 | unsigned long mpfn, pfn; | 2244 | unsigned long mpfn = 0, pfn; |
| 2245 | struct page *page; | 2245 | struct page *page; |
| 2246 | swp_entry_t entry; | 2246 | swp_entry_t entry; |
| 2247 | pte_t pte; | 2247 | pte_t pte; |
| @@ -2255,8 +2255,6 @@ again: · 7 unmodified lines | |||
| 2255 | } | 2255 | } |
| 2256 | 2256 | ||
| 2257 | if (!pte_present(pte)) { | 2257 | if (!pte_present(pte)) { |
| 2258 | mpfn = 0; | ||
| 2259 | |||
| 2260 | /* | 2258 | /* |
| 2261 | * Only care about unaddressable device page special | 2259 | * Only care about unaddressable device page special |
| 2262 | * page table entry. Other special swap entries are not | 2260 | * page table entry. Other special swap entries are not |
| @@ -2267,11 +2265,16 @@ again: · 4 unmodified lines | |||
| 2267 | goto next; | 2265 | goto next; |
| 2268 | 2266 | ||
| 2269 | page = device_private_entry_to_page(entry); | 2267 | page = device_private_entry_to_page(entry); |
| 2268 | if (page->pgmap->owner != migrate->src_owner) | ||
| 2269 | goto next; | ||
| 2270 | |||
| 2270 | mpfn = migrate_pfn(page_to_pfn(page)) | | 2271 | mpfn = migrate_pfn(page_to_pfn(page)) | |
| 2271 | MIGRATE_PFN_MIGRATE; | 2272 | MIGRATE_PFN_MIGRATE; |
| 2272 | if (is_write_device_private_entry(entry)) | 2273 | if (is_write_device_private_entry(entry)) |
| 2273 | mpfn |= MIGRATE_PFN_WRITE; | 2274 | mpfn |= MIGRATE_PFN_WRITE; |
| 2274 | } else { | 2275 | } else { |
| 2276 | if (migrate->src_owner) | ||
| 2277 | goto next; | ||
| 2275 | pfn = pte_pfn(pte); | 2278 | pfn = pte_pfn(pte); |
| 2276 | if (is_zero_pfn(pfn)) { | 2279 | if (is_zero_pfn(pfn)) { |
| 2277 | mpfn = MIGRATE_PFN_MIGRATE; | 2280 | mpfn = MIGRATE_PFN_MIGRATE; |