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)