> 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
> 
> 

Reply via email to