Specifications
This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
Memory Management in Linux
|
417
there is one struct page for each physical page on the system. Some of the fields of
this structure include the following:
atomic_t count;
The number of references there are to this page. When the count drops to 0, the
page is returned to the free list.
void *virtual;
The kernel virtual address of the page, if it is mapped; NULL, otherwise. Low-
memory pages are always mapped; high-memory pages usually are not. This
field does not appear on all architectures; it generally is compiled only where the
kernel virtual address of a page cannot be easily calculated. If you want to look
at this field, the proper method is to use the page_address macro, described
below.
unsigned long flags;
A set of bit flags describing the status of the page. These include PG_locked,
which indicates that the page has been locked in memory, and
PG_reserved,
which prevents the memory management system from working with the page at
all.
There is much more information within
struct page, but it is part of the deeper
black magic of memory management and is not of concern to driver writers.
The kernel maintains one or more arrays of
struct page entries that track all of the
physical memory on the system. On some systems, there is a single array called
mem_map.
On some systems, however, the situation is more complicated. Nonuniform memory
access (NUMA) systems and those with widely discontiguous physical memory may
have more than one memory map array, so code that is meant to be portable should
avoid direct access to the array whenever possible. Fortunately, it is usually quite easy to
just work with
struct page pointers without worrying about where they come from.
Some functions and macros are defined for translating between
struct page pointers
and virtual addresses:
struct page *virt_to_page(void *kaddr);
This macro, defined in <asm/page.h>, takes a kernel logical address and returns
its associated
struct page pointer. Since it requires a logical address, it does not
work with memory from vmalloc or high memory.
struct page *pfn_to_page(int pfn);
Returns the struct page pointer for the given page frame number. If necessary,
it checks a page frame number for validity with pfn_valid before passing it to
pfn_to_page.
void *page_address(struct page *page);
Returns the kernel virtual address of this page, if such an address exists. For high
memory, that address exists only if the page has been mapped. This function is
,ch15.13676 Page 417 Friday, January 21, 2005 11:04 AM