diff options
| author | Nick Piggin <npiggin@suse.de> | 2006-09-26 02:31:35 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:48:49 -0400 |
| commit | da6052f7b33abe55fbfd7d2213815f58c00a88d4 (patch) | |
| tree | a2deda88ae8e9fc33d9a0ce80f42fde2c55c7bbc | |
| parent | e5ac9c5aec7c4bc57fa93f2d37d760a22cb7bd33 (diff) | |
[PATCH] update some mm/ comments
Let's try to keep mm/ comments more useful and up to date. This is a start.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | include/linux/mm.h | 68 | ||||
| -rw-r--r-- | include/linux/page-flags.h | 35 | ||||
| -rw-r--r-- | mm/filemap.c | 8 |
3 files changed, 64 insertions, 47 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 2db4229a0066..f2018775b995 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -219,7 +219,8 @@ struct inode; | |||
| 219 | * Each physical page in the system has a struct page associated with | 219 | * Each physical page in the system has a struct page associated with |
| 220 | * it to keep track of whatever it is we are using the page for at the | 220 | * it to keep track of whatever it is we are using the page for at the |
| 221 | * moment. Note that we have no way to track which tasks are using | 221 | * moment. Note that we have no way to track which tasks are using |
| 222 | * a page. | 222 | * a page, though if it is a pagecache page, rmap structures can tell us |
| 223 | * who is mapping it. | ||
| 223 | */ | 224 | */ |
| 224 | struct page { | 225 | struct page { |
| 225 | unsigned long flags; /* Atomic flags, some possibly | 226 | unsigned long flags; /* Atomic flags, some possibly |
| @@ -299,8 +300,7 @@ struct page { | |||
| 299 | */ | 300 | */ |
| 300 | 301 | ||
| 301 | /* | 302 | /* |
| 302 | * Drop a ref, return true if the logical refcount fell to zero (the page has | 303 | * Drop a ref, return true if the refcount fell to zero (the page has no users) |
| 303 | * no users) | ||
| 304 | */ | 304 | */ |
| 305 | static inline int put_page_testzero(struct page *page) | 305 | static inline int put_page_testzero(struct page *page) |
| 306 | { | 306 | { |
| @@ -356,43 +356,55 @@ void split_page(struct page *page, unsigned int order); | |||
| 356 | * For the non-reserved pages, page_count(page) denotes a reference count. | 356 | * For the non-reserved pages, page_count(page) denotes a reference count. |
| 357 | * page_count() == 0 means the page is free. page->lru is then used for | 357 | * page_count() == 0 means the page is free. page->lru is then used for |
| 358 | * freelist management in the buddy allocator. | 358 | * freelist management in the buddy allocator. |
| 359 | * page_count() == 1 means the page is used for exactly one purpose | 359 | * page_count() > 0 means the page has been allocated. |
| 360 | * (e.g. a private data page of one process). | ||
| 361 | * | 360 | * |
| 362 | * A page may be used for kmalloc() or anyone else who does a | 361 | * Pages are allocated by the slab allocator in order to provide memory |
| 363 | * __get_free_page(). In this case the page_count() is at least 1, and | 362 | * to kmalloc and kmem_cache_alloc. In this case, the management of the |
| 364 | * all other fields are unused but should be 0 or NULL. The | 363 | * page, and the fields in 'struct page' are the responsibility of mm/slab.c |
| 365 | * management of this page is the responsibility of the one who uses | 364 | * unless a particular usage is carefully commented. (the responsibility of |
| 366 | * it. | 365 | * freeing the kmalloc memory is the caller's, of course). |
| 367 | * | 366 | * |
| 368 | * The other pages (we may call them "process pages") are completely | 367 | * A page may be used by anyone else who does a __get_free_page(). |
| 368 | * In this case, page_count still tracks the references, and should only | ||
| 369 | * be used through the normal accessor functions. The top bits of page->flags | ||
| 370 | * and page->virtual store page management information, but all other fields | ||
| 371 | * are unused and could be used privately, carefully. The management of this | ||
| 372 | * page is the responsibility of the one who allocated it, and those who have | ||
| 373 | * subsequently been given references to it. | ||
| 374 | * | ||
| 375 | * The other pages (we may call them "pagecache pages") are completely | ||
| 369 | * managed by the Linux memory manager: I/O, buffers, swapping etc. | 376 | * managed by the Linux memory manager: I/O, buffers, swapping etc. |
| 370 | * The following discussion applies only to them. | 377 | * The following discussion applies only to them. |
| 371 | * | 378 | * |
| 372 | * A page may belong to an inode's memory mapping. In this case, | 379 | * A pagecache page contains an opaque `private' member, which belongs to the |
| 373 | * page->mapping is the pointer to the inode, and page->index is the | 380 | * page's address_space. Usually, this is the address of a circular list of |
| 374 | * file offset of the page, in units of PAGE_CACHE_SIZE. | 381 | * the page's disk buffers. PG_private must be set to tell the VM to call |
| 382 | * into the filesystem to release these pages. | ||
| 375 | * | 383 | * |
| 376 | * A page contains an opaque `private' member, which belongs to the | 384 | * A page may belong to an inode's memory mapping. In this case, page->mapping |
| 377 | * page's address_space. Usually, this is the address of a circular | 385 | * is the pointer to the inode, and page->index is the file offset of the page, |
| 378 | * list of the page's disk buffers. | 386 | * in units of PAGE_CACHE_SIZE. |
| 379 | * | 387 | * |
| 380 | * For pages belonging to inodes, the page_count() is the number of | 388 | * If pagecache pages are not associated with an inode, they are said to be |
| 381 | * attaches, plus 1 if `private' contains something, plus one for | 389 | * anonymous pages. These may become associated with the swapcache, and in that |
| 382 | * the page cache itself. | 390 | * case PG_swapcache is set, and page->private is an offset into the swapcache. |
| 383 | * | 391 | * |
| 384 | * Instead of keeping dirty/clean pages in per address-space lists, we instead | 392 | * In either case (swapcache or inode backed), the pagecache itself holds one |
| 385 | * now tag pages as dirty/under writeback in the radix tree. | 393 | * reference to the page. Setting PG_private should also increment the |
| 394 | * refcount. The each user mapping also has a reference to the page. | ||
| 386 | * | 395 | * |
| 387 | * There is also a per-mapping radix tree mapping index to the page | 396 | * The pagecache pages are stored in a per-mapping radix tree, which is |
| 388 | * in memory if present. The tree is rooted at mapping->root. | 397 | * rooted at mapping->page_tree, and indexed by offset. |
| 398 | * Where 2.4 and early 2.6 kernels kept dirty/clean pages in per-address_space | ||
| 399 | * lists, we instead now tag pages as dirty/writeback in the radix tree. | ||
| 389 | * | 400 | * |
| 390 | * All process pages can do I/O: | 401 | * All pagecache pages may be subject to I/O: |
| 391 | * - inode pages may need to be read from disk, | 402 | * - inode pages may need to be read from disk, |
| 392 | * - inode pages which have been modified and are MAP_SHARED may need | 403 | * - inode pages which have been modified and are MAP_SHARED may need |
| 393 | * to be written to disk, | 404 | * to be written back to the inode on disk, |
| 394 | * - private pages which have been modified may need to be swapped out | 405 | * - anonymous pages (including MAP_PRIVATE file mappings) which have been |
| 395 | * to swap space and (later) to be read back into memory. | 406 | * modified may need to be swapped out to swap space and (later) to be read |
| 407 | * back into memory. | ||
| 396 | */ | 408 | */ |
| 397 | 409 | ||
| 398 | /* | 410 | /* |
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 5748642e9f36..9d7921dd50f0 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h | |||
| @@ -13,24 +13,25 @@ | |||
| 13 | * PG_reserved is set for special pages, which can never be swapped out. Some | 13 | * PG_reserved is set for special pages, which can never be swapped out. Some |
| 14 | * of them might not even exist (eg empty_bad_page)... | 14 | * of them might not even exist (eg empty_bad_page)... |
| 15 | * | 15 | * |
| 16 | * The PG_private bitflag is set if page->private contains a valid value. | 16 | * The PG_private bitflag is set on pagecache pages if they contain filesystem |
| 17 | * specific data (which is normally at page->private). It can be used by | ||
| 18 | * private allocations for its own usage. | ||
| 17 | * | 19 | * |
| 18 | * During disk I/O, PG_locked is used. This bit is set before I/O and | 20 | * During initiation of disk I/O, PG_locked is set. This bit is set before I/O |
| 19 | * reset when I/O completes. page_waitqueue(page) is a wait queue of all tasks | 21 | * and cleared when writeback _starts_ or when read _completes_. PG_writeback |
| 20 | * waiting for the I/O on this page to complete. | 22 | * is set before writeback starts and cleared when it finishes. |
| 23 | * | ||
| 24 | * PG_locked also pins a page in pagecache, and blocks truncation of the file | ||
| 25 | * while it is held. | ||
| 26 | * | ||
| 27 | * page_waitqueue(page) is a wait queue of all tasks waiting for the page | ||
| 28 | * to become unlocked. | ||
| 21 | * | 29 | * |
| 22 | * PG_uptodate tells whether the page's contents is valid. When a read | 30 | * PG_uptodate tells whether the page's contents is valid. When a read |
| 23 | * completes, the page becomes uptodate, unless a disk I/O error happened. | 31 | * completes, the page becomes uptodate, unless a disk I/O error happened. |
| 24 | * | 32 | * |
| 25 | * For choosing which pages to swap out, inode pages carry a PG_referenced bit, | 33 | * PG_referenced, PG_reclaim are used for page reclaim for anonymous and |
| 26 | * which is set any time the system accesses that page through the (mapping, | 34 | * file-backed pagecache (see mm/vmscan.c). |
| 27 | * index) hash table. This referenced bit, together with the referenced bit | ||
| 28 | * in the page tables, is used to manipulate page->age and move the page across | ||
| 29 | * the active, inactive_dirty and inactive_clean lists. | ||
| 30 | * | ||
| 31 | * Note that the referenced bit, the page->lru list_head and the active, | ||
| 32 | * inactive_dirty and inactive_clean lists are protected by the | ||
| 33 | * zone->lru_lock, and *NOT* by the usual PG_locked bit! | ||
| 34 | * | 35 | * |
| 35 | * PG_error is set to indicate that an I/O error occurred on this page. | 36 | * PG_error is set to indicate that an I/O error occurred on this page. |
| 36 | * | 37 | * |
| @@ -42,6 +43,10 @@ | |||
| 42 | * space, they need to be kmapped separately for doing IO on the pages. The | 43 | * space, they need to be kmapped separately for doing IO on the pages. The |
| 43 | * struct page (these bits with information) are always mapped into kernel | 44 | * struct page (these bits with information) are always mapped into kernel |
| 44 | * address space... | 45 | * address space... |
| 46 | * | ||
| 47 | * PG_buddy is set to indicate that the page is free and in the buddy system | ||
| 48 | * (see mm/page_alloc.c). | ||
| 49 | * | ||
| 45 | */ | 50 | */ |
| 46 | 51 | ||
| 47 | /* | 52 | /* |
| @@ -74,7 +79,7 @@ | |||
| 74 | #define PG_checked 8 /* kill me in 2.5.<early>. */ | 79 | #define PG_checked 8 /* kill me in 2.5.<early>. */ |
| 75 | #define PG_arch_1 9 | 80 | #define PG_arch_1 9 |
| 76 | #define PG_reserved 10 | 81 | #define PG_reserved 10 |
| 77 | #define PG_private 11 /* Has something at ->private */ | 82 | #define PG_private 11 /* If pagecache, has fs-private data */ |
| 78 | 83 | ||
| 79 | #define PG_writeback 12 /* Page is under writeback */ | 84 | #define PG_writeback 12 /* Page is under writeback */ |
| 80 | #define PG_nosave 13 /* Used for system suspend/resume */ | 85 | #define PG_nosave 13 /* Used for system suspend/resume */ |
| @@ -83,7 +88,7 @@ | |||
| 83 | 88 | ||
| 84 | #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */ | 89 | #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */ |
| 85 | #define PG_reclaim 17 /* To be reclaimed asap */ | 90 | #define PG_reclaim 17 /* To be reclaimed asap */ |
| 86 | #define PG_nosave_free 18 /* Free, should not be written */ | 91 | #define PG_nosave_free 18 /* Used for system suspend/resume */ |
| 87 | #define PG_buddy 19 /* Page is free, on buddy lists */ | 92 | #define PG_buddy 19 /* Page is free, on buddy lists */ |
| 88 | 93 | ||
| 89 | 94 | ||
diff --git a/mm/filemap.c b/mm/filemap.c index d5af1cab4268..afcdc72b5e90 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -599,8 +599,8 @@ void fastcall __lock_page_nosync(struct page *page) | |||
| 599 | * @mapping: the address_space to search | 599 | * @mapping: the address_space to search |
| 600 | * @offset: the page index | 600 | * @offset: the page index |
| 601 | * | 601 | * |
| 602 | * A rather lightweight function, finding and getting a reference to a | 602 | * Is there a pagecache struct page at the given (mapping, offset) tuple? |
| 603 | * hashed page atomically. | 603 | * If yes, increment its refcount and return it; if no, return NULL. |
| 604 | */ | 604 | */ |
| 605 | struct page * find_get_page(struct address_space *mapping, unsigned long offset) | 605 | struct page * find_get_page(struct address_space *mapping, unsigned long offset) |
| 606 | { | 606 | { |
| @@ -987,7 +987,7 @@ page_not_up_to_date: | |||
| 987 | /* Get exclusive access to the page ... */ | 987 | /* Get exclusive access to the page ... */ |
| 988 | lock_page(page); | 988 | lock_page(page); |
| 989 | 989 | ||
| 990 | /* Did it get unhashed before we got the lock? */ | 990 | /* Did it get truncated before we got the lock? */ |
| 991 | if (!page->mapping) { | 991 | if (!page->mapping) { |
| 992 | unlock_page(page); | 992 | unlock_page(page); |
| 993 | page_cache_release(page); | 993 | page_cache_release(page); |
| @@ -1627,7 +1627,7 @@ no_cached_page: | |||
| 1627 | page_not_uptodate: | 1627 | page_not_uptodate: |
| 1628 | lock_page(page); | 1628 | lock_page(page); |
| 1629 | 1629 | ||
| 1630 | /* Did it get unhashed while we waited for it? */ | 1630 | /* Did it get truncated while we waited for it? */ |
| 1631 | if (!page->mapping) { | 1631 | if (!page->mapping) { |
| 1632 | unlock_page(page); | 1632 | unlock_page(page); |
| 1633 | goto err; | 1633 | goto err; |
