Author: markj
Date: Mon Sep 16 15:09:31 2019
New Revision: 352409
URL: https://svnweb.freebsd.org/changeset/base/352409

Log:
  Fix a page leak in vm_page_reclaim_run().
  
  After r352110 the attempt to remove mappings of the page being replaced
  may fail if the page is wired.  In this case we must free the replacement
  page.
  
  Reviewed by:  alc, kib
  Sponsored by: Netflix
  Differential Revision:        https://reviews.freebsd.org/D21639

Modified:
  head/sys/vm/vm_page.c

Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c       Mon Sep 16 15:06:19 2019        (r352408)
+++ head/sys/vm/vm_page.c       Mon Sep 16 15:09:31 2019        (r352409)
@@ -2597,16 +2597,23 @@ retry:
                                        }
 
                                        /*
-                                        * Replace "m" with the new page.  For
-                                        * vm_page_replace(), "m" must be busy
-                                        * and dequeued.  Finally, change "m"
-                                        * as if vm_page_free() was called.
+                                        * Unmap the page and check for new
+                                        * wirings that may have been acquired
+                                        * through a pmap lookup.
                                         */
                                        if (object->ref_count != 0 &&
                                            !vm_page_try_remove_all(m)) {
+                                               vm_page_free(m_new);
                                                error = EBUSY;
                                                goto unlock;
                                        }
+
+                                       /*
+                                        * Replace "m" with the new page.  For
+                                        * vm_page_replace(), "m" must be busy
+                                        * and dequeued.  Finally, change "m"
+                                        * as if vm_page_free() was called.
+                                        */
                                        m_new->aflags = m->aflags &
                                            ~PGA_QUEUE_STATE_MASK;
                                        KASSERT(m_new->oflags == VPO_UNMANAGED,
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to