> Date: Wed, 4 May 2022 17:58:14 +0200 > From: Martin Pieuchot <m...@openbsd.org> > > On 04/05/22(Wed) 09:16, Sebastien Marie wrote: > > [...] > > we don't have any vclean label ("vclean (inactive)" or "vclean (active)"), > > so > > vclean() was not called in this timeframe. > > So we are narrowing down the issue: > > 1. A file is opened > 2. Then mmaped > 3. Some of its pages are swapped to disk
Hmm, why does this happen? Is this because the mmap(2) was done using MAP_PRIVATE? But then what's the point of setting UVM_VNODE_CANPERSIST? > 4. The process die, closing the file > 5. The reaper calls uvn_detach() on the vnode which has UVM_VNODE_CANPERSIST > . This release the last reference of the vnode without sync' the pages > -> the vnode ends up on the free list > 6. The page daemon tries to sync the pages, grab a reference on the vnode > which has already been recycled. > > I don't understand the mechanism around UVM_VNODE_CANPERSIST. I looked > for missing uvm_vnp_uncache() and found the following two. I doubt > those are the one triggering the bug because they are in NFS & softdep. > > So my question is should UVM_VNODE_CANPERSIST be cleared at some point > in this scenario? If so, when? > > What is the interaction between this flag and mmap pages which are on > swap? In other words, is it safe to call vrele(9) in uvn_detach() if > uvn_flush() hasn't been called with PGO_FREE|PGO_ALLPAGES? If yes, why? > > What it this flag suppose to say? Why is it always cleared before > VOP_REMOVE() & VOP_RENAME()? > > Index: nfs/nfs_serv.c > =================================================================== > RCS file: /cvs/src/sys/nfs/nfs_serv.c,v > retrieving revision 1.120 > diff -u -p -r1.120 nfs_serv.c > --- nfs/nfs_serv.c 11 Mar 2021 13:31:35 -0000 1.120 > +++ nfs/nfs_serv.c 4 May 2022 15:29:06 -0000 > @@ -1488,6 +1488,9 @@ nfsrv_rename(struct nfsrv_descript *nfsd > error = -1; > out: > if (!error) { > + if (tvp) { > + (void)uvm_vnp_uncache(tvp); > + } > error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, > tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); > } else { > Index: ufs/ffs/ffs_inode.c > =================================================================== > RCS file: /cvs/src/sys/ufs/ffs/ffs_inode.c,v > retrieving revision 1.81 > diff -u -p -r1.81 ffs_inode.c > --- ufs/ffs/ffs_inode.c 12 Dec 2021 09:14:59 -0000 1.81 > +++ ufs/ffs/ffs_inode.c 4 May 2022 15:32:15 -0000 > @@ -172,11 +172,12 @@ ffs_truncate(struct inode *oip, off_t le > if (length > fs->fs_maxfilesize) > return (EFBIG); > > - uvm_vnp_setsize(ovp, length); > oip->i_ci.ci_lasta = oip->i_ci.ci_clen > = oip->i_ci.ci_cstart = oip->i_ci.ci_lastw = 0; > > if (DOINGSOFTDEP(ovp)) { > + uvm_vnp_setsize(ovp, length); > + (void) uvm_vnp_uncache(ovp); > if (length > 0 || softdep_slowdown(ovp)) { > /* > * If a file is only partially truncated, then > >