Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm Improve description on struct vm_page and explain lo...
details: https://anonhg.NetBSD.org/src/rev/fa9e4b1a41d7
branches: trunk
changeset: 773143:fa9e4b1a41d7
user: rmind <rmind%NetBSD.org@localhost>
date: Sat Jan 28 19:12:10 2012 +0000
description:
Improve description on struct vm_page and explain locking a little bit more.
diffstat:
sys/uvm/uvm_page.h | 113 ++++++++++++++++++++++++----------------------------
1 files changed, 53 insertions(+), 60 deletions(-)
diffs (145 lines):
diff -r cfc9bcac4cde -r fa9e4b1a41d7 sys/uvm/uvm_page.h
--- a/sys/uvm/uvm_page.h Sat Jan 28 18:02:56 2012 +0000
+++ b/sys/uvm/uvm_page.h Sat Jan 28 19:12:10 2012 +0000
@@ -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
- */
-
-/*
- * Resident memory system definitions.
- */
-
-/*
- * 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.
- *
- * 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.
- *
- * 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].
- */
-
-/*
- * 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>
+/*
+ * Management of resident (logical) pages.
+ *
+ * Each resident page has a vm_page structure, indexed by page number.
+ * There are several lists in the structure:
+ *
+ * - 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
+ *
+ * UVM and pmap(9) may use uvm_page_locked_p() to assert whether the
+ * page owner's lock is acquired.
+ */
+
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)
Home |
Main Index |
Thread Index |
Old Index