Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 18: Page Reclaim and Swapping


code). On the other hand, some changes are necessary to handle special cases, (e.g., the lumpy page
reclaim technique). These exceptions are discussed in the course of this chapter.

Several auxiliary functions are provided by the kernel to support moving pages between both LRU lists:

<mm_inline.h>
void add_page_to_active_list(struct zone *zone, struct page *page)
void add_page_to_inactive_list(struct zone *zone, struct page *page)

void del_page_from_active_list(struct zone *zone, struct page *page)
void del_page_from_inactive_list(struct zone *zone, struct page *page)

void del_page_from_lru(struct zone *zone, struct page *page)

The function names say it all, and the implementation is also a matter of simple list manipulation. The
only thing to note is thatdel_page_from_lrumust be used if the current LRU list of the page is unknown
to the caller.

Moving pages from the active to the inactive list does, however, require more than just handling the list
entries. To promote an inactive page to the active list,activate_pageis responsible. Without locking and
statistics accounting, the code looks as follows:

mm/swap.c
void fastcall activate_page(struct page *page)
{
struct zone *zone = page_zone(page);

if (PageLRU(page) && !PageActive(page)) {
del_page_from_inactive_list(zone, page);
SetPageActive(page);
add_page_to_active_list(zone, page);
}
}

This implements exactly the transition as discussed above.

Moving a page from the active to the inactive list is hidden within a larger function that is also respon-
sible to handle shrinking of caches in a wider context,shrink_active_list, discussed in Section 18.6.6.
Internally, the function relies onpage_referenced. Besides handling thePG_referencedbit in the way
described above, the function is responsible to query how often the page is referenced from the page
table. This is mainly an application of the reverse mapping mechanism.page_referencedrequires the
parameteris_locked, which declares whether the page under consideration is locked by the caller:

mm/rmap.c
int page_referenced(struct page *page, int is_locked)
{
int referenced = 0;
...
if (TestClearPageReferenced(page))
referenced++;

if (page_mapped(page) && page->mapping) {
if (PageAnon(page))
referenced += page_referenced_anon(page);
Free download pdf