vma.c (25d3925fa51ddeec9d5a2c9b89140f5218ec3ef4) | vma.c (65e0aa64df916861ad8579e23f885e56e5ec8647) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2 3/* 4 * VMA-specific functions. 5 */ 6 7#include "vma_internal.h" 8#include "vma.h" --- 571 unchanged lines hidden (view full) --- 580 if (i != mm->map_count) { 581 pr_emerg("map_count %d vma iterator %d\n", mm->map_count, i); 582 bug = 1; 583 } 584 VM_BUG_ON_MM(bug, mm); 585} 586#endif /* CONFIG_DEBUG_VM_MAPLE_TREE */ 587 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2 3/* 4 * VMA-specific functions. 5 */ 6 7#include "vma_internal.h" 8#include "vma.h" --- 571 unchanged lines hidden (view full) --- 580 if (i != mm->map_count) { 581 pr_emerg("map_count %d vma iterator %d\n", mm->map_count, i); 582 bug = 1; 583 } 584 VM_BUG_ON_MM(bug, mm); 585} 586#endif /* CONFIG_DEBUG_VM_MAPLE_TREE */ 587 |
588/* Actually perform the VMA merge operation. */ 589static int commit_merge(struct vma_merge_struct *vmg, 590 struct vm_area_struct *remove) 591{ 592 struct vma_prepare vp; 593 594 init_multi_vma_prep(&vp, vmg->vma, NULL, remove, NULL); 595 596 /* Note: vma iterator must be pointing to 'start'. */ 597 vma_iter_config(vmg->vmi, vmg->start, vmg->end); 598 599 if (vma_iter_prealloc(vmg->vmi, vmg->vma)) 600 return -ENOMEM; 601 602 vma_prepare(&vp); 603 vma_adjust_trans_huge(vmg->vma, vmg->start, vmg->end, 0); 604 vma_set_range(vmg->vma, vmg->start, vmg->end, vmg->pgoff); 605 606 vma_iter_store(vmg->vmi, vmg->vma); 607 608 vma_complete(&vp, vmg->vmi, vmg->vma->vm_mm); 609 610 return 0; 611} 612 |
|
588/* 589 * vma_merge_new_range - Attempt to merge a new VMA into address space 590 * 591 * @vmg: Describes the VMA we are adding, in the range @vmg->start to @vmg->end 592 * (exclusive), which we try to merge with any adjacent VMAs if possible. 593 * 594 * We are about to add a VMA to the address space starting at @vmg->start and 595 * ending at @vmg->end. There are three different possible scenarios: --- 111 unchanged lines hidden (view full) --- 707 * - The caller must have set @vmg->vma and @vmg->next. 708 */ 709int vma_expand(struct vma_merge_struct *vmg) 710{ 711 struct vm_area_struct *anon_dup = NULL; 712 bool remove_next = false; 713 struct vm_area_struct *vma = vmg->vma; 714 struct vm_area_struct *next = vmg->next; | 613/* 614 * vma_merge_new_range - Attempt to merge a new VMA into address space 615 * 616 * @vmg: Describes the VMA we are adding, in the range @vmg->start to @vmg->end 617 * (exclusive), which we try to merge with any adjacent VMAs if possible. 618 * 619 * We are about to add a VMA to the address space starting at @vmg->start and 620 * ending at @vmg->end. There are three different possible scenarios: --- 111 unchanged lines hidden (view full) --- 732 * - The caller must have set @vmg->vma and @vmg->next. 733 */ 734int vma_expand(struct vma_merge_struct *vmg) 735{ 736 struct vm_area_struct *anon_dup = NULL; 737 bool remove_next = false; 738 struct vm_area_struct *vma = vmg->vma; 739 struct vm_area_struct *next = vmg->next; |
715 struct vma_prepare vp; | |
716 717 mmap_assert_write_locked(vmg->mm); 718 719 vma_start_write(vma); 720 if (next && (vma != next) && (vmg->end == next->vm_end)) { 721 int ret; 722 723 remove_next = true; 724 vma_start_write(next); 725 ret = dup_anon_vma(vma, next, &anon_dup); 726 if (ret) 727 return ret; 728 } 729 | 740 741 mmap_assert_write_locked(vmg->mm); 742 743 vma_start_write(vma); 744 if (next && (vma != next) && (vmg->end == next->vm_end)) { 745 int ret; 746 747 remove_next = true; 748 vma_start_write(next); 749 ret = dup_anon_vma(vma, next, &anon_dup); 750 if (ret) 751 return ret; 752 } 753 |
730 init_multi_vma_prep(&vp, vma, NULL, remove_next ? next : NULL, NULL); | |
731 /* Not merging but overwriting any part of next is not handled. */ | 754 /* Not merging but overwriting any part of next is not handled. */ |
732 VM_WARN_ON(next && !vp.remove && | 755 VM_WARN_ON(next && !remove_next && |
733 next != vma && vmg->end > next->vm_start); 734 /* Only handles expanding */ 735 VM_WARN_ON(vma->vm_start < vmg->start || vma->vm_end > vmg->end); 736 | 756 next != vma && vmg->end > next->vm_start); 757 /* Only handles expanding */ 758 VM_WARN_ON(vma->vm_start < vmg->start || vma->vm_end > vmg->end); 759 |
737 /* Note: vma iterator must be pointing to 'start' */ 738 vma_iter_config(vmg->vmi, vmg->start, vmg->end); 739 if (vma_iter_prealloc(vmg->vmi, vma)) | 760 if (commit_merge(vmg, remove_next ? next : NULL)) |
740 goto nomem; 741 | 761 goto nomem; 762 |
742 vma_prepare(&vp); 743 vma_adjust_trans_huge(vma, vmg->start, vmg->end, 0); 744 vma_set_range(vma, vmg->start, vmg->end, vmg->pgoff); 745 vma_iter_store(vmg->vmi, vma); 746 747 vma_complete(&vp, vmg->vmi, vma->vm_mm); | |
748 return 0; 749 750nomem: 751 vmg->state = VMA_MERGE_ERROR_NOMEM; 752 if (anon_dup) 753 unlink_anon_vmas(anon_dup); 754 return -ENOMEM; 755} --- 1271 unchanged lines hidden --- | 763 return 0; 764 765nomem: 766 vmg->state = VMA_MERGE_ERROR_NOMEM; 767 if (anon_dup) 768 unlink_anon_vmas(anon_dup); 769 return -ENOMEM; 770} --- 1271 unchanged lines hidden --- |