On Thu, Apr 28, 2022 at 12:28:45PM +0200, Martin Pieuchot wrote: > rw_enter(9) can sleep. When the lock is finally acquired by the > pagedaemon the previous check might no longer be true and the page > could be busy. In this case we shouldn't touch it. > > Diff below recheck for PG_BUSY after acquiring the lock and also > use a variable for the lock to reduce the differences with NetBSD. > > ok?
hep. ok semarie@ just cosmetic comment below, but if it makes the code diverges from NetBSD, feel free to ignore. > Index: uvm/uvm_pdaemon.c > =================================================================== > RCS file: /cvs/src/sys/uvm/uvm_pdaemon.c,v > retrieving revision 1.96 > diff -u -p -r1.96 uvm_pdaemon.c > --- uvm/uvm_pdaemon.c 11 Apr 2022 16:43:49 -0000 1.96 > +++ uvm/uvm_pdaemon.c 28 Apr 2022 10:22:52 -0000 > @@ -879,6 +879,8 @@ uvmpd_scan(void) > int free, inactive_shortage, swap_shortage, pages_freed; > struct vm_page *p, *nextpg; > struct uvm_object *uobj; > + struct vm_anon *anon; > + struct rwlock *slock; > boolean_t got_it; > > MUTEX_ASSERT_LOCKED(&uvm.pageqlock); > @@ -947,20 +949,34 @@ uvmpd_scan(void) > p != NULL && (inactive_shortage > 0 || swap_shortage > 0); > p = nextpg) { > nextpg = TAILQ_NEXT(p, pageq); > - > - /* skip this page if it's busy. */ > - if (p->pg_flags & PG_BUSY) > + if (p->pg_flags & PG_BUSY) { > continue; > + } > > - if (p->pg_flags & PQ_ANON) { > - KASSERT(p->uanon != NULL); > - if (rw_enter(p->uanon->an_lock, RW_WRITE|RW_NOSLEEP)) > + /* > + * lock the page's owner. > + */ > + if (p->uobject != NULL) { > + uobj = p->uobject; > + slock = uobj->vmobjlock; > + if (rw_enter(slock, RW_WRITE|RW_NOSLEEP)) { > continue; > + } > } else { > - KASSERT(p->uobject != NULL); > - if (rw_enter(p->uobject->vmobjlock, > - RW_WRITE|RW_NOSLEEP)) > + anon = p->uanon; > + KASSERT(p->uanon != NULL); > + slock = anon->an_lock; > + if (rw_enter(slock, RW_WRITE|RW_NOSLEEP)) { > continue; > + } > + } I would move the rw_enter() call after the if(p->pg_flags & PQ_ANON), for better readability. if (p->uobject != NULL) { uobj = p->uobject; slock = uobj->vmobjlock; } else { anon = p->uanon; KASSERT(p->uanon != NULL); slock = anon->an_lock; } if (rw_enter(slock, RW_WRITE|RW_NOSLEEP)) { continue; } > + > + /* > + * skip this page if it's busy. > + */ > + if ((p->pg_flags & PG_BUSY) != 0) { > + rw_exit(slock); > + continue; > } > > /* > @@ -997,10 +1013,11 @@ uvmpd_scan(void) > uvmexp.pddeact++; > inactive_shortage--; > } > - if (p->pg_flags & PQ_ANON) > - rw_exit(p->uanon->an_lock); > - else > - rw_exit(p->uobject->vmobjlock); > + > + /* > + * we're done with this page. > + */ > + rw_exit(slock); > } > } > > -- Sebastien Marie