Author: alc
Date: Wed Nov  2 05:42:51 2011
New Revision: 227012
URL: http://svn.freebsd.org/changeset/base/227012

Log:
  Add support for VM_ALLOC_WIRED and VM_ALLOC_ZERO to vm_page_alloc_freelist()
  and use these new options in the mips pmap.
  
  Wake up the page daemon in vm_page_alloc_freelist() if the number of free
  and cached pages becomes too low.
  
  Tidy up vm_page_alloc_init().  In particular, add a comment about an
  important restriction on its use.
  
  Tested by:    jchandra@

Modified:
  head/sys/mips/mips/pmap.c
  head/sys/vm/vm_page.c

Modified: head/sys/mips/mips/pmap.c
==============================================================================
--- head/sys/mips/mips/pmap.c   Wed Nov  2 04:21:20 2011        (r227011)
+++ head/sys/mips/mips/pmap.c   Wed Nov  2 05:42:51 2011        (r227012)
@@ -1077,7 +1077,8 @@ pmap_alloc_direct_page(unsigned int inde
 {
        vm_page_t m;
 
-       m = vm_page_alloc_freelist(VM_FREELIST_DIRECT, req);
+       m = vm_page_alloc_freelist(VM_FREELIST_DIRECT, req | VM_ALLOC_WIRED |
+           VM_ALLOC_ZERO);
        if (m == NULL)
                return (NULL);
 
@@ -1085,8 +1086,6 @@ pmap_alloc_direct_page(unsigned int inde
                pmap_zero_page(m);
 
        m->pindex = index;
-       atomic_add_int(&cnt.v_wire_count, 1);
-       m->wire_count = 1;
        return (m);
 }
 

Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c       Wed Nov  2 04:21:20 2011        (r227011)
+++ head/sys/vm/vm_page.c       Wed Nov  2 05:42:51 2011        (r227012)
@@ -1482,6 +1482,8 @@ vm_page_alloc(vm_object_t object, vm_pin
  * Initialize a page that has been freshly dequeued from a freelist.
  * The caller has to drop the vnode returned, if it is not NULL.
  *
+ * This function may only be used to initialize unmanaged pages.
+ *
  * To be called with vm_page_queue_free_mtx held.
  */
 struct vnode *
@@ -1507,11 +1509,12 @@ vm_page_alloc_init(vm_page_t m)
        mtx_assert(&vm_page_queue_free_mtx, MA_OWNED);
        drop = NULL;
        if ((m->flags & PG_CACHED) != 0) {
+               KASSERT((m->flags & PG_ZERO) == 0,
+                   ("vm_page_alloc_init: cached page %p is PG_ZERO", m));
                m->valid = 0;
                m_object = m->object;
                vm_page_cache_remove(m);
-               if (m_object->type == OBJT_VNODE &&
-                   m_object->cache == NULL)
+               if (m_object->type == OBJT_VNODE && m_object->cache == NULL)
                        drop = m_object->handle;
        } else {
                KASSERT(VM_PAGE_IS_FREE(m),
@@ -1519,9 +1522,9 @@ vm_page_alloc_init(vm_page_t m)
                KASSERT(m->valid == 0,
                    ("vm_page_alloc_init: free page %p is valid", m));
                cnt.v_free_count--;
+               if ((m->flags & PG_ZERO) != 0)
+                       vm_page_zero_count--;
        }
-       if (m->flags & PG_ZERO)
-               vm_page_zero_count--;
        /* Don't clear the PG_ZERO flag; we'll need it later. */
        m->flags &= PG_ZERO;
        m->aflags = 0;
@@ -1532,16 +1535,28 @@ vm_page_alloc_init(vm_page_t m)
 
 /*
  *     vm_page_alloc_freelist:
- * 
- *     Allocate a page from the specified freelist.
- *     Only the ALLOC_CLASS values in req are honored, other request flags
- *     are ignored.
+ *
+ *     Allocate a physical page from the specified free page list.
+ *
+ *     The caller must always specify an allocation class.
+ *
+ *     allocation classes:
+ *     VM_ALLOC_NORMAL         normal process request
+ *     VM_ALLOC_SYSTEM         system *really* needs a page
+ *     VM_ALLOC_INTERRUPT      interrupt time request
+ *
+ *     optional allocation flags:
+ *     VM_ALLOC_WIRED          wire the allocated page
+ *     VM_ALLOC_ZERO           prefer a zeroed page
+ *
+ *     This routine may not sleep.
  */
 vm_page_t
 vm_page_alloc_freelist(int flind, int req)
 {
        struct vnode *drop;
        vm_page_t m;
+       u_int flags;
        int page_req;
 
        m = NULL;
@@ -1563,8 +1578,26 @@ vm_page_alloc_freelist(int flind, int re
        }
        drop = vm_page_alloc_init(m);
        mtx_unlock(&vm_page_queue_free_mtx);
-       if (drop)
+
+       /*
+        * Initialize the page.  Only the PG_ZERO flag is inherited.
+        */
+       flags = 0;
+       if ((req & VM_ALLOC_ZERO) != 0)
+               flags = PG_ZERO;
+       m->flags &= flags;
+       if ((req & VM_ALLOC_WIRED) != 0) {
+               /*
+                * The page lock is not required for wiring a page that does
+                * not belong to an object.
+                */
+               atomic_add_int(&cnt.v_wire_count, 1);
+               m->wire_count = 1;
+       }
+       if (drop != NULL)
                vdrop(drop);
+       if (vm_paging_needed())
+               pagedaemon_wakeup();
        return (m);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to