Download raw body.
KASSERT "uvmexp.swpgonly > 0" in uvm_anfree_list()
> Date: Fri, 5 Apr 2024 16:27:14 +0200 > From: Martin Pieuchot <mpi@openbsd.org> > > Many over the past months have reported this assertion in different > scenarios. All of them involved swapping some pages. > > I figured out that it is due to an accounting bug in uvm_anon_release(). > When that function is called, the given anon has a page attached and it > might also have an allocated swap slot. > > The accounting bugs occurs only when an anon has such allocated swap slot. > In such case the wrong path is taken inside uvm_anfree() because `an_page' > has been cleared by uvm_pagefree() and the global `uvmexp.swpgonly' counter > is decremented. > > Diff below fixes it. Ok? ok kettenis@ > Index: uvm/uvm_anon.c > =================================================================== > RCS file: /cvs/src/sys/uvm/uvm_anon.c,v > diff -u -p -r1.57 uvm_anon.c > --- uvm/uvm_anon.c 27 Oct 2023 19:13:51 -0000 1.57 > +++ uvm/uvm_anon.c 31 Mar 2024 06:49:40 -0000 > @@ -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); > >
KASSERT "uvmexp.swpgonly > 0" in uvm_anfree_list()