diff mbox series

[v3,2/4] mm/mmap/vma_merge: fold curr, next assignment logic

Message ID 36399b6cdc843eb7fe243488ea9b29464f699170.1679468982.git.lstoakes@gmail.com (mailing list archive)
State New
Headers show
Series further cleanup of vma_merge() | expand

Commit Message

Lorenzo Stoakes March 22, 2023, 7:13 a.m. UTC
Use find_vma_intersection() and vma_lookup() to both simplify the logic and
to fold the end == next->vm_start condition into one block.

This groups all of the simple range checks together and establishes the
invariant that, if prev, curr or next are non-NULL then their positions are
as expected.

This has no functional impact.

Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
---
 mm/mmap.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

--
2.39.2

Comments

Vlastimil Babka March 22, 2023, 9:06 a.m. UTC | #1
On 3/22/23 08:13, Lorenzo Stoakes wrote:
> Use find_vma_intersection() and vma_lookup() to both simplify the logic and
> to fold the end == next->vm_start condition into one block.
> 
> This groups all of the simple range checks together and establishes the
> invariant that, if prev, curr or next are non-NULL then their positions are
> as expected.
> 
> This has no functional impact.

I'm not so sure...

> Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
> ---
>  mm/mmap.c | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/mm/mmap.c b/mm/mmap.c
> index c9834364ac98..dbdbb92493b2 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -930,15 +930,14 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
>  	if (vm_flags & VM_SPECIAL)
>  		return NULL;
> 
> -	curr = find_vma(mm, prev ? prev->vm_end : 0);
> -	if (curr && curr->vm_end == end)		/* cases 6, 7, 8 */
> -		next = find_vma(mm, curr->vm_end);
> -	else
> -		next = curr;
> +	/* Does the input range span an existing VMA? (cases 5 - 8) */
> +	curr = find_vma_intersection(mm, prev ? prev->vm_end : 0, end);
> 
> -	/* In cases 1 - 4 there's no CCCC vma */
> -	if (curr && end <= curr->vm_start)
> -		curr = NULL;
> +	if (!curr ||			/* cases 1 - 4 */
> +	    end == curr->vm_end)	/* cases 6 - 8, adjacent VMA */
> +		next = vma_lookup(mm, end);

AFAICS if the next vma is not adjacent to CCCC or ****, but there's a gap,
this will still give you a non-NULL result?

