Chapter 4: Virtual Process Memory
The address of theanon_vmalist head is stored in themappingelement of thepageinstance afterPAGE_
MAPPING_ANONhas been added to the pointer. This enables the kernel to distinguish between anony-
mous pages and pages with a regular mapping by checking whether the least significant bit is 0 (if
PAGE_MAPPING_ANONis not set) or 1 (ifPAGE_MAPPING_ANONis set) as discussed above. Recall that this
trick is valid because the lowest-order bit of a page pointer is guaranteed to be zero because of alignment
requirements.
Pages with a File-BasedMapping
Work is even simpler for pages of this type, as the following code excerpt shows:
mm/rmap.c
void page_add_file_rmap(struct page *page)
{
if (atomic_inc_and_test(&page->_mapcount))
__inc_zone_page_state(page, NR_FILE_MAPPED);
}
Basically, all that needs to be done is to increment the_mapcountvariable atomically and update the
per-zone statistics.
4.8.3 Using Reverse Mapping
The real benefits of reverse mapping do not become clear until Chapter 18, which examines the imple-
mentation of swapping. There we will see that the kernel defines thetry_to_unmapfunction, which
is invoked to delete a specific physical page from the page tables ofallprocesses by which the page is
used. It is apparent that this is only possible with the data structures just described. Nevertheless, the
implementation is influenced by many details of the swap layer, and this is why I won’t go into how
try_to_unmapworksatthispoint.
page_referencedis an important function that puts the data structures of the reverse mapping scheme
to good use. It counts the number of processes that haveactivelyused a shared page recently by accessing
it — this is different from the number of regions into which the page is mapped. Whereas the second
quantity is mostly static, the first changes rapidly if the page is in active use.
The function is a multiplexer that invokespage_referenced_anonfor anonymous pages orpage_
referenced_filefor pages from a file-based mapping. Both try to establish at how many places
a page is used, but each adopts a different approach owing to the different underlying data
structures.
Let’s first look at the version for anonymous pages. We first need thepage_lock_anon_vmahelper
function to find the associated list of regions by reference to a specificpageinstance (by reading the
information discussed in the previous section from the data structure).
<mm/rmap.c>
static struct anon_vma *page_lock_anon_vma(struct page *page)
{
struct anon_vma *anon_vma = NULL;
unsigned long anon_mapping;
anon_mapping = (unsigned long) page->mapping;
if (!(anon_mapping & PAGE_MAPPING_ANON))
goto out;