Livelock / softdep_flush "loop"
Peter Holm
peter at holm.cc
Mon Apr 3 19:28:16 UTC 2006
On Sun, Apr 02, 2006 at 08:48:51PM +0000, Tor Egge wrote:
> > > The enclosed patch might help.
> > >
> >
> > I'm testing it right now.
>
> Similarly to the softdepflush process looping in softdep_flush(), the process
> creating a snapshot might loop in ffs_sync().
>
I ran the same test with your first patch for two hours and your
second patch for 7 hours, without seeing any livelocks.
I added snapshots to the test and still did not get any livelocks, but
I'm not certain that this last test covers your change.
- Peter
> - Tor Egge
> Index: sys/ufs/ffs/ffs_softdep.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_softdep.c,v
> retrieving revision 1.193
> diff -u -r1.193 ffs_softdep.c
> --- sys/ufs/ffs/ffs_softdep.c 12 Mar 2006 05:25:16 -0000 1.193
> +++ sys/ufs/ffs/ffs_softdep.c 2 Apr 2006 20:20:15 -0000
> @@ -718,6 +718,7 @@
> {
> struct mount *nmp;
> struct mount *mp;
> + struct ufsmount *ump;
> struct thread *td;
> int remaining;
> int vfslocked;
> @@ -752,7 +753,9 @@
> continue;
> vfslocked = VFS_LOCK_GIANT(mp);
> softdep_process_worklist(mp, 0);
> - remaining += VFSTOUFS(mp)->softdep_on_worklist;
> + ump = VFSTOUFS(mp);
> + remaining += ump->softdep_on_worklist -
> + ump->softdep_on_worklist_inprogress;
> VFS_UNLOCK_GIANT(vfslocked);
> mtx_lock(&mountlist_mtx);
> nmp = TAILQ_NEXT(mp, mnt_list);
> @@ -914,11 +917,17 @@
> if ((flags & LK_NOWAIT) == 0 || wk->wk_type != D_DIRREM)
> break;
> wk->wk_state |= INPROGRESS;
> + ump->softdep_on_worklist_inprogress++;
> FREE_LOCK(&lk);
> ffs_vget(mp, WK_DIRREM(wk)->dm_oldinum,
> LK_NOWAIT | LK_EXCLUSIVE, &vp);
> ACQUIRE_LOCK(&lk);
> wk->wk_state &= ~INPROGRESS;
> + if (--ump->softdep_on_worklist_inprogress == 0 &&
> + ump->softdep_on_worklist_inprogress_req != 0) {
> + ump->softdep_on_worklist_inprogress_req = 0;
> + wakeup(&ump->softdep_on_worklist_inprogress);
> + }
> if (vp != NULL)
> break;
> }
> @@ -6099,6 +6108,17 @@
> VI_LOCK(devvp);
> continue;
> }
> + if (ump->softdep_on_worklist_inprogress != 0) {
> + VI_UNLOCK(devvp);
> + ump->softdep_on_worklist_inprogress_req = 1;
> + msleep(&ump->softdep_on_worklist_inprogress,
> + &lk,
> + (PUSER - 1) | PDROP,
> + "sdipdr" /* soft dep in progress drain */,
> + 0);
> + VI_LOCK(devvp);
> + continue;
> + }
> if (!MNT_ITRYLOCK(mp)) {
> FREE_LOCK(&lk);
> VI_UNLOCK(devvp);
> Index: sys/ufs/ufs/ufsmount.h
> ===================================================================
> RCS file: /home/ncvs/src/sys/ufs/ufs/ufsmount.h,v
> retrieving revision 1.36
> diff -u -r1.36 ufsmount.h
> --- sys/ufs/ufs/ufsmount.h 8 Mar 2006 23:43:39 -0000 1.36
> +++ sys/ufs/ufs/ufsmount.h 2 Apr 2006 20:20:15 -0000
> @@ -76,6 +76,8 @@
> struct workhead softdep_workitem_pending; /* softdep work queue */
> struct worklist *softdep_worklist_tail; /* Tail pointer for above */
> int softdep_on_worklist; /* Items on the worklist */
> + int softdep_on_worklist_inprogress; /* Busy items on worklist */
> + int softdep_on_worklist_inprogress_req;/* Wakeup when not busy */
> int softdep_deps; /* Total dependency count */
> int softdep_accdeps; /* accumulated dep count */
> int softdep_req; /* Wakeup when deps hits 0. */
--
Peter Holm
More information about the freebsd-current
mailing list