On Tue, May 31, 2022 at 04:40:32PM +0200, Martin Pieuchot wrote:
> Any of you got the chance to try this diff?  Could you reproduce the
> panic with it?

With this diff I could build a release.  It worked twice.

Usually it crashes after a day.  This time it finished release after
30 hours.

bluhm

> > Index: uvm/uvm_vnode.c
> > ===================================================================
> > RCS file: /cvs/src/sys/uvm/uvm_vnode.c,v
> > retrieving revision 1.124
> > diff -u -p -r1.124 uvm_vnode.c
> > --- uvm/uvm_vnode.c 3 May 2022 21:20:35 -0000       1.124
> > +++ uvm/uvm_vnode.c 20 May 2022 09:04:08 -0000
> > @@ -162,12 +162,9 @@ uvn_attach(struct vnode *vp, vm_prot_t a
> >      * add it to the writeable list, and then return.
> >      */
> >     if (uvn->u_flags & UVM_VNODE_VALID) {   /* already active? */
> > +           KASSERT(uvn->u_obj.uo_refs > 0);
> >  
> >             rw_enter(uvn->u_obj.vmobjlock, RW_WRITE);
> > -           /* regain vref if we were persisting */
> > -           if (uvn->u_obj.uo_refs == 0) {
> > -                   vref(vp);
> > -           }
> >             uvn->u_obj.uo_refs++;           /* bump uvn ref! */
> >             rw_exit(uvn->u_obj.vmobjlock);
> >  
> > @@ -234,7 +231,7 @@ uvn_attach(struct vnode *vp, vm_prot_t a
> >     KASSERT(uvn->u_obj.uo_refs == 0);
> >     uvn->u_obj.uo_refs++;
> >     oldflags = uvn->u_flags;
> > -   uvn->u_flags = UVM_VNODE_VALID|UVM_VNODE_CANPERSIST;
> > +   uvn->u_flags = UVM_VNODE_VALID;
> >     uvn->u_nio = 0;
> >     uvn->u_size = used_vnode_size;
> >  
> > @@ -247,7 +244,7 @@ uvn_attach(struct vnode *vp, vm_prot_t a
> >     /*
> >      * add a reference to the vnode.   this reference will stay as long
> >      * as there is a valid mapping of the vnode.   dropped when the
> > -    * reference count goes to zero [and we either free or persist].
> > +    * reference count goes to zero.
> >      */
> >     vref(vp);
> >     if (oldflags & UVM_VNODE_WANTED)
> > @@ -320,16 +317,6 @@ uvn_detach(struct uvm_object *uobj)
> >      */
> >     vp->v_flag &= ~VTEXT;
> >  
> > -   /*
> > -    * we just dropped the last reference to the uvn.   see if we can
> > -    * let it "stick around".
> > -    */
> > -   if (uvn->u_flags & UVM_VNODE_CANPERSIST) {
> > -           /* won't block */
> > -           uvn_flush(uobj, 0, 0, PGO_DEACTIVATE|PGO_ALLPAGES);
> > -           goto out;
> > -   }
> > -
> >     /* its a goner! */
> >     uvn->u_flags |= UVM_VNODE_DYING;
> >  
> > @@ -379,7 +366,6 @@ uvn_detach(struct uvm_object *uobj)
> >     /* wake up any sleepers */
> >     if (oldflags & UVM_VNODE_WANTED)
> >             wakeup(uvn);
> > -out:
> >     rw_exit(uobj->vmobjlock);
> >  
> >     /* drop our reference to the vnode. */
> > @@ -495,8 +481,8 @@ uvm_vnp_terminate(struct vnode *vp)
> >     }
> >  
> >     /*
> > -    * done.   now we free the uvn if its reference count is zero
> > -    * (true if we are zapping a persisting uvn).   however, if we are
> > +    * done.   now we free the uvn if its reference count is zero.
> > +    * however, if we are
> >      * terminating a uvn with active mappings we let it live ... future
> >      * calls down to the vnode layer will fail.
> >      */
> > @@ -504,14 +490,14 @@ uvm_vnp_terminate(struct vnode *vp)
> >     if (uvn->u_obj.uo_refs) {
> >             /*
> >              * uvn must live on it is dead-vnode state until all references
> > -            * are gone.   restore flags.    clear CANPERSIST state.
> > +            * are gone.   restore flags.
> >              */
> >             uvn->u_flags &= ~(UVM_VNODE_DYING|UVM_VNODE_VNISLOCKED|
> > -                 UVM_VNODE_WANTED|UVM_VNODE_CANPERSIST);
> > +                 UVM_VNODE_WANTED);
> >     } else {
> >             /*
> >              * free the uvn now.   note that the vref reference is already
> > -            * gone [it is dropped when we enter the persist state].
> > +            * gone.
> >              */
> >             if (uvn->u_flags & UVM_VNODE_IOSYNCWANTED)
> >                     panic("uvm_vnp_terminate: io sync wanted bit set");
> > @@ -1350,46 +1336,14 @@ uvm_vnp_uncache(struct vnode *vp)
> >     }
> >  
> >     /*
> > -    * we have a valid, non-blocked uvn.   clear persist flag.
> > +    * we have a valid, non-blocked uvn.
> >      * if uvn is currently active we can return now.
> >      */
> > -   uvn->u_flags &= ~UVM_VNODE_CANPERSIST;
> >     if (uvn->u_obj.uo_refs) {
> >             rw_exit(uobj->vmobjlock);
> >             return FALSE;
> >     }
> >  
> > -   /*
> > -    * uvn is currently persisting!   we have to gain a reference to
> > -    * it so that we can call uvn_detach to kill the uvn.
> > -    */
> > -   vref(vp);                       /* seems ok, even with VOP_LOCK */
> > -   uvn->u_obj.uo_refs++;           /* value is now 1 */
> > -   rw_exit(uobj->vmobjlock);
> > -
> > -#ifdef VFSLCKDEBUG
> > -   /*
> > -    * carry over sanity check from old vnode pager: the vnode should
> > -    * be VOP_LOCK'd, and we confirm it here.
> > -    */
> > -   if ((vp->v_flag & VLOCKSWORK) && !VOP_ISLOCKED(vp))
> > -           panic("uvm_vnp_uncache: vnode not locked!");
> > -#endif
> > -
> > -   /*
> > -    * now drop our reference to the vnode.   if we have the sole
> > -    * reference to the vnode then this will cause it to die [as we
> > -    * just cleared the persist flag].   we have to unlock the vnode
> > -    * while we are doing this as it may trigger I/O.
> > -    *
> > -    * XXX: it might be possible for uvn to get reclaimed while we are
> > -    * unlocked causing us to return TRUE when we should not.   we ignore
> > -    * this as a false-positive return value doesn't hurt us.
> > -    */
> > -   VOP_UNLOCK(vp);
> > -   uvn_detach(&uvn->u_obj);
> > -   vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
> > -
> >     return TRUE;
> >  }
> >  
> > @@ -1491,11 +1445,9 @@ uvm_vnp_sync(struct mount *mp)
> >             }
> >  
> >             /*
> > -            * gain reference.   watch out for persisting uvns (need to
> > -            * regain vnode REF).
> > +            * gain reference.
> >              */
> > -           if (uvn->u_obj.uo_refs == 0)
> > -                   vref(vp);
> > +           KASSERT(uvn->u_obj.uo_refs > 0);
> >             uvn->u_obj.uo_refs++;
> >             rw_exit(uvn->u_obj.vmobjlock);
> >  
> > 

Reply via email to