Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Oct 2019 03:48:22 +0000 (UTC)
From:      Jeff Roberson <jeff@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r353540 - head/sys/vm
Message-ID:  <201910150348.x9F3mMkk028943@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jeff
Date: Tue Oct 15 03:48:22 2019
New Revision: 353540
URL: https://svnweb.freebsd.org/changeset/base/353540

Log:
  (5/6) Move the VPO_NOSYNC to PGA_NOSYNC to eliminate the dependency on the
  object lock in vm_page_set_validclean().
  
  Reviewed by:    kib, markj
  Tested by:      pho
  Sponsored by:   Netflix, Intel
  Differential Revision:	https://reviews.freebsd.org/D21595

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

Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c	Tue Oct 15 03:45:41 2019	(r353539)
+++ head/sys/vm/vm_fault.c	Tue Oct 15 03:48:22 2019	(r353540)
@@ -225,15 +225,14 @@ vm_fault_dirty(vm_map_entry_t entry, vm_page_t m, vm_p
 		 * FALSE, one for the map entry with MAP_ENTRY_NOSYNC
 		 * flag set, other with flag clear, race, it is
 		 * possible for the no-NOSYNC thread to see m->dirty
-		 * != 0 and not clear VPO_NOSYNC.  Take vm_page lock
-		 * around manipulation of VPO_NOSYNC and
-		 * vm_page_dirty() call, to avoid the race and keep
-		 * m->oflags consistent.
+		 * != 0 and not clear PGA_NOSYNC.  Take vm_page lock
+		 * around manipulation of PGA_NOSYNC and
+		 * vm_page_dirty() call to avoid the race.
 		 */
 		vm_page_lock(m);
 
 	/*
-	 * If this is a NOSYNC mmap we do not want to set VPO_NOSYNC
+	 * If this is a NOSYNC mmap we do not want to set PGA_NOSYNC
 	 * if the page is already dirty to prevent data written with
 	 * the expectation of being synced from not being synced.
 	 * Likewise if this entry does not request NOSYNC then make
@@ -242,10 +241,10 @@ vm_fault_dirty(vm_map_entry_t entry, vm_page_t m, vm_p
 	 */
 	if ((entry->eflags & MAP_ENTRY_NOSYNC) != 0) {
 		if (m->dirty == 0) {
-			m->oflags |= VPO_NOSYNC;
+			vm_page_aflag_set(m, PGA_NOSYNC);
 		}
 	} else {
-		m->oflags &= ~VPO_NOSYNC;
+		vm_page_aflag_clear(m, PGA_NOSYNC);
 	}
 
 	/*

Modified: head/sys/vm/vm_object.c
==============================================================================
--- head/sys/vm/vm_object.c	Tue Oct 15 03:45:41 2019	(r353539)
+++ head/sys/vm/vm_object.c	Tue Oct 15 03:48:22 2019	(r353540)
@@ -772,12 +772,14 @@ static boolean_t
 vm_object_page_remove_write(vm_page_t p, int flags, boolean_t *clearobjflags)
 {
 
+	vm_page_assert_busied(p);
+
 	/*
 	 * If we have been asked to skip nosync pages and this is a
 	 * nosync page, skip it.  Note that the object flags were not
 	 * cleared in this case so we do not have to set them.
 	 */
-	if ((flags & OBJPC_NOSYNC) != 0 && (p->oflags & VPO_NOSYNC) != 0) {
+	if ((flags & OBJPC_NOSYNC) != 0 && (p->aflags & PGA_NOSYNC) != 0) {
 		*clearobjflags = FALSE;
 		return (FALSE);
 	} else {
@@ -791,7 +793,7 @@ vm_object_page_remove_write(vm_page_t p, int flags, bo
  *
  *	Clean all dirty pages in the specified range of object.  Leaves page 
  * 	on whatever queue it is currently on.   If NOSYNC is set then do not
- *	write out pages with VPO_NOSYNC set (originally comes from MAP_NOSYNC),
+ *	write out pages with PGA_NOSYNC set (originally comes from MAP_NOSYNC),
  *	leaving the object dirty.
  *
  *	When stuffing pages asynchronously, allow clustering.  XXX we need a
@@ -2270,7 +2272,6 @@ void
 vm_object_unbusy(vm_object_t obj)
 {
 
-	VM_OBJECT_ASSERT_LOCKED(obj);
 
 	refcount_release(&obj->busy);
 }

Modified: head/sys/vm/vm_object.h
==============================================================================
--- head/sys/vm/vm_object.h	Tue Oct 15 03:45:41 2019	(r353539)
+++ head/sys/vm/vm_object.h	Tue Oct 15 03:48:22 2019	(r353540)
@@ -209,7 +209,7 @@ struct vm_object {
 
 #define OBJPC_SYNC	0x1			/* sync I/O */
 #define OBJPC_INVAL	0x2			/* invalidate */
-#define OBJPC_NOSYNC	0x4			/* skip if VPO_NOSYNC */
+#define OBJPC_NOSYNC	0x4			/* skip if PGA_NOSYNC */
 
 /*
  * The following options are supported by vm_object_page_remove().

Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c	Tue Oct 15 03:45:41 2019	(r353539)
+++ head/sys/vm/vm_page.c	Tue Oct 15 03:48:22 2019	(r353540)
@@ -2506,7 +2506,7 @@ retry:
 				KASSERT((m->oflags & (VPO_SWAPINPROG |
 				    VPO_SWAPSLEEP | VPO_UNMANAGED)) == 0,
 				    ("page %p has unexpected oflags", m));
-				/* Don't care: VPO_NOSYNC. */
+				/* Don't care: PGA_NOSYNC. */
 				run_ext = 1;
 			} else
 				run_ext = 0;
@@ -2655,7 +2655,7 @@ retry:
 				KASSERT((m->oflags & (VPO_SWAPINPROG |
 				    VPO_SWAPSLEEP | VPO_UNMANAGED)) == 0,
 				    ("page %p has unexpected oflags", m));
-				/* Don't care: VPO_NOSYNC. */
+				/* Don't care: PGA_NOSYNC. */
 				if (!vm_page_none_valid(m)) {
 					/*
 					 * First, try to allocate a new page
@@ -2721,7 +2721,6 @@ retry:
 					    ~PGA_QUEUE_STATE_MASK;
 					KASSERT(m_new->oflags == VPO_UNMANAGED,
 					    ("page %p is managed", m_new));
-					m_new->oflags = m->oflags & VPO_NOSYNC;
 					pmap_copy_page(m, m_new);
 					m_new->valid = m->valid;
 					m_new->dirty = m->dirty;
@@ -4703,8 +4702,6 @@ vm_page_set_validclean(vm_page_t m, int base, int size
 	vm_page_bits_t oldvalid, pagebits;
 	int endoff, frag;
 
-	/* Object lock for VPO_NOSYNC */
-	VM_OBJECT_ASSERT_WLOCKED(m->object);
 	vm_page_assert_busied(m);
 	if (size == 0)	/* handle degenerate case */
 		return;
@@ -4732,7 +4729,7 @@ vm_page_set_validclean(vm_page_t m, int base, int size
 	/*
 	 * Set valid, clear dirty bits.  If validating the entire
 	 * page we can safely clear the pmap modify bit.  We also
-	 * use this opportunity to clear the VPO_NOSYNC flag.  If a process
+	 * use this opportunity to clear the PGA_NOSYNC flag.  If a process
 	 * takes a write fault on a MAP_NOSYNC memory area the flag will
 	 * be set again.
 	 *
@@ -4773,7 +4770,7 @@ vm_page_set_validclean(vm_page_t m, int base, int size
 			 */
 			pmap_clear_modify(m);
 		m->dirty = 0;
-		m->oflags &= ~VPO_NOSYNC;
+		vm_page_aflag_clear(m, PGA_NOSYNC);
 	} else if (oldvalid != VM_PAGE_BITS_ALL && vm_page_xbusied(m))
 		m->dirty &= ~pagebits;
 	else

Modified: head/sys/vm/vm_page.h
==============================================================================
--- head/sys/vm/vm_page.h	Tue Oct 15 03:45:41 2019	(r353539)
+++ head/sys/vm/vm_page.h	Tue Oct 15 03:48:22 2019	(r353540)
@@ -287,7 +287,6 @@ struct vm_page {
 #define	VPO_SWAPSLEEP	0x02		/* waiting for swap to finish */
 #define	VPO_UNMANAGED	0x04		/* no PV management for page */
 #define	VPO_SWAPINPROG	0x08		/* swap I/O in progress on page */
-#define	VPO_NOSYNC	0x10		/* do not collect for syncer */
 
 /*
  * Busy page implementation details.
@@ -390,6 +389,8 @@ extern struct mtx_padalign pa_lock[];
  * PGA_EXECUTABLE may be set by pmap routines, and indicates that a page has
  * at least one executable mapping.  It is not consumed by the MI VM layer.
  *
+ * PGA_NOSYNC must be set and cleared with the page busy lock held.
+ *
  * PGA_ENQUEUED is set and cleared when a page is inserted into or removed
  * from a page queue, respectively.  It determines whether the plinks.q field
  * of the page is valid.  To set or clear this flag, the queue lock for the
@@ -420,6 +421,7 @@ extern struct mtx_padalign pa_lock[];
 #define	PGA_DEQUEUE	0x10		/* page is due to be dequeued */
 #define	PGA_REQUEUE	0x20		/* page is due to be requeued */
 #define	PGA_REQUEUE_HEAD 0x40		/* page requeue should bypass LRU */
+#define	PGA_NOSYNC	0x80		/* do not collect for syncer */
 
 #define	PGA_QUEUE_STATE_MASK	(PGA_ENQUEUED | PGA_DEQUEUE | PGA_REQUEUE | \
 				PGA_REQUEUE_HEAD)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910150348.x9F3mMkk028943>