Revert previous: unref of amap outside of the KERNEL_LOCK().
authormpi <mpi@openbsd.org>
Thu, 17 Jun 2021 16:10:39 +0000 (16:10 +0000)
committermpi <mpi@openbsd.org>
Thu, 17 Jun 2021 16:10:39 +0000 (16:10 +0000)
This change introduced or exposed a leak of anons which result in system
freezes.

anton@ observed a high number of INUSE for anonpl and semarie@ saw multiple
processes waiting in the fault handler on "flt_noramX" probably the one
related to allocating an anon.

sys/uvm/uvm_map.c

index fad8303..3c4e885 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_map.c,v 1.276 2021/06/15 16:35:21 mpi Exp $       */
+/*     $OpenBSD: uvm_map.c,v 1.277 2021/06/17 16:10:39 mpi Exp $       */
 /*     $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
 
 /*
@@ -1571,16 +1571,10 @@ uvm_unmap_detach(struct uvm_map_deadq *deadq, int flags)
 
        TAILQ_FOREACH_SAFE(entry, deadq, dfree.deadq, tmp) {
                /* Skip entries for which we have to grab the kernel lock. */
-               if (UVM_ET_ISSUBMAP(entry) || UVM_ET_ISOBJ(entry))
+               if (entry->aref.ar_amap || UVM_ET_ISSUBMAP(entry) ||
+                   UVM_ET_ISOBJ(entry))
                        continue;
 
-               /* Drop reference to amap, if we've got one. */
-               if (entry->aref.ar_amap)
-                       amap_unref(entry->aref.ar_amap,
-                           entry->aref.ar_pageoff,
-                           atop(entry->end - entry->start),
-                           flags & AMAP_REFALL);
-
                TAILQ_REMOVE(deadq, entry, dfree.deadq);
                uvm_mapent_free(entry);
        }
@@ -1592,6 +1586,12 @@ uvm_unmap_detach(struct uvm_map_deadq *deadq, int flags)
        while ((entry = TAILQ_FIRST(deadq)) != NULL) {
                if (waitok)
                        uvm_pause();
+               /* Drop reference to amap, if we've got one. */
+               if (entry->aref.ar_amap)
+                       amap_unref(entry->aref.ar_amap,
+                           entry->aref.ar_pageoff,
+                           atop(entry->end - entry->start),
+                           flags & AMAP_REFALL);
 
                /* Drop reference to our backing object, if we've got one. */
                if (UVM_ET_ISSUBMAP(entry)) {