Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm Elaborate on locking scheme and vm_page states.
details: https://anonhg.NetBSD.org/src/rev/a609a2643d6b
branches: trunk
changeset: 336812:a609a2643d6b
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Mar 21 13:11:14 2015 +0000
description:
Elaborate on locking scheme and vm_page states.
diffstat:
sys/uvm/uvm_page.h | 71 ++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 53 insertions(+), 18 deletions(-)
diffs (108 lines):
diff -r 58fe3754b21f -r a609a2643d6b sys/uvm/uvm_page.h
--- a/sys/uvm/uvm_page.h Sat Mar 21 05:50:19 2015 +0000
+++ b/sys/uvm/uvm_page.h Sat Mar 21 13:11:14 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page.h,v 1.76 2013/10/25 14:30:21 martin Exp $ */
+/* $NetBSD: uvm_page.h,v 1.77 2015/03/21 13:11:14 riastradh Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -98,36 +98,71 @@
*
* 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
+ * f: free page queue lock, uvm_fpageqlock
+ * o: page owner (uvm_object::vmobjlock, vm_amap::am_lock, vm_anon::an_lock)
+ * p: page queue lock, uvm_pageqlock
+ * o,p: o|p for read, o&p for write
+ * w: wired page queue or uvm_pglistalloc:
+ * => wired page queue: o&p to change, stable from wire to unwire
+ * XXX What about concurrent or nested wire?
+ * => uvm_pglistalloc: owned by caller
* ?: 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.
+ *
+ * A page can be in one of four life states:
+ *
+ * o free
+ * => pageq.list is entry on global free page queue
+ * => listq.list is entry on per-CPU free page queue
+ * => uanon is unused (or (void *)0xdeadbeef for DEBUG)
+ * => uobject is unused (or (void *)0xdeadbeef for DEBUG)
+ * => PQ_FREE is set in pqflags
+ * o owned by a uvm_object
+ * => pageq.queue is entry on wired page queue, if any
+ * => listq.queue is entry on list of pages in object
+ * => uanon is NULL
+ * => uobject is owner
+ * o owned by a vm_anon
+ * => pageq is unused (XXX correct?)
+ * => listq is unused (XXX correct?)
+ * => uanon is owner
+ * => uobject is NULL
+ * => PQ_ANON is set in pqflags
+ * o allocated by uvm_pglistalloc
+ * => pageq.queue is entry on resulting pglist, owned by caller
+ * => listq is unused (XXX correct?)
+ * => uanon is unused
+ * => uobject is unused
+ *
+ * The following transitions are allowed:
+ *
+ * - uvm_pagealloc: free -> owned by a uvm_object/vm_anon
+ * - uvm_pagefree: owned by a uvm_object/vm_anon -> free
+ * - uvm_pglistalloc: free -> allocated by uvm_pglistalloc
+ * - uvm_pglistfree: allocated by uvm_pglistalloc -> free
*/
struct vm_page {
struct rb_node rb_node; /* o: tree of pages in obj */
union {
- TAILQ_ENTRY(vm_page) queue;
- LIST_ENTRY(vm_page) list;
- } pageq; /* p: queue info for FIFO
- * queue or free list */
+ TAILQ_ENTRY(vm_page) queue; /* w: wired page queue
+ * or uvm_pglistalloc output */
+ LIST_ENTRY(vm_page) list; /* f: global free page queue */
+ } pageq;
+
union {
- TAILQ_ENTRY(vm_page) queue;
- LIST_ENTRY(vm_page) list;
- } listq; /* o: pages in same object */
+ TAILQ_ENTRY(vm_page) queue; /* o: pages in same object */
+ LIST_ENTRY(vm_page) list; /* f: CPU free page queue */
+ } listq;
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
- * o|p: for reading
- * o&p: for modification */
+ uint16_t loan_count; /* o,p: num. active loans */
uint16_t wire_count; /* p: wired down map refs */
uint16_t pqflags; /* p: page queue flags */
paddr_t phys_addr; /* physical address of page */
@@ -149,9 +184,9 @@
*
* Locking notes:
*
- * PG_, struct vm_page::flags => locked by the owner
- * PQ_, struct vm_page::pqflags => locked by the page-queue lock
- * PQ_FREE => additionally locked by free-queue lock
+ * PG_, struct vm_page::flags => locked by owner
+ * PQ_, struct vm_page::pqflags => locked by uvm_pageqlock
+ * PQ_FREE => additionally locked by uvm_fpageqlock
*
* Flag descriptions:
*
Home |
Main Index |
Thread Index |
Old Index