svn commit: r331444 - user/markj/vm-playground/sys/vm

Jeff Roberson jeff at FreeBSD.org
Fri Mar 23 17:58:34 UTC 2018


Author: jeff
Date: Fri Mar 23 17:58:33 2018
New Revision: 331444
URL: https://svnweb.freebsd.org/changeset/base/331444

Log:
  Re-implement vm_pageout_free_pages().

Modified:
  user/markj/vm-playground/sys/vm/vm_pageout.c

Modified: user/markj/vm-playground/sys/vm/vm_pageout.c
==============================================================================
--- user/markj/vm-playground/sys/vm/vm_pageout.c	Fri Mar 23 17:33:14 2018	(r331443)
+++ user/markj/vm-playground/sys/vm/vm_pageout.c	Fri Mar 23 17:58:33 2018	(r331444)
@@ -1126,6 +1126,65 @@ dolaundry:
 	}
 }
 
+static int
+vm_pageout_free_pages(vm_object_t object, vm_page_t m, struct mtx **mtxp)
+{
+	vm_page_t p, pp;
+	vm_pindex_t start;
+	int pcount, count;
+
+	pcount = MAX(object->iosize / PAGE_SIZE, 1);
+	count = 1;
+	if (pcount == 1) {
+		vm_page_free(m);
+		goto out;
+	}
+
+	/* Find the first page in the block. */
+	start = m->pindex - (m->pindex % pcount);
+	for (p = m; p->pindex > start && (pp = vm_page_prev(p)) != NULL; 
+	    p = pp);
+
+	/* Free the original page so we don't validate it twice. */
+	if (p == m)
+		p = vm_page_next(m);
+	vm_page_free(m);
+	/* Iterate through the block range and free compatible pages. */
+	/* XXX Fix cache miss on last page. */
+	for (m = p; m != NULL && m->pindex < start + pcount; m = p) {
+		p = TAILQ_NEXT(m, listq);
+		vm_page_change_lock(m, mtxp);
+		if (vm_page_held(m) || vm_page_busied(m) ||
+		    m->queue != PQ_INACTIVE)
+			continue;
+		if (m->valid == 0)
+			goto free_page;
+		if ((m->aflags & PGA_REFERENCED) != 0)
+			continue;
+		if (object->ref_count != 0) {
+			if (pmap_ts_referenced(m)) {
+				vm_page_aflag_set(m, PGA_REFERENCED);
+				continue;
+			}
+			vm_page_test_dirty(m);
+			if (m->dirty == 0)
+				pmap_remove_all(m);
+		}
+		if (m->dirty) {
+			if ((object->flags & OBJ_DEAD) == 0)
+				vm_page_launder(m);
+			continue;
+		}
+free_page:
+		vm_page_free(m);
+		count++;
+	}
+out:
+	VM_CNT_ADD(v_dfree, count);
+
+	return (count);
+}
+
 /*
  *	vm_pageout_scan does the dirty work for the pageout daemon.
  *
@@ -1364,9 +1423,8 @@ recheck:
 			 */
 			if (m->dirty == 0) {
 free_page:
-				vm_page_free(m);
-				page_shortage--;
-				VM_CNT_INC(v_dfree);
+				page_shortage -= vm_pageout_free_pages(object,
+				    m, &mtx);
 			} else if ((object->flags & OBJ_DEAD) == 0)
 				vm_page_launder(m);
 			continue;


More information about the svn-src-user mailing list