summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2017-10-07 17:20:31 +0000
committerLuiz Souza <luiz@netgate.com>2018-02-21 15:14:38 -0300
commit77c23f6c7df09a861b606acaa485ba1ab8883533 (patch)
tree3266ac58ca9f0ed4f85fe6f3eb4c6a8c53936086 /sys/vm
parent12f2f0718d897b1324f4d7e1a3b6319e21d32a17 (diff)
downloadFreeBSD-src-77c23f6c7df09a861b606acaa485ba1ab8883533.zip
FreeBSD-src-77c23f6c7df09a861b606acaa485ba1ab8883533.tar.gz
MFC r323973,324087
Optimize vm_page_try_to_free(). Specifically, the call to pmap_remove_all() can be avoided when the page's containing object has a reference count of zero. (If the object has a reference count of zero, then none of its pages can possibly be mapped.) Address nearby style issues in vm_page_try_to_free(), and change its return type to "bool". Optimize vm_object_page_remove() by eliminating pointless calls to pmap_remove_all(). If the object to which a page belongs has no references, then that page cannot possibly be mapped. (cherry picked from commit 2d2427db5b735ecdb6fe8ad9251f524b4260bb6a)
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_object.c10
-rw-r--r--sys/vm/vm_page.c20
-rw-r--r--sys/vm/vm_page.h2
3 files changed, 18 insertions, 14 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index ccac79a..c7c5dfa 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -1934,7 +1934,8 @@ again:
goto again;
}
if (p->wire_count != 0) {
- if ((options & OBJPR_NOTMAPPED) == 0)
+ if ((options & OBJPR_NOTMAPPED) == 0 &&
+ object->ref_count != 0)
pmap_remove_all(p);
if ((options & OBJPR_CLEANONLY) == 0) {
p->valid = 0;
@@ -1951,12 +1952,13 @@ again:
KASSERT((p->flags & PG_FICTITIOUS) == 0,
("vm_object_page_remove: page %p is fictitious", p));
if ((options & OBJPR_CLEANONLY) != 0 && p->valid != 0) {
- if ((options & OBJPR_NOTMAPPED) == 0)
+ if ((options & OBJPR_NOTMAPPED) == 0 &&
+ object->ref_count != 0)
pmap_remove_write(p);
- if (p->dirty)
+ if (p->dirty != 0)
continue;
}
- if ((options & OBJPR_NOTMAPPED) == 0)
+ if ((options & OBJPR_NOTMAPPED) == 0 && object->ref_count != 0)
pmap_remove_all(p);
vm_page_free(p);
}
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 08203f2..155d1a8 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -3056,23 +3056,25 @@ vm_page_launder(vm_page_t m)
* vm_page_try_to_free()
*
* Attempt to free the page. If we cannot free it, we do nothing.
- * 1 is returned on success, 0 on failure.
+ * true is returned on success, false on failure.
*/
-int
+bool
vm_page_try_to_free(vm_page_t m)
{
- vm_page_lock_assert(m, MA_OWNED);
+ vm_page_assert_locked(m);
if (m->object != NULL)
VM_OBJECT_ASSERT_WLOCKED(m->object);
- if (m->dirty || m->hold_count || m->wire_count ||
+ if (m->dirty != 0 || m->hold_count != 0 || m->wire_count != 0 ||
(m->oflags & VPO_UNMANAGED) != 0 || vm_page_busied(m))
- return (0);
- pmap_remove_all(m);
- if (m->dirty)
- return (0);
+ return (false);
+ if (m->object != NULL && m->object->ref_count != 0) {
+ pmap_remove_all(m);
+ if (m->dirty != 0)
+ return (false);
+ }
vm_page_free(m);
- return (1);
+ return (true);
}
/*
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 3cc0fee..e0ae041 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -456,7 +456,6 @@ void vm_page_change_lock(vm_page_t m, struct mtx **mtx);
vm_page_t vm_page_grab (vm_object_t, vm_pindex_t, int);
int vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags,
vm_page_t *ma, int count);
-int vm_page_try_to_free (vm_page_t);
void vm_page_deactivate (vm_page_t);
void vm_page_deactivate_noreuse(vm_page_t);
void vm_page_dequeue(vm_page_t m);
@@ -492,6 +491,7 @@ void vm_page_set_valid_range(vm_page_t m, int base, int size);
int vm_page_sleep_if_busy(vm_page_t m, const char *msg);
vm_offset_t vm_page_startup(vm_offset_t vaddr);
void vm_page_sunbusy(vm_page_t m);
+bool vm_page_try_to_free(vm_page_t m);
int vm_page_trysbusy(vm_page_t m);
void vm_page_unhold_pages(vm_page_t *ma, int count);
boolean_t vm_page_unwire(vm_page_t m, uint8_t queue);
OpenPOWER on IntegriCloud