svn commit: r333703 - head/sys/vm

Mark Johnston markj at FreeBSD.org
Thu May 17 04:27:09 UTC 2018


Author: markj
Date: Thu May 17 04:27:08 2018
New Revision: 333703
URL: https://svnweb.freebsd.org/changeset/base/333703

Log:
  Fix a race in vm_page_pagequeue_lockptr().
  
  The value of m->queue must be cached after comparing it with PQ_NONE,
  since it may be concurrently changing.
  
  Reported by:	glebius
  Reviewed by:	jeff
  Differential Revision:	https://reviews.freebsd.org/D15462

Modified:
  head/sys/vm/vm_page.c
  head/sys/vm/vm_page.h

Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c	Thu May 17 04:08:57 2018	(r333702)
+++ head/sys/vm/vm_page.c	Thu May 17 04:27:08 2018	(r333703)
@@ -3088,10 +3088,11 @@ vm_page_pagequeue(vm_page_t m)
 static struct mtx *
 vm_page_pagequeue_lockptr(vm_page_t m)
 {
+	uint8_t queue;
 
-	if (m->queue == PQ_NONE)
+	if ((queue = m->queue) == PQ_NONE)
 		return (NULL);
-	return (&vm_page_pagequeue(m)->pq_mutex);
+	return (&vm_pagequeue_domain(m)->vmd_pagequeues[queue].pq_mutex);
 }
 
 static inline void

Modified: head/sys/vm/vm_page.h
==============================================================================
--- head/sys/vm/vm_page.h	Thu May 17 04:08:57 2018	(r333702)
+++ head/sys/vm/vm_page.h	Thu May 17 04:27:08 2018	(r333703)
@@ -208,7 +208,7 @@ struct vm_page {
 	uint16_t flags;			/* page PG_* flags (P) */
 	uint8_t aflags;			/* access is atomic */
 	uint8_t oflags;			/* page VPO_* flags (O) */
-	uint8_t	queue;			/* page queue index (Q) */
+	volatile uint8_t queue;		/* page queue index (Q) */
 	int8_t psind;			/* pagesizes[] index (O) */
 	int8_t segind;			/* vm_phys segment index (C) */
 	uint8_t	order;			/* index of the buddy queue (F) */


More information about the svn-src-head mailing list