Chapter3:MemoryManagement
Creating avm_area
Before a new virtual memory area can be created, it isnecessary to find a suitable location for it. A linked
list with instances ofvm_areamanages the sections already created in thevmallocarea. The global
variablevmlistdefined inmm/vmallocis the list head.
mm/vmalloc.c
struct vm_struct *vmlist;
The kernel provides theget_vm_areahelper function inmm/vmalloc; it acts as a parameter-preparation
front end for__get_vm_area. In turn, the latter function is a frontend for__get_vm_area_nodethat does
the actual work. On the basis of the size information for the area, the function tries to find a suitable place
in the virtualvmallocspace.
As a safety gap of 1 page (guard page) is inserted between eachvmallocarea, the kernel first increases
thesizespecification by the appropriate amount.
mm/vmalloc.c
struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end, int node)
{
struct vm_struct **p, *tmp, *area;
...
size = PAGE_ALIGN(size);
....
/*
* We always allocate a guard page.
*/
size += PAGE_SIZE;
...
Thestartandendparameters are set toVMALLOC_STARTandVMALLOC_END, respectively, by the calling
functions.
A loop then iterates over all elements of thevmlistlist to find a suitable entry.
mm/vmalloc.c
for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
if ((unsigned long)tmp->addr < addr) {
if((unsigned long)tmp->addr + tmp->size >= addr)
addr = ALIGN(tmp->size +
(unsigned long)tmp->addr, align);
continue;
}
if ((size + addr) < addr)
goto out;
if (size + addr <= (unsigned long)tmp->addr)
goto found;
addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);