diff options
author | alc <alc@FreeBSD.org> | 2015-09-05 17:34:49 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2015-09-05 17:34:49 +0000 |
commit | 2a8ccb368f2422f28e8c147e0373d922672552d5 (patch) | |
tree | 32702b7a2e3e1a5139c6439f5600c230149bc800 | |
parent | e9883c17255ba7ab2db5451deeaf55e57f9cbfbb (diff) | |
download | FreeBSD-src-2a8ccb368f2422f28e8c147e0373d922672552d5.zip FreeBSD-src-2a8ccb368f2422f28e8c147e0373d922672552d5.tar.gz |
Eliminate pointless requeueing of pages from terminated objects. These
pages will have left the inactive queue before the page daemon performs
its next scan. Also, ignore references to pages from terminated objects.
This allows the clean pages to be freed a little sooner.
Move some comments to their proper place, i.e., next to the code that
they describe, and update other nearby comments.
Reviewed by: kib
Sponsored by: EMC / Isilon Storage Division
-rw-r--r-- | sys/vm/vm_pageout.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index f3c0d2c..c52b384 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1186,13 +1186,9 @@ unlock_page: } /* - * We bump the activation count if the page has been - * referenced while in the inactive queue. This makes - * it less likely that the page will be added back to the - * inactive queue prematurely again. Here we check the - * page tables (or emulated bits, if any), given the upper - * level VM system not knowing anything about existing - * references. + * If the page has been referenced and the object is not dead, + * reactivate or requeue the page depending on whether the + * object is mapped. */ if ((m->aflags & PGA_REFERENCED) != 0) { vm_page_aflag_clear(m, PGA_REFERENCED); @@ -1205,21 +1201,25 @@ unlock_page: KASSERT(!pmap_page_is_mapped(m), ("vm_pageout_scan: page %p is mapped", m)); } - - /* - * If the upper level VM system knows about any page - * references, we reactivate the page or requeue it. - */ if (act_delta != 0) { if (object->ref_count != 0) { vm_page_activate(m); + + /* + * Increase the activation count if the page + * was referenced while in the inactive queue. + * This makes it less likely that the page will + * be returned prematurely to the inactive + * queue. + */ m->act_count += act_delta + ACT_ADVANCE; - } else { + goto drop_page; + } else if ((object->flags & OBJ_DEAD) == 0) { vm_pagequeue_lock(pq); queues_locked = TRUE; vm_page_requeue_locked(m); + goto drop_page; } - goto drop_page; } /* @@ -1243,6 +1243,15 @@ unlock_page: vm_page_free(m); PCPU_INC(cnt.v_dfree); --page_shortage; + } else if ((object->flags & OBJ_DEAD) != 0) { + /* + * Leave dirty pages from dead objects at the front of + * the queue. They are being paged out and freed by + * the thread that destroyed the object. They will + * leave the queue shortly after the scan finishes, so + * they should be discounted from the inactive count. + */ + addl_page_shortage++; } else if ((m->flags & PG_WINATCFLS) == 0 && pass < 2) { /* * Dirty pages need to be paged out, but flushing @@ -1278,18 +1287,11 @@ unlock_page: pageout_ok = vm_page_count_min(); else pageout_ok = TRUE; - - /* - * We don't bother paging objects that are "dead". - * Those objects are in a "rundown" state. - */ - if (!pageout_ok || (object->flags & OBJ_DEAD) != 0) { + if (!pageout_ok) { vm_pagequeue_lock(pq); - vm_page_unlock(m); - VM_OBJECT_WUNLOCK(object); queues_locked = TRUE; vm_page_requeue_locked(m); - goto relock_queues; + goto drop_page; } error = vm_pageout_clean(m); /* |