Date: Wed, 2 Nov 2011 05:42:51 +0000 (UTC) From: Alan Cox <alc@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r227012 - in head/sys: mips/mips vm Message-ID: <201111020542.pA25gpAi002096@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111020542.pA25gpAi002096>