Author: alc
Date: Mon Oct 29 06:15:04 2012
New Revision: 242300
URL: http://svn.freebsd.org/changeset/base/242300

Log:
  Replace the page hold queue, PQ_HOLD, by a new page flag, PG_UNHOLDFREE,
  because the queue itself serves no purpose.  When a held page is freed,
  inserting the page into the hold queue has the side effect of setting the
  page's "queue" field to PQ_HOLD.  Later, when the page is unheld, it will
  be freed because the "queue" field is PQ_HOLD.  In other words, PQ_HOLD is
  used as a flag, not a queue.  So, this change replaces it with a flag.
  
  To accomodate the new page flag, make the page's "flags" field wider and
  "oflags" field narrower.
  
  Reviewed by:  kib

Modified:
  head/sys/vm/vm_page.c
  head/sys/vm/vm_page.h

Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c       Mon Oct 29 04:51:51 2012        (r242299)
+++ head/sys/vm/vm_page.c       Mon Oct 29 06:15:04 2012        (r242300)
@@ -308,7 +308,6 @@ vm_page_startup(vm_offset_t vaddr)
                TAILQ_INIT(&vm_page_queues[i].pl);
        vm_page_queues[PQ_INACTIVE].cnt = &cnt.v_inactive_count;
        vm_page_queues[PQ_ACTIVE].cnt = &cnt.v_active_count;
-       vm_page_queues[PQ_HOLD].cnt = &cnt.v_active_count;
 
        /*
         * Allocate memory for use when boot strapping the kernel memory
@@ -540,7 +539,7 @@ vm_page_unhold(vm_page_t mem)
        vm_page_lock_assert(mem, MA_OWNED);
        --mem->hold_count;
        KASSERT(mem->hold_count >= 0, ("vm_page_unhold: hold count < 0!!!"));
-       if (mem->hold_count == 0 && mem->queue == PQ_HOLD)
+       if (mem->hold_count == 0 && (mem->flags & PG_UNHOLDFREE) != 0)
                vm_page_free_toq(mem);
 }
 
@@ -2042,9 +2041,9 @@ vm_page_free_toq(vm_page_t m)
                panic("vm_page_free: freeing wired page %p", m);
        if (m->hold_count != 0) {
                m->flags &= ~PG_ZERO;
-               vm_page_lock_queues();
-               vm_page_enqueue(PQ_HOLD, m);
-               vm_page_unlock_queues();
+               KASSERT((m->flags & PG_UNHOLDFREE) == 0,
+                   ("vm_page_free: freeing PG_UNHOLDFREE page %p", m));
+               m->flags |= PG_UNHOLDFREE;
        } else {
                /*
                 * Restore the default memory attribute to the page.

Modified: head/sys/vm/vm_page.h
==============================================================================
--- head/sys/vm/vm_page.h       Mon Oct 29 04:51:51 2012        (r242299)
+++ head/sys/vm/vm_page.h       Mon Oct 29 06:15:04 2012        (r242300)
@@ -145,8 +145,8 @@ struct vm_page {
        u_short cow;                    /* page cow mapping count (P) */
        u_int wire_count;               /* wired down maps refs (P) */
        uint8_t aflags;                 /* access is atomic */
-       uint8_t flags;                  /* see below, often immutable after 
alloc */
-       u_short oflags;                 /* page flags (O) */
+       uint8_t oflags;                 /* page VPO_* flags (O) */
+       uint16_t flags;                 /* page PG_* flags (P) */
        u_char  act_count;              /* page usage count (O) */
        u_char  busy;                   /* page busy count (O) */
        /* NOTE that these must support one bit per DEV_BSIZE in a page!!! */
@@ -169,17 +169,16 @@ struct vm_page {
  *      mappings, and such pages are also not on any PQ queue.
  *
  */
-#define        VPO_BUSY        0x0001  /* page is in transit */
-#define        VPO_WANTED      0x0002  /* someone is waiting for page */
-#define        VPO_UNMANAGED   0x0004          /* No PV management for page */
-#define        VPO_SWAPINPROG  0x0200  /* swap I/O in progress on page */
-#define        VPO_NOSYNC      0x0400  /* do not collect for syncer */
+#define        VPO_BUSY        0x01            /* page is in transit */
+#define        VPO_WANTED      0x02            /* someone is waiting for page 
*/
+#define        VPO_UNMANAGED   0x04            /* no PV management for page */
+#define        VPO_SWAPINPROG  0x08            /* swap I/O in progress on page 
*/
+#define        VPO_NOSYNC      0x10            /* do not collect for syncer */
 
 #define        PQ_NONE         255
 #define        PQ_INACTIVE     0
 #define        PQ_ACTIVE       1
-#define        PQ_HOLD         2
-#define        PQ_COUNT        3
+#define        PQ_COUNT        2
 
 struct vpgqueues {
        struct pglist pl;
@@ -263,14 +262,15 @@ extern struct vpglocks pa_lock[];
  * Page flags.  If changed at any other time than page allocation or
  * freeing, the modification must be protected by the vm_page lock.
  */
-#define        PG_CACHED       0x01            /* page is cached */
-#define        PG_FREE         0x02            /* page is free */
-#define        PG_FICTITIOUS   0x04            /* physical page doesn't exist 
*/
-#define        PG_ZERO         0x08            /* page is zeroed */
-#define        PG_MARKER       0x10            /* special queue marker page */
-#define        PG_SLAB         0x20            /* object pointer is actually a 
slab */
-#define        PG_WINATCFLS    0x40            /* flush dirty page on inactive 
q */
-#define        PG_NODUMP       0x80            /* don't include this page in a 
dump */
+#define        PG_CACHED       0x0001          /* page is cached */
+#define        PG_FREE         0x0002          /* page is free */
+#define        PG_FICTITIOUS   0x0004          /* physical page doesn't exist 
*/
+#define        PG_ZERO         0x0008          /* page is zeroed */
+#define        PG_MARKER       0x0010          /* special queue marker page */
+#define        PG_SLAB         0x0020          /* object pointer is actually a 
slab */
+#define        PG_WINATCFLS    0x0040          /* flush dirty page on inactive 
q */
+#define        PG_NODUMP       0x0080          /* don't include this page in a 
dump */
+#define        PG_UNHOLDFREE   0x0100          /* delayed free of a held page 
*/
 
 /*
  * Misc constants.
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to