 
            Add comments to the map_count limit checks in do_mmap() and do_brk_flags() to clarify their intended behavior.
The use of a strict inequality ('>') in these checks is intentional but non-obvious. It allows these functions to succeed when the VMA count is exactly at the sysctl_max_map_count limit. This historical behavior accounts for cases where the operation might not create a new VMA, but instead merge with or expand an existing one, in which case the VMA count does not increase.
These comments clarify the long-standing behavior and will help prevent future misinterpretation as an off-by-one error.
Signed-off-by: Kalesh Singh kaleshsingh@google.com ---
Changes in v4: - Keep the existing lenient behavior, per Hugh - Document this is intended, per Lorenzo
Changes in v3: - Collect Reviewed-by and Acked-by tags.
Changes in v2: - Fix mmap check, per Pedro
mm/mmap.c | 9 +++++++++ mm/vma.c | 6 ++++++ 2 files changed, 15 insertions(+)
diff --git a/mm/mmap.c b/mm/mmap.c index 644f02071a41..78843a2fae42 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -374,6 +374,15 @@ unsigned long do_mmap(struct file *file, unsigned long addr, return -EOVERFLOW;
/* Too many mappings? */ + /* + * The check is intentionally lenient (>) to allow an mmap() at the limit + * to succeed. This is for historical reasons, as the new mapping might + * merge with an adjacent VMA and not increase the total VMA count. + * + * If a merge does not occur, the process is allowed to exceed the + * sysctl_max_map_count limit by one. This behavior is preserved to + * avoid breaking existing applications. + */ if (mm->map_count > sysctl_max_map_count) return -ENOMEM;
diff --git a/mm/vma.c b/mm/vma.c index 919d1fc63a52..d0bb3127280e 100644 --- a/mm/vma.c +++ b/mm/vma.c @@ -2813,6 +2813,12 @@ int do_brk_flags(struct vma_iterator *vmi, struct vm_area_struct *vma, if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT)) return -ENOMEM;
+ /* + * The check is intentionally lenient (>) to allow brk() to succeed at + * the limit. This is for historical reasons, as expanding the heap + * typically extends the existing brk VMA rather than creating a new one. + * See also the comment in do_mmap(). + */ if (mm->map_count > sysctl_max_map_count) return -ENOMEM;