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)

Reply via email to