svn commit: r227012 - in head/sys: mips/mips vm
Alan Cox
alc at FreeBSD.org
Wed Nov 2 05:42:51 UTC 2011
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);
}
More information about the svn-src-all
mailing list