The Linux Kernel Primer. A Top-Down Approach for x86 and PowerPC Architectures

4.1. Pages

As the basic unit of memory managed by the memory manager, a page has a lot of state that it needs to be kept track of. For example, the kernel needs to know when pages become available for reallocation. To do this, the kernel uses page descriptors. Every physical page in memory is assigned a page descriptor.

This section describes various fields in the page descriptor and how the memory manager uses them. The page structure is defined in include/linux/mm.h.

----------------------------------------------------------------------------- include/linux/mm.h 170 struct page { 171 unsigned long flags; 172 173 atomic_t count; 174 struct list_head list; 175 struct address_space *mapping; 176 unsigned long index; 177 struct list_head lru; 178 179 union { 180 struct pte_chain *chain; 181 182 pte_addr_t direct; 183 } pte; 184 unsigned long private; 185 ... 196 #if defined(WANT_PAGE_VIRTUAL) 197 void *virtual; 198 199 #endif 200 }; -----------------------------------------------------------------------------

4.1.1. flags

Atomic flags describe the state of the page frame. Each flag is represented by one of the bits in the 32-bit value. Some helper functions allow us to manipulate and test particular flags. Also, some helper functions allow us to access the value of the bit corresponding to the particular flag. The flags themselves, as well as the helper functions, are defined in include/linux/page-flags.h. Table 4.1 identifies and explains some of the flags that can be set in the flags field of the page structure.

Table 4.1. Flag Values for page->flags

Flag Name

Description

PG_locked

This page is locked so it shouldn't be touched. This bit is used during disk I/O, being set before the I/O operation and reset upon completion.

PG_error

Indicates that an I/O error occurred on this page.

PG_referenced

Indicates that this page was accessed for a disk I/O operation. This is used to determine which active or inactive page list the page is on.

PG_uptodate

Indicates that the page's contents are valid, being set when a read completes upon that page. This is mutually exclusive to having PG_error set.

PG_dirty

Indicates a modified page.

PG_lru

The page is in one of the Least Recently Used lists used for page swapping. See the description of lru page struct field in this section for more information regarding LRU lists.

PG_active

Indicates that the page is in the active page list.

PG_slab

This page belongs to a slab created by the slab allocator, which is described in the "Slab Allocator" section in this chapter.

PG_highmem

Indicates that this page is in the high memory zone (ZONE_HIGHMEM) and so it cannot be permanently mapped into the kernel virtual address space. The high memory zone pages are identified as such during kernel bootup in mem_init() (see Chapter 8, "Booting the Kernel," for more detail).

PG_checked

Used by the ext2 filesystem. Killed in 2.5.

PG_arch_1

Architecture-specific page state bit.

PG_reserved

Marks pages that cannot be swapped out, do not exist, or were allocated by the boot memory allocator.

PG_private

Indicates that the page is valid and is set if page->private contains a valid value.

PG_writeback

Indicates that the page is under writeback.

PG_mappedtodisk

This page has blocks currently allocated on a system disk.

PG_reclaim

Indicates that the page should be reclaimed.

PG_compound

Indicates that the page is part of a higher order compound page.

4.1.1.1. count

The count field serves as the usage or reference counter for a page. A value of 0 indicates that the page frame is available for reuse. A positive value indicates the number of processes that can access the page data.[4]

[4] A page is free when the data it was holding is no longer used or needed.

4.1.1.2. list

The list field is the structure that holds the next and prev pointers to the corresponding elements in a doubly linked list. The doubly linked list that this page is a member of is determined in part by the mapping it is associated with and the state of the page.

4.1.1.3. mapping

Each page can be associated with an address_space structure when it holds the data for a file memory mapping. The mapping field is a pointer to the address_space of which this page is a member. An address_space is a collection of pages that belongs to a memory object (for example, an inode). For more information on how address_space is used, go to Chapter 7, "Scheduling and Kernel Synchronization," Section 7.14.

4.1.1.4. lru

The lru field holds the next and prev pointers to the corresponding elements in the Least Recently Used (LRU) lists. These lists are involved with page reclamation and consist of two lists: active_list, which contains pages that are in use, and incactive_list, which contains pages that can be reused.

4.1.1.5. virtual

virtual is a pointer to the page's corresponding virtual address. In a system with highmem,[5] the memory mapping can occur dynamically, making it necessary to recalculate the virtual address when needed. In these cases, this value is set to NULL.

[5] Highmem is the physical memory that surpasses the virtually addressable range. See Section 4.2, "Memory Zones."

Compound Page

A compound page is a higher-order page. To enable compound page support in the kernel, "Huge TLB Page Support" must be enabled at compile time. A compound page is composed of more than one page, the first of which is called the "head" page and the remainder of which are called "tail" pages. All compound pages will have the PG_compound bit set in their respective page->flags, and the page->lru.next pointing to the head page.

Категории