Subject: Re: Now: Fs suspension take 2
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Juergen Hannken-Illjes <hannken@eis.cs.tu-bs.de>
List: tech-kern
Date: 08/18/2006 11:52:06
On Fri, Aug 18, 2006 at 06:08:32PM +0900, YAMAMOTO Takashi wrote:
> > @@ -704,12 +700,22 @@ uvmpd_scan_inactive(struct pglist *pglst
> >  		}
> >  #endif /* defined(READAHEAD_STATS) */
> >  
> >  		if ((p->pqflags & PQ_SWAPBACKED) == 0) {
> > +			struct vnode *vp = (struct vnode *)uobj;
> > +
> > +			if (UVM_OBJ_IS_VNODE(uobj) && fstrans_start(vp->v_mount,
> > +			    FSTRANS_SHARED | FSTRANS_NOWAIT) != 0) {
> > +				uvmexp.pdobscan--;
> > +				simple_unlock(slock);
> > +				continue;
> > +			}
> >  			uvm_unlock_pageq();
> >  			(void) (uobj->pgops->pgo_put)(uobj, p->offset,
> >  			    p->offset + PAGE_SIZE, PGO_CLEANIT|PGO_FREE);
> >  			uvm_lock_pageq();
> > +			if (UVM_OBJ_IS_VNODE(uobj))
> > +				fstrans_done(vp->v_mount);
> >  			if (nextpg &&
> >  			    (nextpg->pqflags & PQ_INACTIVE) == 0) {
> >  				nextpg = TAILQ_FIRST(pglst);
> >  			}
> 
> why is it done here, rather than ffs_putpages or vnode pager?

From here it goes down (with flags == PGO_CLEANIT|PGO_FREE) as

    uobj->pgops->pgo_put -> uvn_put -> VOP_PUTPAGES -> genfs_putpages

Here genfs_putpages is allowed to sleep because flags has PGO_CLEANIT.
This would put uvmpd_scan_inactive() to sleep if there is a suspension on
this vnode leading to out-of-memory deadlocks.

To avoid it we start a FSTRANS_NOWAIT transaction here.
This way we will either succeed and have a valid transaction or
we simply skip this page and try the next one.

-- 
Juergen Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (Germany)