Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 4: Virtual Process Memory


...
newbrk = PAGE_ALIGN(brk);
oldbrk = PAGE_ALIGN(mm->brk);
...

This code ensures that the new (and, as a precaution, the old) value ofbrkis a multiple of the system
page size. In other words, a page is the smallest memory area that can be reserved withbrk.^15


do_munmap, with which we are familiar from Section 4.7.2, is invoked when it is necessary to shrink
the heap.


<mm/mmap.c>
/* Always allow shrinking brk. */
if (brk <= mm->brk) {
if (!do_munmap(mm, newbrk, oldbrk-newbrk))
goto set_brk;
goto out;
}
...

If the heap is to be enlarged, the kernel must first check whether the new size is outside the limit set as
the maximum heap size for the process.find_vma_intersectionthen checks whether the enlarged heap
would overlap with an existing mapping of the process; if so, it returns without doing anything.


<mm/mmap.c>
/* Check against existing mmap mappings. */
if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
goto out;
...

Otherwise, the actual work of enlarging the heap is delegated todo_brk. The new value ofmm->brkis
always returned regardless of whether it is larger,smaller, or unchanged as compared to the old value.


<mm/mmap.c>
/* Ok, looks good - let it rip. */
if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk)
goto out;
set_brk:
mm->brk = brk;
out:
retval = mm->brk;
return retval;
}

We need not discussdo_brkseparately as essentially it is a simplified version ofdo_mmap_pgoffand
reveals no new aspects. Like the latter, it creates an anonymous mapping in user address space but omits
some safety checks and the handling of special situations to improve code performance.


(^15) It is therefore essential to interpose a further allocator function in userspace to split the page into smaller areas; this is the task of
the C standard library.

Free download pdf