> +	else
> +		next = NULL;		/* case 5 */
> 
>  	/* verify some invariant that must be enforced by the caller */
>  	VM_WARN_ON(prev && addr <= prev->vm_start);
> @@ -959,11 +958,10 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
>  		}
>  	}
>  	/* Can we merge the successor? */
> -	if (next && end == next->vm_start &&

And then without this end == next->vm_start check, merge will be done
despite the gap.

> -			mpol_equal(policy, vma_policy(next)) &&
> -			can_vma_merge_before(next, vm_flags,
> -					     anon_vma, file, pgoff+pglen,
> -					     vm_userfaultfd_ctx, anon_name)) {
> +	if (next && mpol_equal(policy, vma_policy(next)) &&
> +	    can_vma_merge_before(next, vm_flags,
> +				 anon_vma, file, pgoff+pglen,
> +				 vm_userfaultfd_ctx, anon_name)) {
>  		merge_next = true;
>  	}
> 
> --
> 2.39.2
Vlastimil Babka March 22, 2023, 9:10 a.m. UTC | #2
On 3/22/23 10:06, Vlastimil Babka wrote:
> On 3/22/23 08:13, Lorenzo Stoakes wrote:
>> Use find_vma_intersection() and vma_lookup() to both simplify the logic and
>> to fold the end == next->vm_start condition into one block.
>> 
>> This groups all of the simple range checks together and establishes the
>> invariant that, if prev, curr or next are non-NULL then their positions are
>> as expected.
>> 
>> This has no functional impact.
> 
> I'm not so sure...

Disregard that, vma_lookup() is not find_vma(). Next cleanup challenge: more
obvious naming of those two.

>> Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>

Reviewed-by: Vlastimil Babka <vbabka@suse.cz>

>> ---
>>  mm/mmap.c | 24 +++++++++++-------------
>>  1 file changed, 11 insertions(+), 13 deletions(-)
>> 
>> diff --git a/mm/mmap.c b/mm/mmap.c
>> index c9834364ac98..dbdbb92493b2 100644
>> --- a/mm/mmap.c
>> +++ b/mm/mmap.c
>> @@ -930,15 +930,14 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
>>  	if (vm_flags & VM_SPECIAL)
>>  		return NULL;
>> 
>> -	curr = find_vma(mm, prev ? prev->vm_end : 0);
>> -	if (curr && curr->vm_end == end)		/* cases 6, 7, 8 */
>> -		next = find_vma(mm, curr->vm_end);
>> -	else
>> -		next = curr;
>> +	/* Does the input range span an existing VMA? (cases 5 - 8) */
>> +	curr = find_vma_intersection(mm, prev ? prev->vm_end : 0, end);
>> 
>> -	/* In cases 1 - 4 there's no CCCC vma */
>> -	if (curr && end <= curr->vm_start)
>> -		curr = NULL;
>> +	if (!curr ||			/* cases 1 - 4 */
>> +	    end == curr->vm_end)	/* cases 6 - 8, adjacent VMA */
>> +		next = vma_lookup(mm, end);
> 
> AFAICS if the next vma is not adjacent to CCCC or ****, but there's a gap,
> this will still give you a non-NULL result?
> 
>> +	else
>> +		next = NULL;		/* case 5 */
>> 
>>  	/* verify some invariant that must be enforced by the caller */
>>  	VM_WARN_ON(prev && addr <= prev->vm_start);
>> @@ -959,11 +958,10 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
>>  		}
>>  	}
>>  	/* Can we merge the successor? */
>> -	if (next && end == next->vm_start &&
> 
> And then without this end == next->vm_start check, merge will be done
> despite the gap.
> 
>> -			mpol_equal(policy, vma_policy(next)) &&
>> -			can_vma_merge_before(next, vm_flags,
>> -					     anon_vma, file, pgoff+pglen,
>> -					     vm_userfaultfd_ctx, anon_name)) {
>> +	if (next && mpol_equal(policy, vma_policy(next)) &&
>> +	    can_vma_merge_before(next, vm_flags,
>> +				 anon_vma, file, pgoff+pglen,
>> +				 vm_userfaultfd_ctx, anon_name)) {
>>  		merge_next = true;
>>  	}
>> 
>> --
>> 2.39.2
>
Liam R. Howlett March 22, 2023, 3:36 p.m. UTC | #3
* Lorenzo Stoakes <lstoakes@gmail.com> [230322 03:13]:
> Use find_vma_intersection() and vma_lookup() to both simplify the logic and
> to fold the end == next->vm_start condition into one block.
> 
> This groups all of the simple range checks together and establishes the
> invariant that, if prev, curr or next are non-NULL then their positions are
> as expected.
> 
> This has no functional impact.
> 
> Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>

Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>

Nit below.

> ---
>  mm/mmap.c | 24 +++++++++++-------------
>  1 file changed, 11 insertions(+), 13 deletions(-)
> 
> diff --git a/mm/mmap.c b/mm/mmap.c
> index c9834364ac98..dbdbb92493b2 100644
> --- a/mm/mmap.c
> +++ b/mm/mmap.c
> @@ -930,15 +930,14 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
>  	if (vm_flags & VM_SPECIAL)
>  		return NULL;
> 
> -	curr = find_vma(mm, prev ? prev->vm_end : 0);
> -	if (curr && curr->vm_end == end)		/* cases 6, 7, 8 */
> -		next = find_vma(mm, curr->vm_end);
> -	else
> -		next = curr;
> +	/* Does the input range span an existing VMA? (cases 5 - 8) */
> +	curr = find_vma_intersection(mm, prev ? prev->vm_end : 0, end);
> 
> -	/* In cases 1 - 4 there's no CCCC vma */
> -	if (curr && end <= curr->vm_start)
> -		curr = NULL;
> +	if (!curr ||			/* cases 1 - 4 */
> +	    end == curr->vm_end)	/* cases 6 - 8, adjacent VMA */
> +		next = vma_lookup(mm, end);
> +	else
> +		next = NULL;		/* case 5 */
> 
>  	/* verify some invariant that must be enforced by the caller */
>  	VM_WARN_ON(prev && addr <= prev->vm_start);
> @@ -959,11 +958,10 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
>  		}
>  	}
>  	/* Can we merge the successor? */
> -	if (next && end == next->vm_start &&
> -			mpol_equal(policy, vma_policy(next)) &&
> -			can_vma_merge_before(next, vm_flags,
> -					     anon_vma, file, pgoff+pglen,
> -					     vm_userfaultfd_ctx, anon_name)) {
> +	if (next && mpol_equal(policy, vma_policy(next)) &&
> +	    can_vma_merge_before(next, vm_flags,
> +				 anon_vma, file, pgoff+pglen,
> +				 vm_userfaultfd_ctx, anon_name)) {

Can this be compacted to less lines?  Pretty much the same thing
Vlastimil said in patch 4.

>  		merge_next = true;
>  	}
> 
> --
> 2.39.2
diff mbox series

Patch

diff --git a/mm/mmap.c b/mm/mmap.c
index c9834364ac98..dbdbb92493b2 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -930,15 +930,14 @@  struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
 	if (vm_flags & VM_SPECIAL)
 		return NULL;

-	curr = find_vma(mm, prev ? prev->vm_end : 0);
-	if (curr && curr->vm_end == end)		/* cases 6, 7, 8 */
-		next = find_vma(mm, curr->vm_end);
-	else
-		next = curr;
+	/* Does the input range span an existing VMA? (cases 5 - 8) */
+	curr = find_vma_intersection(mm, prev ? prev->vm_end : 0, end);

-	/* In cases 1 - 4 there's no CCCC vma */
-	if (curr && end <= curr->vm_start)
-		curr = NULL;
+	if (!curr ||			/* cases 1 - 4 */
+	    end == curr->vm_end)	/* cases 6 - 8, adjacent VMA */
+		next = vma_lookup(mm, end);
+	else
+		next = NULL;		/* case 5 */

 	/* verify some invariant that must be enforced by the caller */
 	VM_WARN_ON(prev && addr <= prev->vm_start);
@@ -959,11 +958,10 @@  struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
 		}
 	}
 	/* Can we merge the successor? */
-	if (next && end == next->vm_start &&
-			mpol_equal(policy, vma_policy(next)) &&
-			can_vma_merge_before(next, vm_flags,
-					     anon_vma, file, pgoff+pglen,
-					     vm_userfaultfd_ctx, anon_name)) {
+	if (next && mpol_equal(policy, vma_policy(next)) &&
+	    can_vma_merge_before(next, vm_flags,
+				 anon_vma, file, pgoff+pglen,
+				 vm_userfaultfd_ctx, anon_name)) {
 		merge_next = true;
 	}