Unref/free amaps before grabbing the KERNEL_LOCK().
authormpi <mpi@openbsd.org>
Tue, 5 Oct 2021 15:37:21 +0000 (15:37 +0000)
committermpi <mpi@openbsd.org>
Tue, 5 Oct 2021 15:37:21 +0000 (15:37 +0000)
This is possible now that amaps & anons are protected by a per-map rwlock.

Tested by many as part of a bigger diff.

ok kettenis@

sys/uvm/uvm_map.c

index 3c4e885..e36c761 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_map.c,v 1.277 2021/06/17 16:10:39 mpi Exp $       */
+/*     $OpenBSD: uvm_map.c,v 1.278 2021/10/05 15:37:21 mpi Exp $       */
 /*     $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
 
 /*
@@ -1570,9 +1570,15 @@ uvm_unmap_detach(struct uvm_map_deadq *deadq, int flags)
        int waitok = flags & UVM_PLA_WAITOK;
 
        TAILQ_FOREACH_SAFE(entry, deadq, dfree.deadq, tmp) {
+               /* 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);
+
                /* Skip entries for which we have to grab the kernel lock. */
-               if (entry->aref.ar_amap || UVM_ET_ISSUBMAP(entry) ||
-                   UVM_ET_ISOBJ(entry))
+               if (UVM_ET_ISSUBMAP(entry) || UVM_ET_ISOBJ(entry))
                        continue;
 
                TAILQ_REMOVE(deadq, entry, dfree.deadq);
@@ -1586,13 +1592,6 @@ 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)) {
                        /* ... unlikely to happen, but play it safe */