svn commit: r290271 - stable/10/sys/vm

Konstantin Belousov kib at FreeBSD.org
Mon Nov 2 13:14:28 UTC 2015


Author: kib
Date: Mon Nov  2 13:14:27 2015
New Revision: 290271
URL: https://svnweb.freebsd.org/changeset/base/290271

Log:
  MFC r289496:
  Modify the 'unchanged' calculation bu dereferencing the marker tailq
  pointers, which is known to belong to the queue.

Modified:
  stable/10/sys/vm/vm_pageout.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/vm/vm_pageout.c
==============================================================================
--- stable/10/sys/vm/vm_pageout.c	Mon Nov  2 11:06:51 2015	(r290270)
+++ stable/10/sys/vm/vm_pageout.c	Mon Nov  2 13:14:27 2015	(r290271)
@@ -286,11 +286,21 @@ vm_pageout_fallback_object_lock(vm_page_
 	vm_page_lock(m);
 	vm_pagequeue_lock(pq);
 
-	/* Page queue might have changed. */
+	/*
+	 * The page's object might have changed, and/or the page might
+	 * have moved from its original position in the queue.  If the
+	 * page's object has changed, then the caller should abandon
+	 * processing the page because the wrong object lock was
+	 * acquired.  Use the marker's plinks.q, not the page's, to
+	 * determine if the page has been moved.  The state of the
+	 * page's plinks.q can be indeterminate; whereas, the marker's
+	 * plinks.q must be valid.
+	 */
 	*next = TAILQ_NEXT(&marker, plinks.q);
-	unchanged = (m->queue == queue &&
-		     m->object == object &&
-		     &marker == TAILQ_NEXT(m, plinks.q));
+	unchanged = m->object == object &&
+	    m == TAILQ_PREV(&marker, pglist, plinks.q);
+	KASSERT(!unchanged || m->queue == queue,
+	    ("page %p queue %d %d", m, queue, m->queue));
 	TAILQ_REMOVE(&pq->pq_pl, &marker, plinks.q);
 	return (unchanged);
 }
@@ -327,7 +337,9 @@ vm_pageout_page_lock(vm_page_t m, vm_pag
 
 	/* Page queue might have changed. */
 	*next = TAILQ_NEXT(&marker, plinks.q);
-	unchanged = (m->queue == queue && &marker == TAILQ_NEXT(m, plinks.q));
+	unchanged = m == TAILQ_PREV(&marker, pglist, plinks.q);
+	KASSERT(!unchanged || m->queue == queue,
+	    ("page %p queue %d %d", m, queue, m->queue));
 	TAILQ_REMOVE(&pq->pq_pl, &marker, plinks.q);
 	return (unchanged);
 }


More information about the svn-src-all mailing list