Module Name: src
Committed By: rmind
Date: Sat Jan 28 19:12:10 UTC 2012
Modified Files:
src/sys/uvm: uvm_page.h
Log Message:
Improve description on struct vm_page and explain locking a little bit more.
To generate a diff of this commit:
cvs rdiff -u -r1.73 -r1.74 src/sys/uvm/uvm_page.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/uvm/uvm_page.h
diff -u src/sys/uvm/uvm_page.h:1.73 src/sys/uvm/uvm_page.h:1.74
--- src/sys/uvm/uvm_page.h:1.73 Sun Jun 12 03:36:03 2011
+++ src/sys/uvm/uvm_page.h Sat Jan 28 19:12:10 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page.h,v 1.73 2011/06/12 03:36:03 rmind Exp $ */
+/* $NetBSD: uvm_page.h,v 1.74 2012/01/28 19:12:10 rmind Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -64,83 +64,76 @@
#ifndef _UVM_UVM_PAGE_H_
#define _UVM_UVM_PAGE_H_
-/*
- * uvm_page.h
- */
+#include <uvm/uvm_extern.h>
+#include <uvm/uvm_pglist.h>
-/*
- * Resident memory system definitions.
- */
+#include <sys/rbtree.h>
/*
- * Management of resident (logical) pages.
- *
- * A small structure is kept for each resident
- * page, indexed by page number. Each structure
- * is an element of several lists:
- *
- * A red-black tree rooted with the containing
- * object is used to quickly perform object+
- * offset lookups
- *
- * A list of all pages for a given object,
- * so they can be quickly deactivated at
- * time of deallocation.
+ * Management of resident (logical) pages.
*
- * An ordered list of pages due for pageout.
+ * Each resident page has a vm_page structure, indexed by page number.
+ * There are several lists in the structure:
*
- * In addition, the structure contains the object
- * and offset to which this page belongs (for pageout),
- * and sundry status bits.
+ * - A red-black tree rooted with the containing object is used to
+ * quickly perform object+offset lookups.
+ * - A list of all pages for a given object, for a quick deactivation
+ * at a time of deallocation.
+ * - An ordered list of pages due for pageout.
+ *
+ * In addition, the structure contains the object and offset to which
+ * this page belongs (for pageout) and sundry status bits.
+ *
+ * Note that the page structure has no lock of its own. The page is
+ * generally protected by its owner's lock (UVM object or amap/anon).
+ * It should be noted that UVM has to serialize pmap(9) operations on
+ * the managed pages, e.g. for pmap_enter() calls. Hence, the lock
+ * order is as follows:
+ *
+ * [vmpage-owner-lock] ->
+ * any pmap locks (e.g. PV hash lock)
+ *
+ * Since the kernel is always self-consistent, no serialization is
+ * required for unmanaged mappings, e.g. for pmap_kenter_pa() calls.
+ *
+ * Field markings and the corresponding locks:
+ *
+ * o: page owner's lock (UVM object or amap/anon)
+ * p: lock on the page queues
+ * o|p: either lock can be acquired
+ * o&p: both locks are required
+ * ?: locked by pmap or assumed page owner's lock
*
- * Fields in this structure are locked either by the lock on the
- * object that the page belongs to (O) or by the lock on the page
- * queues (P) [or both].
+ * UVM and pmap(9) may use uvm_page_locked_p() to assert whether the
+ * page owner's lock is acquired.
*/
-/*
- * locking note: the mach version of this data structure had bit
- * fields for the flags, and the bit fields were divided into two
- * items (depending on who locked what). some time, in BSD, the bit
- * fields were dumped and all the flags were lumped into one short.
- * that is fine for a single threaded uniprocessor OS, but bad if you
- * want to actual make use of locking. so, we've separated things
- * back out again.
- *
- * note the page structure has no lock of its own.
- */
-
-#include <uvm/uvm_extern.h>
-#include <uvm/uvm_pglist.h>
-
-#include <sys/rbtree.h>
-
struct vm_page {
- struct rb_node rb_node; /* tree of pages in obj (O) */
+ struct rb_node rb_node; /* o: tree of pages in obj */
union {
TAILQ_ENTRY(vm_page) queue;
LIST_ENTRY(vm_page) list;
- } pageq; /* queue info for FIFO
- * queue or free list (P) */
+ } pageq; /* p: queue info for FIFO
+ * queue or free list */
union {
TAILQ_ENTRY(vm_page) queue;
LIST_ENTRY(vm_page) list;
- } listq; /* pages in same object (O)*/
+ } listq; /* o: pages in same object */
- struct vm_anon *uanon; /* anon (O,P) */
- struct uvm_object *uobject; /* object (O,P) */
- voff_t offset; /* offset into object (O,P) */
- uint16_t flags; /* object flags [O] */
+ struct vm_anon *uanon; /* o,p: anon */
+ struct uvm_object *uobject; /* o,p: object */
+ voff_t offset; /* o,p: offset into object */
+ uint16_t flags; /* o: object flags */
uint16_t loan_count; /* number of active loans
- * to read: [O or P]
- * to modify: [O _and_ P] */
- uint16_t wire_count; /* wired down map refs [P] */
- uint16_t pqflags; /* page queue flags [P] */
+ * o|p: for reading
+ * o&p: for modification */
+ uint16_t wire_count; /* p: wired down map refs */
+ uint16_t pqflags; /* p: page queue flags */
paddr_t phys_addr; /* physical address of page */
#ifdef __HAVE_VM_PAGE_MD
- struct vm_page_md mdpage; /* pmap-specific data */
+ struct vm_page_md mdpage; /* ?: pmap-specific data */
#endif
#if defined(UVM_PAGE_TRKOWN)