vma.c (c8d430db8eec7d4fd13a6bea27b7086a54eda6da) vma.c (c4d91e225ff3c9821c85ac6efd8e02c0025c0190)
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"

--- 903 unchanged lines hidden (view full) ---

912{
913 struct vm_area_struct *prev = vmg->prev;
914 struct vm_area_struct *next = vmg->next;
915 unsigned long start = vmg->start;
916 unsigned long end = vmg->end;
917 pgoff_t pgoff = vmg->pgoff;
918 pgoff_t pglen = PHYS_PFN(end - start);
919 bool can_merge_left, can_merge_right;
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"

--- 903 unchanged lines hidden (view full) ---

912{
913 struct vm_area_struct *prev = vmg->prev;
914 struct vm_area_struct *next = vmg->next;
915 unsigned long start = vmg->start;
916 unsigned long end = vmg->end;
917 pgoff_t pgoff = vmg->pgoff;
918 pgoff_t pglen = PHYS_PFN(end - start);
919 bool can_merge_left, can_merge_right;
920 bool just_expand = vmg->merge_flags & VMG_FLAG_JUST_EXPAND;
920
921 mmap_assert_write_locked(vmg->mm);
922 VM_WARN_ON(vmg->vma);
923 /* vmi must point at or before the gap. */
924 VM_WARN_ON(vma_iter_addr(vmg->vmi) > end);
925
926 vmg->state = VMA_MERGE_NOMERGE;
927
928 /* Special VMAs are unmergeable, also if no prev/next. */
929 if ((vmg->flags & VM_SPECIAL) || (!prev && !next))
930 return NULL;
931
932 can_merge_left = can_vma_merge_left(vmg);
921
922 mmap_assert_write_locked(vmg->mm);
923 VM_WARN_ON(vmg->vma);
924 /* vmi must point at or before the gap. */
925 VM_WARN_ON(vma_iter_addr(vmg->vmi) > end);
926
927 vmg->state = VMA_MERGE_NOMERGE;
928
929 /* Special VMAs are unmergeable, also if no prev/next. */
930 if ((vmg->flags & VM_SPECIAL) || (!prev && !next))
931 return NULL;
932
933 can_merge_left = can_vma_merge_left(vmg);
933 can_merge_right = can_vma_merge_right(vmg, can_merge_left);
934 can_merge_right = !just_expand && can_vma_merge_right(vmg, can_merge_left);
934
935 /* If we can merge with the next VMA, adjust vmg accordingly. */
936 if (can_merge_right) {
937 vmg->end = next->vm_end;
938 vmg->vma = next;
939 vmg->pgoff = next->vm_pgoff - pglen;
940 }
941

--- 6 unchanged lines hidden (view full) ---

948 /*
949 * If this merge would result in removal of the next VMA but we
950 * are not permitted to do so, reduce the operation to merging
951 * prev and vma.
952 */
953 if (can_merge_right && !can_merge_remove_vma(next))
954 vmg->end = end;
955
935
936 /* If we can merge with the next VMA, adjust vmg accordingly. */
937 if (can_merge_right) {
938 vmg->end = next->vm_end;
939 vmg->vma = next;
940 vmg->pgoff = next->vm_pgoff - pglen;
941 }
942

--- 6 unchanged lines hidden (view full) ---

949 /*
950 * If this merge would result in removal of the next VMA but we
951 * are not permitted to do so, reduce the operation to merging
952 * prev and vma.
953 */
954 if (can_merge_right && !can_merge_remove_vma(next))
955 vmg->end = end;
956
956 vma_prev(vmg->vmi); /* Equivalent to going to the previous range */
957 /* In expand-only case we are already positioned at prev. */
958 if (!just_expand) {
959 /* Equivalent to going to the previous range. */
960 vma_prev(vmg->vmi);
961 }
957 }
958
959 /*
960 * Now try to expand adjacent VMA(s). This takes care of removing the
961 * following VMA if we have VMAs on both sides.
962 */
963 if (vmg->vma && !vma_expand(vmg)) {
964 khugepaged_enter_vma(vmg->vma, vmg->flags);
965 vmg->state = VMA_MERGE_SUCCESS;
966 return vmg->vma;
967 }
968
969 /* If expansion failed, reset state. Allows us to retry merge later. */
962 }
963
964 /*
965 * Now try to expand adjacent VMA(s). This takes care of removing the
966 * following VMA if we have VMAs on both sides.
967 */
968 if (vmg->vma && !vma_expand(vmg)) {
969 khugepaged_enter_vma(vmg->vma, vmg->flags);
970 vmg->state = VMA_MERGE_SUCCESS;
971 return vmg->vma;
972 }
973
974 /* If expansion failed, reset state. Allows us to retry merge later. */
970 vmg->vma = NULL;
971 vmg->start = start;
972 vmg->end = end;
973 vmg->pgoff = pgoff;
974 if (vmg->vma == prev)
975 vma_iter_set(vmg->vmi, start);
975 if (!just_expand) {
976 vmg->vma = NULL;
977 vmg->start = start;
978 vmg->end = end;
979 vmg->pgoff = pgoff;
980 if (vmg->vma == prev)
981 vma_iter_set(vmg->vmi, start);
982 }
976
977 return NULL;
978}
979
980/*
981 * vma_expand - Expand an existing VMA
982 *
983 * @vmg: Describes a VMA expansion operation.

--- 1085 unchanged lines hidden ---
983
984 return NULL;
985}
986
987/*
988 * vma_expand - Expand an existing VMA
989 *
990 * @vmg: Describes a VMA expansion operation.

--- 1085 unchanged lines hidden ---