svn commit: r323804 - stable/11/sys/vm
Konstantin Belousov
kib at FreeBSD.org
Wed Sep 20 09:29:04 UTC 2017
Author: kib
Date: Wed Sep 20 09:29:03 2017
New Revision: 323804
URL: https://svnweb.freebsd.org/changeset/base/323804
Log:
MFC r323561:
Do not relock free queue mutex for each page, free whole terminating
object' page queue under the single mutex lock.
Modified:
stable/11/sys/vm/vm_object.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/vm/vm_object.c
==============================================================================
--- stable/11/sys/vm/vm_object.c Wed Sep 20 09:22:47 2017 (r323803)
+++ stable/11/sys/vm/vm_object.c Wed Sep 20 09:29:03 2017 (r323804)
@@ -713,9 +713,14 @@ static void
vm_object_terminate_pages(vm_object_t object)
{
vm_page_t p, p_next;
+ struct mtx *mtx, *mtx1;
+ struct vm_pagequeue *pq, *pq1;
VM_OBJECT_ASSERT_WLOCKED(object);
+ mtx = NULL;
+ pq = NULL;
+
/*
* Free any remaining pageable pages. This also removes them from the
* paging queues. However, don't free wired pages, just remove them
@@ -724,21 +729,51 @@ vm_object_terminate_pages(vm_object_t object)
*/
TAILQ_FOREACH_SAFE(p, &object->memq, listq, p_next) {
vm_page_assert_unbusied(p);
- vm_page_lock(p);
- /*
- * Optimize the page's removal from the object by resetting
- * its "object" field. Specifically, if the page is not
- * wired, then the effect of this assignment is that
- * vm_page_free()'s call to vm_page_remove() will return
- * immediately without modifying the page or the object.
- */
+ if ((object->flags & OBJ_UNMANAGED) == 0) {
+ /*
+ * vm_page_free_prep() only needs the page
+ * lock for managed pages.
+ */
+ mtx1 = vm_page_lockptr(p);
+ if (mtx1 != mtx) {
+ if (mtx != NULL)
+ mtx_unlock(mtx);
+ if (pq != NULL) {
+ vm_pagequeue_unlock(pq);
+ pq = NULL;
+ }
+ mtx = mtx1;
+ mtx_lock(mtx);
+ }
+ }
p->object = NULL;
- if (p->wire_count == 0) {
- vm_page_free(p);
- PCPU_INC(cnt.v_pfree);
+ if (p->wire_count != 0)
+ goto unlist;
+ PCPU_INC(cnt.v_pfree);
+ p->flags &= ~PG_ZERO;
+ if (p->queue != PQ_NONE) {
+ KASSERT(p->queue < PQ_COUNT, ("vm_object_terminate: "
+ "page %p is not queued", p));
+ pq1 = vm_page_pagequeue(p);
+ if (pq != pq1) {
+ if (pq != NULL)
+ vm_pagequeue_unlock(pq);
+ pq = pq1;
+ vm_pagequeue_lock(pq);
+ }
}
- vm_page_unlock(p);
+ if (vm_page_free_prep(p, true))
+ continue;
+unlist:
+ TAILQ_REMOVE(&object->memq, p, listq);
}
+ if (pq != NULL)
+ vm_pagequeue_unlock(pq);
+ if (mtx != NULL)
+ mtx_unlock(mtx);
+
+ vm_page_free_phys_pglist(&object->memq);
+
/*
* If the object contained any pages, then reset it to an empty state.
* None of the object's fields, including "resident_page_count", were
More information about the svn-src-stable
mailing list