diff options
Diffstat (limited to 'mm/rmap.c')
-rw-r--r-- | mm/rmap.c | 45 |
1 files changed, 0 insertions, 45 deletions
@@ -269,51 +269,6 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src) | |||
269 | } | 269 | } |
270 | 270 | ||
271 | /* | 271 | /* |
272 | * Some rmap walk that needs to find all ptes/hugepmds without false | ||
273 | * negatives (like migrate and split_huge_page) running concurrent | ||
274 | * with operations that copy or move pagetables (like mremap() and | ||
275 | * fork()) to be safe. They depend on the anon_vma "same_anon_vma" | ||
276 | * list to be in a certain order: the dst_vma must be placed after the | ||
277 | * src_vma in the list. This is always guaranteed by fork() but | ||
278 | * mremap() needs to call this function to enforce it in case the | ||
279 | * dst_vma isn't newly allocated and chained with the anon_vma_clone() | ||
280 | * function but just an extension of a pre-existing vma through | ||
281 | * vma_merge. | ||
282 | * | ||
283 | * NOTE: the same_anon_vma list can still be changed by other | ||
284 | * processes while mremap runs because mremap doesn't hold the | ||
285 | * anon_vma mutex to prevent modifications to the list while it | ||
286 | * runs. All we need to enforce is that the relative order of this | ||
287 | * process vmas isn't changing (we don't care about other vmas | ||
288 | * order). Each vma corresponds to an anon_vma_chain structure so | ||
289 | * there's no risk that other processes calling anon_vma_moveto_tail() | ||
290 | * and changing the same_anon_vma list under mremap() will screw with | ||
291 | * the relative order of this process vmas in the list, because we | ||
292 | * they can't alter the order of any vma that belongs to this | ||
293 | * process. And there can't be another anon_vma_moveto_tail() running | ||
294 | * concurrently with mremap() coming from this process because we hold | ||
295 | * the mmap_sem for the whole mremap(). fork() ordering dependency | ||
296 | * also shouldn't be affected because fork() only cares that the | ||
297 | * parent vmas are placed in the list before the child vmas and | ||
298 | * anon_vma_moveto_tail() won't reorder vmas from either the fork() | ||
299 | * parent or child. | ||
300 | */ | ||
301 | void anon_vma_moveto_tail(struct vm_area_struct *dst) | ||
302 | { | ||
303 | struct anon_vma_chain *pavc; | ||
304 | struct anon_vma *root = NULL; | ||
305 | |||
306 | list_for_each_entry_reverse(pavc, &dst->anon_vma_chain, same_vma) { | ||
307 | struct anon_vma *anon_vma = pavc->anon_vma; | ||
308 | VM_BUG_ON(pavc->vma != dst); | ||
309 | root = lock_anon_vma_root(root, anon_vma); | ||
310 | list_del(&pavc->same_anon_vma); | ||
311 | list_add_tail(&pavc->same_anon_vma, &anon_vma->head); | ||
312 | } | ||
313 | unlock_anon_vma_root(root); | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * Attach vma to its own anon_vma, as well as to the anon_vmas that | 272 | * Attach vma to its own anon_vma, as well as to the anon_vmas that |
318 | * the corresponding VMA in the parent process is attached to. | 273 | * the corresponding VMA in the parent process is attached to. |
319 | * Returns 0 on success, non-zero on failure. | 274 | * Returns 0 on success, non-zero on failure. |