Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 4: Virtual Process Memory


/*
* Should we do an early C-O-W break?
*/
if (flags & FAULT_FLAG_WRITE) {
if (!(vma->vm_flags & VM_SHARED)) {
anon = 1;
if (unlikely(anon_vma_prepare(vma))) {
ret = VM_FAULT_OOM;
goto out;
}
page = alloc_page_vma(GFP_HIGHUSER_MOVABLE,
vma, address);
...
}
copy_user_highpage(page, vmf.page, address, vma);
}
...

A new page must be allocated once a newanon_vmainstance has been created for the region with
anon_vma_prepare(the pointer to the old region is redirected to the new region inanon_vma_prepare).
The high memory area is preferably used for this purposeasitpresentsnoproblemsforuserspacepages.
copy_user_highpagethen creates a copy of the data (routines for copying data between kernel and
userspace are discussed in Section 4.13).

Now that the position of the page is known, it must be added to the page table of the process and incor-
porated in the reverse mapping data structures. Before this is done, a check is made to ensure that the
page contents are visible in userspace by updating the caches withflush_icache_page. (Most processors
don’t need to do this and define an empty operation.)

A page table entry that normally points to a read-only page is generated using themk_ptefunction
discussed in Section 3.3.2. If a page with write access is created, the kernel must explicitly set write
permission withpte_mkwrite.

How pages are integrated into the reverse mappingdepends on their type. If the page generated when
handling the write access is anonymous, it is added to the active area of the LRU cache usinglru_cache_
add_active(Chapter 16 examines the caching mechanisms used in more detail) and then integrated into
the reverse mapping withpage_add_new_anon_rmap.page_add_file_rmapis invoked for all other pages
associated with a file-based mapping. Both functionsare discussed in Section 4.8. Finally, the MMU cache
of the processor has to be updated if required because the page tables have been modified.

4.11.2 Anonymous Pages


do_anonymous_pageis invoked to map pages not associated with a file as a backing store. Except that no
data must be read into a page, the procedure hardly differs from the way in which file-based data are
mapped. A new page is created in the highmem area, and all its contents are deleted. The page is then
added to the page tables of the process, and the caches/MMU are updated.

Notice that earlier kernels distinguished between read-only and write access to anonymous mappings: In
the first case, a single, global page filled with zero bytes was used to satisfy read requests to anonymous
regions. During the development of kernel 2.6.24,this behavior has, however, been dropped because
measurements have shown that the performance gain is negligible, while larger systems can experience
several problems with shared zero mappings, which I do not want to discuss in detail here.
Free download pdf