Prevent accounting bug when an anon w/ swap slot is passed to uvm_anon_release()
authormpi <mpi@openbsd.org>
Sat, 6 Apr 2024 10:59:52 +0000 (10:59 +0000)
committermpi <mpi@openbsd.org>
Sat, 6 Apr 2024 10:59:52 +0000 (10:59 +0000)
uvm_anon_release() is always called for anon that have an associated page so
decrementing `uvmexp.swpgonly' is incorrect.  This happened because the page
was cleared before calling uvm_anfree().

Reported by many including mvs@, miod@ and robert@

ok kettenis@, miod@

sys/uvm/uvm_anon.c

index 4c4bf8e..0fc2a0c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_anon.c,v 1.57 2023/10/27 19:13:51 mpi Exp $       */
+/*     $OpenBSD: uvm_anon.c,v 1.58 2024/04/06 10:59:52 mpi Exp $       */
 /*     $NetBSD: uvm_anon.c,v 1.10 2000/11/25 06:27:59 chs Exp $        */
 
 /*
@@ -260,7 +260,8 @@ uvm_anon_release(struct vm_anon *anon)
        uvm_unlock_pageq();
        KASSERT(anon->an_page == NULL);
        lock = anon->an_lock;
-       uvm_anfree(anon);
+       uvm_anon_dropswap(anon);
+       pool_put(&uvm_anon_pool, anon);
        rw_exit(lock);
        /* Note: extra reference is held for PG_RELEASED case. */
        rw_obj_free(lock);