diff options
author | alc <alc@FreeBSD.org> | 2013-06-10 01:48:21 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2013-06-10 01:48:21 +0000 |
commit | 53ffec3a56d5ab2cc946cc172c6d2ee82170f189 (patch) | |
tree | f2a0c8780bba045aedb1ca3a44f475c8509be627 /sys/vm/vm_page.c | |
parent | ac0545a5fe5499c5778d468bbe69f9267b5cfeec (diff) | |
download | FreeBSD-src-53ffec3a56d5ab2cc946cc172c6d2ee82170f189.zip FreeBSD-src-53ffec3a56d5ab2cc946cc172c6d2ee82170f189.tar.gz |
Revise the interface between vm_object_madvise() and vm_page_dontneed() so
that pointless calls to pmap_is_modified() can be easily avoided when
performing madvise(..., MADV_FREE).
Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'sys/vm/vm_page.c')
-rw-r--r-- | sys/vm/vm_page.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 300b20a..2dde31f 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/limits.h> #include <sys/malloc.h> +#include <sys/mman.h> #include <sys/msgbuf.h> #include <sys/mutex.h> #include <sys/proc.h> @@ -2238,15 +2239,15 @@ vm_page_cache(vm_page_t m) } /* - * vm_page_dontneed + * vm_page_advise * * Cache, deactivate, or do nothing as appropriate. This routine - * is typically used by madvise() MADV_DONTNEED. + * is used by madvise(). * * Generally speaking we want to move the page into the cache so * it gets reused quickly. However, this can result in a silly syndrome * due to the page recycling too quickly. Small objects will not be - * fully cached. On the otherhand, if we move the page to the inactive + * fully cached. On the other hand, if we move the page to the inactive * queue we wind up with a problem whereby very large objects * unnecessarily blow away our inactive and cache queues. * @@ -2261,13 +2262,31 @@ vm_page_cache(vm_page_t m) * The object and page must be locked. */ void -vm_page_dontneed(vm_page_t m) +vm_page_advise(vm_page_t m, int advice) { - int dnw; - int head; + int dnw, head; - vm_page_lock_assert(m, MA_OWNED); + vm_page_assert_locked(m); VM_OBJECT_ASSERT_WLOCKED(m->object); + if (advice == MADV_FREE) { + /* + * Mark the page clean. This will allow the page to be freed + * up by the system. However, such pages are often reused + * quickly by malloc() so we do not do anything that would + * cause a page fault if we can help it. + * + * Specifically, we do not try to actually free the page now + * nor do we try to put it in the cache (which would cause a + * page fault on reuse). + * + * But we do make the page is freeable as we can without + * actually taking the step of unmapping it. + */ + pmap_clear_modify(m); + m->dirty = 0; + m->act_count = 0; + } else if (advice != MADV_DONTNEED) + return; dnw = PCPU_GET(dnweight); PCPU_INC(dnweight); @@ -2294,7 +2313,7 @@ vm_page_dontneed(vm_page_t m) pmap_clear_reference(m); vm_page_aflag_clear(m, PGA_REFERENCED); - if (m->dirty == 0 && pmap_is_modified(m)) + if (advice != MADV_FREE && m->dirty == 0 && pmap_is_modified(m)) vm_page_dirty(m); if (m->dirty || (dnw & 0x0070) == 0) { |